From 94b9cb2bbff53371ec18c61a286bb91834f649a3 Mon Sep 17 00:00:00 2001 From: Martin Fouilleul Date: Sat, 19 Aug 2023 14:49:23 +0200 Subject: [PATCH] Auto-formatting with clang-format --- .clang-format | 9 +- ext/.clang-format | 1 + samples/fluid/src/main.c | 925 +- samples/fluid/src/shaders/advect.glsl | 44 +- .../fluid/src/shaders/blit_div_fragment.glsl | 41 +- .../fluid/src/shaders/blit_div_vertex.glsl | 4 +- samples/fluid/src/shaders/blit_fragment.glsl | 4 +- .../src/shaders/blit_residue_fragment.glsl | 81 +- samples/fluid/src/shaders/blit_vertex.glsl | 8 +- samples/fluid/src/shaders/common_vertex.glsl | 4 +- samples/fluid/src/shaders/divergence.glsl | 42 +- samples/fluid/src/shaders/jacobi_step.glsl | 62 +- .../fluid/src/shaders/multigrid_correct.glsl | 54 +- .../shaders/multigrid_restrict_residual.glsl | 66 +- samples/fluid/src/shaders/splat.glsl | 14 +- .../fluid/src/shaders/subtract_pressure.glsl | 40 +- samples/glesTriangle/src/main.c | 96 +- samples/pong/src/main.c | 36 +- samples/ui/src/main.c | 646 +- sketches/atlas/main.c | 143 +- sketches/canvas/main.c | 425 +- sketches/image/main.c | 143 +- sketches/multi_surface/main.c | 175 +- sketches/perf_text/main.c | 654 +- sketches/polygon/main.c | 236 +- sketches/render_thread/main.c | 133 +- sketches/simpleWindow/main.c | 240 +- sketches/smooth_resize/main.c | 291 +- sketches/surface_sharing/main.c | 418 +- sketches/tiger/main.c | 488 +- sketches/tiger/tiger.c | 9713 +++++---- sketches/triangleGL/main.c | 314 +- sketches/triangleGLES/main.c | 224 +- sketches/triangleMetal/main.m | 175 +- sketches/triangleMetal/vertex.h | 14 +- sketches/ui/main.c | 1253 +- src/app/app.c | 246 +- src/app/app.h | 651 +- src/app/app_internal.h | 77 +- src/app/orca_app.c | 2 +- src/app/osx_app.h | 78 +- src/app/osx_app.m | 2667 +-- src/app/win32_app.c | 2067 +- src/app/win32_app.h | 28 +- src/graphics/egl_surface.c | 228 +- src/graphics/egl_surface.h | 6 +- src/graphics/gl_api.h | 1108 +- src/graphics/gl_canvas.c | 3646 ++-- src/graphics/gl_loader.c | 16694 ++++++++-------- src/graphics/gl_loader.h | 4 +- src/graphics/glsl_shaders/backprop.glsl | 62 +- .../glsl_shaders/balance_workgroups.glsl | 19 +- src/graphics/glsl_shaders/blit_fragment.glsl | 4 +- src/graphics/glsl_shaders/blit_vertex.glsl | 10 +- src/graphics/glsl_shaders/common.glsl | 238 +- src/graphics/glsl_shaders/merge.glsl | 287 +- src/graphics/glsl_shaders/path_setup.glsl | 84 +- src/graphics/glsl_shaders/raster.glsl | 356 +- src/graphics/glsl_shaders/segment_setup.glsl | 1228 +- src/graphics/graphics.h | 185 +- src/graphics/graphics_common.c | 2193 +- src/graphics/graphics_common.h | 85 +- src/graphics/graphics_surface.c | 581 +- src/graphics/graphics_surface.h | 155 +- src/graphics/mtl_renderer.h | 118 +- src/graphics/mtl_renderer.m | 3213 +-- src/graphics/mtl_renderer.metal | 2369 +-- src/graphics/mtl_surface.h | 6 +- src/graphics/mtl_surface.m | 343 +- src/graphics/wgl_surface.c | 379 +- src/graphics/wgl_surface.h | 4 +- src/libc-shim/include/assert.h | 8 +- src/libc-shim/include/bits/errno.h | 262 +- src/libc-shim/include/errno.h | 13 +- src/libc-shim/include/float.h | 5 +- src/libc-shim/include/math.h | 135 +- src/libc-shim/include/stdarg.h | 2 +- src/libc-shim/include/stdlib.h | 5 +- src/libc-shim/include/string.h | 16 +- src/libc-shim/src/__cos.c | 26 +- src/libc-shim/src/__cosdf.c | 20 +- src/libc-shim/src/__errno_location.c | 2 +- src/libc-shim/src/__math_invalid.c | 2 +- src/libc-shim/src/__math_invalidf.c | 2 +- src/libc-shim/src/__math_oflow.c | 2 +- src/libc-shim/src/__math_uflow.c | 2 +- src/libc-shim/src/__math_xflow.c | 4 +- src/libc-shim/src/__rem_pio2.c | 334 +- src/libc-shim/src/__rem_pio2_large.c | 1174 +- src/libc-shim/src/__rem_pio2f.c | 111 +- src/libc-shim/src/__sin.c | 30 +- src/libc-shim/src/__sindf.c | 22 +- src/libc-shim/src/abs.c | 2 +- src/libc-shim/src/acos.c | 110 +- src/libc-shim/src/ceil.c | 52 +- src/libc-shim/src/cos.c | 58 +- src/libc-shim/src/cosf.c | 110 +- src/libc-shim/src/exp_data.h | 20 +- src/libc-shim/src/fabs.c | 11 +- src/libc-shim/src/floor.c | 52 +- src/libc-shim/src/fmod.c | 135 +- src/libc-shim/src/libm.h | 158 +- src/libc-shim/src/pow.c | 469 +- src/libc-shim/src/pow_data.h | 20 +- src/libc-shim/src/scalbn.c | 60 +- src/libc-shim/src/sin.c | 60 +- src/libc-shim/src/sinf.c | 106 +- src/libc-shim/src/sqrt.c | 151 +- src/libc-shim/src/sqrt_data.c | 144 +- src/libc-shim/src/sqrtf.c | 130 +- src/libc-shim/src/string.c | 171 +- src/orca.c | 114 +- src/orca.h | 52 +- src/orca.m | 18 +- src/platform/native_debug.c | 158 +- src/platform/orca_clock.c | 4 +- src/platform/orca_debug.c | 115 +- src/platform/orca_malloc.c | 4840 ++--- src/platform/orca_memory.c | 24 +- src/platform/osx_clock.c | 218 +- src/platform/osx_path.m | 49 +- src/platform/platform.h | 108 +- src/platform/platform_clock.h | 57 +- src/platform/platform_debug.c | 46 +- src/platform/platform_debug.h | 26 +- src/platform/platform_io.h | 223 +- src/platform/platform_io_common.c | 115 +- src/platform/platform_io_internal.c | 534 +- src/platform/platform_io_internal.h | 45 +- src/platform/platform_memory.h | 111 +- src/platform/platform_path.c | 128 +- src/platform/platform_path.h | 4 +- src/platform/platform_thread.h | 113 +- src/platform/posix_io.c | 834 +- src/platform/posix_thread.c | 276 +- src/platform/unix_memory.c | 28 +- src/platform/win32_clock.c | 39 +- src/platform/win32_io.c | 851 +- src/platform/win32_memory.c | 34 +- src/platform/win32_path.c | 46 +- src/platform/win32_string_helpers.c | 28 +- src/platform/win32_string_helpers.h | 5 +- src/platform/win32_thread.c | 234 +- src/runtime.c | 1340 +- src/runtime.h | 136 +- src/runtime_io.c | 62 +- src/runtime_memory.c | 72 +- src/ui/input_state.c | 429 +- src/ui/input_state.h | 82 +- src/ui/ui.c | 5599 +++--- src/ui/ui.h | 1112 +- src/util/algebra.c | 48 +- src/util/algebra.h | 4 +- src/util/debug.h | 45 +- src/util/hash.c | 273 +- src/util/hash.h | 23 +- src/util/lists.h | 435 +- src/util/macros.h | 158 +- src/util/memory.c | 274 +- src/util/memory.h | 141 +- src/util/ringbuffer.c | 126 +- src/util/ringbuffer.h | 43 +- src/util/strings.c | 448 +- src/util/strings.h | 210 +- src/util/typedefs.h | 112 +- src/util/utf8.c | 385 +- src/util/utf8.h | 327 +- src/wasmbind/gles_api_bind_manual.c | 1526 +- 168 files changed, 42897 insertions(+), 40823 deletions(-) create mode 100644 ext/.clang-format diff --git a/.clang-format b/.clang-format index e4db128..7b68829 100644 --- a/.clang-format +++ b/.clang-format @@ -1,14 +1,17 @@ AllowAllArgumentsOnNextLine: false BreakBeforeBraces: Allman -ColumnLimit: 0 Cpp11BracedListStyle: false +ColumnLimit: 0 +BreakBeforeBinaryOperators: NonAssignment +AlignOperands: AlignAfterOperator IndentPPDirectives: BeforeHash +IndentCaseLabels: true IndentWidth: 4 +TabWidth: 4 +UseTab: Never LineEnding: LF MaxEmptyLinesToKeep: 1 PointerAlignment: Left SeparateDefinitionBlocks: Always SpaceBeforeParens: Never -TabWidth: 4 -UseTab: Never ReflowComments: false \ No newline at end of file diff --git a/ext/.clang-format b/ext/.clang-format new file mode 100644 index 0000000..e384528 --- /dev/null +++ b/ext/.clang-format @@ -0,0 +1 @@ +DisableFormat: true diff --git a/samples/fluid/src/main.c b/samples/fluid/src/main.c index f805835..c473e65 100644 --- a/samples/fluid/src/main.c +++ b/samples/fluid/src/main.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: main.cpp * @author: Martin Fouilleul @@ -7,113 +7,116 @@ * *****************************************************************/ -#include"orca.h" -#include"math.h" -#include"glsl_shaders.h" +#include "glsl_shaders.h" +#include "math.h" +#include "orca.h" //---------------------------------------------------------------- //NOTE(martin): GL vertex struct and identifiers //---------------------------------------------------------------- -typedef struct Vertex { float x, y; } Vertex; +typedef struct Vertex +{ + float x, y; +} Vertex; typedef struct advect_program { - GLuint prog; + GLuint prog; - GLint pos; - GLint src; - GLint velocity; - GLint delta; - GLint dissipation; + GLint pos; + GLint src; + GLint velocity; + GLint delta; + GLint dissipation; } advect_program; typedef struct div_program { - GLuint prog; - GLint pos; - GLint src; + GLuint prog; + GLint pos; + GLint src; } div_program; typedef struct jacobi_program { - GLuint prog; - GLint pos; - GLint xTex; - GLint bTex; + GLuint prog; + GLint pos; + GLint xTex; + GLint bTex; } jacobi_program; typedef struct blit_residue_program { - GLuint prog; + GLuint prog; - GLint pos; - GLint mvp; - GLint xTex; - GLint bTex; + GLint pos; + GLint mvp; + GLint xTex; + GLint bTex; } blit_residue_program; typedef struct multigrid_restrict_residual_program { - GLuint prog; - GLint pos; - GLint xTex; - GLint bTex; + GLuint prog; + GLint pos; + GLint xTex; + GLint bTex; } multigrid_restrict_residual_program; typedef struct multigrid_correct_program { - GLuint prog; - GLint pos; - GLint src; - GLint error; - GLint invGridSize; + GLuint prog; + GLint pos; + GLint src; + GLint error; + GLint invGridSize; } multigrid_correct_program; typedef struct subtract_program { - GLuint prog; + GLuint prog; - GLint pos; - GLint src; - GLint pressure; - GLint invGridSize; + GLint pos; + GLint src; + GLint pressure; + GLint invGridSize; } subtract_program; typedef struct blit_program { - GLuint prog; + GLuint prog; - GLint pos; - GLint mvp; - GLint gridSize; - GLint tex; + GLint pos; + GLint mvp; + GLint gridSize; + GLint tex; } blit_program; typedef struct splat_program { - GLuint prog; + GLuint prog; - GLint pos; - GLint src; - GLint splatPos; - GLint splatColor; - GLint radius; - GLint additive; - GLint blending; - GLint randomize; + GLint pos; + GLint src; + GLint splatPos; + GLint splatColor; + GLint radius; + GLint additive; + GLint blending; + GLint randomize; } splat_program; typedef struct frame_buffer { - GLuint textures[2]; - GLuint fbos[2]; + GLuint textures[2]; + GLuint fbos[2]; } frame_buffer; advect_program advectProgram; @@ -143,201 +146,199 @@ GLuint vertexBuffer; GLuint compile_shader(const char* vs, const char* fs) { - GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); - glShaderSource(vertexShader, 1, &vs, 0); - glCompileShader(vertexShader); + GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); + glShaderSource(vertexShader, 1, &vs, 0); + glCompileShader(vertexShader); - GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - glShaderSource(fragmentShader, 1, &fs, 0); - glCompileShader(fragmentShader); + GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + glShaderSource(fragmentShader, 1, &fs, 0); + glCompileShader(fragmentShader); - GLuint prog = glCreateProgram(); - glAttachShader(prog, vertexShader); - glAttachShader(prog, fragmentShader); - glLinkProgram(prog); + GLuint prog = glCreateProgram(); + glAttachShader(prog, vertexShader); + glAttachShader(prog, fragmentShader); + glLinkProgram(prog); + //TODO errors + int status = 0; + glGetProgramiv(prog, GL_LINK_STATUS, &status); + if(status != GL_TRUE) + { + oc_log_error("program failed to link: "); + int logSize = 0; + glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logSize); - //TODO errors - int status = 0; - glGetProgramiv(prog, GL_LINK_STATUS, &status); - if(status != GL_TRUE) - { - oc_log_error("program failed to link: "); - int logSize = 0; - glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &logSize); + oc_arena_scope scratch = oc_scratch_begin(); + char* log = oc_arena_push(scratch.arena, logSize); - oc_arena_scope scratch = oc_scratch_begin(); - char* log = oc_arena_push(scratch.arena, logSize); + glGetProgramInfoLog(prog, logSize, 0, log); + oc_log_error("%s\n", log); - glGetProgramInfoLog(prog, logSize, 0, log); - oc_log_error("%s\n", log); + oc_scratch_end(scratch); + } - oc_scratch_end(scratch); - } + int err = glGetError(); + if(err) + { + oc_log_error("gl error %i\n", err); + } - int err = glGetError(); - if(err) - { - oc_log_error("gl error %i\n", err); - } - - return(prog); + return (prog); } void init_advect(advect_program* program) { - oc_log_info("compiling advect..."); - program->prog = compile_shader(glsl_common_vertex, glsl_advect); - program->pos = glGetAttribLocation(program->prog, "pos"); - program->src = glGetUniformLocation(program->prog, "src"); - program->velocity = glGetUniformLocation(program->prog, "velocity"); - program->delta = glGetUniformLocation(program->prog, "delta"); - program->dissipation = glGetUniformLocation(program->prog, "dissipation"); + oc_log_info("compiling advect..."); + program->prog = compile_shader(glsl_common_vertex, glsl_advect); + program->pos = glGetAttribLocation(program->prog, "pos"); + program->src = glGetUniformLocation(program->prog, "src"); + program->velocity = glGetUniformLocation(program->prog, "velocity"); + program->delta = glGetUniformLocation(program->prog, "delta"); + program->dissipation = glGetUniformLocation(program->prog, "dissipation"); } void init_div(div_program* program) { - oc_log_info("compiling div..."); - program->prog = compile_shader(glsl_common_vertex, glsl_divergence); - program->pos = glGetAttribLocation(program->prog, "pos"); - program->src = glGetUniformLocation(program->prog, "src"); + oc_log_info("compiling div..."); + program->prog = compile_shader(glsl_common_vertex, glsl_divergence); + program->pos = glGetAttribLocation(program->prog, "pos"); + program->src = glGetUniformLocation(program->prog, "src"); } void init_jacobi(jacobi_program* program) { - oc_log_info("compiling jacobi..."); - program->prog = compile_shader(glsl_common_vertex, glsl_jacobi_step); - program->pos = glGetAttribLocation(program->prog, "pos"); - program->xTex = glGetUniformLocation(program->prog, "xTex"); - program->bTex = glGetUniformLocation(program->prog, "bTex"); + oc_log_info("compiling jacobi..."); + program->prog = compile_shader(glsl_common_vertex, glsl_jacobi_step); + program->pos = glGetAttribLocation(program->prog, "pos"); + program->xTex = glGetUniformLocation(program->prog, "xTex"); + program->bTex = glGetUniformLocation(program->prog, "bTex"); } void init_multigrid_restrict_residual(multigrid_restrict_residual_program* program) { - oc_log_info("compiling multigrid restrict residual..."); - program->prog = compile_shader(glsl_common_vertex, glsl_multigrid_restrict_residual); - program->pos = glGetAttribLocation(program->prog, "pos"); - program->xTex = glGetUniformLocation(program->prog, "xTex"); - program->bTex = glGetUniformLocation(program->prog, "bTex"); + oc_log_info("compiling multigrid restrict residual..."); + program->prog = compile_shader(glsl_common_vertex, glsl_multigrid_restrict_residual); + program->pos = glGetAttribLocation(program->prog, "pos"); + program->xTex = glGetUniformLocation(program->prog, "xTex"); + program->bTex = glGetUniformLocation(program->prog, "bTex"); } void init_multigrid_correct(multigrid_correct_program* program) { - oc_log_info("compiling multigrid correct..."); - program->prog = compile_shader(glsl_common_vertex, glsl_multigrid_correct); - program->pos = glGetAttribLocation(program->prog, "pos"); - program->src = glGetUniformLocation(program->prog, "src"); - program->error = glGetUniformLocation(program->prog, "error"); - program->invGridSize = glGetUniformLocation(program->prog, "invGridSize"); + oc_log_info("compiling multigrid correct..."); + program->prog = compile_shader(glsl_common_vertex, glsl_multigrid_correct); + program->pos = glGetAttribLocation(program->prog, "pos"); + program->src = glGetUniformLocation(program->prog, "src"); + program->error = glGetUniformLocation(program->prog, "error"); + program->invGridSize = glGetUniformLocation(program->prog, "invGridSize"); } void init_subtract(subtract_program* program) { - oc_log_info("compiling subtract..."); - program->prog = compile_shader(glsl_common_vertex, glsl_subtract_pressure); - program->pos = glGetAttribLocation(program->prog, "pos"); - program->src = glGetUniformLocation(program->prog, "src"); - program->pressure = glGetUniformLocation(program->prog, "pressure"); - program->invGridSize = glGetUniformLocation(program->prog, "invGridSize"); + oc_log_info("compiling subtract..."); + program->prog = compile_shader(glsl_common_vertex, glsl_subtract_pressure); + program->pos = glGetAttribLocation(program->prog, "pos"); + program->src = glGetUniformLocation(program->prog, "src"); + program->pressure = glGetUniformLocation(program->prog, "pressure"); + program->invGridSize = glGetUniformLocation(program->prog, "invGridSize"); } void init_splat(splat_program* program) { - oc_log_info("compiling splat..."); - program->prog = compile_shader(glsl_common_vertex, glsl_splat); - program->pos = glGetAttribLocation(program->prog, "pos"); - program->src = glGetUniformLocation(program->prog, "src"); - program->splatPos = glGetUniformLocation(program->prog, "splatPos"); - program->splatColor = glGetUniformLocation(program->prog, "splatColor"); - program->radius = glGetUniformLocation(program->prog, "radius"); - program->additive = glGetUniformLocation(program->prog, "additive"); - program->blending = glGetUniformLocation(program->prog, "blending"); - program->randomize = glGetUniformLocation(program->prog, "randomize"); + oc_log_info("compiling splat..."); + program->prog = compile_shader(glsl_common_vertex, glsl_splat); + program->pos = glGetAttribLocation(program->prog, "pos"); + program->src = glGetUniformLocation(program->prog, "src"); + program->splatPos = glGetUniformLocation(program->prog, "splatPos"); + program->splatColor = glGetUniformLocation(program->prog, "splatColor"); + program->radius = glGetUniformLocation(program->prog, "radius"); + program->additive = glGetUniformLocation(program->prog, "additive"); + program->blending = glGetUniformLocation(program->prog, "blending"); + program->randomize = glGetUniformLocation(program->prog, "randomize"); } void init_blit(blit_program* program) { - oc_log_info("compiling blit..."); - program->prog = compile_shader(glsl_blit_vertex, glsl_blit_fragment); - program->pos = glGetAttribLocation(program->prog, "pos"); - program->mvp = glGetUniformLocation(program->prog, "mvp"); - program->tex = glGetUniformLocation(program->prog, "tex"); - program->gridSize = glGetUniformLocation(program->prog, "gridSize"); + oc_log_info("compiling blit..."); + program->prog = compile_shader(glsl_blit_vertex, glsl_blit_fragment); + program->pos = glGetAttribLocation(program->prog, "pos"); + program->mvp = glGetUniformLocation(program->prog, "mvp"); + program->tex = glGetUniformLocation(program->prog, "tex"); + program->gridSize = glGetUniformLocation(program->prog, "gridSize"); } void init_blit_div(blit_program* program) { - oc_log_info("compiling blit div..."); - program->prog = compile_shader(glsl_blit_div_vertex, glsl_blit_div_fragment); - program->pos = glGetAttribLocation(program->prog, "pos"); - program->mvp = glGetUniformLocation(program->prog, "mvp"); - program->tex = glGetUniformLocation(program->prog, "tex"); + oc_log_info("compiling blit div..."); + program->prog = compile_shader(glsl_blit_div_vertex, glsl_blit_div_fragment); + program->pos = glGetAttribLocation(program->prog, "pos"); + program->mvp = glGetUniformLocation(program->prog, "mvp"); + program->tex = glGetUniformLocation(program->prog, "tex"); } void init_blit_residue(blit_residue_program* program) { - oc_log_info("compiling blit residue..."); - program->prog = compile_shader(glsl_blit_div_vertex, glsl_blit_residue_fragment); - program->pos = glGetAttribLocation(program->prog, "pos"); - program->mvp = glGetUniformLocation(program->prog, "mvp"); - program->xTex = glGetUniformLocation(program->prog, "xTex"); - program->bTex = glGetUniformLocation(program->prog, "bTex"); + oc_log_info("compiling blit residue..."); + program->prog = compile_shader(glsl_blit_div_vertex, glsl_blit_residue_fragment); + program->pos = glGetAttribLocation(program->prog, "pos"); + program->mvp = glGetUniformLocation(program->prog, "mvp"); + program->xTex = glGetUniformLocation(program->prog, "xTex"); + program->bTex = glGetUniformLocation(program->prog, "bTex"); } - GLuint create_texture(int width, int height, GLenum internalFormat, GLenum format, GLenum type, char* initData) { - GLuint texture; - glGenTextures(1, &texture); - glBindTexture(GL_TEXTURE_2D, texture); - glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, initData); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - return(texture); + GLuint texture; + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format, type, initData); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + return (texture); } GLuint create_fbo(GLuint texture) { - GLuint fbo; - glGenFramebuffers(1, &fbo); - glBindFramebuffer(GL_FRAMEBUFFER, fbo); - glBindTexture(GL_TEXTURE_2D, texture); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); - return(fbo); + GLuint fbo; + glGenFramebuffers(1, &fbo); + glBindFramebuffer(GL_FRAMEBUFFER, fbo); + glBindTexture(GL_TEXTURE_2D, texture); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0); + return (fbo); } void init_frame_buffer(frame_buffer* framebuffer, - int width, + int width, int height, GLenum internalFormat, GLenum format, GLenum type, char* initData) { - for(int i=0; i<2; i++) - { - framebuffer->textures[i] = create_texture(width, height, internalFormat, format, type, initData); - framebuffer->fbos[i] = create_fbo(framebuffer->textures[i]); - } + for(int i = 0; i < 2; i++) + { + framebuffer->textures[i] = create_texture(width, height, internalFormat, format, type, initData); + framebuffer->fbos[i] = create_fbo(framebuffer->textures[i]); + } - GLenum err = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if(err != GL_FRAMEBUFFER_COMPLETE) - { - oc_log_info("Frame buffer incomplete, %i", err); - } + GLenum err = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if(err != GL_FRAMEBUFFER_COMPLETE) + { + oc_log_info("Frame buffer incomplete, %i", err); + } } void frame_buffer_swap(frame_buffer* buffer) { - GLuint tmp = buffer->fbos[0]; - buffer->fbos[0] = buffer->fbos[1]; - buffer->fbos[1] = tmp; + GLuint tmp = buffer->fbos[0]; + buffer->fbos[0] = buffer->fbos[1]; + buffer->fbos[1] = tmp; - tmp = buffer->textures[0]; - buffer->textures[0] = buffer->textures[1]; - buffer->textures[1] = tmp; + tmp = buffer->textures[0]; + buffer->textures[0] = buffer->textures[1]; + buffer->textures[1] = tmp; } //---------------------------------------------------------------- @@ -347,18 +348,18 @@ void frame_buffer_swap(frame_buffer* buffer) #define texWidth (256) #define texHeight (256) -float colorInitData[texWidth][texHeight][4] = {0}; -float velocityInitData[texWidth][texHeight][4] = {0}; +float colorInitData[texWidth][texHeight][4] = { 0 }; +float velocityInitData[texWidth][texHeight][4] = { 0 }; const float EPSILON = 1., - INV_GRID_SIZE = 1./(float)texWidth, - DELTA = 1./120.; + INV_GRID_SIZE = 1. / (float)texWidth, + DELTA = 1. / 120.; const GLenum TEX_INTERNAL_FORMAT = GL_RGBA32F; const GLenum TEX_FORMAT = GL_RGBA; const GLenum TEX_TYPE = GL_FLOAT; -#define square(x) ((x)*(x)) +#define square(x) ((x) * (x)) /* void reset_texture(GLuint texture, float width, float height, char* initData) @@ -393,332 +394,327 @@ void reset() typedef struct mouse_input { - float x; - float y; - float deltaX; - float deltaY; - bool down; + float x; + float y; + float deltaX; + float deltaY; + bool down; } mouse_input; -mouse_input mouseInput = {0}; +mouse_input mouseInput = { 0 }; int frameWidth = 800; int frameHeight = 600; - ORCA_EXPORT void oc_on_mouse_down(int button) { - mouseInput.down = true; + mouseInput.down = true; } ORCA_EXPORT void oc_on_mouse_up(int button) { - mouseInput.down = false; + mouseInput.down = false; } ORCA_EXPORT void oc_on_mouse_move(float x, float y, float dx, float dy) { - mouseInput.x = x * 2; - mouseInput.y = y * 2; - mouseInput.deltaX = dx * 2; - mouseInput.deltaY = dy * 2; + mouseInput.x = x * 2; + mouseInput.y = y * 2; + mouseInput.deltaX = dx * 2; + mouseInput.deltaY = dy * 2; } void init_color_checker() { - for(int i=0; ifbos[1]); + for(int i = 0; i < iterationCount; i++) + { + glBindFramebuffer(GL_FRAMEBUFFER, x->fbos[1]); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, x->textures[0]); - glUniform1i(jacobiProgram.xTex, 0); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, x->textures[0]); + glUniform1i(jacobiProgram.xTex, 0); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, b->textures[0]); - glUniform1i(jacobiProgram.bTex, 1); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, b->textures[0]); + glUniform1i(jacobiProgram.bTex, 1); - glDrawArrays(GL_TRIANGLES, 0, 6); + glDrawArrays(GL_TRIANGLES, 0, 6); - frame_buffer_swap(x); - } + frame_buffer_swap(x); + } } void multigrid_coarsen_residual(frame_buffer* output, frame_buffer* x, frame_buffer* b, float invFineGridSize) { - //NOTE: compute residual and downsample to coarser grid, put result in coarser buffer - glUseProgram(multigridRestrictResidualProgram.prog); - glBindFramebuffer(GL_FRAMEBUFFER, output->fbos[1]); + //NOTE: compute residual and downsample to coarser grid, put result in coarser buffer + glUseProgram(multigridRestrictResidualProgram.prog); + glBindFramebuffer(GL_FRAMEBUFFER, output->fbos[1]); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, x->textures[0]); - glUniform1i(multigridRestrictResidualProgram.xTex, 0); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, x->textures[0]); + glUniform1i(multigridRestrictResidualProgram.xTex, 0); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, b->textures[0]); - glUniform1i(multigridRestrictResidualProgram.bTex, 1); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, b->textures[0]); + glUniform1i(multigridRestrictResidualProgram.bTex, 1); - glDrawArrays(GL_TRIANGLES, 0, 6); + glDrawArrays(GL_TRIANGLES, 0, 6); - frame_buffer_swap(output); + frame_buffer_swap(output); } void multigrid_prolongate_and_correct(frame_buffer* x, frame_buffer* error, float invFineGridSize) { - //NOTE: correct finer pressure - glUseProgram(multigridCorrectProgram.prog); - glBindFramebuffer(GL_FRAMEBUFFER, x->fbos[1]); + //NOTE: correct finer pressure + glUseProgram(multigridCorrectProgram.prog); + glBindFramebuffer(GL_FRAMEBUFFER, x->fbos[1]); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, x->textures[0]); - glUniform1i(multigridCorrectProgram.src, 0); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, x->textures[0]); + glUniform1i(multigridCorrectProgram.src, 0); - glActiveTexture(GL_TEXTURE1); - glBindTexture(GL_TEXTURE_2D, error->textures[0]); - glUniform1i(multigridCorrectProgram.error, 1); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_2D, error->textures[0]); + glUniform1i(multigridCorrectProgram.error, 1); - glUniform1f(multigridCorrectProgram.invGridSize, invFineGridSize); + glUniform1f(multigridCorrectProgram.invGridSize, invFineGridSize); - glDrawArrays(GL_TRIANGLES, 0, 6); + glDrawArrays(GL_TRIANGLES, 0, 6); - frame_buffer_swap(x); + frame_buffer_swap(x); } void multigrid_clear(frame_buffer* error) { - glBindFramebuffer(GL_FRAMEBUFFER, error->fbos[0]); - glClear(GL_COLOR_BUFFER_BIT); + glBindFramebuffer(GL_FRAMEBUFFER, error->fbos[0]); + glClear(GL_COLOR_BUFFER_BIT); } void input_splat(float t) { - //NOTE: apply force and dye - if(mouseInput.down && (mouseInput.deltaX || mouseInput.deltaY)) - { - // account for margin - float margin = 32; + //NOTE: apply force and dye + if(mouseInput.down && (mouseInput.deltaX || mouseInput.deltaY)) + { + // account for margin + float margin = 32; - float offset = margin/texWidth; - float ratio = 1 - 2*margin/texWidth; + float offset = margin / texWidth; + float ratio = 1 - 2 * margin / texWidth; - float splatPosX = (mouseInput.x/frameWidth)*ratio + offset; - float splatPosY = (1 - mouseInput.y/frameHeight)*ratio + offset; + float splatPosX = (mouseInput.x / frameWidth) * ratio + offset; + float splatPosY = (1 - mouseInput.y / frameHeight) * ratio + offset; - float splatVelX = (10000.*DELTA*mouseInput.deltaX/frameWidth)*ratio; - float splatVelY = (-10000.*DELTA*mouseInput.deltaY/frameWidth)*ratio; + float splatVelX = (10000. * DELTA * mouseInput.deltaX / frameWidth) * ratio; + float splatVelY = (-10000. * DELTA * mouseInput.deltaY / frameWidth) * ratio; - float intensity = 100*sqrtf(square(ratio*mouseInput.deltaX/frameWidth) + square(ratio*mouseInput.deltaY/frameHeight)); + float intensity = 100 * sqrtf(square(ratio * mouseInput.deltaX / frameWidth) + square(ratio * mouseInput.deltaY / frameHeight)); - float r = intensity * (sinf(2*M_PI*0.1*t) + 1); - float g = 0.5*intensity * (cosf(2*M_PI*0.1/M_E*t + 654) + 1); - float b = intensity * (sinf(2*M_PI*0.1/M_SQRT2*t + 937) + 1); + float r = intensity * (sinf(2 * M_PI * 0.1 * t) + 1); + float g = 0.5 * intensity * (cosf(2 * M_PI * 0.1 / M_E * t + 654) + 1); + float b = intensity * (sinf(2 * M_PI * 0.1 / M_SQRT2 * t + 937) + 1); - float radius = 0.005; + float radius = 0.005; - apply_splat(splatPosX, splatPosY, radius, splatVelX, splatVelY, r, g, b, false); + apply_splat(splatPosX, splatPosY, radius, splatVelX, splatVelY, r, g, b, false); - mouseInput.deltaX = 0; - mouseInput.deltaY = 0; - } + mouseInput.deltaX = 0; + mouseInput.deltaY = 0; + } } -float testDiv[texWidth/2][texWidth/2][4]; +float testDiv[texWidth / 2][texWidth / 2][4]; oc_surface surface; ORCA_EXPORT void oc_on_init() { - oc_log_info("Hello, world (from C)"); + oc_log_info("Hello, world (from C)"); - surface = oc_surface_gles(); - oc_surface_select(surface); + surface = oc_surface_gles(); + oc_surface_select(surface); -// init_color_checker(); -// init_velocity_vortex(); + // init_color_checker(); + // init_velocity_vortex(); - // init programs - init_advect(&advectProgram); - init_div(&divProgram); - init_jacobi(&jacobiProgram); - init_multigrid_restrict_residual(&multigridRestrictResidualProgram); - init_multigrid_correct(&multigridCorrectProgram); - init_blit_residue(&blitResidueProgram); + // init programs + init_advect(&advectProgram); + init_div(&divProgram); + init_jacobi(&jacobiProgram); + init_multigrid_restrict_residual(&multigridRestrictResidualProgram); + init_multigrid_correct(&multigridCorrectProgram); + init_blit_residue(&blitResidueProgram); - init_subtract(&subtractProgram); - init_splat(&splatProgram); - init_blit(&blitProgram); - init_blit_div(&blitDivProgram); + init_subtract(&subtractProgram); + init_splat(&splatProgram); + init_blit(&blitProgram); + init_blit_div(&blitDivProgram); - // init frame buffers - oc_log_info("create color buffer"); - init_frame_buffer(&colorBuffer, texWidth, texHeight, TEX_INTERNAL_FORMAT, TEX_FORMAT, TEX_TYPE, (char*)colorInitData); - oc_log_info("create velocity buffer"); - init_frame_buffer(&velocityBuffer, texWidth, texHeight, TEX_INTERNAL_FORMAT, TEX_FORMAT, TEX_TYPE, (char*)velocityInitData); + // init frame buffers + oc_log_info("create color buffer"); + init_frame_buffer(&colorBuffer, texWidth, texHeight, TEX_INTERNAL_FORMAT, TEX_FORMAT, TEX_TYPE, (char*)colorInitData); + oc_log_info("create velocity buffer"); + init_frame_buffer(&velocityBuffer, texWidth, texHeight, TEX_INTERNAL_FORMAT, TEX_FORMAT, TEX_TYPE, (char*)velocityInitData); - int gridFactor = 1; - for(int i=0; i= textureSize(src, 0).x - || coord.y < 0 - || coord.y >= textureSize(src, 0).y) - { - return(vec4(0.)); - } - return(texelFetch(src, coord, 0)); + if(coord.x < 0 + || coord.x >= textureSize(src, 0).x + || coord.y < 0 + || coord.y >= textureSize(src, 0).y) + { + return (vec4(0.)); + } + return (texelFetch(src, coord, 0)); } vec4 bilerpSrc(vec2 pos) { - vec2 offset = fract(pos); + vec2 offset = fract(pos); - ivec2 bl = ivec2(floor(pos)); + ivec2 bl = ivec2(floor(pos)); - ivec2 br = bl + ivec2(1, 0); - ivec2 tl = bl + ivec2(0, 1); - ivec2 tr = bl + ivec2(1, 1); + ivec2 br = bl + ivec2(1, 0); + ivec2 tl = bl + ivec2(0, 1); + ivec2 tr = bl + ivec2(1, 1); - vec4 lerpTop = (1.-offset.x)*q(tl) + offset.x*q(tr); - vec4 lerpBottom = (1.-offset.x)*q(bl) + offset.x*q(br); - vec4 result = (1.-offset.y)*lerpBottom + offset.y*lerpTop; + vec4 lerpTop = (1. - offset.x) * q(tl) + offset.x * q(tr); + vec4 lerpBottom = (1. - offset.x) * q(bl) + offset.x * q(br); + vec4 result = (1. - offset.y) * lerpBottom + offset.y * lerpTop; - return(result); + return (result); } void main() { - float texWidth = float(textureSize(velocity, 0).x); + float texWidth = float(textureSize(velocity, 0).x); - ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy)); + ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy)); - vec2 samplePos = vec2(pixelCoord) - texWidth * delta * u(pixelCoord); - fragColor = bilerpSrc(samplePos) / (1. + dissipation*delta); + vec2 samplePos = vec2(pixelCoord) - texWidth * delta * u(pixelCoord); + fragColor = bilerpSrc(samplePos) / (1. + dissipation * delta); } diff --git a/samples/fluid/src/shaders/blit_div_fragment.glsl b/samples/fluid/src/shaders/blit_div_fragment.glsl index 2beaac8..6ff6c36 100644 --- a/samples/fluid/src/shaders/blit_div_fragment.glsl +++ b/samples/fluid/src/shaders/blit_div_fragment.glsl @@ -10,25 +10,34 @@ uniform sampler2D tex; vec3 color_map(float v) { - float logv = log(abs(v))/log(10.0); - float f = floor(logv + 7.0); - float i = floor(4.0*(logv + 7.0 - f)); + float logv = log(abs(v)) / log(10.0); + float f = floor(logv + 7.0); + float i = floor(4.0 * (logv + 7.0 - f)); - if(f < 0.0) return vec3(0.0); - if(f < 1.0) return mix(vec3(1.0, 0.0, 0.0), vec3(1.0), i/4.0); - if(f < 2.0) return mix(vec3(0.0, 1.0, 0.0), vec3(1.0), i/4.0); - if(f < 3.0) return mix(vec3(0.0, 0.0, 1.0), vec3(1.0), i/4.0); - if(f < 4.0) return mix(vec3(1.0, 1.0, 0.0), vec3(1.0), i/4.0); - if(f < 5.0) return mix(vec3(1.0, 0.0, 1.0), vec3(1.0), i/4.0); - if(f < 6.0) return mix(vec3(0.0, 1.0, 1.0), vec3(1.0), i/4.0); - if(f < 7.0) return mix(vec3(1.0, 0.5, 0.0), vec3(1.0), i/4.0); - if(f < 8.0) return mix(vec3(1.0, 1.0, 1.0), vec3(1.0), i/4.0); - return vec3(1.0); + if(f < 0.0) + return vec3(0.0); + if(f < 1.0) + return mix(vec3(1.0, 0.0, 0.0), vec3(1.0), i / 4.0); + if(f < 2.0) + return mix(vec3(0.0, 1.0, 0.0), vec3(1.0), i / 4.0); + if(f < 3.0) + return mix(vec3(0.0, 0.0, 1.0), vec3(1.0), i / 4.0); + if(f < 4.0) + return mix(vec3(1.0, 1.0, 0.0), vec3(1.0), i / 4.0); + if(f < 5.0) + return mix(vec3(1.0, 0.0, 1.0), vec3(1.0), i / 4.0); + if(f < 6.0) + return mix(vec3(0.0, 1.0, 1.0), vec3(1.0), i / 4.0); + if(f < 7.0) + return mix(vec3(1.0, 0.5, 0.0), vec3(1.0), i / 4.0); + if(f < 8.0) + return mix(vec3(1.0, 1.0, 1.0), vec3(1.0), i / 4.0); + return vec3(1.0); } void main() { - ivec2 pixelCoord = ivec2(floor(texCoord.xy * vec2(textureSize(tex, 0).xy))); - float f = texelFetch(tex, pixelCoord, 0).x; - fragColor = vec4(color_map(f), 1.0); + ivec2 pixelCoord = ivec2(floor(texCoord.xy * vec2(textureSize(tex, 0).xy))); + float f = texelFetch(tex, pixelCoord, 0).x; + fragColor = vec4(color_map(f), 1.0); } diff --git a/samples/fluid/src/shaders/blit_div_vertex.glsl b/samples/fluid/src/shaders/blit_div_vertex.glsl index f69dc76..0b4d570 100644 --- a/samples/fluid/src/shaders/blit_div_vertex.glsl +++ b/samples/fluid/src/shaders/blit_div_vertex.glsl @@ -9,6 +9,6 @@ uniform mat4 mvp; void main() { - texCoord = 0.5*(pos + vec2(1,1)); - gl_Position = mvp * vec4(pos, 0, 1); + texCoord = 0.5 * (pos + vec2(1, 1)); + gl_Position = mvp * vec4(pos, 0, 1); } diff --git a/samples/fluid/src/shaders/blit_fragment.glsl b/samples/fluid/src/shaders/blit_fragment.glsl index 4e905a3..00a471e 100644 --- a/samples/fluid/src/shaders/blit_fragment.glsl +++ b/samples/fluid/src/shaders/blit_fragment.glsl @@ -10,6 +10,6 @@ uniform sampler2D tex; void main() { - fragColor = texture(tex, texCoord); - fragColor.a = 1.0; + fragColor = texture(tex, texCoord); + fragColor.a = 1.0; } diff --git a/samples/fluid/src/shaders/blit_residue_fragment.glsl b/samples/fluid/src/shaders/blit_residue_fragment.glsl index f630f41..4353a0e 100644 --- a/samples/fluid/src/shaders/blit_residue_fragment.glsl +++ b/samples/fluid/src/shaders/blit_residue_fragment.glsl @@ -11,55 +11,64 @@ uniform sampler2D bTex; float x(ivec2 coord) { - if( coord.x <= 0 - || coord.x >= textureSize(xTex, 0).x - || coord.y <= 0 - || coord.y >= textureSize(xTex, 0).y) - { - return(0.); - } - return(texelFetch(xTex, coord, 0).x); + if(coord.x <= 0 + || coord.x >= textureSize(xTex, 0).x + || coord.y <= 0 + || coord.y >= textureSize(xTex, 0).y) + { + return (0.); + } + return (texelFetch(xTex, coord, 0).x); } float b(ivec2 coord) { - if( coord.x <= 0 - || coord.x >= textureSize(bTex, 0).x - || coord.y <= 0 - || coord.y >= textureSize(bTex, 0).y) - { - return(0.); - } - return(texelFetch(bTex, coord, 0).x); + if(coord.x <= 0 + || coord.x >= textureSize(bTex, 0).x + || coord.y <= 0 + || coord.y >= textureSize(bTex, 0).y) + { + return (0.); + } + return (texelFetch(bTex, coord, 0).x); } vec3 color_map(float v) { - float logv = log(abs(v))/log(10.0); - float f = floor(logv + 7.0); - float i = floor(4.0*(logv + 7.0 - f)); + float logv = log(abs(v)) / log(10.0); + float f = floor(logv + 7.0); + float i = floor(4.0 * (logv + 7.0 - f)); - if(f < 0.0) return vec3(0.0); - if(f < 1.0) return mix(vec3(1.0, 0.0, 0.0), vec3(1.0), i/4.0); - if(f < 2.0) return mix(vec3(0.0, 1.0, 0.0), vec3(1.0), i/4.0); - if(f < 3.0) return mix(vec3(0.0, 0.0, 1.0), vec3(1.0), i/4.0); - if(f < 4.0) return mix(vec3(1.0, 1.0, 0.0), vec3(1.0), i/4.0); - if(f < 5.0) return mix(vec3(1.0, 0.0, 1.0), vec3(1.0), i/4.0); - if(f < 6.0) return mix(vec3(0.0, 1.0, 1.0), vec3(1.0), i/4.0); - if(f < 7.0) return mix(vec3(1.0, 0.5, 0.0), vec3(1.0), i/4.0); - if(f < 8.0) return mix(vec3(1.0, 1.0, 1.0), vec3(1.0), i/4.0); - return vec3(1.0); + if(f < 0.0) + return vec3(0.0); + if(f < 1.0) + return mix(vec3(1.0, 0.0, 0.0), vec3(1.0), i / 4.0); + if(f < 2.0) + return mix(vec3(0.0, 1.0, 0.0), vec3(1.0), i / 4.0); + if(f < 3.0) + return mix(vec3(0.0, 0.0, 1.0), vec3(1.0), i / 4.0); + if(f < 4.0) + return mix(vec3(1.0, 1.0, 0.0), vec3(1.0), i / 4.0); + if(f < 5.0) + return mix(vec3(1.0, 0.0, 1.0), vec3(1.0), i / 4.0); + if(f < 6.0) + return mix(vec3(0.0, 1.0, 1.0), vec3(1.0), i / 4.0); + if(f < 7.0) + return mix(vec3(1.0, 0.5, 0.0), vec3(1.0), i / 4.0); + if(f < 8.0) + return mix(vec3(1.0, 1.0, 1.0), vec3(1.0), i / 4.0); + return vec3(1.0); } void main() { - ivec2 pixelCoord = ivec2(floor(texCoord.xy * vec2(textureSize(xTex, 0).xy))); + ivec2 pixelCoord = ivec2(floor(texCoord.xy * vec2(textureSize(xTex, 0).xy))); - float tl = x(pixelCoord + ivec2(-1, 1)); - float tr = x(pixelCoord + ivec2(1, 1)); - float bl = x(pixelCoord + ivec2(-1, -1)); - float br = x(pixelCoord + ivec2(1, -1)); + float tl = x(pixelCoord + ivec2(-1, 1)); + float tr = x(pixelCoord + ivec2(1, 1)); + float bl = x(pixelCoord + ivec2(-1, -1)); + float br = x(pixelCoord + ivec2(1, -1)); - float residue = b(pixelCoord) - (-tl - tr - bl - br + 4.*x(pixelCoord)); - fragColor = vec4(color_map(residue), 1); + float residue = b(pixelCoord) - (-tl - tr - bl - br + 4. * x(pixelCoord)); + fragColor = vec4(color_map(residue), 1); } diff --git a/samples/fluid/src/shaders/blit_vertex.glsl b/samples/fluid/src/shaders/blit_vertex.glsl index d397a76..10b32f7 100644 --- a/samples/fluid/src/shaders/blit_vertex.glsl +++ b/samples/fluid/src/shaders/blit_vertex.glsl @@ -10,9 +10,9 @@ uniform ivec2 gridSize; void main() { - float margin = 32.; - float ratio = 1. - 2.*margin/float(gridSize.x); + float margin = 32.; + float ratio = 1. - 2. * margin / float(gridSize.x); - texCoord = margin/float(gridSize.x) + ratio*(0.5*(pos + vec2(1,1))); - gl_Position = mvp * vec4(pos, 0, 1); + texCoord = margin / float(gridSize.x) + ratio * (0.5 * (pos + vec2(1, 1))); + gl_Position = mvp * vec4(pos, 0, 1); } diff --git a/samples/fluid/src/shaders/common_vertex.glsl b/samples/fluid/src/shaders/common_vertex.glsl index 1dd2519..7ee17c3 100644 --- a/samples/fluid/src/shaders/common_vertex.glsl +++ b/samples/fluid/src/shaders/common_vertex.glsl @@ -7,6 +7,6 @@ out vec2 texCoord; void main() { - texCoord = 0.5*(pos + vec2(1,1)); - gl_Position = vec4(pos, 0, 1); + texCoord = 0.5 * (pos + vec2(1, 1)); + gl_Position = vec4(pos, 0, 1); } diff --git a/samples/fluid/src/shaders/divergence.glsl b/samples/fluid/src/shaders/divergence.glsl index 8b23781..e5d431e 100644 --- a/samples/fluid/src/shaders/divergence.glsl +++ b/samples/fluid/src/shaders/divergence.glsl @@ -10,32 +10,32 @@ uniform sampler2D src; vec2 u(ivec2 coord) { - return(texelFetch(src, coord, 0).xy); + return (texelFetch(src, coord, 0).xy); } void main() { - ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy)); + ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy)); - if( pixelCoord.x <= 0 - || pixelCoord.x >= textureSize(src, 0).x - || pixelCoord.y <= 0 - || pixelCoord.y >= textureSize(src, 0).y) - { - fragColor = vec4(0, 0, 0, 1); - } - else - { - vec2 tl = u(pixelCoord + ivec2(-1, 0)); - vec2 tr = u(pixelCoord); - vec2 bl = u(pixelCoord + ivec2(-1, -1)); - vec2 br = u(pixelCoord + ivec2(0, -1)); + if(pixelCoord.x <= 0 + || pixelCoord.x >= textureSize(src, 0).x + || pixelCoord.y <= 0 + || pixelCoord.y >= textureSize(src, 0).y) + { + fragColor = vec4(0, 0, 0, 1); + } + else + { + vec2 tl = u(pixelCoord + ivec2(-1, 0)); + vec2 tr = u(pixelCoord); + vec2 bl = u(pixelCoord + ivec2(-1, -1)); + vec2 br = u(pixelCoord + ivec2(0, -1)); - float r = (tr.x + br.x)/2.; - float l = (tl.x + bl.x)/2.; - float t = (tl.y + tr.y)/2.; - float b = (bl.y + br.y)/2.; + float r = (tr.x + br.x) / 2.; + float l = (tl.x + bl.x) / 2.; + float t = (tl.y + tr.y) / 2.; + float b = (bl.y + br.y) / 2.; - fragColor = vec4(-2.*(r - l + t - b), 0, 0, 1); - } + fragColor = vec4(-2. * (r - l + t - b), 0, 0, 1); + } } diff --git a/samples/fluid/src/shaders/jacobi_step.glsl b/samples/fluid/src/shaders/jacobi_step.glsl index 35418b9..5e7c9e5 100644 --- a/samples/fluid/src/shaders/jacobi_step.glsl +++ b/samples/fluid/src/shaders/jacobi_step.glsl @@ -11,45 +11,45 @@ uniform sampler2D bTex; float x(ivec2 coord) { - if( coord.x <= 0 - || coord.x >= textureSize(xTex, 0).x - || coord.y <= 0 - || coord.y >= textureSize(xTex, 0).y) - { - return(0.); - } - return(texelFetch(xTex, coord, 0).x); + if(coord.x <= 0 + || coord.x >= textureSize(xTex, 0).x + || coord.y <= 0 + || coord.y >= textureSize(xTex, 0).y) + { + return (0.); + } + return (texelFetch(xTex, coord, 0).x); } float b(ivec2 coord) { - if( coord.x <= 0 - || coord.x >= textureSize(bTex, 0).x - || coord.y <= 0 - || coord.y >= textureSize(bTex, 0).y) - { - return(0.); - } - return(texelFetch(bTex, coord, 0).x); + if(coord.x <= 0 + || coord.x >= textureSize(bTex, 0).x + || coord.y <= 0 + || coord.y >= textureSize(bTex, 0).y) + { + return (0.); + } + return (texelFetch(bTex, coord, 0).x); } void main() { - ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy)); + ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy)); - if( pixelCoord.x <= 0 - || pixelCoord.y <= 0) - { - fragColor = vec4(0, 0, 0, 1); - } - else - { - float tl = x(pixelCoord + ivec2(-1, 1)); - float tr = x(pixelCoord + ivec2(1, 1)); - float bl = x(pixelCoord + ivec2(-1, -1)); - float br = x(pixelCoord + ivec2(1, -1)); + if(pixelCoord.x <= 0 + || pixelCoord.y <= 0) + { + fragColor = vec4(0, 0, 0, 1); + } + else + { + float tl = x(pixelCoord + ivec2(-1, 1)); + float tr = x(pixelCoord + ivec2(1, 1)); + float bl = x(pixelCoord + ivec2(-1, -1)); + float br = x(pixelCoord + ivec2(1, -1)); - float jacobi = (tl + tr + bl + br + b(pixelCoord))/4.; - fragColor = vec4(jacobi, 0, 0, 1); - } + float jacobi = (tl + tr + bl + br + b(pixelCoord)) / 4.; + fragColor = vec4(jacobi, 0, 0, 1); + } } diff --git a/samples/fluid/src/shaders/multigrid_correct.glsl b/samples/fluid/src/shaders/multigrid_correct.glsl index 1d59ec7..dc0372f 100644 --- a/samples/fluid/src/shaders/multigrid_correct.glsl +++ b/samples/fluid/src/shaders/multigrid_correct.glsl @@ -12,42 +12,42 @@ uniform float invGridSize; float e(ivec2 coord) { - if( coord.x <= 0 - || coord.x >= textureSize(error, 0).x - || coord.y <= 0 - || coord.y >= textureSize(error, 0).y) - { - return(0.); - } - return(texelFetch(error, coord, 0).x); + if(coord.x <= 0 + || coord.x >= textureSize(error, 0).x + || coord.y <= 0 + || coord.y >= textureSize(error, 0).y) + { + return (0.); + } + return (texelFetch(error, coord, 0).x); } float p(ivec2 coord) { - if( coord.x <= 0 - || coord.x >= textureSize(src, 0).x - || coord.y <= 0 - || coord.y >= textureSize(src, 0).y) - { - return(0.); - } - return(texelFetch(src, coord, 0).x); + if(coord.x <= 0 + || coord.x >= textureSize(src, 0).x + || coord.y <= 0 + || coord.y >= textureSize(src, 0).y) + { + return (0.); + } + return (texelFetch(src, coord, 0).x); } void main() { - ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy)); - vec2 coarseCoord = vec2(pixelCoord)/2.; - vec2 offset = fract(coarseCoord); + ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy)); + vec2 coarseCoord = vec2(pixelCoord) / 2.; + vec2 offset = fract(coarseCoord); - ivec2 bl = ivec2(floor(coarseCoord)); - ivec2 br = bl + ivec2(1, 0); - ivec2 tl = bl + ivec2(0, 1); - ivec2 tr = bl + ivec2(1, 1); + ivec2 bl = ivec2(floor(coarseCoord)); + ivec2 br = bl + ivec2(1, 0); + ivec2 tl = bl + ivec2(0, 1); + ivec2 tr = bl + ivec2(1, 1); - float topLerp = (1.-offset.x)*e(tl)+ offset.x*e(tr); - float bottomLerp = (1.-offset.x)*e(bl) + offset.x*e(br); - float bilerpError = (1.-offset.y)*bottomLerp + offset.y*topLerp; + float topLerp = (1. - offset.x) * e(tl) + offset.x * e(tr); + float bottomLerp = (1. - offset.x) * e(bl) + offset.x * e(br); + float bilerpError = (1. - offset.y) * bottomLerp + offset.y * topLerp; - fragColor = vec4(p(pixelCoord) + bilerpError, 0, 0, 1); + fragColor = vec4(p(pixelCoord) + bilerpError, 0, 0, 1); } diff --git a/samples/fluid/src/shaders/multigrid_restrict_residual.glsl b/samples/fluid/src/shaders/multigrid_restrict_residual.glsl index bea8b9c..6de844d 100644 --- a/samples/fluid/src/shaders/multigrid_restrict_residual.glsl +++ b/samples/fluid/src/shaders/multigrid_restrict_residual.glsl @@ -11,51 +11,51 @@ uniform sampler2D bTex; float x(ivec2 coord) { - if( coord.x <= 0 - || coord.x >= textureSize(xTex, 0).x - || coord.y <= 0 - || coord.y >= textureSize(xTex, 0).y) - { - return(0.); - } - return(texelFetch(xTex, coord, 0).x); + if(coord.x <= 0 + || coord.x >= textureSize(xTex, 0).x + || coord.y <= 0 + || coord.y >= textureSize(xTex, 0).y) + { + return (0.); + } + return (texelFetch(xTex, coord, 0).x); } float b(ivec2 coord) { - if( coord.x <= 0 - || coord.x >= textureSize(bTex, 0).x - || coord.y <= 0 - || coord.y >= textureSize(bTex, 0).y) - { - return(0.); - } - return(texelFetch(bTex, coord, 0).x); + if(coord.x <= 0 + || coord.x >= textureSize(bTex, 0).x + || coord.y <= 0 + || coord.y >= textureSize(bTex, 0).y) + { + return (0.); + } + return (texelFetch(bTex, coord, 0).x); } float residual(ivec2 coord) { - ivec2 vr = coord + ivec2(1, 0); - ivec2 vl = coord - ivec2(1, 0); - ivec2 vt = coord + ivec2(0, 1); - ivec2 vb = coord - ivec2(0, 1); + ivec2 vr = coord + ivec2(1, 0); + ivec2 vl = coord - ivec2(1, 0); + ivec2 vt = coord + ivec2(0, 1); + ivec2 vb = coord - ivec2(0, 1); - return((x(vl) + x(vr) + x(vt) + x(vb) + b(coord) - 4.*x(coord))*4.); + return ((x(vl) + x(vr) + x(vt) + x(vb) + b(coord) - 4. * x(coord)) * 4.); } void main() { - ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy)); + ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy)); - float restricted = residual(2*pixelCoord + ivec2(-1, -1)) - + residual(2*pixelCoord + ivec2(1, -1)) - + residual(2*pixelCoord + ivec2(1, 1)) - + residual(2*pixelCoord + ivec2(-1, 1)) - + 2.*residual(2*pixelCoord + ivec2(-1, 0)) - + 2.*residual(2*pixelCoord + ivec2(1, 0)) - + 2.*residual(2*pixelCoord + ivec2(0, -1)) - + 2.*residual(2*pixelCoord + ivec2(0, 1)) - + 4.*residual(2*pixelCoord); - restricted /= 16.; - fragColor = vec4(restricted, 0, 0, 1); + float restricted = residual(2 * pixelCoord + ivec2(-1, -1)) + + residual(2 * pixelCoord + ivec2(1, -1)) + + residual(2 * pixelCoord + ivec2(1, 1)) + + residual(2 * pixelCoord + ivec2(-1, 1)) + + 2. * residual(2 * pixelCoord + ivec2(-1, 0)) + + 2. * residual(2 * pixelCoord + ivec2(1, 0)) + + 2. * residual(2 * pixelCoord + ivec2(0, -1)) + + 2. * residual(2 * pixelCoord + ivec2(0, 1)) + + 4. * residual(2 * pixelCoord); + restricted /= 16.; + fragColor = vec4(restricted, 0, 0, 1); } diff --git a/samples/fluid/src/shaders/splat.glsl b/samples/fluid/src/shaders/splat.glsl index 34a1347..83a2fea 100644 --- a/samples/fluid/src/shaders/splat.glsl +++ b/samples/fluid/src/shaders/splat.glsl @@ -17,13 +17,13 @@ uniform float randomize; void main() { - float d2 = dot(texCoord - splatPos, texCoord - splatPos); - float intensity = exp(-10.*d2/radius); - vec2 force = splatColor.xy; + float d2 = dot(texCoord - splatPos, texCoord - splatPos); + float intensity = exp(-10. * d2 / radius); + vec2 force = splatColor.xy; - vec3 u = texture(src, texCoord).xyz; - vec3 uAdd = u + intensity*splatColor.xyz; - vec3 uBlend = u*(1.-intensity) + intensity * splatColor; + vec3 u = texture(src, texCoord).xyz; + vec3 uAdd = u + intensity * splatColor.xyz; + vec3 uBlend = u * (1. - intensity) + intensity * splatColor; - fragColor = vec4(uAdd*additive + uBlend*blending, 1); + fragColor = vec4(uAdd * additive + uBlend * blending, 1); } diff --git a/samples/fluid/src/shaders/subtract_pressure.glsl b/samples/fluid/src/shaders/subtract_pressure.glsl index 7905df9..6855bef 100644 --- a/samples/fluid/src/shaders/subtract_pressure.glsl +++ b/samples/fluid/src/shaders/subtract_pressure.glsl @@ -12,36 +12,36 @@ uniform float invGridSize; vec2 u(ivec2 coord) { - return(texelFetch(src, coord, 0).xy); + return (texelFetch(src, coord, 0).xy); } float p(ivec2 coord) { - if( coord.x <= 0 - || coord.x >= textureSize(pressure, 0).x - || coord.y <= 0 - || coord.y >= textureSize(pressure, 0).y) - { - return(0.); - } - return(texelFetch(pressure, coord, 0).x); + if(coord.x <= 0 + || coord.x >= textureSize(pressure, 0).x + || coord.y <= 0 + || coord.y >= textureSize(pressure, 0).y) + { + return (0.); + } + return (texelFetch(pressure, coord, 0).x); } void main() { - ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy)); + ivec2 pixelCoord = ivec2(floor(gl_FragCoord.xy)); - float tl = p(pixelCoord + ivec2(0, 1)); - float tr = p(pixelCoord + ivec2(1, 1)); - float bl = p(pixelCoord); - float br = p(pixelCoord + ivec2(1, 0)); + float tl = p(pixelCoord + ivec2(0, 1)); + float tr = p(pixelCoord + ivec2(1, 1)); + float bl = p(pixelCoord); + float br = p(pixelCoord + ivec2(1, 0)); - float r = (tr + br)/2.; - float l = (tl + bl)/2.; - float t = (tl + tr)/2.; - float b = (bl + br)/2.; + float r = (tr + br) / 2.; + float l = (tl + bl) / 2.; + float t = (tl + tr) / 2.; + float b = (bl + br) / 2.; - vec2 gradP = vec2(r - l, t - b); + vec2 gradP = vec2(r - l, t - b); - fragColor = vec4(u(pixelCoord) - gradP, 0, 1); + fragColor = vec4(u(pixelCoord) - gradP, 0, 1); } diff --git a/samples/glesTriangle/src/main.c b/samples/glesTriangle/src/main.c index 00e80c2..2f4501c 100644 --- a/samples/glesTriangle/src/main.c +++ b/samples/glesTriangle/src/main.c @@ -2,37 +2,37 @@ #include -oc_vec2 frameSize = {100, 100}; +oc_vec2 frameSize = { 100, 100 }; oc_surface surface; unsigned int program; const char* vshaderSource = - "attribute vec4 vPosition;\n" - "uniform mat4 transform;\n" - "void main()\n" - "{\n" - " gl_Position = transform*vPosition;\n" - "}\n"; + "attribute vec4 vPosition;\n" + "uniform mat4 transform;\n" + "void main()\n" + "{\n" + " gl_Position = transform*vPosition;\n" + "}\n"; const char* fshaderSource = - "precision mediump float;\n" - "void main()\n" - "{\n" - " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" - "}\n"; + "precision mediump float;\n" + "void main()\n" + "{\n" + " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" + "}\n"; void compile_shader(GLuint shader, const char* source) { - glShaderSource(shader, 1, &source, 0); - glCompileShader(shader); + glShaderSource(shader, 1, &source, 0); + glCompileShader(shader); - int err = glGetError(); - if(err) - { - oc_log_info("gl error"); - } + int err = glGetError(); + if(err) + { + oc_log_info("gl error"); + } } ORCA_EXPORT void oc_on_init(void) @@ -45,32 +45,32 @@ ORCA_EXPORT void oc_on_init(void) int extensionCount = 0; glGetIntegerv(GL_NUM_EXTENSIONS, &extensionCount); - for(int i=0; i -#include -#include +#include +#include +#include #define _USE_MATH_DEFINES //NOTE: necessary for MSVC -#include +#include -#include"milepost.h" +#include "milepost.h" int main() { - mp_init(); - mp_clock_init(); //TODO put that in mp_init()? + mp_init(); + mp_clock_init(); //TODO put that in mp_init()? - mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610}; - mp_window window = mp_window_create(windowRect, "test", 0); + mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 }; + mp_window window = mp_window_create(windowRect, "test", 0); - mp_rect contentRect = mp_window_get_content_rect(window); + mp_rect contentRect = mp_window_get_content_rect(window); - //NOTE: create surface - mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS); - if(mg_surface_is_nil(surface)) - { - log_error("couldn't create surface\n"); - return(-1); - } - mg_surface_swap_interval(surface, 0); + //NOTE: create surface + mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS); + if(mg_surface_is_nil(surface)) + { + log_error("couldn't create surface\n"); + return (-1); + } + mg_surface_swap_interval(surface, 0); - //NOTE: create canvas - mg_canvas canvas = mg_canvas_create(); - if(mg_canvas_is_nil(canvas)) - { - log_error("Error: couldn't create canvas\n"); - return(-1); - } + //NOTE: create canvas + mg_canvas canvas = mg_canvas_create(); + if(mg_canvas_is_nil(canvas)) + { + log_error("Error: couldn't create canvas\n"); + return (-1); + } - //NOTE: create atlas - mem_arena permanentArena = {0}; - mem_arena_init(&permanentArena); + //NOTE: create atlas + mem_arena permanentArena = { 0 }; + mem_arena_init(&permanentArena); - mg_rect_atlas* atlas = mg_rect_atlas_create(&permanentArena, 16000, 16000); - mg_image atlasImage = mg_image_create(surface, 16000, 16000); + mg_rect_atlas* atlas = mg_rect_atlas_create(&permanentArena, 16000, 16000); + mg_image atlasImage = mg_image_create(surface, 16000, 16000); - str8 path1 = path_executable_relative(mem_scratch(), STR8("../../sketches/resources/triceratops.png")); - str8 path2 = path_executable_relative(mem_scratch(), STR8("../../sketches/resources/Top512.png")); + str8 path1 = path_executable_relative(mem_scratch(), STR8("../../sketches/resources/triceratops.png")); + str8 path2 = path_executable_relative(mem_scratch(), STR8("../../sketches/resources/Top512.png")); - mg_image_region image1 = mg_image_atlas_alloc_from_file(atlas, atlasImage, path1, false); - mg_image_region image2 = mg_image_atlas_alloc_from_file(atlas, atlasImage, path2, false); + mg_image_region image1 = mg_image_atlas_alloc_from_file(atlas, atlasImage, path1, false); + mg_image_region image2 = mg_image_atlas_alloc_from_file(atlas, atlasImage, path2, false); - // start app - mp_window_bring_to_front(window); - mp_window_focus(window); + // start app + mp_window_bring_to_front(window); + mp_window_focus(window); - while(!mp_should_quit()) - { - mp_pump_events(0); - mp_event* event = 0; - while((event = mp_next_event(mem_scratch())) != 0) - { - switch(event->type) - { - case MP_EVENT_WINDOW_CLOSE: - { - mp_request_quit(); - } break; + while(!mp_should_quit()) + { + mp_pump_events(0); + mp_event* event = 0; + while((event = mp_next_event(mem_scratch())) != 0) + { + switch(event->type) + { + case MP_EVENT_WINDOW_CLOSE: + { + mp_request_quit(); + } + break; - default: - break; - } - } + default: + break; + } + } - mg_surface_prepare(surface); + mg_surface_prepare(surface); - mg_set_color_rgba(0, 1, 1, 1); - mg_clear(); + mg_set_color_rgba(0, 1, 1, 1); + mg_clear(); - mg_set_color_rgba(1, 1, 1, 1); + mg_set_color_rgba(1, 1, 1, 1); - mg_image_draw_region(image1.image, image1.rect, (mp_rect){100, 100, 300, 300}); - mg_image_draw_region(image2.image, image2.rect, (mp_rect){300, 200, 300, 300}); + mg_image_draw_region(image1.image, image1.rect, (mp_rect){ 100, 100, 300, 300 }); + mg_image_draw_region(image2.image, image2.rect, (mp_rect){ 300, 200, 300, 300 }); - mg_render(surface, canvas); - mg_surface_present(surface); + mg_render(surface, canvas); + mg_surface_present(surface); - mem_arena_clear(mem_scratch()); - } + mem_arena_clear(mem_scratch()); + } - mg_image_atlas_recycle(atlas, image1); - mg_image_atlas_recycle(atlas, image2); + mg_image_atlas_recycle(atlas, image1); + mg_image_atlas_recycle(atlas, image2); - mg_canvas_destroy(canvas); - mg_surface_destroy(surface); - mp_window_destroy(window); + mg_canvas_destroy(canvas); + mg_surface_destroy(surface); + mp_window_destroy(window); - mp_terminate(); + mp_terminate(); - return(0); + return (0); } diff --git a/sketches/canvas/main.c b/sketches/canvas/main.c index 1596add..32e302b 100644 --- a/sketches/canvas/main.c +++ b/sketches/canvas/main.c @@ -1,218 +1,219 @@ -/************************************************************//** +/************************************************************/ /** * * @file: main.cpp * @author: Martin Fouilleul * @date: 30/07/2022 * @revision: * -*****************************************************************/ -#include -#include -#include -#include - -#define _USE_MATH_DEFINES //NOTE: necessary for MSVC -#include - -#include"milepost.h" - -#define LOG_SUBSYSTEM "Main" - - -mg_font create_font() -{ - //NOTE(martin): create font - str8 fontPath = path_executable_relative(mem_scratch(), STR8("../resources/OpenSansLatinSubset.ttf")); - char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath); - - FILE* fontFile = fopen(fontPathCString, "r"); - if(!fontFile) - { - log_error("Could not load font file '%s': %s\n", fontPathCString, strerror(errno)); - return(mg_font_nil()); - } - unsigned char* fontData = 0; - fseek(fontFile, 0, SEEK_END); - u32 fontDataSize = ftell(fontFile); - rewind(fontFile); - fontData = (unsigned char*)malloc(fontDataSize); - fread(fontData, 1, fontDataSize, fontFile); - fclose(fontFile); - - unicode_range ranges[5] = {UNICODE_RANGE_BASIC_LATIN, - UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT, - UNICODE_RANGE_LATIN_EXTENDED_A, - UNICODE_RANGE_LATIN_EXTENDED_B, - UNICODE_RANGE_SPECIALS}; - - mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges); - free(fontData); - - return(font); -} - -int main() -{ - mp_init(); - mp_clock_init(); //TODO put that in mp_init()? - - mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610}; - mp_window window = mp_window_create(windowRect, "test", 0); - - mp_rect contentRect = mp_window_get_content_rect(window); - - //NOTE: create surface - mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS); - if(mg_surface_is_nil(surface)) - { - printf("Error: couldn't create surface\n"); - return(-1); - } - mg_surface_swap_interval(surface, 0); - - mg_canvas canvas = mg_canvas_create(); - - if(mg_canvas_is_nil(canvas)) - { - printf("Error: couldn't create canvas\n"); - return(-1); - } - - mg_font font = create_font(); - - // start app - mp_window_bring_to_front(window); - mp_window_focus(window); - - f32 x = 400, y = 300; - f32 speed = 0; - f32 dx = speed, dy = speed; - f64 frameTime = 0; - - while(!mp_should_quit()) - { - f64 startTime = mp_get_time(MP_CLOCK_MONOTONIC); - - mp_pump_events(0); - mp_event* event = 0; - while((event = mp_next_event(mem_scratch())) != 0) - { - switch(event->type) - { - case MP_EVENT_WINDOW_CLOSE: - { - mp_request_quit(); - } break; - - case MP_EVENT_KEYBOARD_KEY: - { - if(event->key.action == MP_KEY_PRESS || event->key.action == MP_KEY_REPEAT) - { - f32 factor = (event->key.mods & MP_KEYMOD_SHIFT) ? 10 : 1; - - if(event->key.code == MP_KEY_LEFT) - { - x-=0.3*factor; - } - else if(event->key.code == MP_KEY_RIGHT) - { - x+=0.3*factor; - } - else if(event->key.code == MP_KEY_UP) - { - y-=0.3*factor; - } - else if(event->key.code == MP_KEY_DOWN) - { - y+=0.3*factor; - } - } - } break; - - default: - break; - } - } - - if(x-200 < 0) - { - x = 200; - dx = speed; - } - if(x+200 > contentRect.w) - { - x = contentRect.w - 200; - dx = -speed; - } - if(y-200 < 0) - { - y = 200; - dy = speed; - } - if(y+200 > contentRect.h) - { - y = contentRect.h - 200; - dy = -speed; - } - x += dx; - y += dy; - - // background - mg_set_color_rgba(0, 1, 1, 1); - mg_clear(); - - mg_set_color_rgba(1, 0, 1, 1); - mg_rectangle_fill(0, 0, 100, 100); - - // head - mg_set_color_rgba(1, 1, 0, 1); - - mg_circle_fill(x, y, 200); - - // smile - f32 frown = frameTime > 0.033 ? -100 : 0; - - mg_set_color_rgba(0, 0, 0, 1); - mg_set_width(20); - mg_move_to(x-100, y+100); - mg_cubic_to(x-50, y+150+frown, x+50, y+150+frown, x+100, y+100); - mg_stroke(); - - // eyes - mg_ellipse_fill(x-70, y-50, 30, 50); - mg_ellipse_fill(x+70, y-50, 30, 50); - - // text - mg_set_color_rgba(0, 0, 1, 1); - mg_set_font(font); - mg_set_font_size(12); - mg_move_to(50, 600-50); - - str8 text = str8_pushf(mem_scratch(), - "Milepost vector graphics test program (frame time = %fs, fps = %f)...", - frameTime, - 1./frameTime); - mg_text_outlines(text); - mg_fill(); - - printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n", - frameTime, - 1./frameTime); - - mg_surface_prepare(surface); - mg_render(surface, canvas); - mg_surface_present(surface); - - mem_arena_clear(mem_scratch()); - frameTime = mp_get_time(MP_CLOCK_MONOTONIC) - startTime; - } - - mg_font_destroy(font); - mg_canvas_destroy(canvas); - mg_surface_destroy(surface); - mp_window_destroy(window); - - mp_terminate(); - - return(0); -} +*****************************************************************/ +#include +#include +#include +#include + +#define _USE_MATH_DEFINES //NOTE: necessary for MSVC +#include + +#include "milepost.h" + +#define LOG_SUBSYSTEM "Main" + +mg_font create_font() +{ + //NOTE(martin): create font + str8 fontPath = path_executable_relative(mem_scratch(), STR8("../resources/OpenSansLatinSubset.ttf")); + char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath); + + FILE* fontFile = fopen(fontPathCString, "r"); + if(!fontFile) + { + log_error("Could not load font file '%s': %s\n", fontPathCString, strerror(errno)); + return (mg_font_nil()); + } + unsigned char* fontData = 0; + fseek(fontFile, 0, SEEK_END); + u32 fontDataSize = ftell(fontFile); + rewind(fontFile); + fontData = (unsigned char*)malloc(fontDataSize); + fread(fontData, 1, fontDataSize, fontFile); + fclose(fontFile); + + unicode_range ranges[5] = { UNICODE_RANGE_BASIC_LATIN, + UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT, + UNICODE_RANGE_LATIN_EXTENDED_A, + UNICODE_RANGE_LATIN_EXTENDED_B, + UNICODE_RANGE_SPECIALS }; + + mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges); + free(fontData); + + return (font); +} + +int main() +{ + mp_init(); + mp_clock_init(); //TODO put that in mp_init()? + + mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 }; + mp_window window = mp_window_create(windowRect, "test", 0); + + mp_rect contentRect = mp_window_get_content_rect(window); + + //NOTE: create surface + mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS); + if(mg_surface_is_nil(surface)) + { + printf("Error: couldn't create surface\n"); + return (-1); + } + mg_surface_swap_interval(surface, 0); + + mg_canvas canvas = mg_canvas_create(); + + if(mg_canvas_is_nil(canvas)) + { + printf("Error: couldn't create canvas\n"); + return (-1); + } + + mg_font font = create_font(); + + // start app + mp_window_bring_to_front(window); + mp_window_focus(window); + + f32 x = 400, y = 300; + f32 speed = 0; + f32 dx = speed, dy = speed; + f64 frameTime = 0; + + while(!mp_should_quit()) + { + f64 startTime = mp_get_time(MP_CLOCK_MONOTONIC); + + mp_pump_events(0); + mp_event* event = 0; + while((event = mp_next_event(mem_scratch())) != 0) + { + switch(event->type) + { + case MP_EVENT_WINDOW_CLOSE: + { + mp_request_quit(); + } + break; + + case MP_EVENT_KEYBOARD_KEY: + { + if(event->key.action == MP_KEY_PRESS || event->key.action == MP_KEY_REPEAT) + { + f32 factor = (event->key.mods & MP_KEYMOD_SHIFT) ? 10 : 1; + + if(event->key.code == MP_KEY_LEFT) + { + x -= 0.3 * factor; + } + else if(event->key.code == MP_KEY_RIGHT) + { + x += 0.3 * factor; + } + else if(event->key.code == MP_KEY_UP) + { + y -= 0.3 * factor; + } + else if(event->key.code == MP_KEY_DOWN) + { + y += 0.3 * factor; + } + } + } + break; + + default: + break; + } + } + + if(x - 200 < 0) + { + x = 200; + dx = speed; + } + if(x + 200 > contentRect.w) + { + x = contentRect.w - 200; + dx = -speed; + } + if(y - 200 < 0) + { + y = 200; + dy = speed; + } + if(y + 200 > contentRect.h) + { + y = contentRect.h - 200; + dy = -speed; + } + x += dx; + y += dy; + + // background + mg_set_color_rgba(0, 1, 1, 1); + mg_clear(); + + mg_set_color_rgba(1, 0, 1, 1); + mg_rectangle_fill(0, 0, 100, 100); + + // head + mg_set_color_rgba(1, 1, 0, 1); + + mg_circle_fill(x, y, 200); + + // smile + f32 frown = frameTime > 0.033 ? -100 : 0; + + mg_set_color_rgba(0, 0, 0, 1); + mg_set_width(20); + mg_move_to(x - 100, y + 100); + mg_cubic_to(x - 50, y + 150 + frown, x + 50, y + 150 + frown, x + 100, y + 100); + mg_stroke(); + + // eyes + mg_ellipse_fill(x - 70, y - 50, 30, 50); + mg_ellipse_fill(x + 70, y - 50, 30, 50); + + // text + mg_set_color_rgba(0, 0, 1, 1); + mg_set_font(font); + mg_set_font_size(12); + mg_move_to(50, 600 - 50); + + str8 text = str8_pushf(mem_scratch(), + "Milepost vector graphics test program (frame time = %fs, fps = %f)...", + frameTime, + 1. / frameTime); + mg_text_outlines(text); + mg_fill(); + + printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n", + frameTime, + 1. / frameTime); + + mg_surface_prepare(surface); + mg_render(surface, canvas); + mg_surface_present(surface); + + mem_arena_clear(mem_scratch()); + frameTime = mp_get_time(MP_CLOCK_MONOTONIC) - startTime; + } + + mg_font_destroy(font); + mg_canvas_destroy(canvas); + mg_surface_destroy(surface); + mp_window_destroy(window); + + mp_terminate(); + + return (0); +} diff --git a/sketches/image/main.c b/sketches/image/main.c index f342298..2e3b870 100644 --- a/sketches/image/main.c +++ b/sketches/image/main.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: main.cpp * @author: Martin Fouilleul @@ -6,81 +6,82 @@ * @revision: * *****************************************************************/ -#include -#include -#include -#include +#include +#include +#include +#include #define _USE_MATH_DEFINES //NOTE: necessary for MSVC -#include +#include -#include"milepost.h" +#include "milepost.h" int main() { - mp_init(); - mp_clock_init(); //TODO put that in mp_init()? + mp_init(); + mp_clock_init(); //TODO put that in mp_init()? - mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610}; - mp_window window = mp_window_create(windowRect, "test", 0); + mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 }; + mp_window window = mp_window_create(windowRect, "test", 0); - mp_rect contentRect = mp_window_get_content_rect(window); + mp_rect contentRect = mp_window_get_content_rect(window); - //NOTE: create surface - mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS); - if(mg_surface_is_nil(surface)) - { - log_error("couldn't create surface\n"); - return(-1); - } - mg_surface_swap_interval(surface, 0); + //NOTE: create surface + mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS); + if(mg_surface_is_nil(surface)) + { + log_error("couldn't create surface\n"); + return (-1); + } + mg_surface_swap_interval(surface, 0); - //NOTE: create canvas - mg_canvas canvas = mg_canvas_create(); - if(mg_canvas_is_nil(canvas)) - { - printf("Error: couldn't create canvas\n"); - return(-1); - } + //NOTE: create canvas + mg_canvas canvas = mg_canvas_create(); + if(mg_canvas_is_nil(canvas)) + { + printf("Error: couldn't create canvas\n"); + return (-1); + } - //NOTE: create image - str8 imagePath = path_executable_relative(mem_scratch(), STR8("../../sketches/resources/triceratops.png")); - mg_image image = mg_image_create_from_file(surface, imagePath, false); - vec2 imageSize = mg_image_size(image); + //NOTE: create image + str8 imagePath = path_executable_relative(mem_scratch(), STR8("../../sketches/resources/triceratops.png")); + mg_image image = mg_image_create_from_file(surface, imagePath, false); + vec2 imageSize = mg_image_size(image); - str8 imagePath2 = path_executable_relative(mem_scratch(), STR8("../../sketches/resources/Top512.png")); - mg_image image2 = mg_image_create_from_file(surface, imagePath2, false); - vec2 imageSize2 = mg_image_size(image2); + str8 imagePath2 = path_executable_relative(mem_scratch(), STR8("../../sketches/resources/Top512.png")); + mg_image image2 = mg_image_create_from_file(surface, imagePath2, false); + vec2 imageSize2 = mg_image_size(image2); - // start app - mp_window_bring_to_front(window); - mp_window_focus(window); + // start app + mp_window_bring_to_front(window); + mp_window_focus(window); - while(!mp_should_quit()) - { - mp_pump_events(0); - mp_event* event = 0; - while((event = mp_next_event(mem_scratch())) != 0) - { - switch(event->type) - { - case MP_EVENT_WINDOW_CLOSE: - { - mp_request_quit(); - } break; + while(!mp_should_quit()) + { + mp_pump_events(0); + mp_event* event = 0; + while((event = mp_next_event(mem_scratch())) != 0) + { + switch(event->type) + { + case MP_EVENT_WINDOW_CLOSE: + { + mp_request_quit(); + } + break; - default: - break; - } - } + default: + break; + } + } - mg_surface_prepare(surface); + mg_surface_prepare(surface); - mg_set_color_rgba(0, 1, 1, 1); - mg_clear(); + mg_set_color_rgba(0, 1, 1, 1); + mg_clear(); - mg_set_color_rgba(1, 1, 1, 1); -/* + mg_set_color_rgba(1, 1, 1, 1); + /* mg_matrix_push((mg_mat2x3){0.707, -0.707, 200, 0.707, 0.707, 100}); mg_set_image(image); @@ -99,23 +100,21 @@ int main() mg_image_draw(image2, (mp_rect){300, 200, 300, 300}); */ - mg_image_draw(image, (mp_rect){100, 100, 300, 300}); - mg_image_draw(image2, (mp_rect){300, 200, 300, 300}); + mg_image_draw(image, (mp_rect){ 100, 100, 300, 300 }); + mg_image_draw(image2, (mp_rect){ 300, 200, 300, 300 }); + mg_render(surface, canvas); + mg_surface_present(surface); + mem_arena_clear(mem_scratch()); + } - mg_render(surface, canvas); - mg_surface_present(surface); + mg_image_destroy(image); + mg_canvas_destroy(canvas); + mg_surface_destroy(surface); + mp_window_destroy(window); - mem_arena_clear(mem_scratch()); - } + mp_terminate(); - mg_image_destroy(image); - mg_canvas_destroy(canvas); - mg_surface_destroy(surface); - mp_window_destroy(window); - - mp_terminate(); - - return(0); + return (0); } diff --git a/sketches/multi_surface/main.c b/sketches/multi_surface/main.c index f826f01..9dbf71c 100644 --- a/sketches/multi_surface/main.c +++ b/sketches/multi_surface/main.c @@ -1,114 +1,115 @@ -#include -#include +#include +#include #define MG_INCLUDE_GL_API 1 -#include"milepost.h" +#include "milepost.h" int main() { - mp_init(); - mp_clock_init(); //TODO put that in mp_init()? + mp_init(); + mp_clock_init(); //TODO put that in mp_init()? - mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610}; - mp_window window = mp_window_create(windowRect, "test", 0); + mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 }; + mp_window window = mp_window_create(windowRect, "test", 0); - mp_rect contentRect = mp_window_get_content_rect(window); + mp_rect contentRect = mp_window_get_content_rect(window); - //NOTE: create surface - mg_surface surface1 = mg_surface_create_for_window(window, MG_CANVAS); - if(mg_surface_is_nil(surface1)) - { - printf("Error: couldn't create surface 1\n"); - return(-1); - } - mg_surface_swap_interval(surface1, 0); -//* - mg_surface surface2 = mg_surface_create_for_window(window, MG_CANVAS); - if(mg_surface_is_nil(surface2)) - { - printf("Error: couldn't create surface 2\n"); - return(-1); - } - mg_surface_swap_interval(surface2, 0); -//*/ - mg_canvas canvas1 = mg_canvas_create(); - if(mg_canvas_is_nil(canvas1)) - { - printf("Error: couldn't create canvas 1\n"); - return(-1); - } -//* - mg_canvas canvas2 = mg_canvas_create(); - if(mg_canvas_is_nil(canvas2)) - { - printf("Error: couldn't create canvas 2\n"); - return(-1); - } -//*/ - // start app - mp_window_center(window); - mp_window_bring_to_front(window); - mp_window_focus(window); + //NOTE: create surface + mg_surface surface1 = mg_surface_create_for_window(window, MG_CANVAS); + if(mg_surface_is_nil(surface1)) + { + printf("Error: couldn't create surface 1\n"); + return (-1); + } + mg_surface_swap_interval(surface1, 0); + //* + mg_surface surface2 = mg_surface_create_for_window(window, MG_CANVAS); + if(mg_surface_is_nil(surface2)) + { + printf("Error: couldn't create surface 2\n"); + return (-1); + } + mg_surface_swap_interval(surface2, 0); + //*/ + mg_canvas canvas1 = mg_canvas_create(); + if(mg_canvas_is_nil(canvas1)) + { + printf("Error: couldn't create canvas 1\n"); + return (-1); + } + //* + mg_canvas canvas2 = mg_canvas_create(); + if(mg_canvas_is_nil(canvas2)) + { + printf("Error: couldn't create canvas 2\n"); + return (-1); + } + //*/ + // start app + mp_window_center(window); + mp_window_bring_to_front(window); + mp_window_focus(window); - while(!mp_should_quit()) - { - f64 startTime = mp_get_time(MP_CLOCK_MONOTONIC); + while(!mp_should_quit()) + { + f64 startTime = mp_get_time(MP_CLOCK_MONOTONIC); - mp_pump_events(0); - mp_event* event = 0; - while((event = mp_next_event(mem_scratch())) != 0) - { - switch(event->type) - { - case MP_EVENT_WINDOW_CLOSE: - { - mp_request_quit(); - } break; + mp_pump_events(0); + mp_event* event = 0; + while((event = mp_next_event(mem_scratch())) != 0) + { + switch(event->type) + { + case MP_EVENT_WINDOW_CLOSE: + { + mp_request_quit(); + } + break; - default: - break; - } - } + default: + break; + } + } - mg_surface_prepare(surface1); - mg_canvas_set_current(canvas1); + mg_surface_prepare(surface1); + mg_canvas_set_current(canvas1); - mg_set_color_rgba(0, 0, 0.5, 0.5); - mg_clear(); + mg_set_color_rgba(0, 0, 0.5, 0.5); + mg_clear(); - mg_set_color_rgba(1, 0, 0, 1); - mg_rectangle_fill(100, 100, 300, 150); + mg_set_color_rgba(1, 0, 0, 1); + mg_rectangle_fill(100, 100, 300, 150); - mg_render(surface1, canvas1); + mg_render(surface1, canvas1); -//* - mg_surface_prepare(surface2); - mg_canvas_set_current(canvas2); + //* + mg_surface_prepare(surface2); + mg_canvas_set_current(canvas2); - mg_set_color_rgba(0, 0, 0, 0); - mg_clear(); + mg_set_color_rgba(0, 0, 0, 0); + mg_clear(); - mg_set_color_rgba(0, 0, 1, 1); - mg_rectangle_fill(300, 300, 300, 200); + mg_set_color_rgba(0, 0, 1, 1); + mg_rectangle_fill(300, 300, 300, 200); - mg_render(surface2, canvas2); -//*/ + mg_render(surface2, canvas2); + //*/ - mg_surface_present(surface1); - mg_surface_present(surface2); + mg_surface_present(surface1); + mg_surface_present(surface2); - mem_arena_clear(mem_scratch()); - } + mem_arena_clear(mem_scratch()); + } - mg_canvas_destroy(canvas1); - mg_surface_destroy(surface1); - mg_canvas_destroy(canvas2); - mg_surface_destroy(surface2); + mg_canvas_destroy(canvas1); + mg_surface_destroy(surface1); + mg_canvas_destroy(canvas2); + mg_surface_destroy(surface2); - mp_window_destroy(window); + mp_window_destroy(window); - mp_terminate(); + mp_terminate(); - return(0); + return (0); } diff --git a/sketches/perf_text/main.c b/sketches/perf_text/main.c index d1e9c58..56093ad 100644 --- a/sketches/perf_text/main.c +++ b/sketches/perf_text/main.c @@ -1,237 +1,243 @@ - -#include -#include - -#define LOG_DEFAULT_LEVEL LOG_LEVEL_MESSAGE -#define LOG_COMPILE_DEBUG - -#include"milepost.h" - -#define LOG_SUBSYSTEM "Main" - -static const char* TEST_STRING = -"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla quam enim, aliquam in placerat luctus, rutrum in quam. " -"Cras urna elit, pellentesque ac ipsum at, lobortis scelerisque eros. Aenean et turpis nibh. Maecenas lectus augue, eleifend " -"nec efficitur eu, faucibus eget turpis. Suspendisse vel nulla mi. Duis imperdiet neque orci, ac ultrices orci molestie a. " -"Etiam malesuada vulputate hendrerit. Cras ultricies diam in lectus finibus, eu laoreet diam rutrum.\n" -"\n" -"Etiam dictum orci arcu, ac fermentum leo dapibus lacinia. Integer vitae elementum ex. Vestibulum tempor nunc eu hendrerit " -"ornare. Nunc pretium ligula sit amet massa pulvinar, vitae imperdiet justo bibendum. Maecenas consectetur elementum mi, sed " -"vehicula neque pulvinar sit amet. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tortor erat, accumsan in laoreet " -"quis, placerat nec enim. Nulla facilisi. Morbi vitae nibh ligula. Suspendisse in molestie magna, eget aliquet mauris. Sed " -"aliquam faucibus magna.\n" -"\n" -"Sed metus odio, imperdiet et consequat non, faucibus nec risus. Suspendisse facilisis sem neque, id scelerisque dui mattis sit " -"amet. Nullam tincidunt nisl nec dui dignissim mattis. Proin fermentum ornare ipsum. Proin eleifend, mi vitae porttitor placerat, " -"neque magna elementum turpis, eu aliquet mi urna et leo. Pellentesque interdum est mauris, sed pellentesque risus blandit in. " -"Phasellus dignissim consequat eros, at aliquam elit finibus posuere. Proin suscipit tortor leo, id vulputate odio lobortis in. " -"Vestibulum et orci ligula. Sed scelerisque nunc non nisi aliquam, vel eleifend felis suscipit. Integer posuere sapien elit, " -"lacinia ultricies nibh sodales nec.\n" -"\n" -"Etiam aliquam purus sit amet purus ultricies tristique. Nunc maximus nunc quis magna ornare, vel interdum urna fermentum. " -"Vestibulum cursus nisl ut nulla egestas, quis mattis elit venenatis. Praesent malesuada mi non magna aliquam fringilla eget eu " -"turpis. Integer suscipit elit vel consectetur vulputate. Integer euismod, erat eget elementum tempus, magna metus consectetur " -"elit, sed feugiat urna sapien sodales sapien. Sed sit amet varius nunc. Curabitur sodales nunc justo, ac scelerisque ipsum semper " -"eget. Integer ornare, velit ut hendrerit dapibus, erat mauris commodo justo, vel semper urna justo non mauris. Proin blandit, " -"enim ut posuere placerat, leo nibh tristique eros, ut pulvinar sapien elit eget enim. Pellentesque et mauris lectus. Curabitur " -"quis lobortis leo, sit amet egestas dui. Nullam ut sapien eu justo lacinia ultrices. Ut tincidunt, sem non luctus tempus, felis " -"purus imperdiet nisi, non ultricies libero ipsum eu augue. Mauris at luctus enim.\n" -"\n" -"Aliquam sed tortor a justo pulvinar dictum consectetur eu felis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices " -"posuere cubilia curae; Etiam vehicula porttitor volutpat. Morbi fringilla tortor nec accumsan aliquet. Aliquam in commodo neque. " -"Sed laoreet tellus in consectetur aliquet. Nullam nibh eros, feugiat sit amet aliquam non, malesuada vel urna. Ut vel egestas nunc. " -"Pellentesque vitae ante quis ante pharetra pretium. Nam quis eros commodo, mattis enim sed, finibus ante. Quisque lacinia tortor ut " -"odio laoreet, vel viverra libero porttitor. Vestibulum vitae dapibus ex. Phasellus varius lorem sed justo sollicitudin faucibus. " -"Etiam aliquam lacinia consectetur. Phasellus nulla ipsum, viverra non nulla in, rhoncus posuere nunc.\n" -"\n" -"Phasellus efficitur commodo tellus, eget lobortis erat porta quis. Aenean condimentum tortor ut neque dapibus, vitae vulputate quam " -"condimentum. Aliquam elementum vitae nulla vitae tristique. Suspendisse feugiat turpis ac magna dapibus, ut blandit diam tincidunt. " -"Integer id dui id enim ullamcorper dictum. Maecenas malesuada vitae ex pharetra iaculis. Curabitur eu dolor consectetur, tempus augue " -"sed, finibus est. Nulla facilisi. Vivamus sed lacinia turpis, in gravida dolor. Aenean interdum consectetur enim a malesuada. Sed turpis " -"nisi, lacinia et fermentum nec, pharetra id dui. Vivamus neque ligula, iaculis sed tempor eget, vehicula blandit quam. Morbi rhoncus quam " -"semper magna mollis luctus. Donec eu dolor ut ante ullamcorper porta. Mauris et est tristique libero pharetra faucibus.\n" -"\n" -"Duis ut elementum sem. Praesent commodo erat nec sem ultricies sollicitudin. Suspendisse a pellentesque sapien. Nunc ac magna a dui " -"elementum luctus non a mi. Cras elementum nunc sed nunc gravida, sit amet accumsan tortor pulvinar. Etiam elit arcu, pellentesque non ex " -"id, vestibulum pellentesque velit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque habitant morbi tristique senectus " -"et netus et malesuada fames ac turpis egestas. Proin sit amet velit eget tellus vulputate sagittis eget non massa. Cras accumsan tempor " -"tortor, quis rutrum neque placerat id. Nullam a egestas eros, eu porta nisi. Aenean rutrum, sapien quis fermentum tempus, dolor orci " -"faucibus eros, vel luctus justo leo vitae ante. Curabitur aliquam condimentum ipsum sit amet ultrices. Nullam ac velit semper, dapibus urna " -"sit amet, malesuada enim. Mauris ultricies nibh orci."; - - -mg_font create_font(const char* path) -{ - //NOTE(martin): create font - str8 fontPath = path_executable_relative(mem_scratch(), STR8(path)); - char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath); - - FILE* fontFile = fopen(fontPathCString, "r"); - if(!fontFile) - { - log_error("Could not load font file '%s'\n", fontPathCString); - return(mg_font_nil()); - } - unsigned char* fontData = 0; - fseek(fontFile, 0, SEEK_END); - u32 fontDataSize = ftell(fontFile); - rewind(fontFile); - fontData = (unsigned char*)malloc(fontDataSize); - fread(fontData, 1, fontDataSize, fontFile); - fclose(fontFile); - - unicode_range ranges[5] = {UNICODE_RANGE_BASIC_LATIN, - UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT, - UNICODE_RANGE_LATIN_EXTENDED_A, - UNICODE_RANGE_LATIN_EXTENDED_B, - UNICODE_RANGE_SPECIALS}; - - mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges); - free(fontData); - - return(font); -} - -enum { FONT_COUNT = 3 }; - -int main() -{ - mp_init(); - mp_clock_init(); - - mp_rect rect = {.x = 100, .y = 100, .w = 980, .h = 600}; - mp_window window = mp_window_create(rect, "test", 0); - - mp_rect contentRect = mp_window_get_content_rect(window); - - //NOTE: create surface, canvas and font - - mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS); - if(mg_surface_is_nil(surface)) - { - log_error("couldn't create surface\n"); - return(-1); - } - mg_surface_swap_interval(surface, 0); - - mg_canvas canvas = mg_canvas_create(); - - int fontIndex = 0; - mg_font fonts[FONT_COUNT] = {create_font("../../resources/OpenSansLatinSubset.ttf"), - create_font("../../sketches/resources/CMUSerif-Roman.ttf"), - create_font("../../sketches/resources/Courier.ttf")}; - - mg_font_extents extents[FONT_COUNT]; - f32 fontScales[FONT_COUNT]; - f32 lineHeights[FONT_COUNT]; - - for(int i=0; itype) - { - case MP_EVENT_WINDOW_CLOSE: - { - mp_request_quit(); - } break; - - case MP_EVENT_MOUSE_BUTTON: - { - if(event->key.code == MP_MOUSE_LEFT) - { - if(event->key.action == MP_KEY_PRESS) - { - tracked = true; - vec2 mousePos = mp_mouse_position(&inputState); - trackPoint.x = mousePos.x/zoom - startX; - trackPoint.y = mousePos.y/zoom - startY; - } - else - { - tracked = false; - } - } - } break; - - case MP_EVENT_MOUSE_WHEEL: - { - vec2 mousePos = mp_mouse_position(&inputState); - f32 trackX = mousePos.x/zoom - startX; - f32 trackY = mousePos.y/zoom - startY; - - zoom *= 1 + event->mouse.deltaY * 0.01; - zoom = Clamp(zoom, 0.2, 10); - - startX = mousePos.x/zoom - trackX; - startY = mousePos.y/zoom - trackY; - } break; - - case MP_EVENT_KEYBOARD_KEY: - { - if(event->key.code == MP_KEY_SPACE && event->key.action == MP_KEY_PRESS) - { - fontIndex = (fontIndex+1)%FONT_COUNT; - } - } break; - - default: - break; - } - } - - if(tracked) - { - vec2 mousePos = mp_mouse_position(&inputState); - startX = mousePos.x/zoom - trackPoint.x; - startY = mousePos.y/zoom - trackPoint.y; - } - - f32 textX = startX; - f32 textY = startY; - -/* + +#include +#include + +#define LOG_DEFAULT_LEVEL LOG_LEVEL_MESSAGE +#define LOG_COMPILE_DEBUG + +#include "milepost.h" + +#define LOG_SUBSYSTEM "Main" + +static const char* TEST_STRING = + "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla quam enim, aliquam in placerat luctus, rutrum in quam. " + "Cras urna elit, pellentesque ac ipsum at, lobortis scelerisque eros. Aenean et turpis nibh. Maecenas lectus augue, eleifend " + "nec efficitur eu, faucibus eget turpis. Suspendisse vel nulla mi. Duis imperdiet neque orci, ac ultrices orci molestie a. " + "Etiam malesuada vulputate hendrerit. Cras ultricies diam in lectus finibus, eu laoreet diam rutrum.\n" + "\n" + "Etiam dictum orci arcu, ac fermentum leo dapibus lacinia. Integer vitae elementum ex. Vestibulum tempor nunc eu hendrerit " + "ornare. Nunc pretium ligula sit amet massa pulvinar, vitae imperdiet justo bibendum. Maecenas consectetur elementum mi, sed " + "vehicula neque pulvinar sit amet. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc tortor erat, accumsan in laoreet " + "quis, placerat nec enim. Nulla facilisi. Morbi vitae nibh ligula. Suspendisse in molestie magna, eget aliquet mauris. Sed " + "aliquam faucibus magna.\n" + "\n" + "Sed metus odio, imperdiet et consequat non, faucibus nec risus. Suspendisse facilisis sem neque, id scelerisque dui mattis sit " + "amet. Nullam tincidunt nisl nec dui dignissim mattis. Proin fermentum ornare ipsum. Proin eleifend, mi vitae porttitor placerat, " + "neque magna elementum turpis, eu aliquet mi urna et leo. Pellentesque interdum est mauris, sed pellentesque risus blandit in. " + "Phasellus dignissim consequat eros, at aliquam elit finibus posuere. Proin suscipit tortor leo, id vulputate odio lobortis in. " + "Vestibulum et orci ligula. Sed scelerisque nunc non nisi aliquam, vel eleifend felis suscipit. Integer posuere sapien elit, " + "lacinia ultricies nibh sodales nec.\n" + "\n" + "Etiam aliquam purus sit amet purus ultricies tristique. Nunc maximus nunc quis magna ornare, vel interdum urna fermentum. " + "Vestibulum cursus nisl ut nulla egestas, quis mattis elit venenatis. Praesent malesuada mi non magna aliquam fringilla eget eu " + "turpis. Integer suscipit elit vel consectetur vulputate. Integer euismod, erat eget elementum tempus, magna metus consectetur " + "elit, sed feugiat urna sapien sodales sapien. Sed sit amet varius nunc. Curabitur sodales nunc justo, ac scelerisque ipsum semper " + "eget. Integer ornare, velit ut hendrerit dapibus, erat mauris commodo justo, vel semper urna justo non mauris. Proin blandit, " + "enim ut posuere placerat, leo nibh tristique eros, ut pulvinar sapien elit eget enim. Pellentesque et mauris lectus. Curabitur " + "quis lobortis leo, sit amet egestas dui. Nullam ut sapien eu justo lacinia ultrices. Ut tincidunt, sem non luctus tempus, felis " + "purus imperdiet nisi, non ultricies libero ipsum eu augue. Mauris at luctus enim.\n" + "\n" + "Aliquam sed tortor a justo pulvinar dictum consectetur eu felis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices " + "posuere cubilia curae; Etiam vehicula porttitor volutpat. Morbi fringilla tortor nec accumsan aliquet. Aliquam in commodo neque. " + "Sed laoreet tellus in consectetur aliquet. Nullam nibh eros, feugiat sit amet aliquam non, malesuada vel urna. Ut vel egestas nunc. " + "Pellentesque vitae ante quis ante pharetra pretium. Nam quis eros commodo, mattis enim sed, finibus ante. Quisque lacinia tortor ut " + "odio laoreet, vel viverra libero porttitor. Vestibulum vitae dapibus ex. Phasellus varius lorem sed justo sollicitudin faucibus. " + "Etiam aliquam lacinia consectetur. Phasellus nulla ipsum, viverra non nulla in, rhoncus posuere nunc.\n" + "\n" + "Phasellus efficitur commodo tellus, eget lobortis erat porta quis. Aenean condimentum tortor ut neque dapibus, vitae vulputate quam " + "condimentum. Aliquam elementum vitae nulla vitae tristique. Suspendisse feugiat turpis ac magna dapibus, ut blandit diam tincidunt. " + "Integer id dui id enim ullamcorper dictum. Maecenas malesuada vitae ex pharetra iaculis. Curabitur eu dolor consectetur, tempus augue " + "sed, finibus est. Nulla facilisi. Vivamus sed lacinia turpis, in gravida dolor. Aenean interdum consectetur enim a malesuada. Sed turpis " + "nisi, lacinia et fermentum nec, pharetra id dui. Vivamus neque ligula, iaculis sed tempor eget, vehicula blandit quam. Morbi rhoncus quam " + "semper magna mollis luctus. Donec eu dolor ut ante ullamcorper porta. Mauris et est tristique libero pharetra faucibus.\n" + "\n" + "Duis ut elementum sem. Praesent commodo erat nec sem ultricies sollicitudin. Suspendisse a pellentesque sapien. Nunc ac magna a dui " + "elementum luctus non a mi. Cras elementum nunc sed nunc gravida, sit amet accumsan tortor pulvinar. Etiam elit arcu, pellentesque non ex " + "id, vestibulum pellentesque velit. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque habitant morbi tristique senectus " + "et netus et malesuada fames ac turpis egestas. Proin sit amet velit eget tellus vulputate sagittis eget non massa. Cras accumsan tempor " + "tortor, quis rutrum neque placerat id. Nullam a egestas eros, eu porta nisi. Aenean rutrum, sapien quis fermentum tempus, dolor orci " + "faucibus eros, vel luctus justo leo vitae ante. Curabitur aliquam condimentum ipsum sit amet ultrices. Nullam ac velit semper, dapibus urna " + "sit amet, malesuada enim. Mauris ultricies nibh orci."; + +mg_font create_font(const char* path) +{ + //NOTE(martin): create font + str8 fontPath = path_executable_relative(mem_scratch(), STR8(path)); + char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath); + + FILE* fontFile = fopen(fontPathCString, "r"); + if(!fontFile) + { + log_error("Could not load font file '%s'\n", fontPathCString); + return (mg_font_nil()); + } + unsigned char* fontData = 0; + fseek(fontFile, 0, SEEK_END); + u32 fontDataSize = ftell(fontFile); + rewind(fontFile); + fontData = (unsigned char*)malloc(fontDataSize); + fread(fontData, 1, fontDataSize, fontFile); + fclose(fontFile); + + unicode_range ranges[5] = { UNICODE_RANGE_BASIC_LATIN, + UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT, + UNICODE_RANGE_LATIN_EXTENDED_A, + UNICODE_RANGE_LATIN_EXTENDED_B, + UNICODE_RANGE_SPECIALS }; + + mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges); + free(fontData); + + return (font); +} + +enum +{ + FONT_COUNT = 3 +}; + +int main() +{ + mp_init(); + mp_clock_init(); + + mp_rect rect = { .x = 100, .y = 100, .w = 980, .h = 600 }; + mp_window window = mp_window_create(rect, "test", 0); + + mp_rect contentRect = mp_window_get_content_rect(window); + + //NOTE: create surface, canvas and font + + mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS); + if(mg_surface_is_nil(surface)) + { + log_error("couldn't create surface\n"); + return (-1); + } + mg_surface_swap_interval(surface, 0); + + mg_canvas canvas = mg_canvas_create(); + + int fontIndex = 0; + mg_font fonts[FONT_COUNT] = { create_font("../../resources/OpenSansLatinSubset.ttf"), + create_font("../../sketches/resources/CMUSerif-Roman.ttf"), + create_font("../../sketches/resources/Courier.ttf") }; + + mg_font_extents extents[FONT_COUNT]; + f32 fontScales[FONT_COUNT]; + f32 lineHeights[FONT_COUNT]; + + for(int i = 0; i < FONT_COUNT; i++) + { + extents[i] = mg_font_get_extents(fonts[i]); + fontScales[i] = mg_font_get_scale_for_em_pixels(fonts[i], 14); + lineHeights[i] = fontScales[i] * (extents[i].ascent + extents[i].descent + extents[i].leading); + } + + int codePointCount = utf8_codepoint_count_for_string(STR8((char*)TEST_STRING)); + u32* codePoints = malloc_array(utf32, codePointCount); + utf8_to_codepoints(codePointCount, codePoints, STR8((char*)TEST_STRING)); + + u32 glyphCount = 0; + for(int i = 0; i < codePointCount; i++) + { + if(codePoints[i] != ' ' && codePoints[i] != '\n') + { + glyphCount++; + } + } + + // start app + mp_window_bring_to_front(window); + mp_window_focus(window); + + f64 frameTime = 0; + + bool tracked = false; + vec2 trackPoint = { 0 }; + f32 zoom = 1; + + f32 startX = 10; + f32 startY = 10 + lineHeights[fontIndex]; + + mp_input_state inputState = { 0 }; + + while(!mp_should_quit()) + { + f64 startFrameTime = mp_get_time(MP_CLOCK_MONOTONIC); + + mp_pump_events(0); + mp_event* event = 0; + while((event = mp_next_event(mem_scratch())) != 0) + { + mp_input_process_event(&inputState, event); + + switch(event->type) + { + case MP_EVENT_WINDOW_CLOSE: + { + mp_request_quit(); + } + break; + + case MP_EVENT_MOUSE_BUTTON: + { + if(event->key.code == MP_MOUSE_LEFT) + { + if(event->key.action == MP_KEY_PRESS) + { + tracked = true; + vec2 mousePos = mp_mouse_position(&inputState); + trackPoint.x = mousePos.x / zoom - startX; + trackPoint.y = mousePos.y / zoom - startY; + } + else + { + tracked = false; + } + } + } + break; + + case MP_EVENT_MOUSE_WHEEL: + { + vec2 mousePos = mp_mouse_position(&inputState); + f32 trackX = mousePos.x / zoom - startX; + f32 trackY = mousePos.y / zoom - startY; + + zoom *= 1 + event->mouse.deltaY * 0.01; + zoom = Clamp(zoom, 0.2, 10); + + startX = mousePos.x / zoom - trackX; + startY = mousePos.y / zoom - trackY; + } + break; + + case MP_EVENT_KEYBOARD_KEY: + { + if(event->key.code == MP_KEY_SPACE && event->key.action == MP_KEY_PRESS) + { + fontIndex = (fontIndex + 1) % FONT_COUNT; + } + } + break; + + default: + break; + } + } + + if(tracked) + { + vec2 mousePos = mp_mouse_position(&inputState); + startX = mousePos.x / zoom - trackPoint.x; + startY = mousePos.y / zoom - trackPoint.y; + } + + f32 textX = startX; + f32 textY = startY; + + /* mg_set_color_rgba(1, 1, 1, 1); mg_clear(); mg_set_color_rgba(1, 0, 0, 1); @@ -239,94 +245,92 @@ int main() { mg_rectangle_fill(0, 0, 100, 100); } -*/ - - mg_matrix_push((mg_mat2x3){zoom, 0, 0, - 0, zoom, 0}); - - mg_set_color_rgba(1, 1, 1, 1); - mg_clear(); - - mg_set_font(fonts[fontIndex]); - mg_set_font_size(14); - mg_set_color_rgba(0, 0, 0, 1); - - mg_move_to(textX, textY); - - int startIndex = 0; - while(startIndex < codePointCount) - { - bool lineBreak = false; - int subIndex = 0; - for(; (startIndex+subIndex) < codePointCount && subIndex < 120; subIndex++) - { - if(codePoints[startIndex + subIndex] == '\n') - { - break; - } - } - - u32 glyphs[512]; - mg_font_get_glyph_indices(fonts[fontIndex], (str32){subIndex, codePoints+startIndex}, (str32){512, glyphs}); - - mg_glyph_outlines((str32){subIndex, glyphs}); - mg_fill(); - - textY += lineHeights[fontIndex]; - mg_move_to(textX, textY); - startIndex++; - - startIndex += subIndex; - } - - mg_matrix_pop(); - - mg_set_color_rgba(0, 0, 1, 1); - mg_set_font(fonts[fontIndex]); - mg_set_font_size(14); - mg_move_to(10, contentRect.h - 10 - lineHeights[fontIndex]); - - str8 text = str8_pushf(mem_scratch(), - "Test program: %i glyphs, frame time = %fs, fps = %f", - glyphCount, - frameTime, - 1./frameTime); - mg_text_outlines(text); - mg_fill(); - - - f64 startFlushTime = mp_get_time(MP_CLOCK_MONOTONIC); - - mg_surface_prepare(surface); - mg_render(surface, canvas); - - f64 startPresentTime = mp_get_time(MP_CLOCK_MONOTONIC); - mg_surface_present(surface); - - f64 endFrameTime = mp_get_time(MP_CLOCK_MONOTONIC); - - frameTime = (endFrameTime - startFrameTime); - - printf("frame time: %.2fms (%.2fFPS), draw = %f.2ms, flush = %.2fms, present = %.2fms\n", - frameTime*1000, - 1./frameTime, - (startFlushTime - startFrameTime)*1000, - (startPresentTime - startFlushTime)*1000, - (endFrameTime - startPresentTime)*1000); - - mp_input_next_frame(&inputState); - mem_arena_clear(mem_scratch()); - } - - - for(int i=0; i -#include -#include -#include +#include +#include +#include +#include #define _USE_MATH_DEFINES //NOTE: necessary for MSVC -#include +#include -#include"milepost.h" +#include "milepost.h" int main() { - mp_init(); - mp_clock_init(); //TODO put that in mp_init()? + mp_init(); + mp_clock_init(); //TODO put that in mp_init()? - mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610}; - mp_window window = mp_window_create(windowRect, "test", 0); + mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 }; + mp_window window = mp_window_create(windowRect, "test", 0); - mp_rect contentRect = mp_window_get_content_rect(window); + mp_rect contentRect = mp_window_get_content_rect(window); - //NOTE: create surface - mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS); - mg_surface_swap_interval(surface, 1); + //NOTE: create surface + mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS); + mg_surface_swap_interval(surface, 1); - if(mg_surface_is_nil(surface)) - { - printf("Error: couldn't create surface\n"); - return(-1); - } + if(mg_surface_is_nil(surface)) + { + printf("Error: couldn't create surface\n"); + return (-1); + } - //TODO: create canvas - mg_canvas canvas = mg_canvas_create(); + //TODO: create canvas + mg_canvas canvas = mg_canvas_create(); - if(mg_canvas_is_nil(canvas)) - { - printf("Error: couldn't create canvas\n"); - return(-1); - } + if(mg_canvas_is_nil(canvas)) + { + printf("Error: couldn't create canvas\n"); + return (-1); + } - // start app - mp_window_bring_to_front(window); - mp_window_focus(window); + // start app + mp_window_bring_to_front(window); + mp_window_focus(window); - f64 frameTime = 0; - f32 x = 0, y = 0; + f64 frameTime = 0; + f32 x = 0, y = 0; - while(!mp_should_quit()) - { - f64 startTime = mp_get_time(MP_CLOCK_MONOTONIC); + while(!mp_should_quit()) + { + f64 startTime = mp_get_time(MP_CLOCK_MONOTONIC); - mp_pump_events(0); - mp_event* event = 0; - while((event = mp_next_event(mem_scratch())) != 0) - { - switch(event->type) - { - case MP_EVENT_WINDOW_CLOSE: - { - mp_request_quit(); - } break; + mp_pump_events(0); + mp_event* event = 0; + while((event = mp_next_event(mem_scratch())) != 0) + { + switch(event->type) + { + case MP_EVENT_WINDOW_CLOSE: + { + mp_request_quit(); + } + break; - case MP_EVENT_KEYBOARD_KEY: - { - if(event->key.action == MP_KEY_PRESS) - { - if(event->key.code == MP_KEY_LEFT) - { - x-=1; - } - if(event->key.code == MP_KEY_RIGHT) - { - x+=1; - } - if(event->key.code == MP_KEY_UP) - { - y-=1; - } - if(event->key.code == MP_KEY_DOWN) - { - y+=1; - } - } - } break; + case MP_EVENT_KEYBOARD_KEY: + { + if(event->key.action == MP_KEY_PRESS) + { + if(event->key.code == MP_KEY_LEFT) + { + x -= 1; + } + if(event->key.code == MP_KEY_RIGHT) + { + x += 1; + } + if(event->key.code == MP_KEY_UP) + { + y -= 1; + } + if(event->key.code == MP_KEY_DOWN) + { + y += 1; + } + } + } + break; - default: - break; - } - } + default: + break; + } + } - mg_surface_prepare(surface); + mg_surface_prepare(surface); - // background - mg_set_color_rgba(0, 1, 1, 1); - mg_clear(); + // background + mg_set_color_rgba(0, 1, 1, 1); + mg_clear(); - mg_move_to(100, 100); - mg_line_to(150, 150); - mg_line_to(100, 200); - mg_line_to(50, 150); - mg_close_path(); - mg_set_color_rgba(1, 0, 0, 1); - mg_fill(); + mg_move_to(100, 100); + mg_line_to(150, 150); + mg_line_to(100, 200); + mg_line_to(50, 150); + mg_close_path(); + mg_set_color_rgba(1, 0, 0, 1); + mg_fill(); - mg_move_to(200, 100); - mg_line_to(410, 100); - mg_line_to(410, 200); - mg_line_to(200, 200); - mg_close_path(); - mg_set_color_rgba(0, 1, 0, 1); - mg_fill(); + mg_move_to(200, 100); + mg_line_to(410, 100); + mg_line_to(410, 200); + mg_line_to(200, 200); + mg_close_path(); + mg_set_color_rgba(0, 1, 0, 1); + mg_fill(); - mg_set_color_rgba(0, 1, 1, 0.5); - mg_rectangle_fill(120, 120, 200, 200); + mg_set_color_rgba(0, 1, 1, 0.5); + mg_rectangle_fill(120, 120, 200, 200); - mg_set_color_rgba(1, 0, 0.5, 1); - mg_rectangle_fill(700, 500, 200, 200); + mg_set_color_rgba(1, 0, 0.5, 1); + mg_rectangle_fill(700, 500, 200, 200); - mg_move_to(300, 300); - mg_quadratic_to(400, 500, 500, 300); - mg_close_path(); - mg_set_color_rgba(0, 0, 1, 1); - mg_fill(); + mg_move_to(300, 300); + mg_quadratic_to(400, 500, 500, 300); + mg_close_path(); + mg_set_color_rgba(0, 0, 1, 1); + mg_fill(); - mg_move_to(200, 450); - mg_cubic_to(200, 250, 400, 550, 400, 450); - mg_close_path(); - mg_set_color_rgba(1, 0.5, 0, 1); - mg_fill(); + mg_move_to(200, 450); + mg_cubic_to(200, 250, 400, 550, 400, 450); + mg_close_path(); + mg_set_color_rgba(1, 0.5, 0, 1); + mg_fill(); -/* + /* mg_set_joint(MG_JOINT_NONE); mg_set_max_joint_excursion(20); @@ -172,22 +174,22 @@ int main() mg_set_color_rgba(0, 0, 1, 1); mg_fill(); */ - printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n", - frameTime, - 1./frameTime); + printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n", + frameTime, + 1. / frameTime); - mg_render(surface, canvas); - mg_surface_present(surface); + mg_render(surface, canvas); + mg_surface_present(surface); - mem_arena_clear(mem_scratch()); - frameTime = mp_get_time(MP_CLOCK_MONOTONIC) - startTime; - } + mem_arena_clear(mem_scratch()); + frameTime = mp_get_time(MP_CLOCK_MONOTONIC) - startTime; + } - mg_canvas_destroy(canvas); - mg_surface_destroy(surface); - mp_window_destroy(window); + mg_canvas_destroy(canvas); + mg_surface_destroy(surface); + mp_window_destroy(window); - mp_terminate(); + mp_terminate(); - return(0); + return (0); } diff --git a/sketches/render_thread/main.c b/sketches/render_thread/main.c index ef7af1b..cbfcd06 100644 --- a/sketches/render_thread/main.c +++ b/sketches/render_thread/main.c @@ -1,98 +1,99 @@ -#include -#include +#include +#include #define MG_INCLUDE_GL_API 1 -#include"milepost.h" +#include "milepost.h" -mg_surface surface = {0}; -mg_canvas canvas = {0}; +mg_surface surface = { 0 }; +mg_canvas canvas = { 0 }; i32 render_thread(void* user) { - while(!mp_should_quit()) - { - mp_event* event = 0; - while((event = mp_next_event(mem_scratch())) != 0) - { - switch(event->type) - { - case MP_EVENT_WINDOW_CLOSE: - { - mp_request_quit(); - } break; + while(!mp_should_quit()) + { + mp_event* event = 0; + while((event = mp_next_event(mem_scratch())) != 0) + { + switch(event->type) + { + case MP_EVENT_WINDOW_CLOSE: + { + mp_request_quit(); + } + break; - default: - break; - } - } + default: + break; + } + } - mg_surface_prepare(surface); - mg_canvas_set_current(canvas); + mg_surface_prepare(surface); + mg_canvas_set_current(canvas); - mg_set_color_rgba(0, 0, 0.5, 0.5); - mg_clear(); + mg_set_color_rgba(0, 0, 0.5, 0.5); + mg_clear(); - mg_set_color_rgba(1, 0, 0, 1); - mg_rectangle_fill(100, 100, 300, 150); + mg_set_color_rgba(1, 0, 0, 1); + mg_rectangle_fill(100, 100, 300, 150); - mg_render(surface, canvas); + mg_render(surface, canvas); - mg_surface_present(surface); + mg_surface_present(surface); - mem_arena_clear(mem_scratch()); - } - return(0); + mem_arena_clear(mem_scratch()); + } + return (0); } int main() { - mp_init(); - mp_clock_init(); //TODO put that in mp_init()? + mp_init(); + mp_clock_init(); //TODO put that in mp_init()? - mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610}; - mp_window window = mp_window_create(windowRect, "test", 0); + mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 }; + mp_window window = mp_window_create(windowRect, "test", 0); - mp_rect contentRect = mp_window_get_content_rect(window); + mp_rect contentRect = mp_window_get_content_rect(window); - //NOTE: create surface - surface = mg_surface_create_for_window(window, MG_CANVAS); - if(mg_surface_is_nil(surface)) - { - printf("Error: couldn't create surface 1\n"); - return(-1); - } - mg_surface_swap_interval(surface, 0); + //NOTE: create surface + surface = mg_surface_create_for_window(window, MG_CANVAS); + if(mg_surface_is_nil(surface)) + { + printf("Error: couldn't create surface 1\n"); + return (-1); + } + mg_surface_swap_interval(surface, 0); - canvas = mg_canvas_create(); - if(mg_canvas_is_nil(canvas)) - { - printf("Error: couldn't create canvas 1\n"); - return(-1); - } + canvas = mg_canvas_create(); + if(mg_canvas_is_nil(canvas)) + { + printf("Error: couldn't create canvas 1\n"); + return (-1); + } - mg_surface dummy = mg_surface_create_for_window(window, MG_CANVAS); + mg_surface dummy = mg_surface_create_for_window(window, MG_CANVAS); - // start app - mp_window_center(window); - mp_window_bring_to_front(window); - mp_window_focus(window); + // start app + mp_window_center(window); + mp_window_bring_to_front(window); + mp_window_focus(window); - mp_thread* renderThread = mp_thread_create(render_thread, NULL); + mp_thread* renderThread = mp_thread_create(render_thread, NULL); - while(!mp_should_quit()) - { - mp_pump_events(0); - } + while(!mp_should_quit()) + { + mp_pump_events(0); + } - mp_thread_join(renderThread, NULL); + mp_thread_join(renderThread, NULL); - mg_canvas_destroy(canvas); - mg_surface_destroy(surface); + mg_canvas_destroy(canvas); + mg_surface_destroy(surface); - mp_window_destroy(window); + mp_window_destroy(window); - mp_terminate(); + mp_terminate(); - return(0); + return (0); } diff --git a/sketches/simpleWindow/main.c b/sketches/simpleWindow/main.c index eddccde..ed561e7 100644 --- a/sketches/simpleWindow/main.c +++ b/sketches/simpleWindow/main.c @@ -1,121 +1,131 @@ -/************************************************************//** +/************************************************************/ /** * * @file: main.cpp * @author: Martin Fouilleul * @date: 30/07/2022 * @revision: * -*****************************************************************/ -#include -#include -#include - -#include"milepost.h" - -int main() -{ - mp_init(); - - mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600}; - mp_window window = mp_window_create(rect, "test", 0); - - mp_window_bring_to_front(window); - mp_window_focus(window); - - mp_window_center(window); - - while(!mp_should_quit()) - { - mp_pump_events(0); - mp_event *event = 0; - while((event = mp_next_event(mem_scratch())) != 0) - { - switch(event->type) - { - case MP_EVENT_WINDOW_CLOSE: - { - mp_request_quit(); - } break; - - case MP_EVENT_WINDOW_RESIZE: - { - printf("resized, frame = {%f, %f, %f, %f}, content = {%f, %f, %f, %f}\n", - event->move.frame.x, - event->move.frame.y, - event->move.frame.w, - event->move.frame.h, - event->move.content.x, - event->move.content.y, - event->move.content.w, - event->move.content.h); - } break; - - case MP_EVENT_WINDOW_MOVE: - { - printf("moved, frame = {%f, %f, %f, %f}, content = {%f, %f, %f, %f}\n", - event->move.frame.x, - event->move.frame.y, - event->move.frame.w, - event->move.frame.h, - event->move.content.x, - event->move.content.y, - event->move.content.w, - event->move.content.h); - } break; - - case MP_EVENT_MOUSE_MOVE: - { - printf("mouse moved, pos = {%f, %f}, delta = {%f, %f}\n", - event->mouse.x, - event->mouse.y, - event->mouse.deltaX, - event->mouse.deltaY); - } break; - - case MP_EVENT_MOUSE_WHEEL: - { - printf("mouse wheel, delta = {%f, %f}\n", - event->mouse.deltaX, - event->mouse.deltaY); - } break; - - case MP_EVENT_MOUSE_ENTER: - { - printf("mouse enter\n"); - } break; - - case MP_EVENT_MOUSE_LEAVE: - { - printf("mouse leave\n"); - } break; - - case MP_EVENT_MOUSE_BUTTON: - { - printf("mouse button %i: %i\n", - event->key.code, - event->key.action == MP_KEY_PRESS ? 1 : 0); - } break; - - case MP_EVENT_KEYBOARD_KEY: - { - printf("key %i: %s\n", - event->key.code, - event->key.action == MP_KEY_PRESS ? "press" : (event->key.action == MP_KEY_RELEASE ? "release" : "repeat")); - } break; - - case MP_EVENT_KEYBOARD_CHAR: - { - printf("entered char %s\n", event->character.sequence); - } break; - - default: - break; - } - } - mem_arena_clear(mem_scratch()); - } - - mp_terminate(); - - return(0); -} +*****************************************************************/ +#include +#include +#include + +#include "milepost.h" + +int main() +{ + mp_init(); + + mp_rect rect = { .x = 100, .y = 100, .w = 800, .h = 600 }; + mp_window window = mp_window_create(rect, "test", 0); + + mp_window_bring_to_front(window); + mp_window_focus(window); + + mp_window_center(window); + + while(!mp_should_quit()) + { + mp_pump_events(0); + mp_event* event = 0; + while((event = mp_next_event(mem_scratch())) != 0) + { + switch(event->type) + { + case MP_EVENT_WINDOW_CLOSE: + { + mp_request_quit(); + } + break; + + case MP_EVENT_WINDOW_RESIZE: + { + printf("resized, frame = {%f, %f, %f, %f}, content = {%f, %f, %f, %f}\n", + event->move.frame.x, + event->move.frame.y, + event->move.frame.w, + event->move.frame.h, + event->move.content.x, + event->move.content.y, + event->move.content.w, + event->move.content.h); + } + break; + + case MP_EVENT_WINDOW_MOVE: + { + printf("moved, frame = {%f, %f, %f, %f}, content = {%f, %f, %f, %f}\n", + event->move.frame.x, + event->move.frame.y, + event->move.frame.w, + event->move.frame.h, + event->move.content.x, + event->move.content.y, + event->move.content.w, + event->move.content.h); + } + break; + + case MP_EVENT_MOUSE_MOVE: + { + printf("mouse moved, pos = {%f, %f}, delta = {%f, %f}\n", + event->mouse.x, + event->mouse.y, + event->mouse.deltaX, + event->mouse.deltaY); + } + break; + + case MP_EVENT_MOUSE_WHEEL: + { + printf("mouse wheel, delta = {%f, %f}\n", + event->mouse.deltaX, + event->mouse.deltaY); + } + break; + + case MP_EVENT_MOUSE_ENTER: + { + printf("mouse enter\n"); + } + break; + + case MP_EVENT_MOUSE_LEAVE: + { + printf("mouse leave\n"); + } + break; + + case MP_EVENT_MOUSE_BUTTON: + { + printf("mouse button %i: %i\n", + event->key.code, + event->key.action == MP_KEY_PRESS ? 1 : 0); + } + break; + + case MP_EVENT_KEYBOARD_KEY: + { + printf("key %i: %s\n", + event->key.code, + event->key.action == MP_KEY_PRESS ? "press" : (event->key.action == MP_KEY_RELEASE ? "release" : "repeat")); + } + break; + + case MP_EVENT_KEYBOARD_CHAR: + { + printf("entered char %s\n", event->character.sequence); + } + break; + + default: + break; + } + } + mem_arena_clear(mem_scratch()); + } + + mp_terminate(); + + return (0); +} diff --git a/sketches/smooth_resize/main.c b/sketches/smooth_resize/main.c index a5c8c4d..af66933 100644 --- a/sketches/smooth_resize/main.c +++ b/sketches/smooth_resize/main.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: main.cpp * @author: Martin Fouilleul @@ -6,221 +6,222 @@ * @revision: * *****************************************************************/ -#include -#include -#include -#include +#include +#include +#include +#include #define _USE_MATH_DEFINES //NOTE: necessary for MSVC -#include +#include #define MG_INCLUDE_GL_API -#include"milepost.h" +#include "milepost.h" unsigned int program; const char* vshaderSource = - "#version 430\n" - "attribute vec4 vPosition;\n" - "uniform mat4 transform;\n" - "void main()\n" - "{\n" - " gl_Position = transform*vPosition;\n" - "}\n"; + "#version 430\n" + "attribute vec4 vPosition;\n" + "uniform mat4 transform;\n" + "void main()\n" + "{\n" + " gl_Position = transform*vPosition;\n" + "}\n"; const char* fshaderSource = - "#version 430\n" - "precision mediump float;\n" - "void main()\n" - "{\n" - " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" - "}\n"; + "#version 430\n" + "precision mediump float;\n" + "void main()\n" + "{\n" + " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" + "}\n"; void compile_shader(GLuint shader, const char* source) { - glShaderSource(shader, 1, &source, 0); - glCompileShader(shader); + glShaderSource(shader, 1, &source, 0); + glCompileShader(shader); - int err = glGetError(); - if(err) - { - printf("gl error: %i\n", err); - } + int err = glGetError(); + if(err) + { + printf("gl error: %i\n", err); + } - int status = 0; - glGetShaderiv(shader, GL_COMPILE_STATUS, &status); - if(!status) - { - char buffer[256]; - int size = 0; - glGetShaderInfoLog(shader, 256, &size, buffer); - printf("shader error: %.*s\n", size, buffer); - } + int status = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + if(!status) + { + char buffer[256]; + int size = 0; + glGetShaderInfoLog(shader, 256, &size, buffer); + printf("shader error: %.*s\n", size, buffer); + } } GLfloat vertices[] = { - -0.866/2, -0.5/2, 0, 0.866/2, -0.5/2, 0, 0, 0.5, 0}; + -0.866 / 2, -0.5 / 2, 0, 0.866 / 2, -0.5 / 2, 0, 0, 0.5, 0 +}; typedef struct app_data { - mp_window window; - mg_surface surface; - mg_canvas canvas; - mg_font font; + mp_window window; + mg_surface surface; + mg_canvas canvas; + mg_font font; - GLuint vertexBuffer; + GLuint vertexBuffer; } app_data; void process_event(app_data* app, mp_event event) { - switch(event.type) - { - case MP_EVENT_WINDOW_CLOSE: - { - mp_request_quit(); - } break; + switch(event.type) + { + case MP_EVENT_WINDOW_CLOSE: + { + mp_request_quit(); + } + break; - case MP_EVENT_WINDOW_RESIZE: - { - log_info("resizing window!\n"); - } break; + case MP_EVENT_WINDOW_RESIZE: + { + log_info("resizing window!\n"); + } + break; - default: - break; - } + default: + break; + } } void update_and_render(app_data* app) { - mg_surface_prepare(app->surface); + mg_surface_prepare(app->surface); - glClearColor(0.3, 0.3, 1, 1); - glClear(GL_COLOR_BUFFER_BIT); + glClearColor(0.3, 0.3, 1, 1); + glClear(GL_COLOR_BUFFER_BIT); - static float alpha = 0; - //f32 aspect = frameSize.x/frameSize.y; - f32 aspect = 800/(f32)600; + static float alpha = 0; + //f32 aspect = frameSize.x/frameSize.y; + f32 aspect = 800 / (f32)600; - GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0, - -sinf(alpha)/aspect, cosf(alpha), 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1}; + GLfloat matrix[] = { cosf(alpha) / aspect, sinf(alpha), 0, 0, + -sinf(alpha) / aspect, cosf(alpha), 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 }; - alpha += 2*M_PI/120; + alpha += 2 * M_PI / 120; - glUniformMatrix4fv(0, 1, false, matrix); + glUniformMatrix4fv(0, 1, false, matrix); + glBindBuffer(GL_ARRAY_BUFFER, app->vertexBuffer); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(0); - glBindBuffer(GL_ARRAY_BUFFER, app->vertexBuffer); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); - glEnableVertexAttribArray(0); + glDrawArrays(GL_TRIANGLES, 0, 3); - glDrawArrays(GL_TRIANGLES, 0, 3); + mg_surface_present(app->surface); - mg_surface_present(app->surface); - - mem_arena_clear(mem_scratch()); + mem_arena_clear(mem_scratch()); } i32 render(void* user) { - app_data* app = (app_data*)user; + app_data* app = (app_data*)user; - //NOTE: init shader and gl state - mg_surface_prepare(app->surface); + //NOTE: init shader and gl state + mg_surface_prepare(app->surface); - GLuint vao; - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); + GLuint vao; + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); - glGenBuffers(1, &app->vertexBuffer); + glGenBuffers(1, &app->vertexBuffer); - GLfloat vertices[] = { - -0.866/2, -0.5/2, 0, 0.866/2, -0.5/2, 0, 0, 0.5, 0}; + GLfloat vertices[] = { + -0.866 / 2, -0.5 / 2, 0, 0.866 / 2, -0.5 / 2, 0, 0, 0.5, 0 + }; - glBindBuffer(GL_ARRAY_BUFFER, app->vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, app->vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + unsigned int vshader = glCreateShader(GL_VERTEX_SHADER); + unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER); + program = glCreateProgram(); - unsigned int vshader = glCreateShader(GL_VERTEX_SHADER); - unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER); - program = glCreateProgram(); + compile_shader(vshader, vshaderSource); + compile_shader(fshader, fshaderSource); - compile_shader(vshader, vshaderSource); - compile_shader(fshader, fshaderSource); + glAttachShader(program, vshader); + glAttachShader(program, fshader); + glLinkProgram(program); - glAttachShader(program, vshader); - glAttachShader(program, fshader); - glLinkProgram(program); + int status = 0; + glGetProgramiv(program, GL_LINK_STATUS, &status); + if(!status) + { + char buffer[256]; + int size = 0; + glGetProgramInfoLog(program, 256, &size, buffer); + printf("link error: %.*s\n", size, buffer); + } - int status = 0; - glGetProgramiv(program, GL_LINK_STATUS, &status); - if(!status) - { - char buffer[256]; - int size = 0; - glGetProgramInfoLog(program, 256, &size, buffer); - printf("link error: %.*s\n", size, buffer); - } + glUseProgram(program); - glUseProgram(program); + while(!mp_should_quit()) + { + mp_event* event = 0; - while(!mp_should_quit()) - { - mp_event* event = 0; + while((event = mp_next_event(mem_scratch())) != 0) + { + process_event(app, *event); + } + update_and_render(app); + mem_arena_clear(mem_scratch()); + } - while((event = mp_next_event(mem_scratch())) != 0) - { - process_event(app, *event); - } - update_and_render(app); - mem_arena_clear(mem_scratch()); - } - - return(0); + return (0); } int main() { - mp_init(); - mp_clock_init(); //TODO put that in mp_init()? + mp_init(); + mp_clock_init(); //TODO put that in mp_init()? - mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610}; - mp_window window = mp_window_create(windowRect, "test", 0); + mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 }; + mp_window window = mp_window_create(windowRect, "test", 0); - //NOTE: create surface - mg_surface surface = mg_surface_create_for_window(window, MG_GL); - if(mg_surface_is_nil(surface)) - { - printf("Error: couldn't create surface\n"); - return(-1); - } + //NOTE: create surface + mg_surface surface = mg_surface_create_for_window(window, MG_GL); + if(mg_surface_is_nil(surface)) + { + printf("Error: couldn't create surface\n"); + return (-1); + } - mg_surface_swap_interval(surface, 1); - mg_surface_deselect(); + mg_surface_swap_interval(surface, 1); + mg_surface_deselect(); + // start app + mp_window_bring_to_front(window); + mp_window_focus(window); - // start app - mp_window_bring_to_front(window); - mp_window_focus(window); + //TODO: start thread + app_data app = { .window = window, + .surface = surface }; - //TODO: start thread - app_data app = {.window = window, - .surface = surface}; + mp_thread* renderThread = mp_thread_create(render, &app); - mp_thread* renderThread = mp_thread_create(render, &app); + while(!mp_should_quit()) + { + mp_pump_events(0); + } - while(!mp_should_quit()) - { - mp_pump_events(0); - } + mp_thread_join(renderThread, NULL); - mp_thread_join(renderThread, NULL); + mg_surface_destroy(surface); + mp_window_destroy(window); - mg_surface_destroy(surface); - mp_window_destroy(window); + mp_terminate(); - mp_terminate(); - - return(0); + return (0); } diff --git a/sketches/surface_sharing/main.c b/sketches/surface_sharing/main.c index 88eb897..e6f8e32 100644 --- a/sketches/surface_sharing/main.c +++ b/sketches/surface_sharing/main.c @@ -1,291 +1,291 @@ -#include -#include +#include +#include #define _USE_MATH_DEFINES //NOTE: necessary for MSVC -#include +#include -#include -#include +#include +#include #define MG_INCLUDE_GL_API 1 -#include"milepost.h" +#include "milepost.h" #define LOG_SUBSYSTEM "Main" #ifdef OS_WIN64 - #include - #include - #include + #include + #include + #include - #define dup2 _dup2 - #define pipe(fds) _pipe(fds, 256, O_BINARY) - #define read _read - #define write _write + #define dup2 _dup2 + #define pipe(fds) _pipe(fds, 256, O_BINARY) + #define read _read + #define write _write - #define process_id HANDLE + #define process_id HANDLE - process_id spawn_child(char* program, char** argv) - { - return((process_id)_spawnv(P_NOWAIT, program, argv)); - } +process_id spawn_child(char* program, char** argv) +{ + return ((process_id)_spawnv(P_NOWAIT, program, argv)); +} - void terminate_child(process_id child) - { - TerminateProcess(child, 0); - } +void terminate_child(process_id child) +{ + TerminateProcess(child, 0); +} #elif OS_MACOS - #include - #include + #include + #include - #define process_id pid_t + #define process_id pid_t - process_id spawn_child(char* program, char** argv) - { - pid_t pid = fork(); - if(!pid) - { - char* envp[] = {0}; - execve(program, argv, envp); - assert(0); - } - return(pid); - } +process_id spawn_child(char* program, char** argv) +{ + pid_t pid = fork(); + if(!pid) + { + char* envp[] = { 0 }; + execve(program, argv, envp); + assert(0); + } + return (pid); +} - void terminate_child(process_id child) - { - kill(child, SIGTERM); - } +void terminate_child(process_id child) +{ + kill(child, SIGTERM); +} #endif - unsigned int program; const char* vshaderSource = - //"#version 320 es\n" - "attribute vec4 vPosition;\n" - "uniform mat4 transform;\n" - "void main()\n" - "{\n" - " gl_Position = transform*vPosition;\n" - "}\n"; + //"#version 320 es\n" + "attribute vec4 vPosition;\n" + "uniform mat4 transform;\n" + "void main()\n" + "{\n" + " gl_Position = transform*vPosition;\n" + "}\n"; const char* fshaderSource = - //"#version 320 es\n" - "precision mediump float;\n" - "void main()\n" - "{\n" - " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" - "}\n"; + //"#version 320 es\n" + "precision mediump float;\n" + "void main()\n" + "{\n" + " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" + "}\n"; void compile_shader(GLuint shader, const char* source) { - glShaderSource(shader, 1, &source, 0); - glCompileShader(shader); + glShaderSource(shader, 1, &source, 0); + glCompileShader(shader); - int err = glGetError(); - if(err) - { - printf("gl error: %i\n", err); - } + int err = glGetError(); + if(err) + { + printf("gl error: %i\n", err); + } - int status = 0; - glGetShaderiv(shader, GL_COMPILE_STATUS, &status); - if(!status) - { - char buffer[256]; - int size = 0; - glGetShaderInfoLog(shader, 256, &size, buffer); - printf("shader error: %.*s\n", size, buffer); - } + int status = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + if(!status) + { + char buffer[256]; + int size = 0; + glGetShaderInfoLog(shader, 256, &size, buffer); + printf("shader error: %.*s\n", size, buffer); + } } int child_main(int writeFd) { - mp_init(); + mp_init(); - mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600}; - mp_window window = mp_window_create(rect, "test", 0); + mp_rect rect = { .x = 100, .y = 100, .w = 800, .h = 600 }; + mp_window window = mp_window_create(rect, "test", 0); - //NOTE: create surface - mg_surface surface = mg_surface_create_remote(800, 600, MG_BACKEND_GLES); - mg_surface_id connectionID = mg_surface_remote_id(surface); + //NOTE: create surface + mg_surface surface = mg_surface_create_remote(800, 600, MG_BACKEND_GLES); + mg_surface_id connectionID = mg_surface_remote_id(surface); - mg_surface_prepare(surface); + mg_surface_prepare(surface); - //NOTE: init shader and gl state - mg_surface_prepare(surface); + //NOTE: init shader and gl state + mg_surface_prepare(surface); - GLuint vao; - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); + GLuint vao; + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); - GLuint vertexBuffer; - glGenBuffers(1, &vertexBuffer); + GLuint vertexBuffer; + glGenBuffers(1, &vertexBuffer); - GLfloat vertices[] = { - -0.866/2, -0.5/2, 0, 0.866/2, -0.5/2, 0, 0, 0.5, 0}; + GLfloat vertices[] = { + -0.866 / 2, -0.5 / 2, 0, 0.866 / 2, -0.5 / 2, 0, 0, 0.5, 0 + }; - glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + unsigned int vshader = glCreateShader(GL_VERTEX_SHADER); + unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER); + program = glCreateProgram(); - unsigned int vshader = glCreateShader(GL_VERTEX_SHADER); - unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER); - program = glCreateProgram(); + compile_shader(vshader, vshaderSource); + compile_shader(fshader, fshaderSource); - compile_shader(vshader, vshaderSource); - compile_shader(fshader, fshaderSource); + glAttachShader(program, vshader); + glAttachShader(program, fshader); + glLinkProgram(program); - glAttachShader(program, vshader); - glAttachShader(program, fshader); - glLinkProgram(program); + int status = 0; + glGetProgramiv(program, GL_LINK_STATUS, &status); + if(!status) + { + char buffer[256]; + int size = 0; + glGetProgramInfoLog(program, 256, &size, buffer); + printf("link error: %.*s\n", size, buffer); + } - int status = 0; - glGetProgramiv(program, GL_LINK_STATUS, &status); - if(!status) - { - char buffer[256]; - int size = 0; - glGetProgramInfoLog(program, 256, &size, buffer); - printf("link error: %.*s\n", size, buffer); - } + glUseProgram(program); - glUseProgram(program); + //NOTE: send context id to parent + write(writeFd, &connectionID, sizeof(connectionID)); - //NOTE: send context id to parent - write(writeFd, &connectionID, sizeof(connectionID)); + //NOTE: render loop + while(!mp_should_quit()) + { + mp_pump_events(0); + mp_event event = { 0 }; + while(mp_next_event(&event)) + { + switch(event.type) + { + case MP_EVENT_WINDOW_CLOSE: + { + mp_request_quit(); + } + break; - //NOTE: render loop - while(!mp_should_quit()) - { - mp_pump_events(0); - mp_event event = {0}; - while(mp_next_event(&event)) - { - switch(event.type) - { - case MP_EVENT_WINDOW_CLOSE: - { - mp_request_quit(); - } break; + default: + break; + } + } - default: - break; - } - } + mg_surface_prepare(surface); - mg_surface_prepare(surface); + mp_rect rect = mg_surface_get_frame(surface); + vec2 scaling = mg_surface_contents_scaling(surface); - mp_rect rect = mg_surface_get_frame(surface); - vec2 scaling = mg_surface_contents_scaling(surface); + glViewport(0, 0, rect.w * scaling.x, rect.h * scaling.y); + glClearColor(0.3, 0.3, 1, 1); + glClear(GL_COLOR_BUFFER_BIT); - glViewport(0, 0, rect.w*scaling.x, rect.h*scaling.y); - glClearColor(0.3, 0.3, 1, 1); - glClear(GL_COLOR_BUFFER_BIT); + static float alpha = 0; + //f32 aspect = frameSize.x/frameSize.y; + f32 aspect = 800 / (f32)600; - static float alpha = 0; - //f32 aspect = frameSize.x/frameSize.y; - f32 aspect = 800/(f32)600; + GLfloat matrix[] = { cosf(alpha) / aspect, sinf(alpha), 0, 0, + -sinf(alpha) / aspect, cosf(alpha), 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 }; - GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0, - -sinf(alpha)/aspect, cosf(alpha), 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1}; + alpha += 2 * M_PI / 120; - alpha += 2*M_PI/120; + glUniformMatrix4fv(0, 1, false, matrix); - glUniformMatrix4fv(0, 1, false, matrix); + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(0); + glDrawArrays(GL_TRIANGLES, 0, 3); - glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); - glEnableVertexAttribArray(0); + mg_surface_present(surface); + } - glDrawArrays(GL_TRIANGLES, 0, 3); + mp_terminate(); - mg_surface_present(surface); - } - - mp_terminate(); - - return(0); + return (0); } int main(int argc, char** argv) { - LogLevel(LOG_LEVEL_DEBUG); + LogLevel(LOG_LEVEL_DEBUG); - if(argc > 1) - { - if(!strcmp(argv[1], "--child")) - { - int writeFd = atoi(argv[2]); - printf("child process created with file desc %i\n", writeFd); - return(child_main(writeFd)); - } - else - { - return(-1); - } - } -// setvbuf( stdout, NULL, _IONBF, 0 ); - mp_init(); + if(argc > 1) + { + if(!strcmp(argv[1], "--child")) + { + int writeFd = atoi(argv[2]); + printf("child process created with file desc %i\n", writeFd); + return (child_main(writeFd)); + } + else + { + return (-1); + } + } + // setvbuf( stdout, NULL, _IONBF, 0 ); + mp_init(); - //NOTE: create main window - mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600}; - mp_window window = mp_window_create(rect, "test", 0); + //NOTE: create main window + mp_rect rect = { .x = 100, .y = 100, .w = 800, .h = 600 }; + mp_window window = mp_window_create(rect, "test", 0); - //NOTE: create surface client - mg_surface surface = mg_surface_create_host(window); + //NOTE: create surface client + mg_surface surface = mg_surface_create_host(window); - //NOTE setup descriptors - int fileDesc[2]; - pipe(fileDesc); + //NOTE setup descriptors + int fileDesc[2]; + pipe(fileDesc); - printf("parent process created readFd %i and writeFd %i\n", fileDesc[0], fileDesc[1]); + printf("parent process created readFd %i and writeFd %i\n", fileDesc[0], fileDesc[1]); - char writeDescStr[64]; - snprintf(writeDescStr, 64, "%i", fileDesc[1]); - char* args[] = {"bin/example_surface_sharing", "--child", writeDescStr, 0}; + char writeDescStr[64]; + snprintf(writeDescStr, 64, "%i", fileDesc[1]); + char* args[] = { "bin/example_surface_sharing", "--child", writeDescStr, 0 }; - process_id child = spawn_child(args[0], args); + process_id child = spawn_child(args[0], args); - //NOTE: read the connection id - mg_surface_id connectionID = 0; - read(fileDesc[0], &connectionID, sizeof(connectionID)); - printf("received child connection id %llu\n", connectionID); + //NOTE: read the connection id + mg_surface_id connectionID = 0; + read(fileDesc[0], &connectionID, sizeof(connectionID)); + printf("received child connection id %llu\n", connectionID); - //NOTE: connect the client - mg_surface_host_connect(surface, connectionID); + //NOTE: connect the client + mg_surface_host_connect(surface, connectionID); - //NOTE: show the window - mp_window_bring_to_front(window); + //NOTE: show the window + mp_window_bring_to_front(window); - while(!mp_should_quit()) - { - mp_pump_events(0); - mp_event event = {0}; - while(mp_next_event(&event)) - { - switch(event.type) - { - case MP_EVENT_WINDOW_CLOSE: - { - mp_request_quit(); - } break; + while(!mp_should_quit()) + { + mp_pump_events(0); + mp_event event = { 0 }; + while(mp_next_event(&event)) + { + switch(event.type) + { + case MP_EVENT_WINDOW_CLOSE: + { + mp_request_quit(); + } + break; - default: - break; - } - } - mg_surface_prepare(surface); - mg_surface_present(surface); - } + default: + break; + } + } + mg_surface_prepare(surface); + mg_surface_present(surface); + } - terminate_child(child); + terminate_child(child); - mp_terminate(); - return(0); + mp_terminate(); + return (0); } diff --git a/sketches/tiger/main.c b/sketches/tiger/main.c index 761daa2..4ca59ec 100644 --- a/sketches/tiger/main.c +++ b/sketches/tiger/main.c @@ -1,247 +1,253 @@ -/************************************************************//** +/************************************************************/ /** * * @file: main.cpp * @author: Martin Fouilleul * @date: 30/07/2022 * @revision: * -*****************************************************************/ -#include -#include -#include -#include - -#define _USE_MATH_DEFINES //NOTE: necessary for MSVC -#include - -#include"milepost.h" - -#include"tiger.c" - -mg_font create_font() -{ - //NOTE(martin): create font - str8 fontPath = path_executable_relative(mem_scratch(), STR8("../resources/OpenSansLatinSubset.ttf")); - char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath); - - FILE* fontFile = fopen(fontPathCString, "r"); - if(!fontFile) - { - log_error("Could not load font file '%s': %s\n", fontPathCString, strerror(errno)); - return(mg_font_nil()); - } - unsigned char* fontData = 0; - fseek(fontFile, 0, SEEK_END); - u32 fontDataSize = ftell(fontFile); - rewind(fontFile); - fontData = (unsigned char*)malloc(fontDataSize); - fread(fontData, 1, fontDataSize, fontFile); - fclose(fontFile); - - unicode_range ranges[5] = {UNICODE_RANGE_BASIC_LATIN, - UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT, - UNICODE_RANGE_LATIN_EXTENDED_A, - UNICODE_RANGE_LATIN_EXTENDED_B, - UNICODE_RANGE_SPECIALS}; - - mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges); - free(fontData); - - return(font); -} - -int main() -{ - mp_init(); - mp_clock_init(); //TODO put that in mp_init()? - - mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610}; - mp_window window = mp_window_create(windowRect, "test", 0); - - mp_rect contentRect = mp_window_get_content_rect(window); - - //NOTE: create surface - mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS); - if(mg_surface_is_nil(surface)) - { - log_error("Couln't create surface\n"); - return(-1); - } - mg_surface_swap_interval(surface, 0); - - //TODO: create canvas - mg_canvas canvas = mg_canvas_create(); - - if(mg_canvas_is_nil(canvas)) - { - printf("Error: couldn't create canvas\n"); - return(-1); - } - - mg_font font = create_font(); - - // start app - mp_window_bring_to_front(window); - mp_window_focus(window); - - bool tracked = false; - vec2 trackPoint = {0}; - - f32 zoom = 1; - f32 startX = 300, startY = 200; - bool singlePath = false; - int singlePathIndex = 0; - - f64 frameTime = 0; - - mp_input_state inputState = {0}; - - while(!mp_should_quit()) - { - f64 startTime = mp_get_time(MP_CLOCK_MONOTONIC); - - mp_pump_events(0); - mp_event* event = 0; - while((event = mp_next_event(mem_scratch())) != 0) - { - mp_input_process_event(&inputState, event); - - switch(event->type) - { - case MP_EVENT_WINDOW_CLOSE: - { - mp_request_quit(); - } break; - - case MP_EVENT_MOUSE_BUTTON: - { - if(event->key.code == MP_MOUSE_LEFT) - { - if(event->key.action == MP_KEY_PRESS) - { - tracked = true; - vec2 mousePos = mp_mouse_position(&inputState); - trackPoint.x = (mousePos.x - startX)/zoom; - trackPoint.y = (mousePos.y - startY)/zoom; - } - else - { - tracked = false; - } - } - } break; - - case MP_EVENT_MOUSE_WHEEL: - { - vec2 mousePos = mp_mouse_position(&inputState); - f32 pinX = (mousePos.x - startX)/zoom; - f32 pinY = (mousePos.y - startY)/zoom; - - zoom *= 1 + event->mouse.deltaY * 0.01; - zoom = Clamp(zoom, 0.5, 5); - - startX = mousePos.x - pinX*zoom; - startY = mousePos.y - pinY*zoom; - } break; - - case MP_EVENT_KEYBOARD_KEY: - { - if(event->key.action == MP_KEY_PRESS || event->key.action == MP_KEY_REPEAT) - { - switch(event->key.code) - { - case MP_KEY_SPACE: - singlePath = !singlePath; - break; - - case MP_KEY_UP: - { - if(event->key.mods & MP_KEYMOD_SHIFT) - { - singlePathIndex++; - } - else - { - zoom += 0.001; - } - } break; - - case MP_KEY_DOWN: - { - if(event->key.mods & MP_KEYMOD_SHIFT) - { - singlePathIndex--; - } - else - { - zoom -= 0.001; - } - } break; - } - } - } break; - - default: - break; - } - } - - if(tracked) - { - vec2 mousePos = mp_mouse_position(&inputState); - startX = mousePos.x - trackPoint.x*zoom; - startY = mousePos.y - trackPoint.y*zoom; - } - - mg_surface_prepare(surface); - - mg_set_color_rgba(1, 0, 1, 1); - mg_clear(); - - mg_matrix_push((mg_mat2x3){zoom, 0, startX, - 0, zoom, startY}); - - draw_tiger(singlePath, singlePathIndex); - - if(singlePath) - { - printf("display single path %i\n", singlePathIndex); - printf("viewpos = (%f, %f), zoom = %f\n", startX, startY, zoom); - } - - mg_matrix_pop(); - - // text - mg_set_color_rgba(0, 0, 1, 1); - mg_set_font(font); - mg_set_font_size(12); - mg_move_to(50, 600-50); - - str8 text = str8_pushf(mem_scratch(), - "Milepost vector graphics test program (frame time = %fs, fps = %f)...", - frameTime, - 1./frameTime); - mg_text_outlines(text); - mg_fill(); - - printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n", - frameTime, - 1./frameTime); - - mg_render(surface, canvas); - mg_surface_present(surface); - - mp_input_next_frame(&inputState); - mem_arena_clear(mem_scratch()); - frameTime = mp_get_time(MP_CLOCK_MONOTONIC) - startTime; - } - - mg_font_destroy(font); - mg_canvas_destroy(canvas); - mg_surface_destroy(surface); - mp_window_destroy(window); - - mp_terminate(); - - return(0); -} +*****************************************************************/ +#include +#include +#include +#include + +#define _USE_MATH_DEFINES //NOTE: necessary for MSVC +#include + +#include "milepost.h" + +#include "tiger.c" + +mg_font create_font() +{ + //NOTE(martin): create font + str8 fontPath = path_executable_relative(mem_scratch(), STR8("../resources/OpenSansLatinSubset.ttf")); + char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath); + + FILE* fontFile = fopen(fontPathCString, "r"); + if(!fontFile) + { + log_error("Could not load font file '%s': %s\n", fontPathCString, strerror(errno)); + return (mg_font_nil()); + } + unsigned char* fontData = 0; + fseek(fontFile, 0, SEEK_END); + u32 fontDataSize = ftell(fontFile); + rewind(fontFile); + fontData = (unsigned char*)malloc(fontDataSize); + fread(fontData, 1, fontDataSize, fontFile); + fclose(fontFile); + + unicode_range ranges[5] = { UNICODE_RANGE_BASIC_LATIN, + UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT, + UNICODE_RANGE_LATIN_EXTENDED_A, + UNICODE_RANGE_LATIN_EXTENDED_B, + UNICODE_RANGE_SPECIALS }; + + mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges); + free(fontData); + + return (font); +} + +int main() +{ + mp_init(); + mp_clock_init(); //TODO put that in mp_init()? + + mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 }; + mp_window window = mp_window_create(windowRect, "test", 0); + + mp_rect contentRect = mp_window_get_content_rect(window); + + //NOTE: create surface + mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS); + if(mg_surface_is_nil(surface)) + { + log_error("Couln't create surface\n"); + return (-1); + } + mg_surface_swap_interval(surface, 0); + + //TODO: create canvas + mg_canvas canvas = mg_canvas_create(); + + if(mg_canvas_is_nil(canvas)) + { + printf("Error: couldn't create canvas\n"); + return (-1); + } + + mg_font font = create_font(); + + // start app + mp_window_bring_to_front(window); + mp_window_focus(window); + + bool tracked = false; + vec2 trackPoint = { 0 }; + + f32 zoom = 1; + f32 startX = 300, startY = 200; + bool singlePath = false; + int singlePathIndex = 0; + + f64 frameTime = 0; + + mp_input_state inputState = { 0 }; + + while(!mp_should_quit()) + { + f64 startTime = mp_get_time(MP_CLOCK_MONOTONIC); + + mp_pump_events(0); + mp_event* event = 0; + while((event = mp_next_event(mem_scratch())) != 0) + { + mp_input_process_event(&inputState, event); + + switch(event->type) + { + case MP_EVENT_WINDOW_CLOSE: + { + mp_request_quit(); + } + break; + + case MP_EVENT_MOUSE_BUTTON: + { + if(event->key.code == MP_MOUSE_LEFT) + { + if(event->key.action == MP_KEY_PRESS) + { + tracked = true; + vec2 mousePos = mp_mouse_position(&inputState); + trackPoint.x = (mousePos.x - startX) / zoom; + trackPoint.y = (mousePos.y - startY) / zoom; + } + else + { + tracked = false; + } + } + } + break; + + case MP_EVENT_MOUSE_WHEEL: + { + vec2 mousePos = mp_mouse_position(&inputState); + f32 pinX = (mousePos.x - startX) / zoom; + f32 pinY = (mousePos.y - startY) / zoom; + + zoom *= 1 + event->mouse.deltaY * 0.01; + zoom = Clamp(zoom, 0.5, 5); + + startX = mousePos.x - pinX * zoom; + startY = mousePos.y - pinY * zoom; + } + break; + + case MP_EVENT_KEYBOARD_KEY: + { + if(event->key.action == MP_KEY_PRESS || event->key.action == MP_KEY_REPEAT) + { + switch(event->key.code) + { + case MP_KEY_SPACE: + singlePath = !singlePath; + break; + + case MP_KEY_UP: + { + if(event->key.mods & MP_KEYMOD_SHIFT) + { + singlePathIndex++; + } + else + { + zoom += 0.001; + } + } + break; + + case MP_KEY_DOWN: + { + if(event->key.mods & MP_KEYMOD_SHIFT) + { + singlePathIndex--; + } + else + { + zoom -= 0.001; + } + } + break; + } + } + } + break; + + default: + break; + } + } + + if(tracked) + { + vec2 mousePos = mp_mouse_position(&inputState); + startX = mousePos.x - trackPoint.x * zoom; + startY = mousePos.y - trackPoint.y * zoom; + } + + mg_surface_prepare(surface); + + mg_set_color_rgba(1, 0, 1, 1); + mg_clear(); + + mg_matrix_push((mg_mat2x3){ zoom, 0, startX, + 0, zoom, startY }); + + draw_tiger(singlePath, singlePathIndex); + + if(singlePath) + { + printf("display single path %i\n", singlePathIndex); + printf("viewpos = (%f, %f), zoom = %f\n", startX, startY, zoom); + } + + mg_matrix_pop(); + + // text + mg_set_color_rgba(0, 0, 1, 1); + mg_set_font(font); + mg_set_font_size(12); + mg_move_to(50, 600 - 50); + + str8 text = str8_pushf(mem_scratch(), + "Milepost vector graphics test program (frame time = %fs, fps = %f)...", + frameTime, + 1. / frameTime); + mg_text_outlines(text); + mg_fill(); + + printf("Milepost vector graphics test program (frame time = %fs, fps = %f)...\n", + frameTime, + 1. / frameTime); + + mg_render(surface, canvas); + mg_surface_present(surface); + + mp_input_next_frame(&inputState); + mem_arena_clear(mem_scratch()); + frameTime = mp_get_time(MP_CLOCK_MONOTONIC) - startTime; + } + + mg_font_destroy(font); + mg_canvas_destroy(canvas); + mg_surface_destroy(surface); + mp_window_destroy(window); + + mp_terminate(); + + return (0); +} diff --git a/sketches/tiger/tiger.c b/sketches/tiger/tiger.c index 6097216..f6700cc 100644 --- a/sketches/tiger/tiger.c +++ b/sketches/tiger/tiger.c @@ -1,4861 +1,4860 @@ void draw_tiger(bool singlePath, int singlePathIndex) { - if(!singlePath || singlePathIndex == 0) - { - mg_move_to(-122.300, 84.285); - mg_cubic_to(-122.300, 84.285, -122.200, 86.179, -123.030, 86.160); - mg_cubic_to(-123.850, 86.141, -140.300, 38.066, -160.830, 40.309); - mg_cubic_to(-160.830, 40.309, -143.050, 32.956, -122.300, 84.285); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 1) - { - mg_set_width(0.17200001); - mg_move_to(-122.300, 84.285); - mg_cubic_to(-122.300, 84.285, -122.200, 86.179, -123.030, 86.160); - mg_cubic_to(-123.850, 86.141, -140.300, 38.066, -160.830, 40.309); - mg_cubic_to(-160.830, 40.309, -143.050, 32.956, -122.300, 84.285); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 2) - { - mg_move_to(-118.770, 81.262); - mg_cubic_to(-118.770, 81.262, -119.320, 83.078, -120.090, 82.779); - mg_cubic_to(-120.860, 82.481, -119.980, 31.675, -140.040, 26.801); - mg_cubic_to(-140.040, 26.801, -120.820, 25.937, -118.770, 81.262); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 3) - { - mg_set_width(0.17200001); - mg_move_to(-118.770, 81.262); - mg_cubic_to(-118.770, 81.262, -119.320, 83.078, -120.090, 82.779); - mg_cubic_to(-120.860, 82.481, -119.980, 31.675, -140.040, 26.801); - mg_cubic_to(-140.040, 26.801, -120.820, 25.937, -118.770, 81.262); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 4) - { - mg_move_to(-91.284, 123.590); - mg_cubic_to(-91.284, 123.590, -89.648, 124.550, -90.118, 125.230); - mg_cubic_to(-90.589, 125.900, -139.760, 113.100, -149.220, 131.460); - mg_cubic_to(-149.220, 131.460, -145.540, 112.570, -91.284, 123.590); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 5) - { - mg_set_width(0.17200001); - mg_move_to(-91.284, 123.590); - mg_cubic_to(-91.284, 123.590, -89.648, 124.550, -90.118, 125.230); - mg_cubic_to(-90.589, 125.900, -139.760, 113.100, -149.220, 131.460); - mg_cubic_to(-149.220, 131.460, -145.540, 112.570, -91.284, 123.590); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 6) - { - mg_move_to(-94.093, 133.800); - mg_cubic_to(-94.093, 133.800, -92.237, 134.200, -92.471, 134.990); - mg_cubic_to(-92.704, 135.780, -143.410, 139.120, -146.600, 159.520); - mg_cubic_to(-146.600, 159.520, -149.060, 140.440, -94.093, 133.800); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 7) - { - mg_set_width(0.17200001); - mg_move_to(-94.093, 133.800); - mg_cubic_to(-94.093, 133.800, -92.237, 134.200, -92.471, 134.990); - mg_cubic_to(-92.704, 135.780, -143.410, 139.120, -146.600, 159.520); - mg_cubic_to(-146.600, 159.520, -149.060, 140.440, -94.093, 133.800); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 8) - { - mg_move_to(-98.304, 128.280); - mg_cubic_to(-98.304, 128.280, -96.526, 128.940, -96.872, 129.690); - mg_cubic_to(-97.218, 130.440, -147.870, 126.350, -154.000, 146.060); - mg_cubic_to(-154.000, 146.060, -153.650, 126.820, -98.304, 128.280); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 9) - { - mg_set_width(0.17200001); - mg_move_to(-98.304, 128.280); - mg_cubic_to(-98.304, 128.280, -96.526, 128.940, -96.872, 129.690); - mg_cubic_to(-97.218, 130.440, -147.870, 126.350, -154.000, 146.060); - mg_cubic_to(-154.000, 146.060, -153.650, 126.820, -98.304, 128.280); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 10) - { - mg_move_to(-109.010, 110.070); - mg_cubic_to(-109.010, 110.070, -107.700, 111.450, -108.340, 111.970); - mg_cubic_to(-108.980, 112.490, -152.720, 86.634, -166.870, 101.680); - mg_cubic_to(-166.870, 101.680, -158.130, 84.533, -109.010, 110.070); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 11) - { - mg_set_width(0.17200001); - mg_move_to(-109.010, 110.070); - mg_cubic_to(-109.010, 110.070, -107.700, 111.450, -108.340, 111.970); - mg_cubic_to(-108.980, 112.490, -152.720, 86.634, -166.870, 101.680); - mg_cubic_to(-166.870, 101.680, -158.130, 84.533, -109.010, 110.070); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 12) - { - mg_move_to(-116.550, 114.260); - mg_cubic_to(-116.550, 114.260, -115.100, 115.480, -115.670, 116.070); - mg_cubic_to(-116.250, 116.660, -162.640, 95.922, -174.990, 112.470); - mg_cubic_to(-174.990, 112.470, -168.250, 94.447, -116.550, 114.260); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 13) - { - mg_set_width(0.17200001); - mg_move_to(-116.550, 114.260); - mg_cubic_to(-116.550, 114.260, -115.100, 115.480, -115.670, 116.070); - mg_cubic_to(-116.250, 116.660, -162.640, 95.922, -174.990, 112.470); - mg_cubic_to(-174.990, 112.470, -168.250, 94.447, -116.550, 114.260); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 14) - { - mg_move_to(-119.150, 118.340); - mg_cubic_to(-119.150, 118.340, -117.550, 119.340, -118.040, 120.010); - mg_cubic_to(-118.530, 120.670, -167.310, 106.450, -177.290, 124.520); - mg_cubic_to(-177.290, 124.520, -173.070, 105.750, -119.150, 118.340); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 15) - { - mg_set_width(0.17200001); - mg_move_to(-119.150, 118.340); - mg_cubic_to(-119.150, 118.340, -117.550, 119.340, -118.040, 120.010); - mg_cubic_to(-118.530, 120.670, -167.310, 106.450, -177.290, 124.520); - mg_cubic_to(-177.290, 124.520, -173.070, 105.750, -119.150, 118.340); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 16) - { - mg_move_to(-108.420, 118.950); - mg_cubic_to(-108.420, 118.950, -107.300, 120.480, -108.000, 120.920); - mg_cubic_to(-108.700, 121.350, -148.770, 90.102, -164.730, 103.210); - mg_cubic_to(-164.730, 103.210, -153.860, 87.326, -108.420, 118.950); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 17) - { - mg_set_width(0.17200001); - mg_move_to(-108.420, 118.950); - mg_cubic_to(-108.420, 118.950, -107.300, 120.480, -108.000, 120.920); - mg_cubic_to(-108.700, 121.350, -148.770, 90.102, -164.730, 103.210); - mg_cubic_to(-164.730, 103.210, -153.860, 87.326, -108.420, 118.950); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 18) - { - mg_move_to(-128.200, 90.000); - mg_cubic_to(-128.200, 90.000, -127.600, 91.800, -128.400, 92.000); - mg_cubic_to(-129.200, 92.200, -157.800, 50.200, -177.000, 57.800); - mg_cubic_to(-177.000, 57.800, -161.800, 46.000, -128.200, 90.000); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 19) - { - mg_set_width(0.17200001); - mg_move_to(-128.200, 90.000); - mg_cubic_to(-128.200, 90.000, -127.600, 91.800, -128.400, 92.000); - mg_cubic_to(-129.200, 92.200, -157.800, 50.200, -177.000, 57.800); - mg_cubic_to(-177.000, 57.800, -161.800, 46.000, -128.200, 90.000); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 20) - { - mg_move_to(-127.500, 96.979); - mg_cubic_to(-127.500, 96.979, -126.530, 98.608, -127.270, 98.975); - mg_cubic_to(-128.010, 99.343, -164.990, 64.499, -182.100, 76.061); - mg_cubic_to(-182.100, 76.061, -169.800, 61.261, -127.500, 96.979); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 21) - { - mg_set_width(0.17200001); - mg_move_to(-127.500, 96.979); - mg_cubic_to(-127.500, 96.979, -126.530, 98.608, -127.270, 98.975); - mg_cubic_to(-128.010, 99.343, -164.990, 64.499, -182.100, 76.061); - mg_cubic_to(-182.100, 76.061, -169.800, 61.261, -127.500, 96.979); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 22) - { - mg_move_to(-127.620, 101.350); - mg_cubic_to(-127.620, 101.350, -126.500, 102.880, -127.200, 103.320); - mg_cubic_to(-127.900, 103.750, -167.970, 72.502, -183.930, 85.607); - mg_cubic_to(-183.930, 85.607, -173.060, 69.726, -127.620, 101.350); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 23) - { - mg_set_width(0.17200001); - mg_move_to(-127.620, 101.350); - mg_cubic_to(-127.620, 101.350, -126.500, 102.880, -127.200, 103.320); - mg_cubic_to(-127.900, 103.750, -167.970, 72.502, -183.930, 85.607); - mg_cubic_to(-183.930, 85.607, -173.060, 69.726, -127.620, 101.350); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 24) - { - mg_move_to(-129.830, 103.060); - mg_cubic_to(-129.330, 109.110, -128.340, 115.680, -126.600, 118.800); - mg_cubic_to(-126.600, 118.800, -130.200, 131.200, -121.400, 144.400); - mg_cubic_to(-121.400, 144.400, -121.800, 151.600, -120.200, 154.800); - mg_cubic_to(-120.200, 154.800, -116.200, 163.200, -111.400, 164.000); - mg_cubic_to(-107.520, 164.650, -98.793, 167.720, -88.932, 169.120); - mg_cubic_to(-88.932, 169.120, -71.800, 183.200, -75.000, 196.000); - mg_cubic_to(-75.000, 196.000, -75.400, 212.400, -79.000, 214.000); - mg_cubic_to(-79.000, 214.000, -67.400, 202.800, -77.000, 219.600); - mg_line_to(-81.400, 238.400); - mg_cubic_to(-81.400, 238.400, -55.800, 216.800, -71.400, 235.200); - mg_line_to(-81.400, 261.200); - mg_cubic_to(-81.400, 261.200, -61.800, 242.800, -69.000, 251.200); - mg_line_to(-72.200, 260.000); - mg_cubic_to(-72.200, 260.000, -29.000, 232.800, -59.800, 262.400); - mg_cubic_to(-59.800, 262.400, -51.800, 258.800, -47.400, 261.600); - mg_cubic_to(-47.400, 261.600, -40.600, 260.400, -41.400, 262.000); - mg_cubic_to(-41.400, 262.000, -62.200, 272.400, -65.800, 290.800); - mg_cubic_to(-65.800, 290.800, -57.400, 280.800, -60.600, 291.600); - mg_line_to(-60.200, 303.200); - mg_cubic_to(-60.200, 303.200, -56.200, 281.600, -56.600, 319.200); - mg_cubic_to(-56.600, 319.200, -37.400, 301.200, -49.000, 322.000); - mg_line_to(-49.000, 338.800); - mg_cubic_to(-49.000, 338.800, -33.800, 322.400, -40.200, 335.200); - mg_cubic_to(-40.200, 335.200, -30.200, 326.400, -34.200, 341.600); - mg_cubic_to(-34.200, 341.600, -35.000, 352.000, -30.600, 340.800); - mg_cubic_to(-30.600, 340.800, -14.600, 310.200, -20.600, 336.400); - mg_cubic_to(-20.600, 336.400, -21.400, 355.600, -16.600, 340.800); - mg_cubic_to(-16.600, 340.800, -16.200, 351.200, -7.000, 358.400); - mg_cubic_to(-7.000, 358.400, -8.200, 307.600, 4.600, 343.600); - mg_line_to(8.600, 360.000); - mg_cubic_to(8.600, 360.000, 11.400, 350.800, 11.000, 345.600); - mg_line_to(19.000, 353.600); - mg_cubic_to(19.000, 353.600, 34.200, 330.800, 31.000, 344.000); - mg_cubic_to(31.000, 344.000, 23.400, 360.000, 25.000, 364.800); - mg_cubic_to(25.000, 364.800, 41.800, 330.000, 43.000, 328.400); - mg_cubic_to(43.000, 328.400, 41.000, 370.800, 51.800, 334.800); - mg_cubic_to(51.800, 334.800, 57.400, 346.800, 54.600, 351.200); - mg_cubic_to(54.600, 351.200, 62.600, 343.200, 61.800, 340.000); - mg_cubic_to(61.800, 340.000, 66.400, 331.800, 69.200, 345.400); - mg_cubic_to(69.200, 345.400, 71.000, 354.800, 72.600, 351.600); - mg_cubic_to(72.600, 351.600, 76.600, 375.600, 77.800, 352.800); - mg_cubic_to(77.800, 352.800, 79.400, 339.200, 72.200, 327.600); - mg_cubic_to(72.200, 327.600, 73.000, 324.400, 70.200, 320.400); - mg_cubic_to(70.200, 320.400, 83.800, 342.000, 76.600, 313.200); - mg_cubic_to(76.600, 313.200, 87.801, 321.200, 89.001, 321.200); - mg_cubic_to(89.001, 321.200, 75.400, 298.000, 84.200, 302.800); - mg_cubic_to(84.200, 302.800, 79.000, 292.400, 97.001, 304.400); - mg_cubic_to(97.001, 304.400, 81.000, 288.400, 98.601, 298.000); - mg_cubic_to(98.601, 298.000, 106.600, 304.400, 99.001, 294.400); - mg_cubic_to(99.001, 294.400, 84.600, 278.400, 106.600, 296.400); - mg_cubic_to(106.600, 296.400, 118.200, 312.800, 119.000, 315.600); - mg_cubic_to(119.000, 315.600, 109.000, 286.400, 104.600, 283.600); - mg_cubic_to(104.600, 283.600, 113.000, 247.200, 154.200, 262.800); - mg_cubic_to(154.200, 262.800, 161.000, 280.000, 165.400, 261.600); - mg_cubic_to(165.400, 261.600, 178.200, 255.200, 189.400, 282.800); - mg_cubic_to(189.400, 282.800, 193.400, 269.200, 192.600, 266.400); - mg_cubic_to(192.600, 266.400, 199.400, 267.600, 198.600, 266.400); - mg_cubic_to(198.600, 266.400, 211.800, 270.800, 213.000, 270.000); - mg_cubic_to(213.000, 270.000, 219.800, 276.800, 220.200, 273.200); - mg_cubic_to(220.200, 273.200, 229.400, 276.000, 227.400, 272.400); - mg_cubic_to(227.400, 272.400, 236.200, 288.000, 236.600, 291.600); - mg_line_to(239.000, 277.600); - mg_line_to(241.000, 280.400); - mg_cubic_to(241.000, 280.400, 242.600, 272.800, 241.800, 271.600); - mg_cubic_to(241.000, 270.400, 261.800, 278.400, 266.600, 299.200); - mg_line_to(268.600, 307.600); - mg_cubic_to(268.600, 307.600, 274.600, 292.800, 273.000, 288.800); - mg_cubic_to(273.000, 288.800, 278.200, 289.600, 278.600, 294.000); - mg_cubic_to(278.600, 294.000, 282.600, 270.800, 277.800, 264.800); - mg_cubic_to(277.800, 264.800, 282.200, 264.000, 283.400, 267.600); - mg_line_to(283.400, 260.400); - mg_cubic_to(283.400, 260.400, 290.600, 261.200, 290.600, 258.800); - mg_cubic_to(290.600, 258.800, 295.000, 254.800, 297.000, 259.600); - mg_cubic_to(297.000, 259.600, 284.600, 224.400, 303.000, 243.600); - mg_cubic_to(303.000, 243.600, 310.200, 254.400, 306.600, 235.600); - mg_cubic_to(303.000, 216.800, 299.000, 215.200, 303.800, 214.800); - mg_cubic_to(303.800, 214.800, 304.600, 211.200, 302.600, 209.600); - mg_cubic_to(300.600, 208.000, 303.800, 209.600, 303.800, 209.600); - mg_cubic_to(303.800, 209.600, 308.600, 213.600, 303.400, 191.600); - mg_cubic_to(303.400, 191.600, 309.800, 193.200, 297.800, 164.000); - mg_cubic_to(297.800, 164.000, 300.600, 161.600, 296.600, 153.200); - mg_cubic_to(296.600, 153.200, 304.600, 157.600, 307.400, 156.000); - mg_cubic_to(307.400, 156.000, 307.000, 154.400, 303.800, 150.400); - mg_cubic_to(303.800, 150.400, 282.200, 95.600, 302.600, 117.600); - mg_cubic_to(302.600, 117.600, 314.450, 131.150, 308.050, 108.350); - mg_cubic_to(308.050, 108.350, 298.940, 84.341, 299.720, 80.045); - mg_line_to(-129.830, 103.060); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 25) - { - mg_set_width(1); - mg_move_to(-129.830, 103.060); - mg_cubic_to(-129.330, 109.110, -128.340, 115.680, -126.600, 118.800); - mg_cubic_to(-126.600, 118.800, -130.200, 131.200, -121.400, 144.400); - mg_cubic_to(-121.400, 144.400, -121.800, 151.600, -120.200, 154.800); - mg_cubic_to(-120.200, 154.800, -116.200, 163.200, -111.400, 164.000); - mg_cubic_to(-107.520, 164.650, -98.793, 167.720, -88.932, 169.120); - mg_cubic_to(-88.932, 169.120, -71.800, 183.200, -75.000, 196.000); - mg_cubic_to(-75.000, 196.000, -75.400, 212.400, -79.000, 214.000); - mg_cubic_to(-79.000, 214.000, -67.400, 202.800, -77.000, 219.600); - mg_line_to(-81.400, 238.400); - mg_cubic_to(-81.400, 238.400, -55.800, 216.800, -71.400, 235.200); - mg_line_to(-81.400, 261.200); - mg_cubic_to(-81.400, 261.200, -61.800, 242.800, -69.000, 251.200); - mg_line_to(-72.200, 260.000); - mg_cubic_to(-72.200, 260.000, -29.000, 232.800, -59.800, 262.400); - mg_cubic_to(-59.800, 262.400, -51.800, 258.800, -47.400, 261.600); - mg_cubic_to(-47.400, 261.600, -40.600, 260.400, -41.400, 262.000); - mg_cubic_to(-41.400, 262.000, -62.200, 272.400, -65.800, 290.800); - mg_cubic_to(-65.800, 290.800, -57.400, 280.800, -60.600, 291.600); - mg_line_to(-60.200, 303.200); - mg_cubic_to(-60.200, 303.200, -56.200, 281.600, -56.600, 319.200); - mg_cubic_to(-56.600, 319.200, -37.400, 301.200, -49.000, 322.000); - mg_line_to(-49.000, 338.800); - mg_cubic_to(-49.000, 338.800, -33.800, 322.400, -40.200, 335.200); - mg_cubic_to(-40.200, 335.200, -30.200, 326.400, -34.200, 341.600); - mg_cubic_to(-34.200, 341.600, -35.000, 352.000, -30.600, 340.800); - mg_cubic_to(-30.600, 340.800, -14.600, 310.200, -20.600, 336.400); - mg_cubic_to(-20.600, 336.400, -21.400, 355.600, -16.600, 340.800); - mg_cubic_to(-16.600, 340.800, -16.200, 351.200, -7.000, 358.400); - mg_cubic_to(-7.000, 358.400, -8.200, 307.600, 4.600, 343.600); - mg_line_to(8.600, 360.000); - mg_cubic_to(8.600, 360.000, 11.400, 350.800, 11.000, 345.600); - mg_line_to(19.000, 353.600); - mg_cubic_to(19.000, 353.600, 34.200, 330.800, 31.000, 344.000); - mg_cubic_to(31.000, 344.000, 23.400, 360.000, 25.000, 364.800); - mg_cubic_to(25.000, 364.800, 41.800, 330.000, 43.000, 328.400); - mg_cubic_to(43.000, 328.400, 41.000, 370.800, 51.800, 334.800); - mg_cubic_to(51.800, 334.800, 57.400, 346.800, 54.600, 351.200); - mg_cubic_to(54.600, 351.200, 62.600, 343.200, 61.800, 340.000); - mg_cubic_to(61.800, 340.000, 66.400, 331.800, 69.200, 345.400); - mg_cubic_to(69.200, 345.400, 71.000, 354.800, 72.600, 351.600); - mg_cubic_to(72.600, 351.600, 76.600, 375.600, 77.800, 352.800); - mg_cubic_to(77.800, 352.800, 79.400, 339.200, 72.200, 327.600); - mg_cubic_to(72.200, 327.600, 73.000, 324.400, 70.200, 320.400); - mg_cubic_to(70.200, 320.400, 83.800, 342.000, 76.600, 313.200); - mg_cubic_to(76.600, 313.200, 87.801, 321.200, 89.001, 321.200); - mg_cubic_to(89.001, 321.200, 75.400, 298.000, 84.200, 302.800); - mg_cubic_to(84.200, 302.800, 79.000, 292.400, 97.001, 304.400); - mg_cubic_to(97.001, 304.400, 81.000, 288.400, 98.601, 298.000); - mg_cubic_to(98.601, 298.000, 106.600, 304.400, 99.001, 294.400); - mg_cubic_to(99.001, 294.400, 84.600, 278.400, 106.600, 296.400); - mg_cubic_to(106.600, 296.400, 118.200, 312.800, 119.000, 315.600); - mg_cubic_to(119.000, 315.600, 109.000, 286.400, 104.600, 283.600); - mg_cubic_to(104.600, 283.600, 113.000, 247.200, 154.200, 262.800); - mg_cubic_to(154.200, 262.800, 161.000, 280.000, 165.400, 261.600); - mg_cubic_to(165.400, 261.600, 178.200, 255.200, 189.400, 282.800); - mg_cubic_to(189.400, 282.800, 193.400, 269.200, 192.600, 266.400); - mg_cubic_to(192.600, 266.400, 199.400, 267.600, 198.600, 266.400); - mg_cubic_to(198.600, 266.400, 211.800, 270.800, 213.000, 270.000); - mg_cubic_to(213.000, 270.000, 219.800, 276.800, 220.200, 273.200); - mg_cubic_to(220.200, 273.200, 229.400, 276.000, 227.400, 272.400); - mg_cubic_to(227.400, 272.400, 236.200, 288.000, 236.600, 291.600); - mg_line_to(239.000, 277.600); - mg_line_to(241.000, 280.400); - mg_cubic_to(241.000, 280.400, 242.600, 272.800, 241.800, 271.600); - mg_cubic_to(241.000, 270.400, 261.800, 278.400, 266.600, 299.200); - mg_line_to(268.600, 307.600); - mg_cubic_to(268.600, 307.600, 274.600, 292.800, 273.000, 288.800); - mg_cubic_to(273.000, 288.800, 278.200, 289.600, 278.600, 294.000); - mg_cubic_to(278.600, 294.000, 282.600, 270.800, 277.800, 264.800); - mg_cubic_to(277.800, 264.800, 282.200, 264.000, 283.400, 267.600); - mg_line_to(283.400, 260.400); - mg_cubic_to(283.400, 260.400, 290.600, 261.200, 290.600, 258.800); - mg_cubic_to(290.600, 258.800, 295.000, 254.800, 297.000, 259.600); - mg_cubic_to(297.000, 259.600, 284.600, 224.400, 303.000, 243.600); - mg_cubic_to(303.000, 243.600, 310.200, 254.400, 306.600, 235.600); - mg_cubic_to(303.000, 216.800, 299.000, 215.200, 303.800, 214.800); - mg_cubic_to(303.800, 214.800, 304.600, 211.200, 302.600, 209.600); - mg_cubic_to(300.600, 208.000, 303.800, 209.600, 303.800, 209.600); - mg_cubic_to(303.800, 209.600, 308.600, 213.600, 303.400, 191.600); - mg_cubic_to(303.400, 191.600, 309.800, 193.200, 297.800, 164.000); - mg_cubic_to(297.800, 164.000, 300.600, 161.600, 296.600, 153.200); - mg_cubic_to(296.600, 153.200, 304.600, 157.600, 307.400, 156.000); - mg_cubic_to(307.400, 156.000, 307.000, 154.400, 303.800, 150.400); - mg_cubic_to(303.800, 150.400, 282.200, 95.600, 302.600, 117.600); - mg_cubic_to(302.600, 117.600, 314.450, 131.150, 308.050, 108.350); - mg_cubic_to(308.050, 108.350, 298.940, 84.341, 299.720, 80.045); - mg_line_to(-129.830, 103.060); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 26) - { - mg_move_to(299.720, 80.245); - mg_cubic_to(300.340, 80.426, 302.550, 81.550, 303.800, 83.200); - mg_cubic_to(303.800, 83.200, 310.600, 94.000, 305.400, 75.600); - mg_cubic_to(305.400, 75.600, 296.200, 46.800, 305.000, 58.000); - mg_cubic_to(305.000, 58.000, 311.000, 65.200, 307.800, 51.600); - mg_cubic_to(303.940, 35.173, 301.400, 28.800, 301.400, 28.800); - mg_cubic_to(301.400, 28.800, 313.000, 33.600, 286.200, -6.000); - mg_line_to(295.000, -2.400); - mg_cubic_to(295.000, -2.400, 275.400, -42.000, 253.800, -47.200); - mg_line_to(245.800, -53.200); - mg_cubic_to(245.800, -53.200, 284.200, -91.200, 271.400, -128.000); - mg_cubic_to(271.400, -128.000, 264.600, -133.200, 255.000, -124.000); - mg_cubic_to(255.000, -124.000, 248.600, -119.200, 242.600, -120.800); - mg_cubic_to(242.600, -120.800, 211.800, -119.600, 209.800, -119.600); - mg_cubic_to(207.800, -119.600, 173.000, -156.800, 107.400, -139.200); - mg_cubic_to(107.400, -139.200, 102.200, -137.200, 97.801, -138.400); - mg_cubic_to(97.801, -138.400, 79.400, -154.400, 30.600, -131.600); - mg_cubic_to(30.600, -131.600, 20.600, -129.600, 19.000, -129.600); - mg_cubic_to(17.400, -129.600, 14.600, -129.600, 6.600, -123.200); - mg_cubic_to(-1.400, -116.800, -1.800, -116.000, -3.800, -114.400); - mg_cubic_to(-3.800, -114.400, -20.200, -103.200, -25.000, -102.400); - mg_cubic_to(-25.000, -102.400, -36.600, -96.000, -41.000, -86.000); - mg_line_to(-44.600, -84.800); - mg_cubic_to(-44.600, -84.800, -46.200, -77.600, -46.600, -76.400); - mg_cubic_to(-46.600, -76.400, -51.400, -72.800, -52.200, -67.200); - mg_cubic_to(-52.200, -67.200, -61.000, -61.200, -60.600, -56.800); - mg_cubic_to(-60.600, -56.800, -62.200, -51.600, -63.000, -46.800); - mg_cubic_to(-63.000, -46.800, -70.200, -42.000, -69.400, -39.200); - mg_cubic_to(-69.400, -39.200, -77.000, -25.200, -75.800, -18.400); - mg_cubic_to(-75.800, -18.400, -82.200, -18.800, -85.000, -16.400); - mg_cubic_to(-85.000, -16.400, -85.800, -11.600, -87.400, -11.200); - mg_cubic_to(-87.400, -11.200, -90.200, -10.000, -87.800, -6.000); - mg_cubic_to(-87.800, -6.000, -89.400, -3.200, -89.800, -1.600); - mg_cubic_to(-89.800, -1.600, -89.000, 1.200, -93.400, 6.800); - mg_cubic_to(-93.400, 6.800, -99.800, 25.600, -97.800, 30.800); - mg_cubic_to(-97.800, 30.800, -97.400, 35.600, -100.200, 37.200); - mg_cubic_to(-100.200, 37.200, -103.800, 36.800, -95.400, 48.800); - mg_cubic_to(-95.400, 48.800, -94.600, 50.000, -97.800, 52.400); - mg_cubic_to(-97.800, 52.400, -115.000, 56.000, -117.400, 72.400); - mg_cubic_to(-117.400, 72.400, -131.000, 87.200, -131.000, 92.400); - mg_cubic_to(-131.000, 94.705, -130.730, 97.852, -130.030, 102.460); - mg_cubic_to(-130.030, 102.460, -130.600, 110.800, -103.000, 111.600); - mg_cubic_to(-75.400, 112.400, 299.720, 80.245, 299.720, 80.245); - mg_close_path(); - mg_set_color_rgba(0.800, 0.447, 0.149, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 27) - { - mg_set_width(1); - mg_move_to(299.720, 80.245); - mg_cubic_to(300.340, 80.426, 302.550, 81.550, 303.800, 83.200); - mg_cubic_to(303.800, 83.200, 310.600, 94.000, 305.400, 75.600); - mg_cubic_to(305.400, 75.600, 296.200, 46.800, 305.000, 58.000); - mg_cubic_to(305.000, 58.000, 311.000, 65.200, 307.800, 51.600); - mg_cubic_to(303.940, 35.173, 301.400, 28.800, 301.400, 28.800); - mg_cubic_to(301.400, 28.800, 313.000, 33.600, 286.200, -6.000); - mg_line_to(295.000, -2.400); - mg_cubic_to(295.000, -2.400, 275.400, -42.000, 253.800, -47.200); - mg_line_to(245.800, -53.200); - mg_cubic_to(245.800, -53.200, 284.200, -91.200, 271.400, -128.000); - mg_cubic_to(271.400, -128.000, 264.600, -133.200, 255.000, -124.000); - mg_cubic_to(255.000, -124.000, 248.600, -119.200, 242.600, -120.800); - mg_cubic_to(242.600, -120.800, 211.800, -119.600, 209.800, -119.600); - mg_cubic_to(207.800, -119.600, 173.000, -156.800, 107.400, -139.200); - mg_cubic_to(107.400, -139.200, 102.200, -137.200, 97.801, -138.400); - mg_cubic_to(97.801, -138.400, 79.400, -154.400, 30.600, -131.600); - mg_cubic_to(30.600, -131.600, 20.600, -129.600, 19.000, -129.600); - mg_cubic_to(17.400, -129.600, 14.600, -129.600, 6.600, -123.200); - mg_cubic_to(-1.400, -116.800, -1.800, -116.000, -3.800, -114.400); - mg_cubic_to(-3.800, -114.400, -20.200, -103.200, -25.000, -102.400); - mg_cubic_to(-25.000, -102.400, -36.600, -96.000, -41.000, -86.000); - mg_line_to(-44.600, -84.800); - mg_cubic_to(-44.600, -84.800, -46.200, -77.600, -46.600, -76.400); - mg_cubic_to(-46.600, -76.400, -51.400, -72.800, -52.200, -67.200); - mg_cubic_to(-52.200, -67.200, -61.000, -61.200, -60.600, -56.800); - mg_cubic_to(-60.600, -56.800, -62.200, -51.600, -63.000, -46.800); - mg_cubic_to(-63.000, -46.800, -70.200, -42.000, -69.400, -39.200); - mg_cubic_to(-69.400, -39.200, -77.000, -25.200, -75.800, -18.400); - mg_cubic_to(-75.800, -18.400, -82.200, -18.800, -85.000, -16.400); - mg_cubic_to(-85.000, -16.400, -85.800, -11.600, -87.400, -11.200); - mg_cubic_to(-87.400, -11.200, -90.200, -10.000, -87.800, -6.000); - mg_cubic_to(-87.800, -6.000, -89.400, -3.200, -89.800, -1.600); - mg_cubic_to(-89.800, -1.600, -89.000, 1.200, -93.400, 6.800); - mg_cubic_to(-93.400, 6.800, -99.800, 25.600, -97.800, 30.800); - mg_cubic_to(-97.800, 30.800, -97.400, 35.600, -100.200, 37.200); - mg_cubic_to(-100.200, 37.200, -103.800, 36.800, -95.400, 48.800); - mg_cubic_to(-95.400, 48.800, -94.600, 50.000, -97.800, 52.400); - mg_cubic_to(-97.800, 52.400, -115.000, 56.000, -117.400, 72.400); - mg_cubic_to(-117.400, 72.400, -131.000, 87.200, -131.000, 92.400); - mg_cubic_to(-131.000, 94.705, -130.730, 97.852, -130.030, 102.460); - mg_cubic_to(-130.030, 102.460, -130.600, 110.800, -103.000, 111.600); - mg_cubic_to(-75.400, 112.400, 299.720, 80.245, 299.720, 80.245); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 28) - { - mg_move_to(-115.600, 102.600); - mg_cubic_to(-140.600, 63.200, -126.200, 119.600, -126.200, 119.600); - mg_cubic_to(-117.400, 154.000, 12.200, 116.400, 12.200, 116.400); - mg_cubic_to(12.200, 116.400, 181.000, 86.000, 192.200, 82.000); - mg_cubic_to(203.400, 78.000, 298.600, 84.400, 298.600, 84.400); - mg_line_to(293.000, 67.600); - mg_cubic_to(228.200, 21.200, 209.000, 44.400, 195.400, 40.400); - mg_cubic_to(181.800, 36.400, 184.200, 46.000, 181.000, 46.800); - mg_cubic_to(177.800, 47.600, 138.600, 22.800, 132.200, 23.600); - mg_cubic_to(125.800, 24.400, 100.460, 0.649, 115.400, 32.400); - mg_cubic_to(131.400, 66.400, 57.000, 71.600, 40.200, 60.400); - mg_cubic_to(23.400, 49.200, 47.400, 78.800, 47.400, 78.800); - mg_cubic_to(65.800, 98.800, 31.400, 82.000, 31.400, 82.000); - mg_cubic_to(-3.000, 69.200, -27.000, 94.800, -30.200, 95.600); - mg_cubic_to(-33.400, 96.400, -38.200, 99.600, -39.000, 93.200); - mg_cubic_to(-39.800, 86.800, -47.310, 70.099, -79.000, 96.400); - mg_cubic_to(-99.000, 113.000, -112.800, 91.000, -112.800, 91.000); - mg_line_to(-115.600, 102.600); - mg_close_path(); - mg_set_color_rgba(0.800, 0.447, 0.149, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 29) - { - mg_move_to(133.510, 25.346); - mg_cubic_to(127.110, 26.146, 101.740, 2.407, 116.710, 34.146); - mg_cubic_to(133.310, 69.346, 58.310, 73.346, 41.510, 62.146); - mg_cubic_to(24.709, 50.946, 48.710, 80.546, 48.710, 80.546); - mg_cubic_to(67.110, 100.550, 32.709, 83.746, 32.709, 83.746); - mg_cubic_to(-1.691, 70.946, -25.691, 96.546, -28.891, 97.346); - mg_cubic_to(-32.091, 98.146, -36.891, 101.350, -37.691, 94.946); - mg_cubic_to(-38.491, 88.546, -45.870, 72.012, -77.691, 98.146); - mg_cubic_to(-98.927, 115.490, -112.420, 94.037, -112.420, 94.037); - mg_line_to(-115.620, 104.150); - mg_cubic_to(-140.620, 64.346, -125.550, 122.660, -125.550, 122.660); - mg_cubic_to(-116.740, 157.060, 13.510, 118.150, 13.510, 118.150); - mg_cubic_to(13.510, 118.150, 182.310, 87.746, 193.510, 83.746); - mg_cubic_to(204.710, 79.746, 299.040, 86.073, 299.040, 86.073); - mg_line_to(293.510, 68.764); - mg_cubic_to(228.710, 22.364, 210.310, 46.146, 196.710, 42.146); - mg_cubic_to(183.110, 38.146, 185.510, 47.746, 182.310, 48.546); - mg_cubic_to(179.110, 49.346, 139.910, 24.546, 133.510, 25.346); - mg_close_path(); - mg_set_color_rgba(0.910, 0.498, 0.227, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 30) - { - mg_move_to(134.820, 27.091); - mg_cubic_to(128.420, 27.891, 103.680, 3.862, 118.020, 35.891); - mg_cubic_to(134.220, 72.092, 59.619, 75.092, 42.819, 63.892); - mg_cubic_to(26.019, 52.692, 50.019, 82.292, 50.019, 82.292); - mg_cubic_to(68.419, 102.290, 34.019, 85.492, 34.019, 85.492); - mg_cubic_to(-0.381, 72.692, -24.382, 98.292, -27.582, 99.092); - mg_cubic_to(-30.782, 99.892, -35.582, 103.090, -36.382, 96.692); - mg_cubic_to(-37.182, 90.292, -44.430, 73.925, -76.382, 99.892); - mg_cubic_to(-98.855, 117.980, -112.040, 97.074, -112.040, 97.074); - mg_line_to(-115.640, 105.690); - mg_cubic_to(-139.440, 66.692, -124.890, 125.710, -124.890, 125.710); - mg_cubic_to(-116.090, 160.110, 14.820, 119.890, 14.820, 119.890); - mg_cubic_to(14.820, 119.890, 183.620, 89.492, 194.820, 85.492); - mg_cubic_to(206.020, 81.492, 299.470, 87.746, 299.470, 87.746); - mg_line_to(294.020, 69.928); - mg_cubic_to(229.220, 23.528, 211.620, 47.891, 198.020, 43.891); - mg_cubic_to(184.420, 39.891, 186.820, 49.491, 183.620, 50.292); - mg_cubic_to(180.420, 51.092, 141.220, 26.291, 134.820, 27.091); - mg_close_path(); - mg_set_color_rgba(0.918, 0.549, 0.302, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 31) - { - mg_move_to(136.130, 28.837); - mg_cubic_to(129.730, 29.637, 105.000, 5.605, 119.330, 37.637); - mg_cubic_to(136.130, 75.193, 60.394, 76.482, 44.128, 65.637); - mg_cubic_to(27.328, 54.437, 51.328, 84.037, 51.328, 84.037); - mg_cubic_to(69.728, 104.040, 35.328, 87.237, 35.328, 87.237); - mg_cubic_to(0.928, 74.437, -23.072, 100.040, -26.272, 100.840); - mg_cubic_to(-29.472, 101.640, -34.272, 104.840, -35.072, 98.437); - mg_cubic_to(-35.872, 92.037, -42.989, 75.839, -75.073, 101.640); - mg_cubic_to(-98.782, 120.470, -111.660, 100.110, -111.660, 100.110); - mg_line_to(-115.660, 107.240); - mg_cubic_to(-137.460, 70.437, -124.240, 128.760, -124.240, 128.760); - mg_cubic_to(-115.440, 163.160, 16.130, 121.640, 16.130, 121.640); - mg_cubic_to(16.130, 121.640, 184.930, 91.237, 196.130, 87.237); - mg_cubic_to(207.330, 83.237, 299.910, 89.419, 299.910, 89.419); - mg_line_to(294.530, 71.092); - mg_cubic_to(229.730, 24.691, 212.930, 49.637, 199.330, 45.637); - mg_cubic_to(185.730, 41.637, 188.130, 51.237, 184.930, 52.037); - mg_cubic_to(181.730, 52.837, 142.530, 28.037, 136.130, 28.837); - mg_close_path(); - mg_set_color_rgba(0.925, 0.600, 0.380, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 32) - { - mg_move_to(137.440, 30.583); - mg_cubic_to(131.040, 31.383, 106.810, 7.129, 120.640, 39.383); - mg_cubic_to(137.440, 78.583, 62.237, 78.583, 45.437, 67.383); - mg_cubic_to(28.637, 56.183, 52.637, 85.783, 52.637, 85.783); - mg_cubic_to(71.037, 105.780, 36.637, 88.983, 36.637, 88.983); - mg_cubic_to(2.237, 76.183, -21.763, 101.780, -24.963, 102.580); - mg_cubic_to(-28.163, 103.380, -32.963, 106.580, -33.763, 100.180); - mg_cubic_to(-34.563, 93.783, -41.548, 77.752, -73.763, 103.380); - mg_cubic_to(-98.709, 122.960, -111.270, 103.150, -111.270, 103.150); - mg_line_to(-115.670, 108.780); - mg_cubic_to(-135.470, 73.982, -123.580, 131.820, -123.580, 131.820); - mg_cubic_to(-114.780, 166.220, 17.440, 123.380, 17.440, 123.380); - mg_cubic_to(17.440, 123.380, 186.240, 92.983, 197.440, 88.983); - mg_cubic_to(208.640, 84.983, 300.350, 91.092, 300.350, 91.092); - mg_line_to(295.040, 72.255); - mg_cubic_to(230.240, 25.855, 214.240, 51.383, 200.640, 47.383); - mg_cubic_to(187.040, 43.383, 189.440, 52.983, 186.240, 53.783); - mg_cubic_to(183.040, 54.583, 143.840, 29.783, 137.440, 30.583); - mg_close_path(); - mg_set_color_rgba(0.933, 0.647, 0.459, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 33) - { - mg_move_to(138.750, 32.328); - mg_cubic_to(132.350, 33.128, 106.380, 9.677, 121.950, 41.128); - mg_cubic_to(141.150, 79.928, 63.546, 80.328, 46.746, 69.128); - mg_cubic_to(29.946, 57.928, 53.946, 87.528, 53.946, 87.528); - mg_cubic_to(72.346, 107.530, 37.946, 90.728, 37.946, 90.728); - mg_cubic_to(3.546, 77.928, -20.454, 103.530, -23.654, 104.330); - mg_cubic_to(-26.854, 105.130, -31.654, 108.330, -32.454, 101.930); - mg_cubic_to(-33.254, 95.528, -40.108, 79.665, -72.454, 105.130); - mg_cubic_to(-98.636, 125.460, -110.890, 106.180, -110.890, 106.180); - mg_line_to(-115.690, 110.330); - mg_cubic_to(-133.690, 77.128, -122.930, 134.870, -122.930, 134.870); - mg_cubic_to(-114.130, 169.270, 18.750, 125.130, 18.750, 125.130); - mg_cubic_to(18.750, 125.130, 187.550, 94.728, 198.750, 90.728); - mg_cubic_to(209.950, 86.728, 300.780, 92.764, 300.780, 92.764); - mg_line_to(295.550, 73.419); - mg_cubic_to(230.750, 27.019, 215.550, 53.128, 201.950, 49.128); - mg_cubic_to(188.350, 45.128, 190.750, 54.728, 187.550, 55.528); - mg_cubic_to(184.350, 56.328, 145.150, 31.528, 138.750, 32.328); - mg_close_path(); - mg_set_color_rgba(0.945, 0.698, 0.533, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 34) - { - mg_move_to(140.060, 34.073); - mg_cubic_to(133.660, 34.873, 107.310, 11.613, 123.260, 42.873); - mg_cubic_to(143.660, 82.874, 64.855, 82.074, 48.055, 70.874); - mg_cubic_to(31.255, 59.674, 55.255, 89.274, 55.255, 89.274); - mg_cubic_to(73.655, 109.270, 39.255, 92.474, 39.255, 92.474); - mg_cubic_to(4.855, 79.674, -19.145, 105.270, -22.345, 106.070); - mg_cubic_to(-25.545, 106.870, -30.345, 110.070, -31.145, 103.670); - mg_cubic_to(-31.945, 97.274, -38.668, 81.578, -71.145, 106.870); - mg_cubic_to(-98.564, 127.950, -110.510, 109.220, -110.510, 109.220); - mg_line_to(-115.710, 111.870); - mg_cubic_to(-131.710, 81.674, -122.270, 137.930, -122.270, 137.930); - mg_cubic_to(-113.470, 172.330, 20.050, 126.870, 20.050, 126.870); - mg_cubic_to(20.050, 126.870, 188.850, 96.474, 200.050, 92.474); - mg_cubic_to(211.250, 88.474, 301.210, 94.437, 301.210, 94.437); - mg_line_to(296.050, 74.583); - mg_cubic_to(231.250, 28.183, 216.850, 54.874, 203.250, 50.874); - mg_cubic_to(189.650, 46.873, 192.050, 56.474, 188.850, 57.274); - mg_cubic_to(185.650, 58.074, 146.450, 33.273, 140.050, 34.073); - mg_close_path(); - mg_set_color_rgba(0.953, 0.749, 0.612, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 35) - { - mg_move_to(141.360, 35.819); - mg_cubic_to(134.960, 36.619, 107.520, 13.944, 124.560, 44.619); - mg_cubic_to(146.560, 84.219, 66.164, 83.819, 49.364, 72.619); - mg_cubic_to(32.564, 61.419, 56.564, 91.019, 56.564, 91.019); - mg_cubic_to(74.964, 111.020, 40.564, 94.219, 40.564, 94.219); - mg_cubic_to(6.164, 81.419, -17.836, 107.020, -21.036, 107.820); - mg_cubic_to(-24.236, 108.620, -29.036, 111.820, -29.836, 105.420); - mg_cubic_to(-30.636, 99.019, -37.227, 83.492, -69.836, 108.620); - mg_cubic_to(-98.491, 130.440, -110.130, 112.260, -110.130, 112.260); - mg_line_to(-115.730, 113.420); - mg_cubic_to(-130.130, 85.019, -121.620, 140.980, -121.620, 140.980); - mg_cubic_to(-112.820, 175.380, 21.360, 128.620, 21.360, 128.620); - mg_cubic_to(21.360, 128.620, 190.160, 98.219, 201.360, 94.219); - mg_cubic_to(212.560, 90.219, 301.660, 96.110, 301.660, 96.110); - mg_line_to(296.560, 75.746); - mg_cubic_to(231.760, 29.346, 218.160, 56.619, 204.560, 52.619); - mg_cubic_to(190.960, 48.619, 193.360, 58.219, 190.160, 59.019); - mg_cubic_to(186.960, 59.819, 147.760, 35.019, 141.360, 35.819); - mg_close_path(); - mg_set_color_rgba(0.961, 0.800, 0.690, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 36) - { - mg_move_to(142.670, 37.565); - mg_cubic_to(136.270, 38.365, 108.830, 15.689, 125.870, 46.365); - mg_cubic_to(147.870, 85.965, 67.474, 85.565, 50.674, 74.365); - mg_cubic_to(33.874, 63.165, 57.874, 92.765, 57.874, 92.765); - mg_cubic_to(76.274, 112.760, 41.874, 95.965, 41.874, 95.965); - mg_cubic_to(7.473, 83.165, -16.527, 108.760, -19.727, 109.560); - mg_cubic_to(-22.927, 110.360, -27.727, 113.560, -28.527, 107.160); - mg_cubic_to(-29.327, 100.760, -35.786, 85.405, -68.527, 110.360); - mg_cubic_to(-98.418, 132.930, -109.740, 115.290, -109.740, 115.290); - mg_line_to(-115.740, 114.960); - mg_cubic_to(-129.350, 88.564, -120.960, 144.040, -120.960, 144.040); - mg_cubic_to(-112.160, 178.440, 22.670, 130.360, 22.670, 130.360); - mg_cubic_to(22.670, 130.360, 191.470, 99.965, 202.670, 95.965); - mg_cubic_to(213.870, 91.965, 302.090, 97.783, 302.090, 97.783); - mg_line_to(297.080, 76.910); - mg_cubic_to(232.270, 30.510, 219.470, 58.365, 205.870, 54.365); - mg_cubic_to(192.270, 50.365, 194.670, 59.965, 191.470, 60.765); - mg_cubic_to(188.270, 61.565, 149.070, 36.765, 142.670, 37.565); - mg_close_path(); - mg_set_color_rgba(0.973, 0.847, 0.769, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 37) - { - mg_move_to(143.980, 39.310); - mg_cubic_to(137.580, 40.110, 110.530, 17.223, 127.180, 48.110); - mg_cubic_to(149.180, 88.910, 68.783, 87.310, 51.983, 76.110); - mg_cubic_to(35.183, 64.910, 59.183, 94.510, 59.183, 94.510); - mg_cubic_to(77.583, 114.510, 43.183, 97.710, 43.183, 97.710); - mg_cubic_to(8.783, 84.910, -15.217, 110.510, -18.417, 111.310); - mg_cubic_to(-21.618, 112.110, -26.418, 115.310, -27.218, 108.910); - mg_cubic_to(-28.018, 102.510, -34.346, 87.318, -67.218, 112.110); - mg_cubic_to(-98.345, 135.420, -109.360, 118.330, -109.360, 118.330); - mg_line_to(-115.760, 116.510); - mg_cubic_to(-128.760, 92.510, -120.310, 147.090, -120.310, 147.090); - mg_cubic_to(-111.510, 181.490, 23.980, 132.110, 23.980, 132.110); - mg_cubic_to(23.980, 132.110, 192.780, 101.710, 203.980, 97.710); - mg_cubic_to(215.180, 93.710, 302.530, 99.456, 302.530, 99.456); - mg_line_to(297.580, 78.074); - mg_cubic_to(232.780, 31.673, 220.780, 60.110, 207.180, 56.110); - mg_cubic_to(193.580, 52.110, 195.980, 61.710, 192.780, 62.510); - mg_cubic_to(189.580, 63.310, 150.380, 38.510, 143.980, 39.310); - mg_close_path(); - mg_set_color_rgba(0.980, 0.898, 0.843, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 38) - { - mg_move_to(145.290, 41.055); - mg_cubic_to(138.890, 41.855, 112.920, 18.411, 128.490, 49.855); - mg_cubic_to(149.690, 92.656, 70.092, 89.056, 53.292, 77.856); - mg_cubic_to(36.492, 66.656, 60.492, 96.256, 60.492, 96.256); - mg_cubic_to(78.892, 116.260, 44.492, 99.456, 44.492, 99.456); - mg_cubic_to(10.092, 86.656, -13.908, 112.260, -17.108, 113.060); - mg_cubic_to(-20.308, 113.860, -25.108, 117.060, -25.908, 110.660); - mg_cubic_to(-26.708, 104.260, -32.905, 89.232, -65.908, 113.860); - mg_cubic_to(-98.273, 137.910, -108.980, 121.360, -108.980, 121.360); - mg_line_to(-115.780, 118.060); - mg_cubic_to(-128.580, 94.856, -119.650, 150.150, -119.650, 150.150); - mg_cubic_to(-110.850, 184.550, 25.290, 133.860, 25.290, 133.860); - mg_cubic_to(25.290, 133.860, 194.090, 103.460, 205.290, 99.456); - mg_cubic_to(216.490, 95.456, 302.960, 101.130, 302.960, 101.130); - mg_line_to(298.090, 79.237); - mg_cubic_to(233.290, 32.837, 222.090, 61.856, 208.490, 57.856); - mg_cubic_to(194.890, 53.855, 197.290, 63.456, 194.090, 64.256); - mg_cubic_to(190.890, 65.056, 151.690, 40.255, 145.290, 41.055); - mg_close_path(); - mg_set_color_rgba(0.988, 0.949, 0.922, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 39) - { - mg_move_to(-115.800, 119.600); - mg_cubic_to(-128.600, 97.600, -119.000, 153.200, -119.000, 153.200); - mg_cubic_to(-110.200, 187.600, 26.600, 135.600, 26.600, 135.600); - mg_cubic_to(26.600, 135.600, 195.400, 105.200, 206.600, 101.200); - mg_cubic_to(217.800, 97.200, 303.400, 102.800, 303.400, 102.800); - mg_line_to(298.600, 80.400); - mg_cubic_to(233.800, 34.000, 223.400, 63.600, 209.800, 59.600); - mg_cubic_to(196.200, 55.600, 198.600, 65.200, 195.400, 66.000); - mg_cubic_to(192.200, 66.800, 153.000, 42.000, 146.600, 42.800); - mg_cubic_to(140.200, 43.600, 114.980, 19.793, 129.800, 51.600); - mg_cubic_to(152.030, 99.307, 69.041, 89.227, 54.600, 79.600); - mg_cubic_to(37.800, 68.400, 61.800, 98.000, 61.800, 98.000); - mg_cubic_to(80.200, 118.000, 45.800, 101.200, 45.800, 101.200); - mg_cubic_to(11.400, 88.400, -12.600, 114.000, -15.800, 114.800); - mg_cubic_to(-19.000, 115.600, -23.800, 118.800, -24.600, 112.400); - mg_cubic_to(-25.400, 106.000, -31.465, 91.144, -64.600, 115.600); - mg_cubic_to(-98.200, 140.400, -108.600, 124.400, -108.600, 124.400); - mg_line_to(-115.800, 119.600); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 40) - { - mg_move_to(-74.200, 149.600); - mg_cubic_to(-74.200, 149.600, -81.400, 161.200, -60.600, 174.400); - mg_cubic_to(-60.600, 174.400, -59.200, 175.800, -77.200, 171.600); - mg_cubic_to(-77.200, 171.600, -83.400, 169.600, -85.000, 159.200); - mg_cubic_to(-85.000, 159.200, -89.800, 154.800, -94.600, 149.200); - mg_cubic_to(-99.400, 143.600, -74.200, 149.600, -74.200, 149.600); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 41) - { - mg_move_to(65.800, 102.000); - mg_cubic_to(65.800, 102.000, 83.498, 128.820, 82.900, 133.600); - mg_cubic_to(81.600, 144.000, 81.400, 153.600, 84.600, 157.600); - mg_cubic_to(87.801, 161.600, 96.601, 194.800, 96.601, 194.800); - mg_cubic_to(96.601, 194.800, 96.201, 196.000, 108.600, 158.000); - mg_cubic_to(108.600, 158.000, 120.200, 142.000, 100.200, 123.600); - mg_cubic_to(100.200, 123.600, 65.000, 94.800, 65.800, 102.000); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 42) - { - mg_move_to(-54.200, 176.400); - mg_cubic_to(-54.200, 176.400, -43.000, 183.600, -57.400, 214.800); - mg_line_to(-51.000, 212.400); - mg_cubic_to(-51.000, 212.400, -51.800, 223.600, -55.000, 226.000); - mg_line_to(-47.800, 222.800); - mg_cubic_to(-47.800, 222.800, -43.000, 230.800, -47.000, 235.600); - mg_cubic_to(-47.000, 235.600, -30.200, 243.600, -31.000, 250.000); - mg_cubic_to(-31.000, 250.000, -24.600, 242.000, -28.600, 235.600); - mg_cubic_to(-32.600, 229.200, -39.800, 233.200, -39.000, 214.800); - mg_line_to(-47.800, 218.000); - mg_cubic_to(-47.800, 218.000, -42.200, 209.200, -42.200, 202.800); - mg_line_to(-50.200, 205.200); - mg_cubic_to(-50.200, 205.200, -34.731, 178.620, -45.400, 177.200); - mg_cubic_to(-51.400, 176.400, -54.200, 176.400, -54.200, 176.400); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 43) - { - mg_move_to(-21.800, 193.200); - mg_cubic_to(-21.800, 193.200, -19.000, 188.800, -21.800, 189.600); - mg_cubic_to(-24.600, 190.400, -55.800, 205.200, -61.800, 214.800); - mg_cubic_to(-61.800, 214.800, -27.400, 190.400, -21.800, 193.200); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 44) - { - mg_move_to(-11.400, 201.200); - mg_cubic_to(-11.400, 201.200, -8.600, 196.800, -11.400, 197.600); - mg_cubic_to(-14.200, 198.400, -45.400, 213.200, -51.400, 222.800); - mg_cubic_to(-51.400, 222.800, -17.000, 198.400, -11.400, 201.200); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 45) - { - mg_move_to(1.800, 186.000); - mg_cubic_to(1.800, 186.000, 4.600, 181.600, 1.800, 182.400); - mg_cubic_to(-1.000, 183.200, -32.200, 198.000, -38.200, 207.600); - mg_cubic_to(-38.200, 207.600, -3.800, 183.200, 1.800, 186.000); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 46) - { - mg_move_to(-21.400, 229.600); - mg_cubic_to(-21.400, 229.600, -21.400, 223.600, -24.200, 224.400); - mg_cubic_to(-27.000, 225.200, -63.000, 242.800, -69.000, 252.400); - mg_cubic_to(-69.000, 252.400, -27.000, 226.800, -21.400, 229.600); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 47) - { - mg_move_to(-20.200, 218.800); - mg_cubic_to(-20.200, 218.800, -19.000, 214.000, -21.800, 214.800); - mg_cubic_to(-23.800, 214.800, -50.200, 226.400, -56.200, 236.000); - mg_cubic_to(-56.200, 236.000, -26.600, 214.400, -20.200, 218.800); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 48) - { - mg_move_to(-34.600, 266.400); - mg_move_to(-44.600, 274.000); - mg_cubic_to(-44.600, 274.000, -34.200, 266.400, -30.600, 267.600); - mg_cubic_to(-30.600, 267.600, -37.400, 278.800, -38.200, 284.000); - mg_cubic_to(-38.200, 284.000, -27.800, 271.200, -22.200, 271.600); - mg_cubic_to(-22.200, 271.600, -14.600, 272.000, -14.600, 282.800); - mg_cubic_to(-14.600, 282.800, -9.000, 272.400, -5.800, 272.800); - mg_cubic_to(-5.800, 272.800, -4.600, 279.200, -5.800, 286.000); - mg_cubic_to(-5.800, 286.000, -1.800, 278.400, 2.200, 280.000); - mg_cubic_to(2.200, 280.000, 8.600, 278.000, 7.800, 289.600); - mg_cubic_to(7.800, 289.600, 7.800, 300.000, 7.000, 302.800); - mg_cubic_to(7.000, 302.800, 12.600, 276.400, 15.000, 276.000); - mg_cubic_to(15.000, 276.000, 23.000, 274.800, 27.800, 283.600); - mg_cubic_to(27.800, 283.600, 23.800, 276.000, 28.600, 278.000); - mg_cubic_to(28.600, 278.000, 39.400, 279.600, 42.600, 286.400); - mg_cubic_to(42.600, 286.400, 35.800, 274.400, 41.400, 277.600); - mg_line_to(49.400, 284.000); - mg_cubic_to(49.400, 284.000, 57.800, 305.200, 59.800, 306.800); - mg_cubic_to(59.800, 306.800, 52.200, 285.200, 53.800, 285.200); - mg_cubic_to(53.800, 285.200, 51.800, 273.200, 57.000, 288.000); - mg_cubic_to(57.000, 288.000, 53.800, 274.000, 59.400, 274.800); - mg_cubic_to(65.000, 275.600, 69.400, 285.600, 77.800, 283.200); - mg_cubic_to(77.800, 283.200, 87.401, 288.800, 89.401, 219.600); - mg_line_to(-34.599, 266.400); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 49) - { - mg_move_to(-29.800, 173.600); - mg_cubic_to(-29.800, 173.600, -15.000, 167.600, 25.000, 173.600); - mg_cubic_to(25.000, 173.600, 32.200, 174.000, 39.000, 165.200); - mg_cubic_to(45.800, 156.400, 72.600, 149.200, 79.000, 151.200); - mg_line_to(88.601, 157.600); - mg_line_to(89.401, 158.800); - mg_cubic_to(89.401, 158.800, 101.800, 169.200, 102.200, 176.800); - mg_cubic_to(102.600, 184.400, 87.801, 232.400, 78.200, 248.400); - mg_cubic_to(68.600, 264.400, 59.000, 276.800, 39.800, 274.400); - mg_cubic_to(39.800, 274.400, 19.000, 270.400, -6.600, 274.400); - mg_cubic_to(-6.600, 274.400, -35.800, 272.800, -38.600, 264.800); - mg_cubic_to(-41.400, 256.800, -27.400, 241.600, -27.400, 241.600); - mg_cubic_to(-27.400, 241.600, -23.000, 233.200, -24.200, 218.800); - mg_cubic_to(-25.400, 204.400, -25.000, 176.400, -29.800, 173.600); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 50) - { - mg_move_to(-7.800, 175.600); - mg_cubic_to(0.600, 194.000, -29.000, 259.200, -29.000, 259.200); - mg_cubic_to(-31.000, 260.800, -16.340, 266.850, -6.200, 264.400); - mg_cubic_to(4.746, 261.760, 45.000, 266.000, 45.000, 266.000); - mg_cubic_to(68.600, 250.400, 81.400, 206.000, 81.400, 206.000); - mg_cubic_to(81.400, 206.000, 91.801, 182.000, 74.200, 178.800); - mg_cubic_to(56.600, 175.600, -7.800, 175.600, -7.800, 175.600); - mg_close_path(); - mg_set_color_rgba(0.898, 0.400, 0.549, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 51) - { - mg_move_to(-9.831, 206.500); - mg_cubic_to(-6.505, 193.710, -4.921, 181.910, -7.800, 175.600); - mg_cubic_to(-7.800, 175.600, 54.600, 182.000, 65.800, 161.200); - mg_cubic_to(70.041, 153.330, 84.801, 184.000, 84.400, 193.600); - mg_cubic_to(84.400, 193.600, 21.400, 208.000, 6.600, 196.800); - mg_line_to(-9.831, 206.500); - mg_close_path(); - mg_set_color_rgba(0.698, 0.196, 0.349, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 52) - { - mg_move_to(-5.400, 222.800); - mg_cubic_to(-5.400, 222.800, -3.400, 230.000, -5.800, 234.000); - mg_cubic_to(-5.800, 234.000, -7.400, 234.800, -8.600, 235.200); - mg_cubic_to(-8.600, 235.200, -7.400, 238.800, -1.400, 240.400); - mg_cubic_to(-1.400, 240.400, 0.600, 244.800, 3.000, 245.200); - mg_cubic_to(5.400, 245.600, 10.200, 251.200, 14.200, 250.000); - mg_cubic_to(18.200, 248.800, 29.400, 244.800, 29.400, 244.800); - mg_cubic_to(29.400, 244.800, 35.000, 241.600, 43.800, 245.200); - mg_cubic_to(43.800, 245.200, 46.175, 244.400, 46.600, 240.400); - mg_cubic_to(47.100, 235.700, 50.200, 232.000, 52.200, 230.000); - mg_cubic_to(54.200, 228.000, 63.800, 215.200, 62.600, 214.800); - mg_cubic_to(61.400, 214.400, -5.400, 222.800, -5.400, 222.800); - mg_close_path(); - mg_set_color_rgba(0.647, 0.149, 0.298, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 53) - { - mg_move_to(-9.800, 174.400); - mg_cubic_to(-9.800, 174.400, -12.600, 196.800, -9.400, 205.200); - mg_cubic_to(-6.200, 213.600, -7.000, 215.600, -7.800, 219.600); - mg_cubic_to(-8.600, 223.600, -4.200, 233.600, 1.400, 239.600); - mg_line_to(13.400, 241.200); - mg_cubic_to(13.400, 241.200, 28.600, 237.600, 37.800, 240.400); - mg_cubic_to(37.800, 240.400, 46.794, 241.740, 50.200, 226.800); - mg_cubic_to(50.200, 226.800, 55.000, 220.400, 62.200, 217.600); - mg_cubic_to(69.400, 214.800, 76.600, 173.200, 72.600, 165.200); - mg_cubic_to(68.600, 157.200, 54.200, 152.800, 38.200, 168.400); - mg_cubic_to(22.200, 184.000, 20.200, 167.200, -9.800, 174.400); - mg_close_path(); - mg_set_color_rgba(1.000, 0.447, 0.498, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 54) - { - mg_set_width(1); - mg_move_to(-9.800, 174.400); - mg_cubic_to(-9.800, 174.400, -12.600, 196.800, -9.400, 205.200); - mg_cubic_to(-6.200, 213.600, -7.000, 215.600, -7.800, 219.600); - mg_cubic_to(-8.600, 223.600, -4.200, 233.600, 1.400, 239.600); - mg_line_to(13.400, 241.200); - mg_cubic_to(13.400, 241.200, 28.600, 237.600, 37.800, 240.400); - mg_cubic_to(37.800, 240.400, 46.794, 241.740, 50.200, 226.800); - mg_cubic_to(50.200, 226.800, 55.000, 220.400, 62.200, 217.600); - mg_cubic_to(69.400, 214.800, 76.600, 173.200, 72.600, 165.200); - mg_cubic_to(68.600, 157.200, 54.200, 152.800, 38.200, 168.400); - mg_cubic_to(22.200, 184.000, 20.200, 167.200, -9.800, 174.400); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 55) - { - mg_move_to(-8.200, 249.200); - mg_cubic_to(-8.200, 249.200, -9.000, 247.200, -13.400, 246.800); - mg_cubic_to(-13.400, 246.800, -35.800, 243.200, -44.200, 230.800); - mg_cubic_to(-44.200, 230.800, -51.000, 225.200, -46.600, 236.800); - mg_cubic_to(-46.600, 236.800, -36.200, 257.200, -29.400, 260.000); - mg_cubic_to(-29.400, 260.000, -13.000, 264.000, -8.200, 249.200); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 0.800, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 56) - { - mg_set_width(0.5); - mg_move_to(-8.200, 249.200); - mg_cubic_to(-8.200, 249.200, -9.000, 247.200, -13.400, 246.800); - mg_cubic_to(-13.400, 246.800, -35.800, 243.200, -44.200, 230.800); - mg_cubic_to(-44.200, 230.800, -51.000, 225.200, -46.600, 236.800); - mg_cubic_to(-46.600, 236.800, -36.200, 257.200, -29.400, 260.000); - mg_cubic_to(-29.400, 260.000, -13.000, 264.000, -8.200, 249.200); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 57) - { - mg_move_to(71.742, 185.230); - mg_cubic_to(72.401, 177.320, 74.354, 168.710, 72.600, 165.200); - mg_cubic_to(66.154, 152.310, 49.181, 157.700, 38.200, 168.400); - mg_cubic_to(22.200, 184.000, 20.200, 167.200, -9.800, 174.400); - mg_cubic_to(-9.800, 174.400, -11.545, 188.360, -10.705, 198.380); - mg_cubic_to(-10.705, 198.380, 26.600, 186.800, 27.400, 192.400); - mg_cubic_to(27.400, 192.400, 29.000, 189.200, 38.200, 189.200); - mg_cubic_to(47.400, 189.200, 70.142, 188.030, 71.742, 185.230); - mg_close_path(); - mg_set_color_rgba(0.800, 0.247, 0.298, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 58) - { - mg_move_to(28.600, 175.200); - mg_cubic_to(28.600, 175.200, 33.400, 180.000, 29.800, 189.600); - mg_cubic_to(29.800, 189.600, 15.400, 205.600, 17.400, 219.600); - } - if(!singlePath || singlePathIndex == 59) - { - mg_set_width(2); - mg_set_color_rgba(0.647, 0.098, 0.149, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 60) - { - mg_move_to(-19.400, 260.000); - mg_cubic_to(-19.400, 260.000, -23.800, 247.200, -15.000, 254.000); - mg_line_to(-11.400, 257.600); - mg_cubic_to(-12.600, 259.200, -18.200, 263.200, -19.400, 260.000); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 0.800, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 61) - { - mg_set_width(0.5); - mg_move_to(-19.400, 260.000); - mg_cubic_to(-19.400, 260.000, -23.800, 247.200, -15.000, 254.000); - mg_line_to(-11.400, 257.600); - mg_cubic_to(-12.600, 259.200, -18.200, 263.200, -19.400, 260.000); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 62) - { - mg_move_to(-14.360, 261.200); - mg_cubic_to(-14.360, 261.200, -17.880, 250.960, -10.840, 256.400); - mg_line_to(-7.960, 259.280); - mg_cubic_to(-12.520, 260.560, -7.960, 263.120, -14.360, 261.200); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 0.800, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 63) - { - mg_set_width(0.5); - mg_move_to(-14.360, 261.200); - mg_cubic_to(-14.360, 261.200, -17.880, 250.960, -10.840, 256.400); - mg_line_to(-7.960, 259.280); - mg_cubic_to(-12.520, 260.560, -7.960, 263.120, -14.360, 261.200); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 64) - { - mg_move_to(-9.560, 261.200); - mg_cubic_to(-9.560, 261.200, -13.080, 250.960, -6.040, 256.400); - mg_line_to(-3.160, 259.280); - mg_cubic_to(-6.520, 260.560, -3.160, 263.120, -9.560, 261.200); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 0.800, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 65) - { - mg_set_width(0.5); - mg_move_to(-9.560, 261.200); - mg_cubic_to(-9.560, 261.200, -13.080, 250.960, -6.040, 256.400); - mg_line_to(-3.160, 259.280); - mg_cubic_to(-6.520, 260.560, -3.160, 263.120, -9.560, 261.200); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 66) - { - mg_move_to(-2.960, 261.400); - mg_cubic_to(-2.960, 261.400, -6.480, 251.160, 0.560, 256.600); - mg_cubic_to(0.560, 256.600, 4.943, 258.930, 3.441, 259.480); - mg_cubic_to(0.480, 260.560, 3.441, 263.320, -2.960, 261.400); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 0.800, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 67) - { - mg_set_width(0.5); - mg_move_to(-2.960, 261.400); - mg_cubic_to(-2.960, 261.400, -6.480, 251.160, 0.560, 256.600); - mg_cubic_to(0.560, 256.600, 4.943, 258.930, 3.441, 259.480); - mg_cubic_to(0.480, 260.560, 3.441, 263.320, -2.960, 261.400); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 68) - { - mg_move_to(3.520, 261.320); - mg_cubic_to(3.520, 261.320, 0.000, 251.080, 7.041, 256.520); - mg_line_to(9.921, 259.400); - mg_cubic_to(8.961, 260.680, 9.921, 263.240, 3.520, 261.320); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 0.800, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 69) - { - mg_set_width(0.5); - mg_move_to(3.520, 261.320); - mg_cubic_to(3.520, 261.320, 0.000, 251.080, 7.041, 256.520); - mg_line_to(9.921, 259.400); - mg_cubic_to(8.961, 260.680, 9.921, 263.240, 3.520, 261.320); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 70) - { - mg_move_to(10.200, 262.000); - mg_cubic_to(10.200, 262.000, 5.400, 249.600, 14.600, 256.000); - mg_line_to(18.200, 259.600); - mg_cubic_to(17.000, 261.200, 18.200, 264.400, 10.200, 262.000); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 0.800, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 71) - { - mg_set_width(0.5); - mg_move_to(10.200, 262.000); - mg_cubic_to(10.200, 262.000, 5.400, 249.600, 14.600, 256.000); - mg_line_to(18.200, 259.600); - mg_cubic_to(17.000, 261.200, 18.200, 264.400, 10.200, 262.000); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 72) - { - mg_move_to(-18.200, 244.800); - mg_cubic_to(-18.200, 244.800, -5.000, 242.000, 1.000, 245.200); - mg_cubic_to(1.000, 245.200, 7.000, 246.400, 8.200, 246.000); - mg_cubic_to(9.400, 245.600, 12.600, 245.200, 12.600, 245.200); - } - if(!singlePath || singlePathIndex == 73) - { - mg_set_width(2); - mg_set_color_rgba(0.647, 0.149, 0.298, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 74) - { - mg_move_to(15.800, 253.600); - mg_cubic_to(15.800, 253.600, 27.800, 240.000, 39.800, 244.400); - mg_cubic_to(46.816, 246.970, 45.800, 243.600, 46.600, 240.800); - mg_cubic_to(47.400, 238.000, 47.600, 233.800, 52.600, 230.800); - } - if(!singlePath || singlePathIndex == 75) - { - mg_set_width(2); - mg_set_color_rgba(0.647, 0.149, 0.298, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 76) - { - mg_move_to(33.000, 237.600); - mg_cubic_to(33.000, 237.600, 29.000, 226.800, 26.200, 239.600); - mg_cubic_to(23.400, 252.400, 20.200, 256.000, 18.600, 258.800); - mg_cubic_to(18.600, 258.800, 18.600, 264.000, 27.000, 263.600); - mg_cubic_to(27.000, 263.600, 37.800, 263.200, 38.200, 260.400); - mg_cubic_to(38.600, 257.600, 37.000, 246.000, 33.000, 237.600); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 0.800, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 77) - { - mg_set_width(0.5); - mg_move_to(33.000, 237.600); - mg_cubic_to(33.000, 237.600, 29.000, 226.800, 26.200, 239.600); - mg_cubic_to(23.400, 252.400, 20.200, 256.000, 18.600, 258.800); - mg_cubic_to(18.600, 258.800, 18.600, 264.000, 27.000, 263.600); - mg_cubic_to(27.000, 263.600, 37.800, 263.200, 38.200, 260.400); - mg_cubic_to(38.600, 257.600, 37.000, 246.000, 33.000, 237.600); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 78) - { - mg_move_to(47.000, 244.800); - mg_cubic_to(47.000, 244.800, 50.600, 242.400, 53.000, 243.600); - } - if(!singlePath || singlePathIndex == 79) - { - mg_set_width(2); - mg_set_color_rgba(0.647, 0.149, 0.298, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 80) - { - mg_move_to(53.500, 228.400); - mg_cubic_to(53.500, 228.400, 56.400, 223.500, 61.200, 222.700); - } - if(!singlePath || singlePathIndex == 81) - { - mg_set_width(2); - mg_set_color_rgba(0.647, 0.149, 0.298, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 82) - { - mg_move_to(-25.800, 265.200); - mg_cubic_to(-25.800, 265.200, -7.800, 268.400, -3.400, 266.800); - mg_line_to(-3.000, 268.800); - mg_line_to(-23.800, 267.600); - mg_cubic_to(-23.800, 267.600, -35.400, 262.000, -25.800, 265.200); - mg_close_path(); - mg_set_color_rgba(0.698, 0.698, 0.698, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 83) - { - mg_move_to(-11.800, 172.000); - mg_move_to(7.800, 172.800); - mg_cubic_to(7.800, 172.800, 15.000, 203.600, 11.400, 211.200); - mg_cubic_to(11.400, 211.200, 10.200, 214.000, 7.400, 208.400); - mg_cubic_to(7.400, 208.400, -11.000, 175.600, -14.200, 173.600); - mg_cubic_to(-17.400, 171.600, -13.000, 172.000, -11.800, 172.000); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 0.800, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 84) - { - mg_set_width(0.5); - mg_move_to(-11.800, 172.000); - mg_move_to(7.800, 172.800); - mg_cubic_to(7.800, 172.800, 15.000, 203.600, 11.400, 211.200); - mg_cubic_to(11.400, 211.200, 10.200, 214.000, 7.400, 208.400); - mg_cubic_to(7.400, 208.400, -11.000, 175.600, -14.200, 173.600); - mg_cubic_to(-17.400, 171.600, -13.000, 172.000, -11.800, 172.000); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 85) - { - mg_move_to(-88.900, 169.300); - mg_cubic_to(-88.900, 169.300, -80.000, 171.000, -67.400, 173.600); - mg_cubic_to(-67.400, 173.600, -62.600, 196.000, -59.400, 200.800); - mg_cubic_to(-56.200, 205.600, -59.800, 205.600, -63.400, 202.800); - mg_cubic_to(-67.000, 200.000, -81.800, 186.000, -83.800, 181.600); - mg_cubic_to(-85.800, 177.200, -88.900, 169.300, -88.900, 169.300); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 0.800, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 86) - { - mg_set_width(0.5); - mg_move_to(-88.900, 169.300); - mg_cubic_to(-88.900, 169.300, -80.000, 171.000, -67.400, 173.600); - mg_cubic_to(-67.400, 173.600, -62.600, 196.000, -59.400, 200.800); - mg_cubic_to(-56.200, 205.600, -59.800, 205.600, -63.400, 202.800); - mg_cubic_to(-67.000, 200.000, -81.800, 186.000, -83.800, 181.600); - mg_cubic_to(-85.800, 177.200, -88.900, 169.300, -88.900, 169.300); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 87) - { - mg_move_to(-67.039, 173.820); - mg_cubic_to(-67.039, 173.820, -61.239, 175.370, -60.230, 177.580); - mg_cubic_to(-59.222, 179.800, -61.432, 183.090, -61.432, 183.090); - mg_cubic_to(-61.432, 183.090, -62.432, 186.400, -63.634, 184.240); - mg_cubic_to(-64.836, 182.070, -67.708, 174.410, -67.039, 173.820); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 0.800, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 88) - { - mg_set_width(0.5); - mg_move_to(-67.039, 173.820); - mg_cubic_to(-67.039, 173.820, -61.239, 175.370, -60.230, 177.580); - mg_cubic_to(-59.222, 179.800, -61.432, 183.090, -61.432, 183.090); - mg_cubic_to(-61.432, 183.090, -62.432, 186.400, -63.634, 184.240); - mg_cubic_to(-64.836, 182.070, -67.708, 174.410, -67.039, 173.820); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 89) - { - mg_move_to(-67.000, 173.600); - mg_cubic_to(-67.000, 173.600, -63.400, 178.800, -59.800, 178.800); - mg_cubic_to(-56.200, 178.800, -55.818, 178.390, -53.000, 179.000); - mg_cubic_to(-48.400, 180.000, -48.800, 178.000, -42.200, 179.200); - mg_cubic_to(-39.560, 179.680, -37.000, 178.800, -34.200, 180.000); - mg_cubic_to(-31.400, 181.200, -28.200, 180.400, -27.000, 178.400); - mg_cubic_to(-25.800, 176.400, -21.000, 172.200, -21.000, 172.200); - mg_cubic_to(-21.000, 172.200, -33.800, 174.000, -36.600, 174.800); - mg_cubic_to(-36.600, 174.800, -59.000, 176.000, -67.000, 173.600); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 90) - { - mg_move_to(-22.400, 173.800); - mg_cubic_to(-22.400, 173.800, -28.850, 177.300, -29.250, 179.700); - mg_cubic_to(-29.650, 182.100, -24.000, 185.800, -24.000, 185.800); - mg_cubic_to(-24.000, 185.800, -21.250, 190.400, -20.650, 188.000); - mg_cubic_to(-20.050, 185.600, -21.600, 174.200, -22.400, 173.800); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 0.800, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 91) - { - mg_set_width(0.5); - mg_move_to(-22.400, 173.800); - mg_cubic_to(-22.400, 173.800, -28.850, 177.300, -29.250, 179.700); - mg_cubic_to(-29.650, 182.100, -24.000, 185.800, -24.000, 185.800); - mg_cubic_to(-24.000, 185.800, -21.250, 190.400, -20.650, 188.000); - mg_cubic_to(-20.050, 185.600, -21.600, 174.200, -22.400, 173.800); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 92) - { - mg_move_to(-59.885, 179.260); - mg_cubic_to(-59.885, 179.260, -52.878, 190.450, -52.661, 179.240); - mg_cubic_to(-52.661, 179.240, -52.104, 177.980, -53.864, 177.960); - mg_cubic_to(-59.939, 177.890, -58.418, 173.780, -59.885, 179.260); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 0.800, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 93) - { - mg_set_width(0.5); - mg_move_to(-59.885, 179.260); - mg_cubic_to(-59.885, 179.260, -52.878, 190.450, -52.661, 179.240); - mg_cubic_to(-52.661, 179.240, -52.104, 177.980, -53.864, 177.960); - mg_cubic_to(-59.939, 177.890, -58.418, 173.780, -59.885, 179.260); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 94) - { - mg_move_to(-52.707, 179.510); - mg_cubic_to(-52.707, 179.510, -44.786, 190.700, -45.422, 179.420); - mg_cubic_to(-45.422, 179.420, -45.415, 179.090, -47.168, 178.940); - mg_cubic_to(-51.915, 178.520, -51.570, 174.000, -52.707, 179.510); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 0.800, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 95) - { - mg_set_width(0.5); - mg_move_to(-52.707, 179.510); - mg_cubic_to(-52.707, 179.510, -44.786, 190.700, -45.422, 179.420); - mg_cubic_to(-45.422, 179.420, -45.415, 179.090, -47.168, 178.940); - mg_cubic_to(-51.915, 178.520, -51.570, 174.000, -52.707, 179.510); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 96) - { - mg_move_to(-45.494, 179.520); - mg_cubic_to(-45.494, 179.520, -37.534, 190.150, -38.203, 180.480); - mg_cubic_to(-38.203, 180.480, -38.084, 179.250, -39.738, 178.950); - mg_cubic_to(-43.630, 178.240, -43.841, 175.000, -45.494, 179.520); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 0.800, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 97) - { - mg_set_width(0.5); - mg_move_to(-45.494, 179.520); - mg_cubic_to(-45.494, 179.520, -37.534, 190.150, -38.203, 180.480); - mg_cubic_to(-38.203, 180.480, -38.084, 179.250, -39.738, 178.950); - mg_cubic_to(-43.630, 178.240, -43.841, 175.000, -45.494, 179.520); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 98) - { - mg_move_to(-38.618, 179.600); - mg_cubic_to(-38.618, 179.600, -30.718, 191.160, -30.370, 181.380); - mg_cubic_to(-30.370, 181.380, -28.726, 180.000, -30.472, 179.780); - mg_cubic_to(-36.290, 179.040, -35.492, 174.590, -38.618, 179.600); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 0.800, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 99) - { - mg_set_width(0.5); - mg_move_to(-38.618, 179.600); - mg_cubic_to(-38.618, 179.600, -30.718, 191.160, -30.370, 181.380); - mg_cubic_to(-30.370, 181.380, -28.726, 180.000, -30.472, 179.780); - mg_cubic_to(-36.290, 179.040, -35.492, 174.590, -38.618, 179.600); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 100) - { - mg_move_to(-74.792, 183.130); - mg_move_to(-82.450, 181.600); - mg_cubic_to(-85.050, 176.600, -87.150, 170.450, -87.150, 170.450); - mg_cubic_to(-87.150, 170.450, -80.800, 171.450, -68.300, 174.250); - mg_cubic_to(-68.300, 174.250, -67.424, 177.570, -65.952, 183.360); - mg_line_to(-74.792, 183.130); - mg_close_path(); - mg_set_color_rgba(0.898, 0.898, 0.698, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 101) - { - mg_move_to(-9.724, 178.470); - mg_cubic_to(-11.390, 175.960, -12.707, 174.210, -13.357, 173.800); - mg_cubic_to(-16.370, 171.920, -12.227, 172.290, -11.098, 172.290); - mg_line_to(7.356, 173.050); - mg_cubic_to(7.356, 173.050, 7.880, 175.290, 8.564, 178.680); - mg_cubic_to(8.564, 178.680, -1.524, 176.670, -9.724, 178.470); - mg_close_path(); - mg_set_color_rgba(0.898, 0.898, 0.698, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 102) - { - mg_move_to(43.880, 40.321); - mg_cubic_to(71.601, 44.281, 97.121, 8.641, 98.881, -1.040); - mg_cubic_to(100.640, -10.720, 90.521, -22.600, 90.521, -22.600); - mg_cubic_to(91.841, -25.680, 87.001, -39.760, 81.721, -49.000); - mg_cubic_to(76.441, -58.240, 60.540, -57.266, 43.000, -58.240); - mg_cubic_to(27.160, -59.120, 8.680, -35.800, 7.360, -34.040); - mg_cubic_to(6.040, -32.280, 12.200, 6.001, 13.520, 11.721); - mg_cubic_to(14.840, 17.441, 12.200, 43.841, 12.200, 43.841); - mg_cubic_to(46.440, 34.741, 16.160, 36.361, 43.880, 40.321); - mg_close_path(); - mg_set_color_rgba(0.800, 0.447, 0.149, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 103) - { - mg_move_to(8.088, -33.392); - mg_cubic_to(6.792, -31.664, 12.840, 5.921, 14.136, 11.537); - mg_cubic_to(15.432, 17.153, 12.840, 43.073, 12.840, 43.073); - mg_cubic_to(45.512, 34.193, 16.728, 35.729, 43.944, 39.617); - mg_cubic_to(71.161, 43.505, 96.217, 8.513, 97.945, -0.992); - mg_cubic_to(99.673, -10.496, 89.737, -22.160, 89.737, -22.160); - mg_cubic_to(91.033, -25.184, 86.281, -39.008, 81.097, -48.080); - mg_cubic_to(75.913, -57.152, 60.302, -56.195, 43.080, -57.152); - mg_cubic_to(27.528, -58.016, 9.384, -35.120, 8.088, -33.392); - mg_close_path(); - mg_set_color_rgba(0.918, 0.557, 0.318, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 104) - { - mg_move_to(8.816, -32.744); - mg_cubic_to(7.544, -31.048, 13.480, 5.841, 14.752, 11.353); - mg_cubic_to(16.024, 16.865, 13.480, 42.305, 13.480, 42.305); - mg_cubic_to(44.884, 33.145, 17.296, 35.097, 44.008, 38.913); - mg_cubic_to(70.721, 42.729, 95.313, 8.385, 97.009, -0.944); - mg_cubic_to(98.705, -10.272, 88.953, -21.720, 88.953, -21.720); - mg_cubic_to(90.225, -24.688, 85.561, -38.256, 80.473, -47.160); - mg_cubic_to(75.385, -56.064, 60.063, -55.125, 43.160, -56.064); - mg_cubic_to(27.896, -56.912, 10.088, -34.440, 8.816, -32.744); - mg_close_path(); - mg_set_color_rgba(0.937, 0.667, 0.486, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 105) - { - mg_move_to(9.544, -32.096); - mg_cubic_to(8.296, -30.432, 14.120, 5.761, 15.368, 11.169); - mg_cubic_to(16.616, 16.577, 14.120, 41.537, 14.120, 41.537); - mg_cubic_to(43.556, 32.497, 17.864, 34.465, 44.072, 38.209); - mg_cubic_to(70.281, 41.953, 94.409, 8.257, 96.073, -0.895); - mg_cubic_to(97.737, -10.048, 88.169, -21.280, 88.169, -21.280); - mg_cubic_to(89.417, -24.192, 84.841, -37.504, 79.849, -46.240); - mg_cubic_to(74.857, -54.976, 59.824, -54.055, 43.240, -54.976); - mg_cubic_to(28.264, -55.808, 10.792, -33.760, 9.544, -32.096); - mg_close_path(); - mg_set_color_rgba(0.957, 0.776, 0.659, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 106) - { - mg_move_to(10.272, -31.448); - mg_cubic_to(9.048, -29.816, 14.760, 5.681, 15.984, 10.985); - mg_cubic_to(17.208, 16.289, 14.760, 40.769, 14.760, 40.769); - mg_cubic_to(42.628, 31.849, 18.432, 33.833, 44.136, 37.505); - mg_cubic_to(69.841, 41.177, 93.505, 8.129, 95.137, -0.848); - mg_cubic_to(96.769, -9.824, 87.385, -20.840, 87.385, -20.840); - mg_cubic_to(88.609, -23.696, 84.121, -36.752, 79.225, -45.320); - mg_cubic_to(74.329, -53.888, 59.585, -52.985, 43.320, -53.888); - mg_cubic_to(28.632, -54.704, 11.496, -33.080, 10.272, -31.448); - mg_close_path(); - mg_set_color_rgba(0.976, 0.886, 0.827, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 107) - { - mg_move_to(44.200, 36.800); - mg_cubic_to(69.400, 40.400, 92.601, 8.000, 94.201, -0.800); - mg_cubic_to(95.801, -9.600, 86.601, -20.400, 86.601, -20.400); - mg_cubic_to(87.801, -23.200, 83.400, -36.000, 78.600, -44.400); - mg_cubic_to(73.800, -52.800, 59.346, -51.914, 43.400, -52.800); - mg_cubic_to(29.000, -53.600, 12.200, -32.400, 11.000, -30.800); - mg_cubic_to(9.800, -29.200, 15.400, 5.600, 16.600, 10.800); - mg_cubic_to(17.800, 16.000, 15.400, 40.000, 15.400, 40.000); - mg_cubic_to(40.900, 31.400, 19.000, 33.200, 44.200, 36.800); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 108) - { - mg_move_to(90.601, 2.800); - mg_cubic_to(90.601, 2.800, 62.800, 10.400, 51.200, 8.800); - mg_cubic_to(51.200, 8.800, 35.400, 2.200, 26.600, 24.000); - mg_cubic_to(26.600, 24.000, 23.000, 31.200, 21.000, 33.200); - mg_cubic_to(19.000, 35.200, 90.601, 2.800, 90.601, 2.800); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 109) - { - mg_move_to(94.401, 0.600); - mg_cubic_to(94.401, 0.600, 65.400, 12.800, 55.400, 12.400); - mg_cubic_to(55.400, 12.400, 39.000, 7.800, 30.600, 22.400); - mg_cubic_to(30.600, 22.400, 22.200, 31.600, 19.000, 33.200); - mg_cubic_to(19.000, 33.200, 18.600, 34.800, 25.000, 30.800); - mg_line_to(35.400, 36.000); - mg_cubic_to(35.400, 36.000, 50.200, 45.600, 59.800, 29.600); - mg_cubic_to(59.800, 29.600, 63.800, 18.400, 63.800, 16.400); - mg_cubic_to(63.800, 14.400, 85.000, 8.800, 86.601, 8.400); - mg_cubic_to(88.201, 8.000, 94.801, 3.800, 94.401, 0.600); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 110) - { - mg_move_to(47.000, 36.514); - mg_cubic_to(40.128, 36.514, 31.755, 32.649, 31.755, 26.400); - mg_cubic_to(31.755, 20.152, 40.128, 13.887, 47.000, 13.887); - mg_cubic_to(53.874, 13.887, 59.446, 18.952, 59.446, 25.200); - mg_cubic_to(59.446, 31.449, 53.874, 36.514, 47.000, 36.514); - mg_close_path(); - mg_set_color_rgba(0.600, 0.800, 0.196, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 111) - { - mg_move_to(43.377, 19.830); - mg_cubic_to(38.531, 20.552, 33.442, 22.055, 33.514, 21.839); - mg_cubic_to(35.054, 17.220, 41.415, 13.887, 47.000, 13.887); - mg_cubic_to(51.296, 13.887, 55.084, 15.865, 57.320, 18.875); - mg_cubic_to(57.320, 18.875, 52.004, 18.545, 43.377, 19.830); - mg_close_path(); - mg_set_color_rgba(0.396, 0.600, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 112) - { - mg_move_to(55.400, 19.600); - mg_cubic_to(55.400, 19.600, 51.000, 16.400, 51.000, 18.600); - mg_cubic_to(51.000, 18.600, 54.600, 23.000, 55.400, 19.600); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 113) - { - mg_move_to(45.400, 27.726); - mg_cubic_to(42.901, 27.726, 40.875, 25.700, 40.875, 23.200); - mg_cubic_to(40.875, 20.701, 42.901, 18.675, 45.400, 18.675); - mg_cubic_to(47.900, 18.675, 49.926, 20.701, 49.926, 23.200); - mg_cubic_to(49.926, 25.700, 47.900, 27.726, 45.400, 27.726); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 114) - { - mg_move_to(-58.600, 14.400); - mg_cubic_to(-58.600, 14.400, -61.800, -6.800, -59.400, -11.200); - mg_cubic_to(-59.400, -11.200, -48.600, -21.200, -49.000, -24.800); - mg_cubic_to(-49.000, -24.800, -49.400, -42.800, -50.600, -43.600); - mg_cubic_to(-51.800, -44.400, -59.400, -50.400, -65.400, -44.000); - mg_cubic_to(-65.400, -44.000, -75.800, -26.000, -75.000, -19.600); - mg_line_to(-75.000, -17.600); - mg_cubic_to(-75.000, -17.600, -82.600, -18.000, -84.200, -16.000); - mg_cubic_to(-84.200, -16.000, -85.400, -10.800, -86.600, -10.400); - mg_cubic_to(-86.600, -10.400, -89.400, -8.000, -87.400, -5.200); - mg_cubic_to(-87.400, -5.200, -89.400, -2.800, -89.000, 1.200); - mg_line_to(-81.400, 5.200); - mg_cubic_to(-81.400, 5.200, -79.400, 19.600, -68.600, 24.800); - mg_cubic_to(-63.764, 27.129, -60.600, 20.400, -58.600, 14.400); - mg_close_path(); - mg_set_color_rgba(0.800, 0.447, 0.149, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 115) - { - mg_move_to(-59.600, 12.560); - mg_cubic_to(-59.600, 12.560, -62.480, -6.520, -60.320, -10.480); - mg_cubic_to(-60.320, -10.480, -50.600, -19.480, -50.960, -22.720); - mg_cubic_to(-50.960, -22.720, -51.320, -38.920, -52.400, -39.640); - mg_cubic_to(-53.480, -40.360, -60.320, -45.760, -65.720, -40.000); - mg_cubic_to(-65.720, -40.000, -75.080, -23.800, -74.360, -18.040); - mg_line_to(-74.360, -16.240); - mg_cubic_to(-74.360, -16.240, -81.200, -16.600, -82.640, -14.800); - mg_cubic_to(-82.640, -14.800, -83.720, -10.120, -84.800, -9.760); - mg_cubic_to(-84.800, -9.760, -87.320, -7.600, -85.520, -5.080); - mg_cubic_to(-85.520, -5.080, -87.320, -2.920, -86.960, 0.680); - mg_line_to(-80.120, 4.280); - mg_cubic_to(-80.120, 4.280, -78.320, 17.240, -68.600, 21.920); - mg_cubic_to(-64.248, 24.015, -61.400, 17.960, -59.600, 12.560); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 116) - { - mg_move_to(-51.050, -42.610); - mg_cubic_to(-52.140, -43.470, -59.630, -49.240, -65.480, -43.000); - mg_cubic_to(-65.480, -43.000, -75.620, -25.450, -74.840, -19.210); - mg_line_to(-74.840, -17.260); - mg_cubic_to(-74.840, -17.260, -82.250, -17.650, -83.810, -15.700); - mg_cubic_to(-83.810, -15.700, -84.980, -10.630, -86.150, -10.240); - mg_cubic_to(-86.150, -10.240, -88.880, -7.900, -86.930, -5.170); - mg_cubic_to(-86.930, -5.170, -88.880, -2.830, -88.490, 1.070); - mg_line_to(-81.080, 4.970); - mg_cubic_to(-81.080, 4.970, -79.130, 19.010, -68.600, 24.080); - mg_cubic_to(-63.886, 26.350, -60.800, 19.790, -58.850, 13.940); - mg_cubic_to(-58.850, 13.940, -61.970, -6.730, -59.630, -11.020); - mg_cubic_to(-59.630, -11.020, -49.100, -20.770, -49.490, -24.280); - mg_cubic_to(-49.490, -24.280, -49.880, -41.830, -51.050, -42.610); - mg_close_path(); - mg_set_color_rgba(0.922, 0.584, 0.361, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 117) - { - mg_move_to(-51.500, -41.620); - mg_cubic_to(-52.480, -42.540, -59.860, -48.080, -65.560, -42.000); - mg_cubic_to(-65.560, -42.000, -75.440, -24.900, -74.680, -18.820); - mg_line_to(-74.680, -16.920); - mg_cubic_to(-74.680, -16.920, -81.900, -17.300, -83.420, -15.400); - mg_cubic_to(-83.420, -15.400, -84.560, -10.460, -85.700, -10.080); - mg_cubic_to(-85.700, -10.080, -88.360, -7.800, -86.460, -5.140); - mg_cubic_to(-86.460, -5.140, -88.360, -2.860, -87.980, 0.940); - mg_line_to(-80.760, 4.740); - mg_cubic_to(-80.760, 4.740, -78.860, 18.420, -68.600, 23.360); - mg_cubic_to(-64.006, 25.572, -61.000, 19.180, -59.100, 13.480); - mg_cubic_to(-59.100, 13.480, -62.140, -6.660, -59.860, -10.840); - mg_cubic_to(-59.860, -10.840, -49.600, -20.340, -49.980, -23.760); - mg_cubic_to(-49.980, -23.760, -50.360, -40.860, -51.500, -41.620); - mg_close_path(); - mg_set_color_rgba(0.949, 0.722, 0.573, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 118) - { - mg_move_to(-51.950, -40.630); - mg_cubic_to(-52.820, -41.610, -60.090, -46.920, -65.640, -41.000); - mg_cubic_to(-65.640, -41.000, -75.260, -24.350, -74.520, -18.430); - mg_line_to(-74.520, -16.580); - mg_cubic_to(-74.520, -16.580, -81.550, -16.950, -83.030, -15.100); - mg_cubic_to(-83.030, -15.100, -84.140, -10.290, -85.250, -9.920); - mg_cubic_to(-85.250, -9.920, -87.840, -7.700, -85.990, -5.110); - mg_cubic_to(-85.990, -5.110, -87.840, -2.890, -87.470, 0.810); - mg_line_to(-80.440, 4.510); - mg_cubic_to(-80.440, 4.510, -78.590, 17.830, -68.600, 22.640); - mg_cubic_to(-64.127, 24.794, -61.200, 18.570, -59.350, 13.020); - mg_cubic_to(-59.350, 13.020, -62.310, -6.590, -60.090, -10.660); - mg_cubic_to(-60.090, -10.660, -50.100, -19.910, -50.470, -23.240); - mg_cubic_to(-50.470, -23.240, -50.840, -39.890, -51.950, -40.630); - mg_close_path(); - mg_set_color_rgba(0.973, 0.863, 0.784, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 119) - { - mg_move_to(-59.600, 12.460); - mg_cubic_to(-59.600, 12.460, -62.480, -6.520, -60.320, -10.480); - mg_cubic_to(-60.320, -10.480, -50.600, -19.480, -50.960, -22.720); - mg_cubic_to(-50.960, -22.720, -51.320, -38.920, -52.400, -39.640); - mg_cubic_to(-53.160, -40.680, -60.320, -45.760, -65.720, -40.000); - mg_cubic_to(-65.720, -40.000, -75.080, -23.800, -74.360, -18.040); - mg_line_to(-74.360, -16.240); - mg_cubic_to(-74.360, -16.240, -81.200, -16.600, -82.640, -14.800); - mg_cubic_to(-82.640, -14.800, -83.720, -10.120, -84.800, -9.760); - mg_cubic_to(-84.800, -9.760, -87.320, -7.600, -85.520, -5.080); - mg_cubic_to(-85.520, -5.080, -87.320, -2.920, -86.960, 0.680); - mg_line_to(-80.120, 4.280); - mg_cubic_to(-80.120, 4.280, -78.320, 17.240, -68.600, 21.920); - mg_cubic_to(-64.248, 24.015, -61.400, 17.860, -59.600, 12.460); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 120) - { - mg_move_to(-62.700, 6.200); - mg_cubic_to(-62.700, 6.200, -84.300, -4.000, -85.200, -4.800); - mg_cubic_to(-85.200, -4.800, -76.100, 3.400, -75.300, 3.400); - mg_cubic_to(-74.500, 3.400, -62.700, 6.200, -62.700, 6.200); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 121) - { - mg_move_to(-79.800, 0.000); - mg_cubic_to(-79.800, 0.000, -61.400, 3.600, -61.400, 8.000); - mg_cubic_to(-61.400, 10.912, -61.643, 24.331, -67.000, 22.800); - mg_cubic_to(-75.400, 20.400, -71.800, 6.000, -79.800, 0.000); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 122) - { - mg_move_to(-71.400, 3.800); - mg_cubic_to(-71.400, 3.800, -62.422, 5.274, -61.400, 8.000); - mg_cubic_to(-60.800, 9.600, -60.137, 17.908, -65.600, 19.000); - mg_cubic_to(-70.152, 19.911, -72.382, 9.690, -71.400, 3.800); - mg_close_path(); - mg_set_color_rgba(0.600, 0.800, 0.196, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 123) - { - mg_move_to(14.595, 46.349); - mg_cubic_to(14.098, 44.607, 15.409, 44.738, 17.200, 44.200); - mg_cubic_to(19.200, 43.600, 31.400, 39.800, 32.200, 37.200); - mg_cubic_to(33.000, 34.600, 46.200, 39.000, 46.200, 39.000); - mg_cubic_to(48.000, 39.800, 52.400, 42.400, 52.400, 42.400); - mg_cubic_to(57.200, 43.600, 63.800, 44.000, 63.800, 44.000); - mg_cubic_to(66.200, 45.000, 69.600, 47.800, 69.600, 47.800); - mg_cubic_to(84.200, 58.000, 96.601, 50.800, 96.601, 50.800); - mg_cubic_to(116.600, 44.200, 110.600, 27.000, 110.600, 27.000); - mg_cubic_to(107.600, 18.000, 110.800, 14.600, 110.800, 14.600); - mg_cubic_to(111.000, 10.800, 118.200, 17.200, 118.200, 17.200); - mg_cubic_to(120.800, 21.400, 121.600, 26.400, 121.600, 26.400); - mg_cubic_to(129.600, 37.600, 126.200, 19.800, 126.200, 19.800); - mg_cubic_to(126.400, 18.800, 123.600, 15.200, 123.600, 14.000); - mg_cubic_to(123.600, 12.800, 121.800, 9.400, 121.800, 9.400); - mg_cubic_to(118.800, 6.000, 121.200, -1.000, 121.200, -1.000); - mg_cubic_to(123.000, -14.800, 120.800, -13.000, 120.800, -13.000); - mg_cubic_to(119.600, -14.800, 110.400, -4.800, 110.400, -4.800); - mg_cubic_to(108.200, -1.400, 102.200, 0.200, 102.200, 0.200); - mg_cubic_to(99.401, 2.000, 96.001, 0.600, 96.001, 0.600); - mg_cubic_to(93.401, 0.200, 87.801, 7.200, 87.801, 7.200); - mg_cubic_to(90.601, 7.000, 93.001, 11.400, 95.401, 11.600); - mg_cubic_to(97.801, 11.800, 99.601, 9.200, 101.200, 8.600); - mg_cubic_to(102.800, 8.000, 105.600, 13.800, 105.600, 13.800); - mg_cubic_to(106.000, 16.400, 100.400, 21.200, 100.400, 21.200); - mg_cubic_to(100.000, 25.800, 98.401, 24.200, 98.401, 24.200); - mg_cubic_to(95.401, 23.600, 94.201, 27.400, 93.201, 32.000); - mg_cubic_to(92.201, 36.600, 88.001, 37.000, 88.001, 37.000); - mg_cubic_to(86.401, 44.400, 85.200, 41.400, 85.200, 41.400); - mg_cubic_to(85.000, 35.800, 79.000, 41.600, 79.000, 41.600); - mg_cubic_to(77.800, 43.600, 73.200, 41.400, 73.200, 41.400); - mg_cubic_to(66.400, 39.400, 68.800, 37.400, 68.800, 37.400); - mg_cubic_to(70.600, 35.200, 81.800, 37.400, 81.800, 37.400); - mg_cubic_to(84.000, 35.800, 76.000, 31.800, 76.000, 31.800); - mg_cubic_to(75.400, 30.000, 76.400, 25.600, 76.400, 25.600); - mg_cubic_to(77.600, 22.400, 84.400, 16.800, 84.400, 16.800); - mg_cubic_to(93.801, 15.600, 91.001, 14.000, 91.001, 14.000); - mg_cubic_to(84.801, 8.800, 79.000, 16.400, 79.000, 16.400); - mg_cubic_to(76.800, 22.600, 59.400, 37.600, 59.400, 37.600); - mg_cubic_to(54.600, 41.000, 57.200, 34.200, 53.200, 37.600); - mg_cubic_to(49.200, 41.000, 28.600, 32.000, 28.600, 32.000); - mg_cubic_to(17.038, 30.807, 14.306, 46.549, 10.777, 43.429); - mg_cubic_to(10.777, 43.429, 16.195, 51.949, 14.595, 46.349); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 124) - { - mg_move_to(209.400, -120.000); - mg_cubic_to(209.400, -120.000, 183.800, -112.000, 181.000, -93.200); - mg_cubic_to(181.000, -93.200, 178.600, -70.400, 199.000, -52.800); - mg_cubic_to(199.000, -52.800, 199.400, -46.400, 201.400, -43.200); - mg_cubic_to(201.400, -43.200, 199.800, -38.400, 218.600, -46.000); - mg_line_to(245.800, -54.400); - mg_cubic_to(245.800, -54.400, 252.200, -56.800, 257.400, -65.600); - mg_cubic_to(262.600, -74.400, 277.800, -93.200, 274.200, -118.400); - mg_cubic_to(274.200, -118.400, 275.400, -129.600, 269.400, -130.000); - mg_cubic_to(269.400, -130.000, 261.000, -131.600, 253.800, -124.000); - mg_cubic_to(253.800, -124.000, 247.000, -120.800, 244.600, -121.200); - mg_line_to(209.400, -120.000); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 125) - { - mg_move_to(264.020, -120.990); - mg_cubic_to(264.020, -120.990, 266.120, -129.920, 261.280, -125.080); - mg_cubic_to(261.280, -125.080, 254.240, -119.360, 246.760, -119.360); - mg_cubic_to(246.760, -119.360, 232.240, -117.160, 227.840, -103.960); - mg_cubic_to(227.840, -103.960, 223.880, -77.120, 231.800, -71.400); - mg_cubic_to(231.800, -71.400, 236.640, -63.920, 243.680, -70.520); - mg_cubic_to(250.720, -77.120, 266.220, -107.350, 264.020, -120.990); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 126) - { - mg_move_to(263.650, -120.630); - mg_cubic_to(263.650, -120.630, 265.740, -129.380, 260.990, -124.620); - mg_cubic_to(260.990, -124.620, 254.070, -119.010, 246.730, -119.010); - mg_cubic_to(246.730, -119.010, 232.470, -116.850, 228.150, -103.890); - mg_cubic_to(228.150, -103.890, 224.260, -77.536, 232.040, -71.920); - mg_cubic_to(232.040, -71.920, 236.790, -64.576, 243.700, -71.056); - mg_cubic_to(250.620, -77.536, 265.810, -107.240, 263.650, -120.630); - mg_close_path(); - mg_set_color_rgba(0.196, 0.196, 0.196, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 127) - { - mg_move_to(263.270, -120.270); - mg_cubic_to(263.270, -120.270, 265.350, -128.830, 260.690, -124.170); - mg_cubic_to(260.690, -124.170, 253.910, -118.660, 246.700, -118.660); - mg_cubic_to(246.700, -118.660, 232.700, -116.540, 228.460, -103.820); - mg_cubic_to(228.460, -103.820, 224.650, -77.952, 232.280, -72.440); - mg_cubic_to(232.280, -72.440, 236.940, -65.232, 243.730, -71.592); - mg_cubic_to(250.510, -77.952, 265.390, -107.130, 263.270, -120.270); - mg_close_path(); - mg_set_color_rgba(0.400, 0.400, 0.400, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 128) - { - mg_move_to(262.900, -119.920); - mg_cubic_to(262.900, -119.920, 264.970, -128.290, 260.390, -123.710); - mg_cubic_to(260.390, -123.710, 253.740, -118.300, 246.660, -118.300); - mg_cubic_to(246.660, -118.300, 232.940, -116.220, 228.780, -103.740); - mg_cubic_to(228.780, -103.740, 225.030, -78.368, 232.520, -72.960); - mg_cubic_to(232.520, -72.960, 237.100, -65.888, 243.750, -72.128); - mg_cubic_to(250.410, -78.368, 264.980, -107.020, 262.900, -119.920); - mg_close_path(); - mg_set_color_rgba(0.600, 0.600, 0.600, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 129) - { - mg_move_to(262.530, -119.560); - mg_cubic_to(262.530, -119.560, 264.590, -127.740, 260.100, -123.260); - mg_cubic_to(260.100, -123.260, 253.570, -117.950, 246.630, -117.950); - mg_cubic_to(246.630, -117.950, 233.170, -115.910, 229.090, -103.670); - mg_cubic_to(229.090, -103.670, 225.420, -78.784, 232.760, -73.480); - mg_cubic_to(232.760, -73.480, 237.250, -66.544, 243.780, -72.664); - mg_cubic_to(250.300, -78.784, 264.570, -106.910, 262.530, -119.560); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 130) - { - mg_move_to(262.150, -119.200); - mg_cubic_to(262.150, -119.200, 264.200, -127.200, 259.800, -122.800); - mg_cubic_to(259.800, -122.800, 253.400, -117.600, 246.600, -117.600); - mg_cubic_to(246.600, -117.600, 233.400, -115.600, 229.400, -103.600); - mg_cubic_to(229.400, -103.600, 225.800, -79.200, 233.000, -74.000); - mg_cubic_to(233.000, -74.000, 237.400, -67.200, 243.800, -73.200); - mg_cubic_to(250.200, -79.200, 264.150, -106.800, 262.150, -119.200); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 131) - { - mg_move_to(50.600, 84.000); - mg_cubic_to(50.600, 84.000, 30.200, 64.800, 22.200, 64.000); - mg_cubic_to(22.200, 64.000, -12.200, 60.000, -27.000, 78.000); - mg_cubic_to(-27.000, 78.000, -9.400, 57.600, 18.200, 63.200); - mg_cubic_to(18.200, 63.200, -3.400, 58.800, -15.800, 62.000); - mg_line_to(-42.200, 76.000); - mg_line_to(-45.000, 80.800); - mg_cubic_to(-45.000, 80.800, -41.000, 66.000, -22.600, 60.000); - mg_cubic_to(-22.600, 60.000, 0.200, 55.200, 11.000, 60.000); - mg_cubic_to(11.000, 60.000, -10.600, 53.200, -20.600, 55.200); - mg_cubic_to(-20.600, 55.200, -51.000, 52.800, -63.800, 79.200); - mg_cubic_to(-63.800, 79.200, -59.800, 64.800, -45.000, 57.600); - mg_cubic_to(-45.000, 57.600, -31.400, 48.800, -11.000, 51.600); - mg_cubic_to(-11.000, 51.600, 3.400, 54.800, 8.600, 57.200); - mg_cubic_to(13.800, 59.600, 12.600, 56.800, 4.200, 52.000); - mg_cubic_to(4.200, 52.000, -1.400, 42.000, -15.400, 42.400); - mg_cubic_to(-15.400, 42.400, -58.200, 46.000, -68.600, 58.000); - mg_cubic_to(-68.600, 58.000, -55.000, 46.800, -44.600, 44.000); - mg_cubic_to(-44.600, 44.000, -22.200, 36.000, -13.800, 36.800); - mg_cubic_to(-13.800, 36.800, 11.000, 37.800, 18.600, 33.800); - mg_cubic_to(18.600, 33.800, 7.400, 38.800, 10.600, 42.000); - mg_cubic_to(13.800, 45.200, 20.600, 52.800, 20.600, 54.000); - mg_cubic_to(20.600, 55.200, 44.800, 77.300, 48.400, 81.700); - mg_line_to(50.600, 84.000); - mg_close_path(); - mg_set_color_rgba(0.600, 0.149, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 132) - { - mg_move_to(189.000, 278.000); - mg_cubic_to(189.000, 278.000, 173.500, 241.500, 161.000, 232.000); - mg_cubic_to(161.000, 232.000, 187.000, 248.000, 190.500, 266.000); - mg_cubic_to(190.500, 266.000, 190.500, 276.000, 189.000, 278.000); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 133) - { - mg_move_to(236.000, 285.500); - mg_cubic_to(236.000, 285.500, 209.500, 230.500, 191.000, 206.500); - mg_cubic_to(191.000, 206.500, 234.500, 244.000, 239.500, 270.500); - mg_line_to(240.000, 276.000); - mg_line_to(237.000, 273.500); - mg_cubic_to(237.000, 273.500, 236.500, 282.500, 236.000, 285.500); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 134) - { - mg_move_to(292.500, 237.000); - mg_cubic_to(292.500, 237.000, 230.000, 177.500, 228.500, 175.000); - mg_cubic_to(228.500, 175.000, 289.000, 241.000, 292.000, 248.500); - mg_cubic_to(292.000, 248.500, 290.000, 239.500, 292.500, 237.000); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 135) - { - mg_move_to(104.000, 280.500); - mg_cubic_to(104.000, 280.500, 123.500, 228.500, 142.500, 251.000); - mg_cubic_to(142.500, 251.000, 157.500, 261.000, 157.000, 264.000); - mg_cubic_to(157.000, 264.000, 153.000, 257.500, 135.000, 258.000); - mg_cubic_to(135.000, 258.000, 116.000, 255.000, 104.000, 280.500); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 136) - { - mg_move_to(294.500, 153.000); - mg_cubic_to(294.500, 153.000, 249.500, 124.500, 242.000, 123.000); - mg_cubic_to(230.190, 120.640, 291.500, 152.000, 296.500, 162.500); - mg_cubic_to(296.500, 162.500, 298.500, 160.000, 294.500, 153.000); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 137) - { - mg_move_to(143.800, 259.600); - mg_cubic_to(143.800, 259.600, 164.200, 257.600, 171.000, 250.800); - mg_line_to(175.400, 254.400); - mg_line_to(193.000, 216.000); - mg_line_to(196.600, 221.200); - mg_cubic_to(196.600, 221.200, 211.000, 206.400, 210.200, 198.400); - mg_cubic_to(209.400, 190.400, 223.000, 204.400, 223.000, 204.400); - mg_cubic_to(223.000, 204.400, 222.200, 192.800, 229.400, 199.600); - mg_cubic_to(229.400, 199.600, 227.000, 184.000, 235.400, 192.000); - mg_cubic_to(235.400, 192.000, 224.860, 161.840, 247.400, 187.600); - mg_cubic_to(253.000, 194.000, 248.600, 187.200, 248.600, 187.200); - mg_cubic_to(248.600, 187.200, 222.600, 139.200, 244.200, 153.600); - mg_cubic_to(244.200, 153.600, 246.200, 130.800, 245.000, 126.400); - mg_cubic_to(243.800, 122.000, 241.800, 99.600, 237.000, 94.400); - mg_cubic_to(232.200, 89.200, 237.400, 87.600, 243.000, 92.800); - mg_cubic_to(243.000, 92.800, 231.800, 68.800, 245.000, 80.800); - mg_cubic_to(245.000, 80.800, 241.400, 65.600, 237.000, 62.800); - mg_cubic_to(237.000, 62.800, 231.400, 45.600, 246.600, 56.400); - mg_cubic_to(246.600, 56.400, 242.200, 44.000, 239.000, 40.800); - mg_cubic_to(239.000, 40.800, 227.400, 13.200, 234.600, 18.000); - mg_line_to(239.000, 21.600); - mg_cubic_to(239.000, 21.600, 232.200, 7.600, 238.600, 12.000); - mg_cubic_to(245.000, 16.400, 245.000, 16.000, 245.000, 16.000); - mg_cubic_to(245.000, 16.000, 223.800, -17.200, 244.200, 0.400); - mg_cubic_to(244.200, 0.400, 236.040, -13.518, 232.600, -20.400); - mg_cubic_to(232.600, -20.400, 213.800, -40.800, 228.200, -34.400); - mg_line_to(233.000, -32.800); - mg_cubic_to(233.000, -32.800, 224.200, -42.800, 216.200, -44.400); - mg_cubic_to(208.200, -46.000, 218.600, -52.400, 225.000, -50.400); - mg_cubic_to(231.400, -48.400, 247.000, -40.800, 247.000, -40.800); - mg_cubic_to(247.000, -40.800, 259.800, -22.000, 263.800, -21.600); - mg_cubic_to(263.800, -21.600, 243.800, -29.200, 249.800, -21.200); - mg_cubic_to(249.800, -21.200, 264.200, -7.200, 257.000, -7.600); - mg_cubic_to(257.000, -7.600, 251.000, -0.400, 255.800, 8.400); - mg_cubic_to(255.800, 8.400, 237.340, -9.991, 252.200, 15.600); - mg_line_to(259.000, 32.000); - mg_cubic_to(259.000, 32.000, 234.600, 7.200, 245.800, 29.200); - mg_cubic_to(245.800, 29.200, 263.000, 52.800, 265.000, 53.200); - mg_cubic_to(267.000, 53.600, 271.400, 62.400, 271.400, 62.400); - mg_line_to(267.000, 60.400); - mg_line_to(272.200, 69.200); - mg_cubic_to(272.200, 69.200, 261.000, 57.200, 267.000, 70.400); - mg_line_to(272.600, 84.800); - mg_cubic_to(272.600, 84.800, 252.200, 62.800, 265.800, 92.400); - mg_cubic_to(265.800, 92.400, 249.400, 87.200, 258.200, 104.400); - mg_cubic_to(258.200, 104.400, 256.600, 120.400, 257.000, 125.600); - mg_cubic_to(257.400, 130.800, 258.600, 159.200, 254.200, 167.200); - mg_cubic_to(249.800, 175.200, 260.200, 194.400, 262.200, 198.400); - mg_cubic_to(264.200, 202.400, 267.800, 213.200, 259.000, 204.000); - mg_cubic_to(250.200, 194.800, 254.600, 200.400, 256.600, 209.200); - mg_cubic_to(258.600, 218.000, 264.600, 233.600, 263.800, 239.200); - mg_cubic_to(263.800, 239.200, 262.600, 240.400, 259.400, 236.800); - mg_cubic_to(259.400, 236.800, 244.600, 214.000, 246.200, 228.400); - mg_cubic_to(246.200, 228.400, 245.000, 236.400, 241.800, 245.200); - mg_cubic_to(241.800, 245.200, 238.600, 256.000, 238.600, 247.200); - mg_cubic_to(238.600, 247.200, 235.400, 230.400, 232.600, 238.000); - mg_cubic_to(229.800, 245.600, 226.200, 251.600, 223.400, 254.000); - mg_cubic_to(220.600, 256.400, 215.400, 233.600, 214.200, 244.000); - mg_cubic_to(214.200, 244.000, 202.200, 231.600, 197.400, 248.000); - mg_line_to(185.800, 264.400); - mg_cubic_to(185.800, 264.400, 185.400, 252.000, 184.200, 258.000); - mg_cubic_to(184.200, 258.000, 154.200, 264.000, 143.800, 259.600); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 138) - { - mg_move_to(109.400, -97.200); - mg_cubic_to(109.400, -97.200, 97.801, -105.200, 93.801, -104.800); - mg_cubic_to(89.801, -104.400, 121.400, -113.600, 162.600, -86.000); - mg_cubic_to(162.600, -86.000, 167.400, -83.200, 171.000, -83.600); - mg_cubic_to(171.000, -83.600, 174.200, -81.200, 171.400, -77.600); - mg_cubic_to(171.400, -77.600, 162.600, -68.000, 173.800, -56.800); - mg_cubic_to(173.800, -56.800, 192.200, -50.000, 186.600, -58.800); - mg_cubic_to(186.600, -58.800, 197.400, -54.800, 199.800, -50.800); - mg_cubic_to(202.200, -46.800, 201.000, -50.800, 201.000, -50.800); - mg_line_to(188.600, -63.200); - mg_cubic_to(188.600, -63.200, 183.400, -65.200, 180.600, -73.600); - mg_cubic_to(177.800, -82.000, 175.400, -92.000, 179.800, -95.200); - mg_cubic_to(179.800, -95.200, 175.800, -90.800, 176.600, -94.800); - mg_cubic_to(177.400, -98.800, 181.000, -102.400, 182.600, -102.800); - mg_cubic_to(184.200, -103.200, 200.600, -119.000, 207.400, -119.400); - mg_cubic_to(207.400, -119.400, 198.200, -118.000, 195.200, -119.000); - mg_cubic_to(192.200, -120.000, 165.600, -131.400, 159.600, -132.600); - mg_cubic_to(159.600, -132.600, 142.800, -139.200, 154.800, -137.200); - mg_cubic_to(154.800, -137.200, 190.600, -133.400, 208.800, -120.200); - mg_cubic_to(208.800, -120.200, 201.600, -128.600, 183.200, -135.600); - mg_cubic_to(183.200, -135.600, 161.000, -148.200, 125.800, -143.200); - mg_cubic_to(125.800, -143.200, 108.000, -140.000, 100.200, -138.200); - mg_cubic_to(100.200, -138.200, 97.601, -138.800, 97.001, -139.200); - mg_cubic_to(96.401, -139.600, 84.600, -148.600, 57.000, -141.600); - mg_cubic_to(57.000, -141.600, 40.000, -137.000, 31.400, -132.200); - mg_cubic_to(31.400, -132.200, 16.200, -131.000, 12.600, -127.800); - mg_cubic_to(12.600, -127.800, -6.000, -113.200, -8.000, -112.400); - mg_cubic_to(-10.000, -111.600, -21.400, -104.000, -22.200, -103.600); - mg_cubic_to(-22.200, -103.600, 2.400, -110.200, 4.800, -112.600); - mg_cubic_to(7.200, -115.000, 24.600, -117.600, 27.000, -116.200); - mg_cubic_to(29.400, -114.800, 37.800, -115.400, 28.200, -114.800); - mg_cubic_to(28.200, -114.800, 103.800, -100.000, 104.600, -98.000); - mg_cubic_to(105.400, -96.000, 109.400, -97.200, 109.400, -97.200); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 139) - { - mg_move_to(180.800, -106.400); - mg_cubic_to(180.800, -106.400, 170.600, -113.800, 168.600, -113.800); - mg_cubic_to(166.600, -113.800, 154.200, -124.000, 150.000, -123.600); - mg_cubic_to(145.800, -123.200, 133.600, -133.200, 106.200, -125.000); - mg_cubic_to(106.200, -125.000, 105.600, -127.000, 109.200, -127.800); - mg_cubic_to(109.200, -127.800, 115.600, -130.000, 116.000, -130.600); - mg_cubic_to(116.000, -130.600, 136.200, -134.800, 143.400, -131.200); - mg_cubic_to(143.400, -131.200, 152.600, -128.600, 158.800, -122.400); - mg_cubic_to(158.800, -122.400, 170.000, -119.200, 173.200, -120.200); - mg_cubic_to(173.200, -120.200, 182.000, -118.000, 182.400, -116.200); - mg_cubic_to(182.400, -116.200, 188.200, -113.200, 186.400, -110.600); - mg_cubic_to(186.400, -110.600, 186.800, -109.000, 180.800, -106.400); - mg_close_path(); - mg_set_color_rgba(0.800, 0.447, 0.149, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 140) - { - mg_move_to(168.330, -108.510); - mg_cubic_to(169.140, -107.880, 170.160, -107.780, 170.760, -106.970); - mg_cubic_to(171.000, -106.660, 170.710, -106.330, 170.390, -106.230); - mg_cubic_to(169.350, -105.920, 168.290, -106.490, 167.150, -105.900); - mg_cubic_to(166.750, -105.690, 166.110, -105.870, 165.550, -106.020); - mg_cubic_to(163.920, -106.460, 162.090, -106.490, 160.400, -105.800); - mg_cubic_to(158.420, -106.930, 156.060, -106.340, 153.980, -107.350); - mg_cubic_to(153.920, -107.370, 153.700, -107.030, 153.620, -107.050); - mg_cubic_to(150.580, -108.200, 146.830, -107.920, 144.400, -110.200); - mg_cubic_to(141.970, -110.610, 139.620, -111.070, 137.190, -111.750); - mg_cubic_to(135.370, -112.260, 133.960, -113.250, 132.340, -114.080); - mg_cubic_to(130.960, -114.790, 129.510, -115.310, 127.970, -115.690); - mg_cubic_to(126.110, -116.140, 124.280, -116.030, 122.390, -116.550); - mg_cubic_to(122.290, -116.570, 122.100, -116.230, 122.020, -116.250); - mg_cubic_to(121.700, -116.360, 121.400, -116.940, 121.230, -116.890); - mg_cubic_to(119.550, -116.370, 118.060, -117.340, 116.400, -117.000); - mg_cubic_to(115.220, -118.220, 113.500, -117.980, 111.950, -118.420); - mg_cubic_to(108.980, -119.270, 105.830, -118.000, 102.800, -119.000); - mg_cubic_to(106.910, -120.840, 111.600, -119.610, 115.660, -121.680); - mg_cubic_to(117.990, -122.860, 120.650, -121.760, 123.220, -122.520); - mg_cubic_to(123.710, -122.670, 124.400, -122.870, 124.800, -122.200); - mg_cubic_to(124.940, -122.340, 125.120, -122.570, 125.180, -122.550); - mg_cubic_to(127.620, -121.390, 129.940, -120.120, 132.420, -119.050); - mg_cubic_to(132.760, -118.900, 133.300, -119.140, 133.550, -118.930); - mg_cubic_to(135.070, -117.720, 137.010, -117.820, 138.400, -116.600); - mg_cubic_to(140.100, -117.100, 141.890, -116.720, 143.620, -117.350); - mg_cubic_to(143.700, -117.370, 143.930, -117.030, 143.960, -117.050); - mg_cubic_to(145.100, -117.800, 146.250, -117.530, 147.140, -117.230); - mg_cubic_to(147.480, -117.110, 148.140, -116.860, 148.450, -116.790); - mg_cubic_to(149.570, -116.520, 150.430, -116.040, 151.610, -115.850); - mg_cubic_to(151.720, -115.830, 151.910, -116.170, 151.980, -116.150); - mg_cubic_to(153.100, -115.710, 154.140, -115.760, 154.800, -114.600); - mg_cubic_to(154.940, -114.740, 155.100, -114.970, 155.180, -114.950); - mg_cubic_to(156.210, -114.610, 156.860, -113.850, 157.960, -113.610); - mg_cubic_to(158.440, -113.510, 159.060, -112.880, 159.630, -112.700); - mg_cubic_to(162.020, -111.970, 163.870, -110.440, 166.060, -109.550); - mg_cubic_to(166.820, -109.240, 167.700, -109.000, 168.330, -108.510); - mg_close_path(); - mg_set_color_rgba(0.800, 0.447, 0.149, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 141) - { - mg_move_to(91.696, -122.740); - mg_cubic_to(89.178, -124.460, 86.810, -125.570, 84.368, -127.360); - mg_cubic_to(84.187, -127.490, 83.827, -127.320, 83.625, -127.440); - mg_cubic_to(82.618, -128.050, 81.730, -128.630, 80.748, -129.330); - mg_cubic_to(80.209, -129.710, 79.388, -129.700, 78.880, -129.960); - mg_cubic_to(76.336, -131.250, 73.707, -131.810, 71.200, -133.000); - mg_cubic_to(71.882, -133.640, 73.004, -133.390, 73.600, -134.200); - mg_cubic_to(73.795, -133.920, 74.033, -133.640, 74.386, -133.830); - mg_cubic_to(76.064, -134.730, 77.914, -134.880, 79.590, -134.790); - mg_cubic_to(81.294, -134.700, 83.014, -134.400, 84.789, -134.120); - mg_cubic_to(85.096, -134.080, 85.295, -133.560, 85.618, -133.460); - mg_cubic_to(87.846, -132.800, 90.235, -133.320, 92.354, -132.480); - mg_cubic_to(93.945, -131.850, 95.515, -131.030, 96.754, -129.760); - mg_cubic_to(97.006, -129.500, 96.681, -129.190, 96.401, -129.000); - mg_cubic_to(96.789, -129.110, 97.062, -128.900, 97.173, -128.590); - mg_cubic_to(97.257, -128.350, 97.257, -128.050, 97.173, -127.810); - mg_cubic_to(97.061, -127.500, 96.782, -127.400, 96.408, -127.350); - mg_cubic_to(95.001, -127.160, 96.773, -128.540, 96.073, -128.090); - mg_cubic_to(94.800, -127.270, 95.546, -125.870, 94.801, -124.600); - mg_cubic_to(94.521, -124.790, 94.291, -125.010, 94.401, -125.400); - mg_cubic_to(94.635, -124.880, 94.033, -124.590, 93.865, -124.270); - mg_cubic_to(93.480, -123.550, 92.581, -122.130, 91.696, -122.740); - mg_close_path(); - mg_set_color_rgba(0.800, 0.447, 0.149, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 142) - { - mg_move_to(59.198, -115.390); - mg_cubic_to(56.044, -116.180, 52.994, -116.070, 49.978, -117.350); - mg_cubic_to(49.911, -117.370, 49.688, -117.030, 49.624, -117.050); - mg_cubic_to(48.258, -117.650, 47.340, -118.610, 46.264, -119.660); - mg_cubic_to(45.351, -120.550, 43.693, -120.160, 42.419, -120.650); - mg_cubic_to(42.095, -120.770, 41.892, -121.280, 41.591, -121.320); - mg_cubic_to(40.372, -121.480, 39.445, -122.430, 38.400, -123.000); - mg_cubic_to(40.736, -123.800, 43.147, -123.760, 45.609, -124.150); - mg_cubic_to(45.722, -124.170, 45.867, -123.840, 46.000, -123.840); - mg_cubic_to(46.136, -123.840, 46.266, -124.070, 46.400, -124.200); - mg_cubic_to(46.595, -123.920, 46.897, -123.590, 47.154, -123.850); - mg_cubic_to(47.702, -124.390, 48.258, -124.200, 48.798, -124.160); - mg_cubic_to(48.942, -124.150, 49.067, -123.840, 49.200, -123.840); - mg_cubic_to(49.336, -123.840, 49.467, -124.160, 49.600, -124.160); - mg_cubic_to(49.736, -124.160, 49.867, -123.840, 50.000, -123.840); - mg_cubic_to(50.136, -123.840, 50.266, -124.070, 50.400, -124.200); - mg_cubic_to(51.092, -123.420, 51.977, -123.970, 52.799, -123.790); - mg_cubic_to(53.837, -123.570, 54.104, -122.420, 55.178, -122.120); - mg_cubic_to(59.893, -120.820, 64.030, -118.670, 68.393, -116.580); - mg_cubic_to(68.700, -116.440, 68.910, -116.190, 68.800, -115.800); - mg_cubic_to(69.067, -115.800, 69.380, -115.890, 69.570, -115.760); - mg_cubic_to(70.628, -115.020, 71.669, -114.480, 72.366, -113.380); - mg_cubic_to(72.582, -113.040, 72.253, -112.630, 72.020, -112.680); - mg_cubic_to(67.591, -113.680, 63.585, -114.290, 59.198, -115.390); - mg_close_path(); - mg_set_color_rgba(0.800, 0.447, 0.149, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 143) - { - mg_move_to(45.338, -71.179); - mg_cubic_to(43.746, -72.398, 43.162, -74.429, 42.034, -76.221); - mg_cubic_to(41.820, -76.561, 42.094, -76.875, 42.411, -76.964); - mg_cubic_to(42.971, -77.123, 43.514, -76.645, 43.923, -76.443); - mg_cubic_to(45.668, -75.581, 47.203, -74.339, 49.200, -74.200); - mg_cubic_to(51.190, -71.966, 55.450, -71.581, 55.457, -68.200); - mg_cubic_to(55.458, -67.341, 54.030, -68.259, 53.600, -67.400); - mg_cubic_to(51.149, -68.403, 48.760, -68.300, 46.380, -69.767); - mg_cubic_to(45.763, -70.148, 46.093, -70.601, 45.338, -71.179); - mg_close_path(); - mg_set_color_rgba(0.800, 0.447, 0.149, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 144) - { - mg_move_to(17.800, -123.760); - mg_cubic_to(17.935, -123.760, 24.966, -123.520, 24.949, -123.410); - mg_cubic_to(24.904, -123.100, 17.174, -122.050, 16.810, -122.220); - mg_cubic_to(16.646, -122.300, 9.134, -119.870, 9.000, -120.000); - mg_cubic_to(9.268, -120.140, 17.534, -123.760, 17.800, -123.760); - mg_close_path(); - mg_set_color_rgba(0.800, 0.447, 0.149, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 145) - { - mg_move_to(33.200, -114.000); - mg_cubic_to(33.200, -114.000, 18.400, -112.200, 14.000, -111.000); - mg_cubic_to(9.600, -109.800, -9.000, -102.200, -12.000, -100.200); - mg_cubic_to(-12.000, -100.200, -25.400, -94.800, -42.400, -74.800); - mg_cubic_to(-42.400, -74.800, -34.800, -78.200, -32.600, -81.000); - mg_cubic_to(-32.600, -81.000, -19.000, -93.600, -19.200, -91.000); - mg_cubic_to(-19.200, -91.000, -7.000, -99.600, -7.600, -97.400); - mg_cubic_to(-7.600, -97.400, 16.800, -108.600, 14.800, -105.400); - mg_cubic_to(14.800, -105.400, 36.400, -110.000, 35.400, -108.000); - mg_cubic_to(35.400, -108.000, 54.200, -103.600, 51.400, -103.400); - mg_cubic_to(51.400, -103.400, 45.600, -102.200, 52.000, -98.600); - mg_cubic_to(52.000, -98.600, 48.600, -94.200, 43.200, -98.200); - mg_cubic_to(37.800, -102.200, 40.800, -100.000, 35.800, -99.000); - mg_cubic_to(35.800, -99.000, 33.200, -98.200, 28.600, -102.200); - mg_cubic_to(28.600, -102.200, 23.000, -106.800, 14.200, -103.200); - mg_cubic_to(14.200, -103.200, -16.400, -90.600, -18.400, -90.000); - mg_cubic_to(-18.400, -90.000, -22.000, -87.200, -24.400, -83.600); - mg_cubic_to(-24.400, -83.600, -30.200, -79.200, -33.200, -77.800); - mg_cubic_to(-33.200, -77.800, -46.000, -66.200, -47.200, -64.800); - mg_cubic_to(-47.200, -64.800, -50.600, -59.600, -51.400, -59.200); - mg_cubic_to(-51.400, -59.200, -45.000, -63.000, -43.000, -65.000); - mg_cubic_to(-43.000, -65.000, -29.000, -75.000, -23.600, -75.800); - mg_cubic_to(-23.600, -75.800, -19.200, -78.800, -18.400, -80.200); - mg_cubic_to(-18.400, -80.200, -4.000, -89.400, 0.200, -89.400); - mg_cubic_to(0.200, -89.400, 9.400, -84.200, 11.800, -91.200); - mg_cubic_to(11.800, -91.200, 17.600, -93.000, 23.200, -91.800); - mg_cubic_to(23.200, -91.800, 26.400, -94.400, 25.600, -96.600); - mg_cubic_to(25.600, -96.600, 27.200, -98.400, 28.200, -94.600); - mg_cubic_to(28.200, -94.600, 31.600, -91.000, 36.400, -93.000); - mg_cubic_to(36.400, -93.000, 40.400, -93.200, 38.400, -90.800); - mg_cubic_to(38.400, -90.800, 34.000, -87.000, 22.200, -86.800); - mg_cubic_to(22.200, -86.800, 9.800, -86.200, -6.600, -78.600); - mg_cubic_to(-6.600, -78.600, -36.400, -68.200, -45.600, -57.800); - mg_cubic_to(-45.600, -57.800, -52.000, -49.000, -57.400, -47.800); - mg_cubic_to(-57.400, -47.800, -63.200, -47.000, -69.200, -39.600); - mg_cubic_to(-69.200, -39.600, -59.400, -45.400, -50.400, -45.400); - mg_cubic_to(-50.400, -45.400, -46.400, -47.800, -50.200, -44.200); - mg_cubic_to(-50.200, -44.200, -53.800, -36.600, -52.200, -31.200); - mg_cubic_to(-52.200, -31.200, -52.800, -26.000, -53.600, -24.400); - mg_cubic_to(-53.600, -24.400, -61.400, -11.600, -61.400, -9.200); - mg_cubic_to(-61.400, -6.800, -60.200, 3.000, -59.800, 3.600); - mg_cubic_to(-59.400, 4.200, -60.800, 2.000, -57.000, 4.400); - mg_cubic_to(-53.200, 6.800, -50.400, 8.400, -49.600, 11.200); - mg_cubic_to(-48.800, 14.000, -51.600, 5.800, -51.800, 4.000); - mg_cubic_to(-52.000, 2.200, -56.200, -5.000, -55.400, -7.400); - mg_cubic_to(-55.400, -7.400, -54.400, -6.400, -53.600, -5.000); - mg_cubic_to(-53.600, -5.000, -54.200, -5.600, -53.600, -9.200); - mg_cubic_to(-53.600, -9.200, -52.800, -14.400, -51.400, -17.600); - mg_cubic_to(-50.000, -20.800, -48.000, -24.600, -47.600, -25.400); - mg_cubic_to(-47.200, -26.200, -47.200, -32.000, -45.800, -29.400); - mg_line_to(-42.400, -26.800); - mg_cubic_to(-42.400, -26.800, -45.200, -29.400, -43.000, -31.600); - mg_cubic_to(-43.000, -31.600, -44.000, -37.200, -42.200, -39.800); - mg_cubic_to(-42.200, -39.800, -35.200, -48.200, -33.600, -49.200); - mg_cubic_to(-32.000, -50.200, -33.400, -49.800, -33.400, -49.800); - mg_cubic_to(-33.400, -49.800, -27.400, -54.000, -33.200, -52.400); - mg_cubic_to(-33.200, -52.400, -37.200, -50.800, -40.200, -50.800); - mg_cubic_to(-40.200, -50.800, -47.800, -48.800, -43.800, -53.000); - mg_cubic_to(-39.800, -57.200, -29.800, -62.600, -26.000, -62.400); - mg_line_to(-25.200, -60.800); - mg_line_to(-14.000, -63.200); - mg_line_to(-15.200, -62.400); - mg_cubic_to(-15.200, -62.400, -15.400, -62.600, -11.200, -63.000); - mg_cubic_to(-7.000, -63.400, -1.200, -62.000, 0.200, -63.800); - mg_cubic_to(1.600, -65.600, 5.000, -66.600, 4.600, -65.200); - mg_cubic_to(4.200, -63.800, 4.000, -61.800, 4.000, -61.800); - mg_cubic_to(4.000, -61.800, 9.000, -67.600, 8.400, -65.400); - mg_cubic_to(7.800, -63.200, -0.400, -58.000, -1.800, -51.800); - mg_line_to(8.600, -60.000); - mg_line_to(12.200, -63.000); - mg_cubic_to(12.200, -63.000, 15.800, -60.800, 16.000, -62.400); - mg_cubic_to(16.200, -64.000, 20.800, -69.800, 22.000, -69.600); - mg_cubic_to(23.200, -69.400, 25.200, -72.200, 25.000, -69.600); - mg_cubic_to(24.800, -67.000, 32.400, -61.600, 32.400, -61.600); - mg_cubic_to(32.400, -61.600, 35.600, -63.400, 37.000, -62.000); - mg_cubic_to(38.400, -60.600, 42.600, -81.800, 42.600, -81.800); - mg_line_to(67.600, -92.400); - mg_line_to(111.200, -95.800); - mg_line_to(94.201, -102.600); - mg_line_to(33.200, -114.000); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 146) - { - mg_move_to(51.400, 85.000); - mg_cubic_to(51.400, 85.000, 36.400, 68.200, 28.000, 65.600); - mg_cubic_to(28.000, 65.600, 14.600, 58.800, -10.000, 66.600); - } - if(!singlePath || singlePathIndex == 147) - { - mg_set_width(2); - mg_set_color_rgba(0.298, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 148) - { - mg_move_to(24.800, 64.200); - mg_cubic_to(24.800, 64.200, -0.400, 56.200, -15.800, 60.400); - mg_cubic_to(-15.800, 60.400, -34.200, 62.400, -42.600, 76.200); - } - if(!singlePath || singlePathIndex == 149) - { - mg_set_width(2); - mg_set_color_rgba(0.298, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 150) - { - mg_move_to(21.200, 63.000); - mg_cubic_to(21.200, 63.000, 4.200, 55.800, -10.600, 53.600); - mg_cubic_to(-10.600, 53.600, -27.200, 51.000, -43.800, 58.200); - mg_cubic_to(-43.800, 58.200, -56.000, 64.200, -61.400, 74.400); - } - if(!singlePath || singlePathIndex == 151) - { - mg_set_width(2); - mg_set_color_rgba(0.298, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 152) - { - mg_move_to(22.200, 63.400); - mg_cubic_to(22.200, 63.400, 6.800, 52.400, 5.800, 51.000); - mg_cubic_to(5.800, 51.000, -1.200, 40.000, -14.200, 39.600); - mg_cubic_to(-14.200, 39.600, -35.600, 40.400, -52.800, 48.400); - } - if(!singlePath || singlePathIndex == 153) - { - mg_set_width(2); - mg_set_color_rgba(0.298, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 154) - { - mg_move_to(20.895, 54.407); - mg_cubic_to(22.437, 55.870, 49.400, 84.800, 49.400, 84.800); - mg_cubic_to(84.600, 121.400, 56.600, 87.200, 56.600, 87.200); - mg_cubic_to(49.000, 82.400, 39.800, 63.600, 39.800, 63.600); - mg_cubic_to(38.600, 60.800, 53.800, 70.800, 53.800, 70.800); - mg_cubic_to(57.800, 71.600, 71.400, 90.800, 71.400, 90.800); - mg_cubic_to(64.600, 88.400, 69.400, 95.600, 69.400, 95.600); - mg_cubic_to(72.200, 97.600, 92.601, 113.200, 92.601, 113.200); - mg_cubic_to(96.201, 117.200, 100.200, 118.800, 100.200, 118.800); - mg_cubic_to(114.200, 113.600, 107.800, 126.800, 107.800, 126.800); - mg_cubic_to(110.200, 133.600, 115.800, 122.000, 115.800, 122.000); - mg_cubic_to(127.000, 105.200, 110.600, 107.600, 110.600, 107.600); - mg_cubic_to(80.600, 110.400, 73.800, 94.400, 73.800, 94.400); - mg_cubic_to(71.400, 92.000, 80.200, 94.400, 80.200, 94.400); - mg_cubic_to(88.601, 96.400, 73.000, 82.000, 73.000, 82.000); - mg_cubic_to(75.400, 82.000, 84.600, 88.800, 84.600, 88.800); - mg_cubic_to(95.001, 98.000, 97.001, 96.000, 97.001, 96.000); - mg_cubic_to(115.000, 87.200, 125.400, 94.800, 125.400, 94.800); - mg_cubic_to(127.400, 96.400, 121.800, 103.200, 123.400, 108.400); - mg_cubic_to(125.000, 113.600, 129.800, 126.000, 129.800, 126.000); - mg_cubic_to(127.400, 127.600, 127.800, 138.400, 127.800, 138.400); - mg_cubic_to(144.600, 161.600, 135.000, 159.600, 135.000, 159.600); - mg_cubic_to(119.400, 159.200, 134.200, 166.800, 134.200, 166.800); - mg_cubic_to(137.400, 168.800, 146.200, 176.000, 146.200, 176.000); - mg_cubic_to(143.400, 174.800, 141.800, 180.000, 141.800, 180.000); - mg_cubic_to(146.600, 184.000, 143.800, 188.800, 143.800, 188.800); - mg_cubic_to(137.800, 190.000, 136.600, 194.000, 136.600, 194.000); - mg_cubic_to(143.400, 202.000, 133.400, 202.400, 133.400, 202.400); - mg_cubic_to(137.000, 206.800, 132.200, 218.800, 132.200, 218.800); - mg_cubic_to(127.400, 218.800, 121.000, 224.400, 121.000, 224.400); - mg_cubic_to(123.400, 229.200, 113.000, 234.800, 113.000, 234.800); - mg_cubic_to(104.600, 236.400, 107.400, 243.200, 107.400, 243.200); - mg_cubic_to(99.401, 249.200, 97.001, 265.200, 97.001, 265.200); - mg_cubic_to(96.201, 275.600, 93.801, 278.800, 99.001, 276.800); - mg_cubic_to(104.200, 274.800, 103.400, 262.400, 103.400, 262.400); - mg_cubic_to(98.601, 246.800, 141.400, 230.800, 141.400, 230.800); - mg_cubic_to(145.400, 229.200, 146.200, 224.000, 146.200, 224.000); - mg_cubic_to(148.200, 224.400, 157.000, 232.000, 157.000, 232.000); - mg_cubic_to(164.600, 243.200, 165.000, 234.000, 165.000, 234.000); - mg_cubic_to(166.200, 230.400, 164.600, 224.400, 164.600, 224.400); - mg_cubic_to(170.600, 202.800, 156.600, 196.400, 156.600, 196.400); - mg_cubic_to(146.600, 162.800, 160.600, 171.200, 160.600, 171.200); - mg_cubic_to(163.400, 176.800, 174.200, 182.000, 174.200, 182.000); - mg_line_to(177.800, 179.600); - mg_cubic_to(176.200, 174.800, 184.600, 168.800, 184.600, 168.800); - mg_cubic_to(187.400, 175.200, 193.400, 167.200, 193.400, 167.200); - mg_cubic_to(197.000, 142.800, 209.400, 157.200, 209.400, 157.200); - mg_cubic_to(213.400, 158.400, 214.600, 151.600, 214.600, 151.600); - mg_cubic_to(218.200, 141.200, 214.600, 127.600, 214.600, 127.600); - mg_cubic_to(218.200, 127.200, 227.800, 133.200, 227.800, 133.200); - mg_cubic_to(230.600, 129.600, 221.400, 112.800, 225.400, 115.200); - mg_cubic_to(229.400, 117.600, 233.800, 119.200, 233.800, 119.200); - mg_cubic_to(234.600, 117.200, 224.600, 104.800, 224.600, 104.800); - mg_cubic_to(220.200, 102.000, 215.000, 81.600, 215.000, 81.600); - mg_cubic_to(222.200, 85.200, 212.200, 70.000, 212.200, 70.000); - mg_cubic_to(212.200, 66.800, 218.200, 55.600, 218.200, 55.600); - mg_cubic_to(217.400, 48.800, 218.200, 49.200, 218.200, 49.200); - mg_cubic_to(221.000, 50.400, 229.000, 52.000, 222.200, 45.600); - mg_cubic_to(215.400, 39.200, 223.000, 34.400, 223.000, 34.400); - mg_cubic_to(227.400, 31.600, 213.800, 32.000, 213.800, 32.000); - mg_cubic_to(208.600, 27.600, 209.000, 23.600, 209.000, 23.600); - mg_cubic_to(217.000, 25.600, 202.600, 11.200, 200.200, 7.600); - mg_cubic_to(197.800, 4.000, 207.400, -1.200, 207.400, -1.200); - mg_cubic_to(220.600, -4.800, 209.000, -8.000, 209.000, -8.000); - mg_cubic_to(189.400, -7.600, 200.200, -18.400, 200.200, -18.400); - mg_cubic_to(206.200, -18.000, 204.600, -20.400, 204.600, -20.400); - mg_cubic_to(199.400, -21.600, 189.800, -28.000, 189.800, -28.000); - mg_cubic_to(185.800, -31.600, 189.400, -30.800, 189.400, -30.800); - mg_cubic_to(206.200, -29.600, 177.400, -40.800, 177.400, -40.800); - mg_cubic_to(185.400, -40.800, 167.400, -51.200, 167.400, -51.200); - mg_cubic_to(165.400, -52.800, 162.200, -60.400, 162.200, -60.400); - mg_cubic_to(156.200, -65.600, 151.400, -72.400, 151.400, -72.400); - mg_cubic_to(151.000, -76.800, 146.200, -81.600, 146.200, -81.600); - mg_cubic_to(134.600, -95.200, 129.000, -94.800, 129.000, -94.800); - mg_cubic_to(114.200, -98.400, 109.000, -97.600, 109.000, -97.600); - mg_line_to(56.200, -93.200); - mg_cubic_to(29.800, -80.400, 37.600, -59.400, 37.600, -59.400); - mg_cubic_to(44.000, -51.000, 53.200, -54.800, 53.200, -54.800); - mg_cubic_to(57.800, -61.000, 69.400, -58.800, 69.400, -58.800); - mg_cubic_to(89.801, -55.600, 87.201, -59.200, 87.201, -59.200); - mg_cubic_to(84.801, -63.800, 68.600, -70.000, 68.400, -70.600); - mg_cubic_to(68.200, -71.200, 59.400, -74.600, 59.400, -74.600); - mg_cubic_to(56.400, -75.800, 52.000, -85.000, 52.000, -85.000); - mg_cubic_to(48.800, -88.400, 64.600, -82.600, 64.600, -82.600); - mg_cubic_to(63.400, -81.600, 70.800, -77.600, 70.800, -77.600); - mg_cubic_to(88.201, -78.600, 98.801, -67.800, 98.801, -67.800); - mg_cubic_to(109.600, -51.200, 109.800, -59.400, 109.800, -59.400); - mg_cubic_to(112.600, -68.800, 100.800, -90.000, 100.800, -90.000); - mg_cubic_to(101.200, -92.000, 109.400, -85.400, 109.400, -85.400); - mg_cubic_to(110.800, -87.400, 111.600, -81.600, 111.600, -81.600); - mg_cubic_to(111.800, -79.200, 115.600, -71.200, 115.600, -71.200); - mg_cubic_to(118.400, -58.200, 122.000, -65.600, 122.000, -65.600); - mg_line_to(126.600, -56.200); - mg_cubic_to(128.000, -53.600, 122.000, -46.000, 122.000, -46.000); - mg_cubic_to(121.800, -43.200, 122.600, -43.400, 117.000, -35.800); - mg_cubic_to(111.400, -28.200, 114.800, -23.800, 114.800, -23.800); - mg_cubic_to(113.400, -17.200, 122.200, -17.600, 122.200, -17.600); - mg_cubic_to(124.800, -15.400, 128.200, -15.400, 128.200, -15.400); - mg_cubic_to(130.000, -13.400, 132.400, -14.000, 132.400, -14.000); - mg_cubic_to(134.000, -17.800, 140.200, -15.800, 140.200, -15.800); - mg_cubic_to(141.600, -18.200, 149.800, -18.600, 149.800, -18.600); - mg_cubic_to(150.800, -21.200, 151.200, -22.800, 154.600, -23.400); - mg_cubic_to(158.000, -24.000, 133.400, -67.000, 133.400, -67.000); - mg_cubic_to(139.800, -67.800, 131.600, -80.200, 131.600, -80.200); - mg_cubic_to(129.400, -86.800, 140.800, -72.200, 143.000, -70.800); - mg_cubic_to(145.200, -69.400, 146.200, -67.200, 144.600, -67.400); - mg_cubic_to(143.000, -67.600, 141.200, -65.400, 142.600, -65.200); - mg_cubic_to(144.000, -65.000, 157.000, -50.000, 160.400, -39.800); - mg_cubic_to(163.800, -29.600, 169.800, -25.600, 176.000, -19.600); - mg_cubic_to(182.200, -13.600, 181.400, 10.600, 181.400, 10.600); - mg_cubic_to(181.000, 19.400, 187.000, 30.000, 187.000, 30.000); - mg_cubic_to(189.000, 33.800, 184.800, 52.000, 184.800, 52.000); - mg_cubic_to(182.800, 54.200, 184.200, 55.000, 184.200, 55.000); - mg_cubic_to(185.200, 56.200, 192.000, 69.400, 192.000, 69.400); - mg_cubic_to(190.200, 69.200, 193.800, 72.800, 193.800, 72.800); - mg_cubic_to(199.000, 78.800, 192.600, 75.800, 192.600, 75.800); - mg_cubic_to(186.600, 74.200, 193.600, 84.000, 193.600, 84.000); - mg_cubic_to(194.800, 85.800, 185.800, 81.200, 185.800, 81.200); - mg_cubic_to(176.600, 80.600, 188.200, 87.800, 188.200, 87.800); - mg_cubic_to(196.800, 95.000, 185.400, 90.600, 185.400, 90.600); - mg_cubic_to(180.800, 88.800, 184.000, 95.600, 184.000, 95.600); - mg_cubic_to(187.200, 97.200, 204.400, 104.200, 204.400, 104.200); - mg_cubic_to(204.800, 108.000, 201.800, 113.000, 201.800, 113.000); - mg_cubic_to(202.200, 117.000, 200.000, 120.400, 200.000, 120.400); - mg_cubic_to(198.800, 128.600, 198.200, 129.400, 198.200, 129.400); - mg_cubic_to(194.000, 129.600, 186.600, 143.400, 186.600, 143.400); - mg_cubic_to(184.800, 146.000, 174.600, 158.000, 174.600, 158.000); - mg_cubic_to(172.600, 165.000, 154.600, 157.800, 154.600, 157.800); - mg_cubic_to(148.000, 161.200, 150.000, 157.800, 150.000, 157.800); - mg_cubic_to(149.600, 155.600, 154.400, 149.600, 154.400, 149.600); - mg_cubic_to(161.400, 147.000, 158.800, 136.200, 158.800, 136.200); - mg_cubic_to(162.800, 134.800, 151.600, 132.000, 151.800, 130.800); - mg_cubic_to(152.000, 129.600, 157.800, 128.200, 157.800, 128.200); - mg_cubic_to(165.800, 126.200, 161.400, 123.800, 161.400, 123.800); - mg_cubic_to(160.800, 119.800, 163.800, 114.200, 163.800, 114.200); - mg_cubic_to(175.400, 113.400, 163.800, 97.200, 163.800, 97.200); - mg_cubic_to(153.000, 89.600, 152.000, 83.800, 152.000, 83.800); - mg_cubic_to(164.600, 75.600, 156.400, 63.200, 156.600, 59.600); - mg_cubic_to(156.800, 56.000, 158.000, 34.400, 158.000, 34.400); - mg_cubic_to(156.000, 28.200, 153.000, 14.600, 153.000, 14.600); - mg_cubic_to(155.200, 9.400, 162.600, -3.200, 162.600, -3.200); - mg_cubic_to(165.400, -7.400, 174.200, -12.200, 172.000, -15.200); - mg_cubic_to(169.800, -18.200, 162.000, -16.400, 162.000, -16.400); - mg_cubic_to(154.200, -17.800, 154.800, -12.600, 154.800, -12.600); - mg_cubic_to(153.200, -11.600, 152.400, -6.600, 152.400, -6.600); - mg_cubic_to(151.680, 1.333, 142.800, 7.600, 142.800, 7.600); - mg_cubic_to(131.600, 13.800, 140.800, 17.800, 140.800, 17.800); - mg_cubic_to(146.800, 24.400, 137.000, 24.600, 137.000, 24.600); - mg_cubic_to(126.000, 22.800, 134.200, 33.000, 134.200, 33.000); - mg_cubic_to(145.000, 45.800, 142.000, 48.600, 142.000, 48.600); - mg_cubic_to(131.800, 49.600, 144.400, 58.800, 144.400, 58.800); - mg_cubic_to(144.400, 58.800, 143.600, 56.800, 143.800, 58.600); - mg_cubic_to(144.000, 60.400, 147.000, 64.600, 147.800, 66.600); - mg_cubic_to(148.600, 68.600, 144.600, 68.800, 144.600, 68.800); - mg_cubic_to(145.200, 78.400, 129.800, 74.200, 129.800, 74.200); - mg_line_to(128.200, 74.400); - mg_cubic_to(126.600, 74.600, 115.400, 73.800, 109.600, 71.600); - mg_cubic_to(103.800, 69.400, 97.001, 69.400, 97.001, 69.400); - mg_cubic_to(97.001, 69.400, 93.001, 71.200, 85.400, 71.000); - mg_cubic_to(77.800, 70.800, 69.800, 73.600, 69.800, 73.600); - mg_cubic_to(65.400, 73.200, 74.000, 68.800, 74.200, 69.000); - mg_cubic_to(74.400, 69.200, 80.000, 63.600, 72.000, 64.200); - mg_cubic_to(50.203, 65.835, 39.400, 55.600, 39.400, 55.600); - mg_cubic_to(37.400, 54.200, 34.800, 51.400, 34.800, 51.400); - mg_cubic_to(24.800, 49.400, 36.200, 63.800, 36.200, 63.800); - mg_cubic_to(37.400, 65.200, 36.000, 66.200, 36.000, 66.200); - mg_cubic_to(35.200, 64.600, 27.400, 59.200, 27.400, 59.200); - mg_cubic_to(24.589, 58.227, 23.226, 56.893, 20.895, 54.407); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 155) - { - mg_move_to(-3.000, 42.800); - mg_cubic_to(-3.000, 42.800, 8.600, 48.400, 11.200, 51.200); - mg_cubic_to(13.800, 54.000, 27.800, 65.400, 27.800, 65.400); - mg_cubic_to(27.800, 65.400, 22.400, 63.400, 19.800, 61.600); - mg_cubic_to(17.200, 59.800, 6.400, 51.600, 6.400, 51.600); - mg_cubic_to(6.400, 51.600, 2.600, 45.600, -3.000, 42.800); - mg_close_path(); - mg_set_color_rgba(0.298, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 156) - { - mg_move_to(-61.009, 11.603); - mg_cubic_to(-60.672, 11.455, -61.196, 8.743, -61.400, 8.200); - mg_cubic_to(-62.422, 5.474, -71.400, 4.000, -71.400, 4.000); - mg_cubic_to(-71.627, 5.365, -71.682, 6.961, -71.576, 8.599); - mg_cubic_to(-71.576, 8.599, -66.708, 14.118, -61.009, 11.603); - mg_close_path(); - mg_set_color_rgba(0.600, 0.800, 0.196, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 157) - { - mg_move_to(-61.009, 11.403); - mg_cubic_to(-61.458, 11.561, -61.024, 8.669, -61.200, 8.200); - mg_cubic_to(-62.222, 5.474, -71.400, 3.900, -71.400, 3.900); - mg_cubic_to(-71.627, 5.265, -71.682, 6.861, -71.576, 8.499); - mg_cubic_to(-71.576, 8.499, -67.308, 13.618, -61.009, 11.403); - mg_close_path(); - mg_set_color_rgba(0.396, 0.600, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 158) - { - mg_move_to(-65.400, 11.546); - mg_cubic_to(-66.025, 11.546, -66.531, 10.406, -66.531, 9.000); - mg_cubic_to(-66.531, 7.595, -66.025, 6.455, -65.400, 6.455); - mg_cubic_to(-64.775, 6.455, -64.268, 7.595, -64.268, 9.000); - mg_cubic_to(-64.268, 10.406, -64.775, 11.546, -65.400, 11.546); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 159) - { - mg_move_to(-65.400, 9.000); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 160) - { - mg_move_to(-111.000, 109.600); - mg_cubic_to(-111.000, 109.600, -116.600, 119.600, -91.800, 113.600); - mg_cubic_to(-91.800, 113.600, -77.800, 112.400, -75.400, 110.000); - mg_cubic_to(-74.200, 110.800, -65.834, 113.730, -63.000, 114.400); - mg_cubic_to(-56.200, 116.000, -47.800, 106.000, -47.800, 106.000); - mg_cubic_to(-47.800, 106.000, -43.200, 95.500, -40.400, 95.500); - mg_cubic_to(-37.600, 95.500, -40.800, 97.100, -40.800, 97.100); - mg_cubic_to(-40.800, 97.100, -47.400, 107.200, -47.000, 108.800); - mg_cubic_to(-47.000, 108.800, -52.200, 128.800, -68.200, 129.600); - mg_cubic_to(-68.200, 129.600, -84.350, 130.550, -83.000, 136.400); - mg_cubic_to(-83.000, 136.400, -74.200, 134.000, -71.800, 136.400); - mg_cubic_to(-71.800, 136.400, -61.000, 136.000, -69.000, 142.400); - mg_line_to(-75.800, 154.000); - mg_cubic_to(-75.800, 154.000, -75.660, 157.920, -85.800, 154.400); - mg_cubic_to(-95.600, 151.000, -105.900, 138.100, -105.900, 138.100); - mg_cubic_to(-105.900, 138.100, -121.850, 123.550, -111.000, 109.600); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 161) - { - mg_move_to(-112.200, 113.600); - mg_cubic_to(-112.200, 113.600, -114.200, 123.200, -77.400, 112.800); - mg_line_to(-70.600, 113.600); - mg_cubic_to(-68.200, 114.400, -56.200, 117.200, -54.200, 116.000); - mg_cubic_to(-54.200, 116.000, -61.400, 129.600, -73.000, 128.000); - mg_cubic_to(-73.000, 128.000, -86.200, 129.600, -85.800, 134.400); - mg_cubic_to(-85.800, 134.400, -81.800, 141.600, -77.000, 144.000); - mg_cubic_to(-77.000, 144.000, -74.200, 146.400, -74.600, 149.600); - mg_cubic_to(-75.000, 152.800, -77.800, 154.400, -79.800, 155.200); - mg_cubic_to(-81.800, 156.000, -85.000, 152.800, -86.600, 152.800); - mg_cubic_to(-88.200, 152.800, -96.600, 146.400, -101.000, 141.600); - mg_cubic_to(-105.400, 136.800, -113.800, 124.800, -113.400, 122.000); - mg_cubic_to(-113.000, 119.200, -112.200, 113.600, -112.200, 113.600); - mg_close_path(); - mg_set_color_rgba(0.898, 0.600, 0.600, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 162) - { - mg_move_to(-109.000, 131.050); - mg_cubic_to(-106.400, 135.000, -103.200, 139.200, -101.000, 141.600); - mg_cubic_to(-96.600, 146.400, -88.200, 152.800, -86.600, 152.800); - mg_cubic_to(-85.000, 152.800, -81.800, 156.000, -79.800, 155.200); - mg_cubic_to(-77.800, 154.400, -75.000, 152.800, -74.600, 149.600); - mg_cubic_to(-74.200, 146.400, -77.000, 144.000, -77.000, 144.000); - mg_cubic_to(-80.066, 142.470, -82.806, 138.980, -84.385, 136.650); - mg_cubic_to(-84.385, 136.650, -84.200, 139.200, -89.400, 138.400); - mg_cubic_to(-94.600, 137.600, -99.800, 134.800, -101.400, 131.600); - mg_cubic_to(-103.000, 128.400, -105.400, 126.000, -103.800, 129.600); - mg_cubic_to(-102.200, 133.200, -99.800, 136.800, -98.200, 137.200); - mg_cubic_to(-96.600, 137.600, -97.000, 138.800, -99.400, 138.400); - mg_cubic_to(-101.800, 138.000, -104.600, 137.600, -109.000, 132.400); - mg_close_path(); - mg_set_color_rgba(0.698, 0.396, 0.396, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 163) - { - mg_move_to(-111.600, 110.000); - mg_cubic_to(-111.600, 110.000, -109.800, 96.400, -108.600, 92.400); - mg_cubic_to(-108.600, 92.400, -109.400, 85.600, -107.000, 81.400); - mg_cubic_to(-104.600, 77.200, -102.600, 71.000, -99.600, 65.600); - mg_cubic_to(-96.600, 60.200, -96.400, 56.200, -92.400, 54.600); - mg_cubic_to(-88.400, 53.000, -82.400, 44.400, -79.600, 43.400); - mg_cubic_to(-76.800, 42.400, -77.000, 43.200, -77.000, 43.200); - mg_cubic_to(-77.000, 43.200, -70.200, 28.400, -56.600, 32.400); - mg_cubic_to(-56.600, 32.400, -72.800, 29.600, -57.000, 20.200); - mg_cubic_to(-57.000, 20.200, -61.800, 21.300, -58.500, 14.300); - mg_cubic_to(-56.299, 9.632, -56.800, 16.400, -67.800, 28.200); - mg_cubic_to(-67.800, 28.200, -72.800, 36.800, -78.000, 39.800); - mg_cubic_to(-83.200, 42.800, -95.200, 49.800, -96.400, 53.600); - mg_cubic_to(-97.600, 57.400, -100.800, 63.200, -102.800, 64.800); - mg_cubic_to(-104.800, 66.400, -107.600, 70.600, -108.000, 74.000); - mg_cubic_to(-108.000, 74.000, -109.200, 78.000, -110.600, 79.200); - mg_cubic_to(-112.000, 80.400, -112.200, 83.600, -112.200, 85.600); - mg_cubic_to(-112.200, 87.600, -114.200, 90.400, -114.000, 92.800); - mg_cubic_to(-114.000, 92.800, -113.200, 111.800, -113.600, 113.800); - mg_line_to(-111.600, 110.000); - mg_close_path(); - mg_set_color_rgba(0.600, 0.149, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 164) - { - mg_move_to(-120.200, 114.600); - mg_cubic_to(-120.200, 114.600, -122.200, 113.200, -126.600, 119.200); - mg_cubic_to(-126.600, 119.200, -119.300, 152.200, -119.300, 153.600); - mg_cubic_to(-119.300, 153.600, -118.200, 151.500, -119.500, 144.300); - mg_cubic_to(-120.800, 137.100, -121.700, 124.400, -121.700, 124.400); - mg_line_to(-120.200, 114.600); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 165) - { - mg_move_to(-98.600, 54.000); - mg_cubic_to(-98.600, 54.000, -116.200, 57.200, -115.800, 86.400); - mg_line_to(-116.600, 111.200); - mg_cubic_to(-116.600, 111.200, -117.800, 85.600, -119.000, 84.000); - mg_cubic_to(-120.200, 82.400, -116.200, 71.200, -119.400, 77.200); - mg_cubic_to(-119.400, 77.200, -133.400, 91.200, -125.400, 112.400); - mg_cubic_to(-125.400, 112.400, -123.900, 115.700, -126.900, 111.100); - mg_cubic_to(-126.900, 111.100, -131.500, 98.500, -130.400, 92.100); - mg_cubic_to(-130.400, 92.100, -130.200, 89.900, -128.300, 87.100); - mg_cubic_to(-128.300, 87.100, -119.700, 75.400, -117.000, 73.100); - mg_cubic_to(-117.000, 73.100, -115.200, 58.700, -99.800, 53.500); - mg_cubic_to(-99.800, 53.500, -94.100, 51.200, -98.600, 54.000); - mg_close_path(); - mg_set_color_rgba(0.600, 0.149, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 166) - { - mg_move_to(40.800, -12.200); - mg_cubic_to(41.460, -12.554, 41.451, -13.524, 42.031, -13.697); - mg_cubic_to(43.180, -14.041, 43.344, -15.108, 43.862, -15.892); - mg_cubic_to(44.735, -17.211, 44.928, -18.744, 45.510, -20.235); - mg_cubic_to(45.782, -20.935, 45.809, -21.890, 45.496, -22.550); - mg_cubic_to(44.322, -25.031, 43.620, -27.480, 42.178, -29.906); - mg_cubic_to(41.910, -30.356, 41.648, -31.150, 41.447, -31.748); - mg_cubic_to(40.984, -33.132, 39.727, -34.123, 38.867, -35.443); - mg_cubic_to(38.579, -35.884, 39.104, -36.809, 38.388, -36.893); - mg_cubic_to(37.491, -36.998, 36.042, -37.578, 35.809, -36.552); - mg_cubic_to(35.221, -33.965, 36.232, -31.442, 37.200, -29.000); - mg_cubic_to(36.418, -28.308, 36.752, -27.387, 36.904, -26.620); - mg_cubic_to(37.614, -23.014, 36.416, -19.662, 35.655, -16.188); - mg_cubic_to(35.632, -16.084, 35.974, -15.886, 35.946, -15.824); - mg_cubic_to(34.724, -13.138, 33.272, -10.693, 31.453, -8.312); - mg_cubic_to(30.695, -7.320, 29.823, -6.404, 29.326, -5.341); - mg_cubic_to(28.958, -4.554, 28.550, -3.588, 28.800, -2.600); - mg_cubic_to(25.365, 0.180, 23.115, 4.025, 20.504, 7.871); - mg_cubic_to(20.042, 8.551, 20.333, 9.760, 20.884, 10.029); - mg_cubic_to(21.697, 10.427, 22.653, 9.403, 23.123, 8.557); - mg_cubic_to(23.512, 7.859, 23.865, 7.209, 24.356, 6.566); - mg_cubic_to(24.489, 6.391, 24.310, 5.972, 24.445, 5.851); - mg_cubic_to(27.078, 3.504, 28.747, 0.568, 31.200, -1.800); - mg_cubic_to(33.150, -2.129, 34.687, -3.127, 36.435, -4.140); - mg_cubic_to(36.743, -4.319, 37.267, -4.070, 37.557, -4.265); - mg_cubic_to(39.310, -5.442, 39.308, -7.478, 39.414, -9.388); - mg_cubic_to(39.464, -10.272, 39.660, -11.589, 40.800, -12.200); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 167) - { - mg_move_to(31.959, -16.666); - mg_cubic_to(32.083, -16.743, 31.928, -17.166, 32.037, -17.382); - mg_cubic_to(32.199, -17.706, 32.602, -17.894, 32.764, -18.218); - mg_cubic_to(32.873, -18.434, 32.710, -18.814, 32.846, -18.956); - mg_cubic_to(35.179, -21.403, 35.436, -24.427, 34.400, -27.400); - mg_cubic_to(35.424, -28.020, 35.485, -29.282, 35.060, -30.129); - mg_cubic_to(34.207, -31.829, 34.014, -33.755, 33.039, -35.298); - mg_cubic_to(32.237, -36.567, 30.659, -37.811, 29.288, -36.508); - mg_cubic_to(28.867, -36.108, 28.546, -35.321, 28.824, -34.609); - mg_cubic_to(28.888, -34.446, 29.173, -34.300, 29.146, -34.218); - mg_cubic_to(29.039, -33.894, 28.493, -33.670, 28.487, -33.398); - mg_cubic_to(28.457, -31.902, 27.503, -30.391, 28.133, -29.062); - mg_cubic_to(28.905, -27.433, 29.724, -25.576, 30.400, -23.800); - mg_cubic_to(29.166, -21.684, 30.199, -19.235, 28.446, -17.358); - mg_cubic_to(28.310, -17.212, 28.319, -16.826, 28.441, -16.624); - mg_cubic_to(28.733, -16.138, 29.139, -15.732, 29.625, -15.440); - mg_cubic_to(29.827, -15.319, 30.175, -15.317, 30.375, -15.441); - mg_cubic_to(30.953, -15.803, 31.351, -16.290, 31.959, -16.666); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 168) - { - mg_move_to(94.771, -26.977); - mg_cubic_to(96.160, -25.185, 96.450, -22.390, 94.401, -21.000); - mg_cubic_to(94.951, -17.691, 98.302, -19.670, 100.400, -20.200); - mg_cubic_to(100.290, -20.588, 100.520, -20.932, 100.800, -20.937); - mg_cubic_to(101.860, -20.952, 102.540, -21.984, 103.600, -21.800); - mg_cubic_to(104.040, -23.357, 105.670, -24.059, 106.320, -25.439); - mg_cubic_to(108.040, -29.134, 107.450, -33.407, 104.870, -36.653); - mg_cubic_to(104.670, -36.907, 104.880, -37.424, 104.760, -37.786); - mg_cubic_to(104.000, -39.997, 101.940, -40.312, 100.000, -41.000); - mg_cubic_to(98.824, -44.875, 98.163, -48.906, 96.401, -52.600); - mg_cubic_to(94.787, -52.850, 94.089, -54.589, 92.752, -55.309); - mg_cubic_to(91.419, -56.028, 90.851, -54.449, 90.892, -53.403); - mg_cubic_to(90.899, -53.198, 91.351, -52.974, 91.181, -52.609); - mg_cubic_to(91.105, -52.445, 90.845, -52.334, 90.845, -52.200); - mg_cubic_to(90.846, -52.065, 91.067, -51.934, 91.201, -51.800); - mg_cubic_to(90.283, -50.980, 88.860, -50.503, 88.565, -49.358); - mg_cubic_to(87.611, -45.648, 90.184, -42.523, 91.852, -39.322); - mg_cubic_to(92.443, -38.187, 91.707, -36.916, 90.947, -35.708); - mg_cubic_to(90.509, -35.013, 90.617, -33.886, 90.893, -33.030); - mg_cubic_to(91.645, -30.699, 93.236, -28.960, 94.771, -26.977); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 169) - { - mg_move_to(57.611, -8.591); - mg_cubic_to(56.124, -6.740, 52.712, -4.171, 55.629, -2.243); - mg_cubic_to(55.823, -2.114, 56.193, -2.110, 56.366, -2.244); - mg_cubic_to(58.387, -3.809, 60.390, -4.712, 62.826, -5.294); - mg_cubic_to(62.950, -5.323, 63.224, -4.856, 63.593, -5.017); - mg_cubic_to(65.206, -5.720, 67.216, -5.662, 68.400, -7.000); - mg_cubic_to(72.167, -6.776, 75.732, -7.892, 79.123, -9.200); - mg_cubic_to(80.284, -9.648, 81.554, -10.207, 82.755, -10.709); - mg_cubic_to(84.131, -11.285, 85.335, -12.213, 86.447, -13.354); - mg_cubic_to(86.580, -13.490, 86.934, -13.400, 87.201, -13.400); - mg_cubic_to(87.161, -14.263, 88.123, -14.390, 88.370, -15.012); - mg_cubic_to(88.462, -15.244, 88.312, -15.640, 88.445, -15.742); - mg_cubic_to(90.583, -17.372, 91.503, -19.390, 90.334, -21.767); - mg_cubic_to(90.049, -22.345, 89.800, -22.963, 89.234, -23.439); - mg_cubic_to(88.149, -24.350, 87.047, -23.496, 86.000, -23.800); - mg_cubic_to(85.841, -23.172, 85.112, -23.344, 84.726, -23.146); - mg_cubic_to(83.867, -22.707, 82.534, -23.292, 81.675, -22.854); - mg_cubic_to(80.313, -22.159, 79.072, -21.990, 77.650, -21.613); - mg_cubic_to(77.338, -21.531, 76.560, -21.627, 76.400, -21.000); - mg_cubic_to(76.266, -21.134, 76.118, -21.368, 76.012, -21.346); - mg_cubic_to(74.104, -20.950, 72.844, -20.736, 71.543, -19.044); - mg_cubic_to(71.440, -18.911, 70.998, -19.090, 70.839, -18.955); - mg_cubic_to(69.882, -18.147, 69.477, -16.913, 68.376, -16.241); - mg_cubic_to(68.175, -16.118, 67.823, -16.286, 67.629, -16.157); - mg_cubic_to(66.983, -15.726, 66.616, -15.085, 65.974, -14.638); - mg_cubic_to(65.645, -14.409, 65.245, -14.734, 65.277, -14.990); - mg_cubic_to(65.522, -16.937, 66.175, -18.724, 65.600, -20.600); - mg_cubic_to(67.677, -23.120, 70.194, -25.069, 72.000, -27.800); - mg_cubic_to(72.015, -29.966, 72.707, -32.112, 72.594, -34.189); - mg_cubic_to(72.584, -34.382, 72.296, -35.115, 72.170, -35.462); - mg_cubic_to(71.858, -36.316, 72.764, -37.382, 71.920, -38.106); - mg_cubic_to(70.516, -39.309, 69.224, -38.433, 68.400, -37.000); - mg_cubic_to(66.562, -36.610, 64.496, -35.917, 62.918, -37.151); - mg_cubic_to(61.911, -37.938, 61.333, -38.844, 60.534, -39.900); - mg_cubic_to(59.549, -41.202, 59.884, -42.638, 59.954, -44.202); - mg_cubic_to(59.960, -44.330, 59.645, -44.466, 59.645, -44.600); - mg_cubic_to(59.646, -44.735, 59.866, -44.866, 60.000, -45.000); - mg_cubic_to(59.294, -45.626, 59.019, -46.684, 58.000, -47.000); - mg_cubic_to(58.305, -48.092, 57.629, -48.976, 56.758, -49.278); - mg_cubic_to(54.763, -49.969, 53.086, -48.057, 51.194, -47.984); - mg_cubic_to(50.680, -47.965, 50.213, -49.003, 49.564, -49.328); - mg_cubic_to(49.132, -49.544, 48.428, -49.577, 48.066, -49.311); - mg_cubic_to(47.378, -48.807, 46.789, -48.693, 46.031, -48.488); - mg_cubic_to(44.414, -48.052, 43.136, -46.958, 41.656, -46.103); - mg_cubic_to(40.171, -45.246, 39.216, -43.809, 38.136, -42.489); - mg_cubic_to(37.195, -41.337, 37.059, -38.923, 38.479, -38.423); - mg_cubic_to(40.322, -37.773, 41.626, -40.476, 43.592, -40.150); - mg_cubic_to(43.904, -40.099, 44.110, -39.788, 44.000, -39.400); - mg_cubic_to(44.389, -39.291, 44.607, -39.520, 44.800, -39.800); - mg_cubic_to(45.658, -38.781, 46.822, -38.444, 47.760, -37.571); - mg_cubic_to(48.730, -36.667, 50.476, -37.085, 51.491, -36.088); - mg_cubic_to(53.020, -34.586, 52.461, -31.905, 54.400, -30.600); - mg_cubic_to(53.814, -29.287, 53.207, -28.010, 52.872, -26.583); - mg_cubic_to(52.590, -25.377, 53.584, -24.180, 54.795, -24.271); - mg_cubic_to(56.053, -24.365, 56.315, -25.124, 56.800, -26.200); - mg_cubic_to(57.067, -25.933, 57.536, -25.636, 57.495, -25.420); - mg_cubic_to(57.038, -23.033, 56.011, -21.040, 55.553, -18.609); - mg_cubic_to(55.494, -18.292, 55.189, -18.090, 54.800, -18.200); - mg_cubic_to(54.332, -14.051, 50.280, -11.657, 47.735, -8.492); - mg_cubic_to(47.332, -7.990, 47.328, -6.741, 47.737, -6.338); - mg_cubic_to(49.140, -4.951, 51.100, -6.497, 52.800, -7.000); - mg_cubic_to(53.013, -8.206, 53.872, -9.148, 55.204, -9.092); - mg_cubic_to(55.460, -9.082, 55.695, -9.624, 56.019, -9.754); - mg_cubic_to(56.367, -9.892, 56.869, -9.668, 57.155, -9.866); - mg_cubic_to(58.884, -11.061, 60.292, -12.167, 62.030, -13.356); - mg_cubic_to(62.222, -13.487, 62.566, -13.328, 62.782, -13.436); - mg_cubic_to(63.107, -13.598, 63.294, -13.985, 63.617, -14.170); - mg_cubic_to(63.965, -14.370, 64.207, -14.080, 64.400, -13.800); - mg_cubic_to(63.754, -13.451, 63.750, -12.494, 63.168, -12.292); - mg_cubic_to(62.393, -12.024, 61.832, -11.511, 61.158, -11.064); - mg_cubic_to(60.866, -10.871, 60.207, -11.119, 60.103, -10.940); - mg_cubic_to(59.505, -9.912, 58.321, -9.474, 57.611, -8.591); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 170) - { - mg_move_to(2.200, -58.000); - mg_cubic_to(2.200, -58.000, -7.038, -60.872, -18.200, -35.200); - mg_cubic_to(-18.200, -35.200, -20.600, -30.000, -23.000, -28.000); - mg_cubic_to(-25.400, -26.000, -36.600, -22.400, -38.600, -18.400); - mg_line_to(-49.000, -2.400); - mg_cubic_to(-49.000, -2.400, -34.200, -18.400, -31.000, -20.800); - mg_cubic_to(-31.000, -20.800, -23.000, -29.200, -26.200, -22.400); - mg_cubic_to(-26.200, -22.400, -40.200, -11.600, -39.000, -2.400); - mg_cubic_to(-39.000, -2.400, -44.600, 12.000, -45.400, 14.000); - mg_cubic_to(-45.400, 14.000, -29.400, -18.000, -27.000, -19.200); - mg_cubic_to(-24.600, -20.400, -23.400, -20.400, -24.600, -16.800); - mg_cubic_to(-25.800, -13.200, -26.200, 3.200, -29.000, 5.200); - mg_cubic_to(-29.000, 5.200, -21.000, -15.200, -21.800, -18.400); - mg_cubic_to(-21.800, -18.400, -18.600, -22.000, -16.200, -16.800); - mg_line_to(-17.400, -0.800); - mg_line_to(-13.000, 11.200); - mg_cubic_to(-13.000, 11.200, -15.400, -0.000, -13.800, -15.600); - mg_cubic_to(-13.800, -15.600, -15.800, -26.000, -11.800, -20.400); - mg_cubic_to(-7.800, -14.800, 1.800, -8.800, 1.800, -4.000); - mg_cubic_to(1.800, -4.000, -3.400, -21.600, -12.600, -26.400); - mg_line_to(-16.600, -20.400); - mg_line_to(-17.800, -22.400); - mg_cubic_to(-17.800, -22.400, -21.400, -23.200, -17.000, -30.000); - mg_cubic_to(-12.600, -36.800, -13.000, -37.600, -13.000, -37.600); - mg_cubic_to(-13.000, -37.600, -6.600, -30.400, -5.000, -30.400); - mg_cubic_to(-5.000, -30.400, 8.200, -38.000, 9.400, -13.600); - mg_cubic_to(9.400, -13.600, 16.200, -28.000, 7.000, -34.800); - mg_cubic_to(7.000, -34.800, -7.800, -36.800, -6.600, -42.000); - mg_line_to(0.600, -54.400); - mg_cubic_to(4.200, -59.600, 2.600, -56.800, 2.600, -56.800); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 171) - { - mg_move_to(-17.800, -41.600); - mg_move_to(-33.800, -36.400); - mg_move_to(-41.000, -26.800); - mg_cubic_to(-41.000, -26.800, -23.800, -36.800, -19.800, -38.000); - mg_cubic_to(-15.800, -39.200, -17.800, -41.600, -17.800, -41.600); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 172) - { - mg_move_to(-57.800, -35.200); - mg_cubic_to(-57.800, -35.200, -59.800, -34.000, -60.200, -31.200); - mg_cubic_to(-60.600, -28.400, -63.000, -28.000, -62.200, -25.200); - mg_cubic_to(-61.400, -22.400, -59.400, -20.000, -59.400, -24.000); - mg_cubic_to(-59.400, -28.000, -57.800, -30.000, -57.000, -31.200); - mg_cubic_to(-56.200, -32.400, -54.600, -36.800, -57.800, -35.200); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 173) - { - mg_move_to(-66.600, 26.000); - mg_cubic_to(-66.600, 26.000, -75.000, 22.000, -78.200, 18.400); - mg_cubic_to(-81.400, 14.800, -80.948, 19.966, -85.800, 19.600); - mg_cubic_to(-91.647, 19.159, -90.600, 3.200, -90.600, 3.200); - mg_line_to(-94.600, 10.800); - mg_cubic_to(-94.600, 10.800, -95.800, 25.200, -87.800, 22.800); - mg_cubic_to(-83.893, 21.628, -82.600, 23.200, -84.200, 24.000); - mg_cubic_to(-85.800, 24.800, -78.600, 25.200, -81.400, 26.800); - mg_cubic_to(-84.200, 28.400, -69.800, 23.200, -72.200, 33.600); - mg_line_to(-66.600, 26.000); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 174) - { - mg_move_to(-79.200, 40.400); - mg_cubic_to(-79.200, 40.400, -94.600, 44.800, -98.200, 35.200); - mg_cubic_to(-98.200, 35.200, -103.000, 37.600, -100.800, 40.600); - mg_cubic_to(-98.600, 43.600, -97.400, 44.000, -97.400, 44.000); - mg_cubic_to(-97.400, 44.000, -92.000, 45.200, -92.600, 46.000); - mg_cubic_to(-93.200, 46.800, -95.600, 50.200, -95.600, 50.200); - mg_cubic_to(-95.600, 50.200, -85.400, 44.200, -79.200, 40.400); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 175) - { - mg_move_to(149.200, 118.600); - mg_cubic_to(148.770, 120.740, 147.100, 121.540, 145.200, 122.200); - mg_cubic_to(143.280, 121.240, 140.690, 118.140, 138.800, 120.200); - mg_cubic_to(138.330, 119.720, 137.550, 119.660, 137.200, 119.000); - mg_cubic_to(136.740, 118.100, 137.010, 117.060, 136.670, 116.260); - mg_cubic_to(136.120, 114.980, 135.420, 113.620, 135.600, 112.200); - mg_cubic_to(137.410, 111.490, 138.000, 109.580, 137.530, 107.820); - mg_cubic_to(137.460, 107.560, 137.030, 107.370, 137.230, 107.020); - mg_cubic_to(137.420, 106.690, 137.730, 106.470, 138.000, 106.200); - mg_cubic_to(137.870, 106.340, 137.720, 106.570, 137.610, 106.550); - mg_cubic_to(137.000, 106.440, 137.120, 105.800, 137.250, 105.420); - mg_cubic_to(137.840, 103.670, 139.850, 103.410, 141.200, 104.600); - mg_cubic_to(141.460, 104.040, 141.970, 104.230, 142.400, 104.200); - mg_cubic_to(142.350, 103.620, 142.760, 103.090, 142.960, 102.670); - mg_cubic_to(143.480, 101.580, 145.100, 102.680, 145.900, 102.070); - mg_cubic_to(146.980, 101.240, 148.040, 100.550, 149.120, 101.150); - mg_cubic_to(150.930, 102.160, 152.640, 103.370, 153.840, 105.120); - mg_cubic_to(154.410, 105.950, 154.650, 107.230, 154.590, 108.190); - mg_cubic_to(154.550, 108.840, 153.170, 108.480, 152.830, 109.410); - mg_cubic_to(152.180, 111.160, 154.020, 111.680, 154.770, 113.020); - mg_cubic_to(154.970, 113.370, 154.710, 113.670, 154.390, 113.770); - mg_cubic_to(153.980, 113.900, 153.200, 113.710, 153.330, 114.160); - mg_cubic_to(154.310, 117.350, 151.550, 118.030, 149.200, 118.600); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 176) - { - mg_move_to(139.600, 138.200); - mg_cubic_to(139.590, 136.460, 137.990, 134.710, 139.200, 133.000); - mg_cubic_to(139.340, 133.140, 139.470, 133.360, 139.600, 133.360); - mg_cubic_to(139.740, 133.360, 139.870, 133.140, 140.000, 133.000); - mg_cubic_to(141.500, 135.220, 145.150, 136.140, 145.010, 138.990); - mg_cubic_to(144.980, 139.440, 143.900, 140.360, 144.800, 141.000); - mg_cubic_to(142.990, 142.350, 142.930, 144.720, 142.000, 146.600); - mg_cubic_to(140.760, 146.320, 139.550, 145.950, 138.400, 145.400); - mg_cubic_to(138.750, 143.920, 138.640, 142.230, 139.460, 140.910); - mg_cubic_to(139.890, 140.210, 139.600, 139.130, 139.600, 138.200); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 177) - { - mg_move_to(-26.600, 129.200); - mg_cubic_to(-26.600, 129.200, -43.458, 139.340, -29.400, 124.000); - mg_cubic_to(-20.600, 114.400, -10.600, 108.800, -10.600, 108.800); - mg_cubic_to(-10.600, 108.800, -0.200, 104.400, 3.400, 103.200); - mg_cubic_to(7.000, 102.000, 22.200, 96.800, 25.400, 96.400); - mg_cubic_to(28.600, 96.000, 38.200, 92.000, 45.000, 96.000); - mg_cubic_to(51.800, 100.000, 59.800, 104.400, 59.800, 104.400); - mg_cubic_to(59.800, 104.400, 43.400, 96.000, 39.800, 98.400); - mg_cubic_to(36.200, 100.800, 29.000, 100.400, 23.000, 103.600); - mg_cubic_to(23.000, 103.600, 8.200, 108.000, 5.000, 110.000); - mg_cubic_to(1.800, 112.000, -8.600, 123.600, -10.200, 122.800); - mg_cubic_to(-11.800, 122.000, -9.800, 121.600, -8.600, 118.800); - mg_cubic_to(-7.400, 116.000, -9.400, 114.400, -17.400, 120.800); - mg_cubic_to(-25.400, 127.200, -26.600, 129.200, -26.600, 129.200); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 178) - { - mg_move_to(-19.195, 123.230); - mg_cubic_to(-19.195, 123.230, -17.785, 110.190, -9.307, 111.860); - mg_cubic_to(-9.307, 111.860, -1.081, 107.690, 1.641, 105.720); - mg_cubic_to(1.641, 105.720, 9.780, 104.020, 11.090, 103.400); - mg_cubic_to(29.569, 94.702, 44.288, 99.221, 44.835, 98.101); - mg_cubic_to(45.381, 96.982, 65.006, 104.100, 68.615, 108.180); - mg_cubic_to(69.006, 108.630, 58.384, 102.590, 48.686, 100.700); - mg_cubic_to(40.413, 99.083, 18.811, 100.940, 7.905, 106.480); - mg_cubic_to(4.932, 107.990, -4.013, 113.770, -6.544, 113.660); - mg_cubic_to(-9.075, 113.550, -19.195, 123.230, -19.195, 123.230); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 179) - { - mg_move_to(-23.000, 148.800); - mg_cubic_to(-23.000, 148.800, -38.200, 146.400, -21.400, 144.800); - mg_cubic_to(-21.400, 144.800, -3.400, 142.800, 0.600, 137.600); - mg_cubic_to(0.600, 137.600, 14.200, 128.400, 17.000, 128.000); - mg_cubic_to(19.800, 127.600, 49.800, 120.400, 50.200, 118.000); - mg_cubic_to(50.600, 115.600, 56.200, 115.600, 57.800, 116.400); - mg_cubic_to(59.400, 117.200, 58.600, 118.400, 55.800, 119.200); - mg_cubic_to(53.000, 120.000, 21.800, 136.400, 15.400, 137.600); - mg_cubic_to(9.000, 138.800, -2.600, 146.400, -7.400, 147.600); - mg_cubic_to(-12.200, 148.800, -23.000, 148.800, -23.000, 148.800); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 180) - { - mg_move_to(-3.480, 141.400); - mg_cubic_to(-3.480, 141.400, -12.062, 140.570, -3.461, 139.760); - mg_cubic_to(-3.461, 139.760, 5.355, 136.330, 7.403, 133.670); - mg_cubic_to(7.403, 133.670, 14.367, 128.960, 15.800, 128.750); - mg_cubic_to(17.234, 128.550, 31.194, 124.860, 31.399, 123.630); - mg_cubic_to(31.604, 122.400, 65.670, 109.820, 70.090, 113.010); - mg_cubic_to(73.001, 115.110, 63.100, 113.440, 53.466, 117.850); - mg_cubic_to(52.111, 118.470, 18.258, 133.050, 14.981, 133.670); - mg_cubic_to(11.704, 134.280, 5.765, 138.170, 3.307, 138.790); - mg_cubic_to(0.850, 139.400, -3.480, 141.400, -3.480, 141.400); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 181) - { - mg_move_to(-11.400, 143.600); - mg_cubic_to(-11.400, 143.600, -6.200, 143.200, -7.400, 144.800); - mg_cubic_to(-8.600, 146.400, -11.000, 145.600, -11.000, 145.600); - mg_line_to(-11.400, 143.600); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 182) - { - mg_move_to(-18.600, 145.200); - mg_cubic_to(-18.600, 145.200, -13.400, 144.800, -14.600, 146.400); - mg_cubic_to(-15.800, 148.000, -18.200, 147.200, -18.200, 147.200); - mg_line_to(-18.600, 145.200); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 183) - { - mg_move_to(-29.000, 146.800); - mg_cubic_to(-29.000, 146.800, -23.800, 146.400, -25.000, 148.000); - mg_cubic_to(-26.200, 149.600, -28.600, 148.800, -28.600, 148.800); - mg_line_to(-29.000, 146.800); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 184) - { - mg_move_to(-36.600, 147.600); - mg_cubic_to(-36.600, 147.600, -31.400, 147.200, -32.600, 148.800); - mg_cubic_to(-33.800, 150.400, -36.200, 149.600, -36.200, 149.600); - mg_line_to(-36.600, 147.600); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 185) - { - mg_move_to(1.800, 108.000); - mg_move_to(5.000, 109.600); - mg_cubic_to(3.800, 111.200, 0.600, 110.800, 0.600, 110.800); - mg_line_to(1.800, 108.000); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 186) - { - mg_move_to(-8.200, 113.600); - mg_cubic_to(-8.200, 113.600, -1.694, 111.460, -4.200, 114.800); - mg_cubic_to(-5.400, 116.400, -7.800, 115.600, -7.800, 115.600); - mg_line_to(-8.200, 113.600); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 187) - { - mg_move_to(-19.400, 118.400); - mg_cubic_to(-19.400, 118.400, -14.200, 118.000, -15.400, 119.600); - mg_cubic_to(-16.600, 121.200, -19.000, 120.400, -19.000, 120.400); - mg_line_to(-19.400, 118.400); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 188) - { - mg_move_to(-27.000, 124.400); - mg_cubic_to(-27.000, 124.400, -21.800, 124.000, -23.000, 125.600); - mg_cubic_to(-24.200, 127.200, -26.600, 126.400, -26.600, 126.400); - mg_line_to(-27.000, 124.400); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 189) - { - mg_move_to(-33.800, 129.200); - mg_cubic_to(-33.800, 129.200, -28.600, 128.800, -29.800, 130.400); - mg_cubic_to(-31.000, 132.000, -33.400, 131.200, -33.400, 131.200); - mg_line_to(-33.800, 129.200); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 190) - { - mg_move_to(5.282, 135.600); - mg_cubic_to(5.282, 135.600, 12.203, 135.070, 10.606, 137.200); - mg_cubic_to(9.009, 139.320, 5.814, 138.260, 5.814, 138.260); - mg_line_to(5.282, 135.600); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 191) - { - mg_move_to(15.682, 130.800); - mg_cubic_to(15.682, 130.800, 22.603, 130.270, 21.006, 132.400); - mg_cubic_to(19.409, 134.520, 16.214, 133.460, 16.214, 133.460); - mg_line_to(15.682, 130.800); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 192) - { - mg_move_to(26.482, 126.400); - mg_cubic_to(26.482, 126.400, 33.403, 125.870, 31.806, 128.000); - mg_cubic_to(30.209, 130.120, 27.014, 129.060, 27.014, 129.060); - mg_line_to(26.482, 126.400); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 193) - { - mg_move_to(36.882, 121.600); - mg_cubic_to(36.882, 121.600, 43.803, 121.070, 42.206, 123.200); - mg_cubic_to(40.609, 125.320, 37.414, 124.260, 37.414, 124.260); - mg_line_to(36.882, 121.600); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 194) - { - mg_move_to(9.282, 103.600); - mg_cubic_to(9.282, 103.600, 16.203, 103.070, 14.606, 105.200); - mg_cubic_to(13.009, 107.320, 9.014, 107.060, 9.014, 107.060); - mg_line_to(9.282, 103.600); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 195) - { - mg_move_to(19.282, 100.400); - mg_cubic_to(19.282, 100.400, 26.203, 99.866, 24.606, 102.000); - mg_cubic_to(23.009, 104.120, 18.614, 103.860, 18.614, 103.860); - mg_line_to(19.282, 100.400); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 196) - { - mg_move_to(-3.400, 140.400); - mg_cubic_to(-3.400, 140.400, 1.800, 140.000, 0.600, 141.600); - mg_cubic_to(-0.600, 143.200, -3.000, 142.400, -3.000, 142.400); - mg_line_to(-3.400, 140.400); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 197) - { - mg_move_to(-76.600, 41.200); - mg_cubic_to(-76.600, 41.200, -81.000, 50.000, -81.400, 53.200); - mg_cubic_to(-81.400, 53.200, -80.600, 44.400, -79.400, 42.400); - mg_cubic_to(-78.200, 40.400, -76.600, 41.200, -76.600, 41.200); - mg_close_path(); - mg_set_color_rgba(0.600, 0.149, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 198) - { - mg_move_to(-95.000, 55.200); - mg_cubic_to(-95.000, 55.200, -98.200, 69.600, -97.800, 72.400); - mg_cubic_to(-97.800, 72.400, -99.000, 60.800, -98.600, 59.600); - mg_cubic_to(-98.200, 58.400, -95.000, 55.200, -95.000, 55.200); - mg_close_path(); - mg_set_color_rgba(0.600, 0.149, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 199) - { - mg_move_to(-74.200, -19.400); - mg_move_to(-74.400, -16.200); - mg_move_to(-76.600, -16.000); - mg_cubic_to(-76.600, -16.000, -62.400, -3.400, -61.800, 4.200); - mg_cubic_to(-61.800, 4.200, -61.000, -4.000, -74.200, -19.400); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 200) - { - mg_move_to(-70.216, -18.135); - mg_cubic_to(-70.647, -18.551, -70.428, -19.296, -70.836, -19.556); - mg_cubic_to(-71.645, -20.072, -69.538, -20.129, -69.766, -20.845); - mg_cubic_to(-70.149, -22.051, -69.962, -22.072, -70.084, -23.348); - mg_cubic_to(-70.141, -23.946, -69.553, -25.486, -69.168, -25.926); - mg_cubic_to(-67.722, -27.578, -69.046, -30.510, -67.406, -32.061); - mg_cubic_to(-67.102, -32.350, -66.726, -32.902, -66.441, -33.320); - mg_cubic_to(-65.782, -34.283, -64.598, -34.771, -63.648, -35.599); - mg_cubic_to(-63.330, -35.875, -63.531, -36.702, -62.962, -36.610); - mg_cubic_to(-62.248, -36.495, -61.007, -36.625, -61.052, -35.784); - mg_cubic_to(-61.165, -33.664, -62.494, -31.944, -63.774, -30.276); - mg_cubic_to(-63.323, -29.572, -63.781, -28.937, -64.065, -28.380); - mg_cubic_to(-65.400, -25.760, -65.211, -22.919, -65.385, -20.079); - mg_cubic_to(-65.390, -19.994, -65.697, -19.916, -65.689, -19.863); - mg_cubic_to(-65.336, -17.528, -64.752, -15.329, -63.873, -13.100); - mg_cubic_to(-63.507, -12.170, -63.036, -11.275, -62.886, -10.348); - mg_cubic_to(-62.775, -9.662, -62.672, -8.829, -63.080, -8.124); - mg_cubic_to(-61.045, -5.234, -62.354, -2.583, -61.185, 0.948); - mg_cubic_to(-60.978, 1.573, -59.286, 3.487, -59.749, 3.326); - mg_cubic_to(-62.262, 2.455, -62.374, 2.057, -62.551, 1.304); - mg_cubic_to(-62.697, 0.681, -63.027, -0.696, -63.264, -1.298); - mg_cubic_to(-63.328, -1.462, -63.499, -3.346, -63.577, -3.468); - mg_cubic_to(-65.090, -5.850, -63.732, -5.674, -65.102, -8.032); - mg_cubic_to(-66.530, -8.712, -67.496, -9.816, -68.619, -10.978); - mg_cubic_to(-68.817, -11.182, -67.674, -11.906, -67.855, -12.119); - mg_cubic_to(-68.947, -13.408, -70.100, -14.175, -69.764, -15.668); - mg_cubic_to(-69.609, -16.358, -69.472, -17.415, -70.216, -18.135); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 201) - { - mg_move_to(-73.800, -16.400); - mg_cubic_to(-73.800, -16.400, -73.400, -9.600, -71.000, -8.000); - mg_cubic_to(-68.600, -6.400, -69.800, -7.200, -73.000, -8.400); - mg_cubic_to(-76.200, -9.600, -75.000, -10.400, -75.000, -10.400); - mg_cubic_to(-75.000, -10.400, -77.800, -10.000, -75.400, -8.000); - mg_cubic_to(-73.000, -6.000, -69.400, -3.600, -71.000, -3.600); - mg_cubic_to(-72.600, -3.600, -80.200, -7.600, -80.200, -10.400); - mg_cubic_to(-80.200, -13.200, -81.200, -17.300, -81.200, -17.300); - mg_cubic_to(-81.200, -17.300, -80.100, -18.100, -75.300, -18.000); - mg_cubic_to(-75.300, -18.000, -73.900, -17.300, -73.800, -16.400); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 202) - { - mg_move_to(-74.600, 2.200); - mg_cubic_to(-74.600, 2.200, -83.120, -0.591, -101.600, 2.800); - mg_cubic_to(-101.600, 2.800, -92.569, 0.722, -73.800, 3.000); - mg_cubic_to(-63.500, 4.250, -74.600, 2.200, -74.600, 2.200); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 203) - { - mg_set_width(0.1); - mg_move_to(-74.600, 2.200); - mg_cubic_to(-74.600, 2.200, -83.120, -0.591, -101.600, 2.800); - mg_cubic_to(-101.600, 2.800, -92.569, 0.722, -73.800, 3.000); - mg_cubic_to(-63.500, 4.250, -74.600, 2.200, -74.600, 2.200); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 204) - { - mg_move_to(-72.502, 2.129); - mg_cubic_to(-72.502, 2.129, -80.748, -1.389, -99.453, 0.392); - mg_cubic_to(-99.453, 0.392, -90.275, -0.897, -71.774, 2.995); - mg_cubic_to(-61.620, 5.131, -72.502, 2.129, -72.502, 2.129); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 205) - { - mg_set_width(0.1); - mg_move_to(-72.502, 2.129); - mg_cubic_to(-72.502, 2.129, -80.748, -1.389, -99.453, 0.392); - mg_cubic_to(-99.453, 0.392, -90.275, -0.897, -71.774, 2.995); - mg_cubic_to(-61.620, 5.131, -72.502, 2.129, -72.502, 2.129); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 206) - { - mg_move_to(-70.714, 2.222); - mg_cubic_to(-70.714, 2.222, -78.676, -1.899, -97.461, -1.514); - mg_cubic_to(-97.461, -1.514, -88.213, -2.118, -70.052, 3.140); - mg_cubic_to(-60.086, 6.025, -70.714, 2.222, -70.714, 2.222); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 207) - { - mg_set_width(0.1); - mg_move_to(-70.714, 2.222); - mg_cubic_to(-70.714, 2.222, -78.676, -1.899, -97.461, -1.514); - mg_cubic_to(-97.461, -1.514, -88.213, -2.118, -70.052, 3.140); - mg_cubic_to(-60.086, 6.025, -70.714, 2.222, -70.714, 2.222); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 208) - { - mg_move_to(-69.444, 2.445); - mg_cubic_to(-69.444, 2.445, -76.268, -1.862, -93.142, -2.960); - mg_cubic_to(-93.142, -2.960, -84.803, -2.790, -68.922, 3.319); - mg_cubic_to(-60.206, 6.672, -69.444, 2.445, -69.444, 2.445); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 209) - { - mg_set_width(0.1); - mg_move_to(-69.444, 2.445); - mg_cubic_to(-69.444, 2.445, -76.268, -1.862, -93.142, -2.960); - mg_cubic_to(-93.142, -2.960, -84.803, -2.790, -68.922, 3.319); - mg_cubic_to(-60.206, 6.672, -69.444, 2.445, -69.444, 2.445); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 210) - { - mg_move_to(45.840, 12.961); - mg_cubic_to(45.840, 12.961, 44.910, 13.605, 45.124, 12.424); - mg_cubic_to(45.339, 11.243, 73.547, -1.927, 77.161, -1.677); - mg_cubic_to(77.161, -1.677, 46.913, 11.529, 45.840, 12.961); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 211) - { - mg_set_width(0.1); - mg_move_to(45.840, 12.961); - mg_cubic_to(45.840, 12.961, 44.910, 13.605, 45.124, 12.424); - mg_cubic_to(45.339, 11.243, 73.547, -1.927, 77.161, -1.677); - mg_cubic_to(77.161, -1.677, 46.913, 11.529, 45.840, 12.961); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 212) - { - mg_move_to(42.446, 13.600); - mg_cubic_to(42.446, 13.600, 41.570, 14.315, 41.691, 13.121); - mg_cubic_to(41.812, 11.927, 68.899, -3.418, 72.521, -3.452); - mg_cubic_to(72.521, -3.452, 43.404, 12.089, 42.446, 13.600); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 213) - { - mg_set_width(0.1); - mg_move_to(42.446, 13.600); - mg_cubic_to(42.446, 13.600, 41.570, 14.315, 41.691, 13.121); - mg_cubic_to(41.812, 11.927, 68.899, -3.418, 72.521, -3.452); - mg_cubic_to(72.521, -3.452, 43.404, 12.089, 42.446, 13.600); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 214) - { - mg_move_to(39.160, 14.975); - mg_cubic_to(39.160, 14.975, 38.332, 15.747, 38.374, 14.547); - mg_cubic_to(38.416, 13.348, 58.233, -2.149, 68.045, -4.023); - mg_cubic_to(68.045, -4.023, 50.015, 4.104, 39.160, 14.975); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 215) - { - mg_set_width(0.1); - mg_move_to(39.160, 14.975); - mg_cubic_to(39.160, 14.975, 38.332, 15.747, 38.374, 14.547); - mg_cubic_to(38.416, 13.348, 58.233, -2.149, 68.045, -4.023); - mg_cubic_to(68.045, -4.023, 50.015, 4.104, 39.160, 14.975); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 216) - { - mg_move_to(36.284, 16.838); - mg_cubic_to(36.284, 16.838, 35.539, 17.532, 35.577, 16.453); - mg_cubic_to(35.615, 15.373, 53.449, 1.426, 62.280, -0.260); - mg_cubic_to(62.280, -0.260, 46.054, 7.054, 36.284, 16.838); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 217) - { - mg_set_width(0.1); - mg_move_to(36.284, 16.838); - mg_cubic_to(36.284, 16.838, 35.539, 17.532, 35.577, 16.453); - mg_cubic_to(35.615, 15.373, 53.449, 1.426, 62.280, -0.260); - mg_cubic_to(62.280, -0.260, 46.054, 7.054, 36.284, 16.838); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 218) - { - mg_move_to(4.600, 164.800); - mg_cubic_to(4.600, 164.800, -10.600, 162.400, 6.200, 160.800); - mg_cubic_to(6.200, 160.800, 24.200, 158.800, 28.200, 153.600); - mg_cubic_to(28.200, 153.600, 41.800, 144.400, 44.600, 144.000); - mg_cubic_to(47.400, 143.600, 63.800, 140.000, 64.200, 137.600); - mg_cubic_to(64.600, 135.200, 70.600, 132.800, 72.200, 133.600); - mg_cubic_to(73.800, 134.400, 73.800, 143.600, 71.000, 144.400); - mg_cubic_to(68.200, 145.200, 49.400, 152.400, 43.000, 153.600); - mg_cubic_to(36.600, 154.800, 25.000, 162.400, 20.200, 163.600); - mg_cubic_to(15.400, 164.800, 4.600, 164.800, 4.600, 164.800); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 219) - { - mg_move_to(77.600, 127.400); - mg_cubic_to(77.600, 127.400, 74.600, 129.000, 73.400, 131.600); - mg_cubic_to(73.400, 131.600, 67.000, 142.200, 52.800, 145.400); - mg_cubic_to(52.800, 145.400, 29.800, 154.400, 22.000, 156.400); - mg_cubic_to(22.000, 156.400, 8.600, 161.400, 1.200, 160.600); - mg_cubic_to(1.200, 160.600, -5.800, 160.800, 0.400, 162.400); - mg_cubic_to(0.400, 162.400, 20.600, 160.400, 24.000, 158.600); - mg_cubic_to(24.000, 158.600, 39.600, 153.400, 42.600, 150.800); - mg_cubic_to(45.600, 148.200, 63.800, 143.200, 66.000, 141.200); - mg_cubic_to(68.200, 139.200, 78.000, 130.800, 77.600, 127.400); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 220) - { - mg_move_to(18.882, 158.910); - mg_cubic_to(18.882, 158.910, 24.111, 158.680, 22.958, 160.230); - mg_cubic_to(21.805, 161.780, 19.357, 160.910, 19.357, 160.910); - mg_line_to(18.882, 158.910); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 221) - { - mg_move_to(11.680, 160.260); - mg_cubic_to(11.680, 160.260, 16.908, 160.040, 15.756, 161.590); - mg_cubic_to(14.603, 163.140, 12.155, 162.260, 12.155, 162.260); - mg_line_to(11.680, 160.260); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 222) - { - mg_move_to(1.251, 161.510); - mg_cubic_to(1.251, 161.510, 6.480, 161.280, 5.327, 162.830); - mg_cubic_to(4.174, 164.380, 1.726, 163.510, 1.726, 163.510); - mg_line_to(1.251, 161.510); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 223) - { - mg_move_to(-6.383, 162.060); - mg_cubic_to(-6.383, 162.060, -1.154, 161.830, -2.307, 163.380); - mg_cubic_to(-3.460, 164.930, -5.908, 164.050, -5.908, 164.050); - mg_line_to(-6.383, 162.060); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 224) - { - mg_move_to(35.415, 151.510); - mg_cubic_to(35.415, 151.510, 42.375, 151.210, 40.840, 153.270); - mg_cubic_to(39.306, 155.340, 36.047, 154.170, 36.047, 154.170); - mg_line_to(35.415, 151.510); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 225) - { - mg_move_to(45.730, 147.090); - mg_cubic_to(45.730, 147.090, 51.689, 143.790, 51.155, 148.850); - mg_cubic_to(50.885, 151.400, 46.362, 149.750, 46.362, 149.750); - mg_line_to(45.730, 147.090); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 226) - { - mg_move_to(54.862, 144.270); - mg_cubic_to(54.862, 144.270, 62.021, 140.570, 60.287, 146.040); - mg_cubic_to(59.509, 148.480, 55.493, 146.940, 55.493, 146.940); - mg_line_to(54.862, 144.270); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 227) - { - mg_move_to(64.376, 139.450); - mg_cubic_to(64.376, 139.450, 68.735, 134.550, 69.801, 141.210); - mg_cubic_to(70.207, 143.750, 65.008, 142.110, 65.008, 142.110); - mg_line_to(64.376, 139.450); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 228) - { - mg_move_to(26.834, 156.000); - mg_cubic_to(26.834, 156.000, 32.062, 155.770, 30.910, 157.320); - mg_cubic_to(29.757, 158.870, 27.308, 158.000, 27.308, 158.000); - mg_line_to(26.834, 156.000); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 229) - { - mg_move_to(62.434, 34.603); - mg_cubic_to(62.434, 34.603, 61.708, 35.268, 61.707, 34.197); - mg_cubic_to(61.707, 33.127, 79.191, 19.863, 88.034, 18.479); - mg_cubic_to(88.034, 18.479, 71.935, 25.208, 62.434, 34.603); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 230) - { - mg_set_width(0.1); - mg_move_to(62.434, 34.603); - mg_cubic_to(62.434, 34.603, 61.708, 35.268, 61.707, 34.197); - mg_cubic_to(61.707, 33.127, 79.191, 19.863, 88.034, 18.479); - mg_cubic_to(88.034, 18.479, 71.935, 25.208, 62.434, 34.603); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 231) - { - mg_move_to(65.400, 98.400); - mg_cubic_to(65.400, 98.400, 87.401, 120.800, 96.601, 124.400); - mg_cubic_to(96.601, 124.400, 105.800, 135.600, 101.800, 161.600); - mg_cubic_to(101.800, 161.600, 98.601, 169.200, 95.401, 148.400); - mg_cubic_to(95.401, 148.400, 98.601, 123.200, 87.401, 139.200); - mg_cubic_to(87.401, 139.200, 79.000, 129.300, 85.400, 129.600); - mg_cubic_to(85.400, 129.600, 88.601, 131.600, 89.001, 130.000); - mg_cubic_to(89.401, 128.400, 81.400, 114.800, 64.200, 100.400); - mg_cubic_to(47.000, 86.000, 65.400, 98.400, 65.400, 98.400); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 232) - { - mg_move_to(7.000, 137.200); - mg_cubic_to(7.000, 137.200, 6.800, 135.400, 8.600, 136.200); - mg_cubic_to(10.400, 137.000, 104.600, 143.200, 136.200, 167.200); - mg_cubic_to(136.200, 167.200, 91.001, 144.000, 7.000, 137.200); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 233) - { - mg_set_width(0.1); - mg_move_to(7.000, 137.200); - mg_cubic_to(7.000, 137.200, 6.800, 135.400, 8.600, 136.200); - mg_cubic_to(10.400, 137.000, 104.600, 143.200, 136.200, 167.200); - mg_cubic_to(136.200, 167.200, 91.001, 144.000, 7.000, 137.200); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 234) - { - mg_move_to(17.400, 132.800); - mg_cubic_to(17.400, 132.800, 17.200, 131.000, 19.000, 131.800); - mg_cubic_to(20.800, 132.600, 157.400, 131.600, 181.000, 164.000); - mg_cubic_to(181.000, 164.000, 159.000, 138.800, 17.400, 132.800); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 235) - { - mg_set_width(0.1); - mg_move_to(17.400, 132.800); - mg_cubic_to(17.400, 132.800, 17.200, 131.000, 19.000, 131.800); - mg_cubic_to(20.800, 132.600, 157.400, 131.600, 181.000, 164.000); - mg_cubic_to(181.000, 164.000, 159.000, 138.800, 17.400, 132.800); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 236) - { - mg_move_to(29.000, 128.800); - mg_cubic_to(29.000, 128.800, 28.800, 127.000, 30.600, 127.800); - mg_cubic_to(32.400, 128.600, 205.800, 115.600, 229.400, 148.000); - mg_cubic_to(229.400, 148.000, 219.800, 122.400, 29.000, 128.800); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 237) - { - mg_set_width(0.1); - mg_move_to(29.000, 128.800); - mg_cubic_to(29.000, 128.800, 28.800, 127.000, 30.600, 127.800); - mg_cubic_to(32.400, 128.600, 205.800, 115.600, 229.400, 148.000); - mg_cubic_to(229.400, 148.000, 219.800, 122.400, 29.000, 128.800); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 238) - { - mg_move_to(39.000, 124.000); - mg_cubic_to(39.000, 124.000, 38.800, 122.200, 40.600, 123.000); - mg_cubic_to(42.400, 123.800, 164.600, 85.200, 188.200, 117.600); - mg_cubic_to(188.200, 117.600, 174.800, 93.000, 39.000, 124.000); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 239) - { - mg_set_width(0.1); - mg_move_to(39.000, 124.000); - mg_cubic_to(39.000, 124.000, 38.800, 122.200, 40.600, 123.000); - mg_cubic_to(42.400, 123.800, 164.600, 85.200, 188.200, 117.600); - mg_cubic_to(188.200, 117.600, 174.800, 93.000, 39.000, 124.000); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 240) - { - mg_move_to(-19.000, 146.800); - mg_cubic_to(-19.000, 146.800, -19.200, 145.000, -17.400, 145.800); - mg_cubic_to(-15.600, 146.600, 2.200, 148.800, 4.200, 187.600); - mg_cubic_to(4.200, 187.600, -3.000, 145.600, -19.000, 146.800); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 241) - { - mg_set_width(0.1); - mg_move_to(-19.000, 146.800); - mg_cubic_to(-19.000, 146.800, -19.200, 145.000, -17.400, 145.800); - mg_cubic_to(-15.600, 146.600, 2.200, 148.800, 4.200, 187.600); - mg_cubic_to(4.200, 187.600, -3.000, 145.600, -19.000, 146.800); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 242) - { - mg_move_to(-27.800, 148.400); - mg_cubic_to(-27.800, 148.400, -28.000, 146.600, -26.200, 147.400); - mg_cubic_to(-24.400, 148.200, -10.200, 143.600, -13.000, 182.400); - mg_cubic_to(-13.000, 182.400, -11.800, 147.200, -27.800, 148.400); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 243) - { - mg_set_width(0.1); - mg_move_to(-27.800, 148.400); - mg_cubic_to(-27.800, 148.400, -28.000, 146.600, -26.200, 147.400); - mg_cubic_to(-24.400, 148.200, -10.200, 143.600, -13.000, 182.400); - mg_cubic_to(-13.000, 182.400, -11.800, 147.200, -27.800, 148.400); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 244) - { - mg_move_to(-35.800, 148.800); - mg_cubic_to(-35.800, 148.800, -36.000, 147.000, -34.200, 147.800); - mg_cubic_to(-32.400, 148.600, -17.000, 149.200, -29.400, 171.600); - mg_cubic_to(-29.400, 171.600, -19.800, 147.600, -35.800, 148.800); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 245) - { - mg_set_width(0.1); - mg_move_to(-35.800, 148.800); - mg_cubic_to(-35.800, 148.800, -36.000, 147.000, -34.200, 147.800); - mg_cubic_to(-32.400, 148.600, -17.000, 149.200, -29.400, 171.600); - mg_cubic_to(-29.400, 171.600, -19.800, 147.600, -35.800, 148.800); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 246) - { - mg_move_to(11.526, 104.460); - mg_cubic_to(11.526, 104.460, 11.082, 106.460, 12.631, 105.250); - mg_cubic_to(28.699, 92.622, 61.141, 33.720, 116.831, 28.086); - mg_cubic_to(116.831, 28.086, 78.519, 15.976, 11.531, 104.460); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 247) - { - mg_set_width(0.1); - mg_move_to(11.526, 104.460); - mg_cubic_to(11.526, 104.460, 11.082, 106.460, 12.631, 105.250); - mg_cubic_to(28.699, 92.622, 61.141, 33.720, 116.831, 28.086); - mg_cubic_to(116.831, 28.086, 78.519, 15.976, 11.531, 104.460); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 248) - { - mg_move_to(22.726, 102.660); - mg_cubic_to(22.726, 102.660, 21.363, 101.470, 23.231, 100.850); - mg_cubic_to(25.099, 100.220, 137.541, 27.720, 176.831, 35.686); - mg_cubic_to(176.831, 35.686, 149.721, 28.176, 22.731, 102.660); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 249) - { - mg_set_width(0.1); - mg_move_to(22.726, 102.660); - mg_cubic_to(22.726, 102.660, 21.363, 101.470, 23.231, 100.850); - mg_cubic_to(25.099, 100.220, 137.541, 27.720, 176.831, 35.686); - mg_cubic_to(176.831, 35.686, 149.721, 28.176, 22.731, 102.660); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 250) - { - mg_move_to(1.885, 108.770); - mg_cubic_to(1.885, 108.770, 1.376, 110.370, 3.087, 109.390); - mg_cubic_to(12.062, 104.270, 15.677, 47.059, 59.254, 45.804); - mg_cubic_to(59.254, 45.804, 26.843, 31.090, 1.885, 108.770); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 251) - { - mg_set_width(0.1); - mg_move_to(1.885, 108.770); - mg_cubic_to(1.885, 108.770, 1.376, 110.370, 3.087, 109.390); - mg_cubic_to(12.062, 104.270, 15.677, 47.059, 59.254, 45.804); - mg_cubic_to(59.254, 45.804, 26.843, 31.090, 1.885, 108.770); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 252) - { - mg_move_to(-18.038, 119.790); - mg_cubic_to(-18.038, 119.790, -19.115, 121.080, -17.162, 120.820); - mg_cubic_to(-6.916, 119.490, 14.489, 78.222, 58.928, 83.301); - mg_cubic_to(58.928, 83.301, 26.962, 68.955, -18.038, 119.790); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 253) - { - mg_set_width(0.1); - mg_move_to(-18.038, 119.790); - mg_cubic_to(-18.038, 119.790, -19.115, 121.080, -17.162, 120.820); - mg_cubic_to(-6.916, 119.490, 14.489, 78.222, 58.928, 83.301); - mg_cubic_to(58.928, 83.301, 26.962, 68.955, -18.038, 119.790); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 254) - { - mg_move_to(-6.800, 113.670); - mg_cubic_to(-6.800, 113.670, -7.611, 115.140, -5.742, 114.510); - mg_cubic_to(4.057, 111.240, 17.141, 66.625, 61.729, 63.078); - mg_cubic_to(61.729, 63.078, 27.603, 55.135, -6.800, 113.670); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 255) - { - mg_set_width(0.1); - mg_move_to(-6.800, 113.670); - mg_cubic_to(-6.800, 113.670, -7.611, 115.140, -5.742, 114.510); - mg_cubic_to(4.057, 111.240, 17.141, 66.625, 61.729, 63.078); - mg_cubic_to(61.729, 63.078, 27.603, 55.135, -6.800, 113.670); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 256) - { - mg_move_to(-25.078, 124.910); - mg_cubic_to(-25.078, 124.910, -25.951, 125.950, -24.369, 125.750); - mg_cubic_to(-16.070, 124.670, 1.268, 91.240, 37.264, 95.354); - mg_cubic_to(37.264, 95.354, 11.371, 83.734, -25.078, 124.910); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 257) - { - mg_set_width(0.1); - mg_move_to(-25.078, 124.910); - mg_cubic_to(-25.078, 124.910, -25.951, 125.950, -24.369, 125.750); - mg_cubic_to(-16.070, 124.670, 1.268, 91.240, 37.264, 95.354); - mg_cubic_to(37.264, 95.354, 11.371, 83.734, -25.078, 124.910); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 258) - { - mg_move_to(-32.677, 130.820); - mg_cubic_to(-32.677, 130.820, -33.682, 131.870, -32.091, 131.750); - mg_cubic_to(-27.923, 131.440, 2.715, 98.360, 21.183, 113.860); - mg_cubic_to(21.183, 113.860, 9.168, 95.139, -32.677, 130.820); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 259) - { - mg_set_width(0.1); - mg_move_to(-32.677, 130.820); - mg_cubic_to(-32.677, 130.820, -33.682, 131.870, -32.091, 131.750); - mg_cubic_to(-27.923, 131.440, 2.715, 98.360, 21.183, 113.860); - mg_cubic_to(21.183, 113.860, 9.168, 95.139, -32.677, 130.820); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 260) - { - mg_move_to(36.855, 98.898); - mg_cubic_to(36.855, 98.898, 35.654, 97.543, 37.586, 97.158); - mg_cubic_to(39.518, 96.774, 160.216, 39.061, 198.176, 51.927); - mg_cubic_to(198.176, 51.927, 172.236, 41.053, 36.856, 98.898); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 261) - { - mg_set_width(0.1); - mg_move_to(36.855, 98.898); - mg_cubic_to(36.855, 98.898, 35.654, 97.543, 37.586, 97.158); - mg_cubic_to(39.518, 96.774, 160.216, 39.061, 198.176, 51.927); - mg_cubic_to(198.176, 51.927, 172.236, 41.053, 36.856, 98.898); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 262) - { - mg_move_to(3.400, 163.200); - mg_cubic_to(3.400, 163.200, 3.200, 161.400, 5.000, 162.200); - mg_cubic_to(6.800, 163.000, 22.200, 163.600, 9.800, 186.000); - mg_cubic_to(9.800, 186.000, 19.400, 162.000, 3.400, 163.200); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 263) - { - mg_set_width(0.1); - mg_move_to(3.400, 163.200); - mg_cubic_to(3.400, 163.200, 3.200, 161.400, 5.000, 162.200); - mg_cubic_to(6.800, 163.000, 22.200, 163.600, 9.800, 186.000); - mg_cubic_to(9.800, 186.000, 19.400, 162.000, 3.400, 163.200); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 264) - { - mg_move_to(13.800, 161.600); - mg_cubic_to(13.800, 161.600, 13.600, 159.800, 15.400, 160.600); - mg_cubic_to(17.200, 161.400, 35.000, 163.600, 37.000, 202.400); - mg_cubic_to(37.000, 202.400, 29.800, 160.400, 13.800, 161.600); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 265) - { - mg_set_width(0.1); - mg_move_to(13.800, 161.600); - mg_cubic_to(13.800, 161.600, 13.600, 159.800, 15.400, 160.600); - mg_cubic_to(17.200, 161.400, 35.000, 163.600, 37.000, 202.400); - mg_cubic_to(37.000, 202.400, 29.800, 160.400, 13.800, 161.600); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 266) - { - mg_move_to(20.600, 160.000); - mg_cubic_to(20.600, 160.000, 20.400, 158.200, 22.200, 159.000); - mg_cubic_to(24.000, 159.800, 48.600, 163.200, 72.200, 195.600); - mg_cubic_to(72.200, 195.600, 36.600, 158.800, 20.600, 160.000); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 267) - { - mg_set_width(0.1); - mg_move_to(20.600, 160.000); - mg_cubic_to(20.600, 160.000, 20.400, 158.200, 22.200, 159.000); - mg_cubic_to(24.000, 159.800, 48.600, 163.200, 72.200, 195.600); - mg_cubic_to(72.200, 195.600, 36.600, 158.800, 20.600, 160.000); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 268) - { - mg_move_to(28.225, 157.970); - mg_cubic_to(28.225, 157.970, 27.788, 156.210, 29.678, 156.770); - mg_cubic_to(31.568, 157.320, 52.002, 155.420, 90.099, 189.600); - mg_cubic_to(90.099, 189.600, 43.924, 154.660, 28.225, 157.970); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 269) - { - mg_set_width(0.1); - mg_move_to(28.225, 157.970); - mg_cubic_to(28.225, 157.970, 27.788, 156.210, 29.678, 156.770); - mg_cubic_to(31.568, 157.320, 52.002, 155.420, 90.099, 189.600); - mg_cubic_to(90.099, 189.600, 43.924, 154.660, 28.225, 157.970); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 270) - { - mg_move_to(38.625, 153.570); - mg_cubic_to(38.625, 153.570, 38.188, 151.810, 40.078, 152.370); - mg_cubic_to(41.968, 152.920, 76.802, 157.420, 128.500, 192.400); - mg_cubic_to(128.500, 192.400, 54.324, 150.260, 38.625, 153.570); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 271) - { - mg_set_width(0.1); - mg_move_to(38.625, 153.570); - mg_cubic_to(38.625, 153.570, 38.188, 151.810, 40.078, 152.370); - mg_cubic_to(41.968, 152.920, 76.802, 157.420, 128.500, 192.400); - mg_cubic_to(128.500, 192.400, 54.324, 150.260, 38.625, 153.570); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 272) - { - mg_move_to(-1.800, 142.000); - mg_cubic_to(-1.800, 142.000, -2.000, 140.200, -0.200, 141.000); - mg_cubic_to(1.600, 141.800, 55.000, 144.400, 85.400, 171.200); - mg_cubic_to(85.400, 171.200, 50.499, 146.430, -1.800, 142.000); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 273) - { - mg_set_width(0.1); - mg_move_to(-1.800, 142.000); - mg_cubic_to(-1.800, 142.000, -2.000, 140.200, -0.200, 141.000); - mg_cubic_to(1.600, 141.800, 55.000, 144.400, 85.400, 171.200); - mg_cubic_to(85.400, 171.200, 50.499, 146.430, -1.800, 142.000); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 274) - { - mg_move_to(-11.800, 146.000); - mg_cubic_to(-11.800, 146.000, -12.000, 144.200, -10.200, 145.000); - mg_cubic_to(-8.400, 145.800, 16.200, 149.200, 39.800, 181.600); - mg_cubic_to(39.800, 181.600, 4.200, 144.800, -11.800, 146.000); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 275) - { - mg_set_width(0.1); - mg_move_to(-11.800, 146.000); - mg_cubic_to(-11.800, 146.000, -12.000, 144.200, -10.200, 145.000); - mg_cubic_to(-8.400, 145.800, 16.200, 149.200, 39.800, 181.600); - mg_cubic_to(39.800, 181.600, 4.200, 144.800, -11.800, 146.000); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 276) - { - mg_move_to(49.503, 148.960); - mg_cubic_to(49.503, 148.960, 48.938, 147.240, 50.864, 147.660); - mg_cubic_to(52.790, 148.070, 87.860, 150.000, 141.980, 181.100); - mg_cubic_to(141.980, 181.100, 64.317, 146.700, 49.503, 148.960); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 277) - { - mg_set_width(0.1); - mg_move_to(49.503, 148.960); - mg_cubic_to(49.503, 148.960, 48.938, 147.240, 50.864, 147.660); - mg_cubic_to(52.790, 148.070, 87.860, 150.000, 141.980, 181.100); - mg_cubic_to(141.980, 181.100, 64.317, 146.700, 49.503, 148.960); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 278) - { - mg_move_to(57.903, 146.560); - mg_cubic_to(57.903, 146.560, 57.338, 144.840, 59.264, 145.260); - mg_cubic_to(61.190, 145.670, 96.260, 147.600, 150.380, 178.700); - mg_cubic_to(150.380, 178.700, 73.317, 143.900, 57.903, 146.560); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 279) - { - mg_set_width(0.1); - mg_move_to(57.903, 146.560); - mg_cubic_to(57.903, 146.560, 57.338, 144.840, 59.264, 145.260); - mg_cubic_to(61.190, 145.670, 96.260, 147.600, 150.380, 178.700); - mg_cubic_to(150.380, 178.700, 73.317, 143.900, 57.903, 146.560); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 280) - { - mg_move_to(67.503, 141.560); - mg_cubic_to(67.503, 141.560, 66.938, 139.840, 68.864, 140.260); - mg_cubic_to(70.790, 140.670, 113.860, 145.000, 203.584, 179.300); - mg_cubic_to(203.584, 179.300, 82.924, 138.900, 67.504, 141.560); - mg_close_path(); - mg_set_color_rgba(1.000, 1.000, 1.000, 1); - mg_fill(); - } - if(!singlePath || singlePathIndex == 281) - { - mg_set_width(0.1); - mg_move_to(67.503, 141.560); - mg_cubic_to(67.503, 141.560, 66.938, 139.840, 68.864, 140.260); - mg_cubic_to(70.790, 140.670, 113.860, 145.000, 203.584, 179.300); - mg_cubic_to(203.584, 179.300, 82.924, 138.900, 67.504, 141.560); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 282) - { - mg_move_to(-43.800, 148.400); - mg_cubic_to(-43.800, 148.400, -38.600, 148.000, -39.800, 149.600); - mg_cubic_to(-41.000, 151.200, -43.400, 150.400, -43.400, 150.400); - mg_line_to(-43.800, 148.400); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 283) - { - mg_move_to(-13.000, 162.400); - mg_cubic_to(-13.000, 162.400, -7.800, 162.000, -9.000, 163.600); - mg_cubic_to(-10.200, 165.200, -12.600, 164.400, -12.600, 164.400); - mg_line_to(-13.000, 162.400); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 284) - { - mg_move_to(-21.800, 162.000); - mg_cubic_to(-21.800, 162.000, -16.600, 161.600, -17.800, 163.200); - mg_cubic_to(-19.000, 164.800, -21.400, 164.000, -21.400, 164.000); - mg_line_to(-21.800, 162.000); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 285) - { - mg_move_to(-117.170, 150.180); - mg_cubic_to(-117.170, 150.180, -112.120, 151.500, -113.780, 152.620); - mg_cubic_to(-115.440, 153.740, -117.450, 152.200, -117.450, 152.200); - mg_line_to(-117.170, 150.180); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 286) - { - mg_move_to(-115.170, 140.580); - mg_cubic_to(-115.170, 140.580, -110.120, 141.900, -111.780, 143.020); - mg_cubic_to(-113.440, 144.140, -115.450, 142.600, -115.450, 142.600); - mg_line_to(-115.170, 140.580); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 287) - { - mg_move_to(-122.370, 136.180); - mg_cubic_to(-122.370, 136.180, -117.320, 137.500, -118.980, 138.620); - mg_cubic_to(-120.640, 139.740, -122.650, 138.200, -122.650, 138.200); - mg_line_to(-122.370, 136.180); - mg_close_path(); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 288) - { - mg_move_to(-42.600, 211.200); - mg_move_to(-48.200, 213.200); - mg_cubic_to(-50.200, 213.200, -61.400, 216.800, -67.000, 226.800); - mg_cubic_to(-67.000, 226.800, -54.600, 217.200, -42.600, 211.200); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 289) - { - mg_move_to(45.116, 303.850); - mg_cubic_to(45.257, 304.100, 45.312, 304.520, 45.604, 304.540); - mg_cubic_to(46.262, 304.580, 47.495, 304.880, 47.370, 304.250); - mg_cubic_to(46.522, 299.940, 45.648, 295.000, 41.515, 293.200); - mg_cubic_to(40.876, 292.920, 39.434, 293.330, 39.360, 294.220); - mg_cubic_to(39.233, 295.740, 39.116, 297.090, 39.425, 298.550); - mg_cubic_to(39.725, 299.980, 41.883, 299.980, 42.800, 298.600); - mg_cubic_to(43.736, 300.270, 44.168, 302.120, 45.116, 303.850); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 290) - { - mg_move_to(34.038, 308.580); - mg_cubic_to(34.786, 309.990, 34.659, 311.850, 36.074, 312.420); - mg_cubic_to(36.814, 312.710, 38.664, 311.740, 38.246, 310.660); - mg_cubic_to(37.444, 308.600, 37.056, 306.360, 35.667, 304.550); - mg_cubic_to(35.467, 304.290, 35.707, 303.760, 35.547, 303.430); - mg_cubic_to(34.953, 302.210, 33.808, 301.470, 32.400, 301.800); - mg_cubic_to(31.285, 304.000, 32.433, 306.130, 33.955, 307.840); - mg_cubic_to(34.091, 307.990, 33.925, 308.370, 34.038, 308.580); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 291) - { - mg_move_to(-5.564, 303.390); - mg_cubic_to(-5.672, 303.010, -5.710, 302.550, -5.545, 302.230); - mg_cubic_to(-5.014, 301.200, -4.221, 300.080, -4.558, 299.050); - mg_cubic_to(-4.906, 298.000, -6.022, 298.180, -6.672, 298.750); - mg_cubic_to(-7.807, 299.740, -7.856, 301.570, -8.547, 302.930); - mg_cubic_to(-8.743, 303.310, -8.692, 303.890, -9.133, 304.280); - mg_cubic_to(-9.607, 304.700, -10.047, 306.220, -9.951, 306.790); - mg_cubic_to(-9.898, 307.110, -10.081, 317.010, -9.859, 316.750); - mg_cubic_to(-9.240, 316.020, -6.190, 306.280, -6.121, 305.390); - mg_cubic_to(-6.064, 304.660, -5.332, 304.200, -5.564, 303.390); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 292) - { - mg_move_to(-31.202, 296.600); - mg_cubic_to(-28.568, 294.100, -25.778, 291.140, -26.220, 287.430); - mg_cubic_to(-26.336, 286.450, -28.111, 286.980, -28.298, 287.820); - mg_cubic_to(-29.100, 291.450, -31.139, 294.110, -33.707, 296.500); - mg_cubic_to(-35.903, 298.550, -37.765, 304.890, -38.000, 305.400); - mg_cubic_to(-34.303, 300.140, -32.046, 297.400, -31.202, 296.600); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 293) - { - mg_move_to(-44.776, 290.640); - mg_cubic_to(-44.253, 290.260, -44.555, 289.770, -44.338, 289.440); - mg_cubic_to(-43.385, 287.980, -42.084, 286.740, -42.066, 285.000); - mg_cubic_to(-42.063, 284.720, -42.441, 284.410, -42.776, 284.640); - mg_cubic_to(-43.053, 284.820, -43.395, 284.950, -43.503, 285.080); - mg_cubic_to(-45.533, 287.530, -46.933, 290.200, -48.376, 293.010); - mg_cubic_to(-48.559, 293.370, -49.703, 297.860, -49.390, 297.970); - mg_cubic_to(-49.151, 298.060, -47.431, 293.880, -47.221, 293.760); - mg_cubic_to(-45.958, 293.080, -45.946, 291.460, -44.776, 290.640); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 294) - { - mg_move_to(-28.043, 310.180); - mg_cubic_to(-27.599, 309.310, -26.023, 308.110, -26.136, 307.220); - mg_cubic_to(-26.254, 306.290, -25.786, 304.850, -26.698, 305.540); - mg_cubic_to(-27.955, 306.480, -31.404, 307.830, -31.674, 313.640); - mg_cubic_to(-31.700, 314.210, -28.726, 311.520, -28.043, 310.180); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 295) - { - mg_move_to(-13.600, 293.000); - mg_cubic_to(-13.200, 292.330, -12.492, 292.810, -12.033, 292.540); - mg_cubic_to(-11.385, 292.170, -10.774, 291.610, -10.482, 290.960); - mg_cubic_to(-9.512, 288.820, -7.743, 287.000, -7.600, 284.600); - mg_cubic_to(-9.091, 283.200, -9.770, 285.240, -10.400, 286.200); - mg_cubic_to(-11.723, 284.550, -12.722, 286.430, -14.022, 286.950); - mg_cubic_to(-14.092, 286.980, -14.305, 286.630, -14.380, 286.660); - mg_cubic_to(-15.557, 287.100, -16.237, 288.180, -17.235, 288.960); - mg_cubic_to(-17.406, 289.090, -17.811, 288.910, -17.958, 289.050); - mg_cubic_to(-18.610, 289.650, -19.583, 289.980, -19.863, 290.660); - mg_cubic_to(-20.973, 293.360, -24.113, 295.460, -26.000, 303.000); - mg_cubic_to(-25.619, 303.910, -21.488, 296.360, -21.001, 295.660); - mg_cubic_to(-20.165, 294.460, -20.047, 297.320, -18.771, 296.660); - mg_cubic_to(-18.720, 296.630, -18.534, 296.870, -18.400, 297.000); - mg_cubic_to(-18.206, 296.720, -17.988, 296.490, -17.600, 296.600); - mg_cubic_to(-17.600, 296.200, -17.734, 295.640, -17.533, 295.490); - mg_cubic_to(-16.296, 294.510, -16.380, 293.440, -15.600, 292.200); - mg_cubic_to(-15.142, 292.990, -14.081, 292.270, -13.600, 293.000); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 296) - { - mg_move_to(46.200, 347.400); - mg_cubic_to(46.200, 347.400, 53.600, 327.000, 49.200, 315.800); - mg_cubic_to(49.200, 315.800, 60.600, 337.400, 56.000, 348.600); - mg_cubic_to(56.000, 348.600, 55.600, 338.200, 51.600, 333.200); - mg_cubic_to(51.600, 333.200, 47.600, 346.000, 46.200, 347.400); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 297) - { - mg_move_to(31.400, 344.800); - mg_cubic_to(31.400, 344.800, 36.800, 336.000, 28.800, 317.600); - mg_cubic_to(28.800, 317.600, 28.000, 338.000, 21.200, 349.000); - mg_cubic_to(21.200, 349.000, 35.400, 328.800, 31.400, 344.800); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 298) - { - mg_move_to(21.400, 342.800); - mg_cubic_to(21.400, 342.800, 21.200, 322.800, 21.600, 319.800); - mg_cubic_to(21.600, 319.800, 17.800, 336.400, 7.600, 346.000); - mg_cubic_to(7.600, 346.000, 22.000, 334.000, 21.400, 342.800); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 299) - { - mg_move_to(11.800, 310.800); - mg_cubic_to(11.800, 310.800, 17.800, 324.400, 7.800, 342.800); - mg_cubic_to(7.800, 342.800, 14.200, 330.600, 9.400, 323.600); - mg_cubic_to(9.400, 323.600, 12.000, 320.200, 11.800, 310.800); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 300) - { - mg_move_to(-7.400, 342.400); - mg_cubic_to(-7.400, 342.400, -8.400, 326.800, -6.600, 324.600); - mg_cubic_to(-6.600, 324.600, -6.400, 318.200, -6.800, 317.200); - mg_cubic_to(-6.800, 317.200, -2.800, 311.000, -2.600, 318.400); - mg_cubic_to(-2.600, 318.400, -1.200, 326.200, 1.600, 330.800); - mg_cubic_to(1.600, 330.800, 5.200, 336.200, 5.000, 342.600); - mg_cubic_to(5.000, 342.600, -5.000, 312.400, -7.400, 342.400); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 301) - { - mg_move_to(-11.000, 314.800); - mg_cubic_to(-11.000, 314.800, -17.600, 325.600, -19.400, 344.600); - mg_cubic_to(-19.400, 344.600, -20.800, 338.400, -17.000, 324.000); - mg_cubic_to(-17.000, 324.000, -12.800, 308.600, -11.000, 314.800); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 302) - { - mg_move_to(-32.800, 334.600); - mg_cubic_to(-32.800, 334.600, -27.800, 329.200, -26.400, 324.200); - mg_cubic_to(-26.400, 324.200, -22.800, 308.400, -29.200, 317.000); - mg_cubic_to(-29.200, 317.000, -29.000, 325.000, -37.200, 332.400); - mg_cubic_to(-37.200, 332.400, -32.400, 330.000, -32.800, 334.600); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 303) - { - mg_move_to(-38.600, 329.600); - mg_cubic_to(-38.600, 329.600, -35.200, 312.200, -34.400, 311.400); - mg_cubic_to(-34.400, 311.400, -32.600, 308.000, -35.400, 311.200); - mg_cubic_to(-35.400, 311.200, -44.200, 330.400, -48.200, 337.000); - mg_cubic_to(-48.200, 337.000, -40.200, 327.800, -38.600, 329.600); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 304) - { - mg_move_to(-44.400, 313.000); - mg_cubic_to(-44.400, 313.000, -32.800, 290.600, -54.600, 316.400); - mg_cubic_to(-54.600, 316.400, -43.600, 306.600, -44.400, 313.000); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 305) - { - mg_move_to(-59.800, 298.400); - mg_cubic_to(-59.800, 298.400, -55.000, 279.600, -52.400, 279.800); - mg_line_to(-50.800, 281.400); - mg_cubic_to(-50.800, 281.400, -56.800, 291.000, -56.200, 300.800); - mg_cubic_to(-56.200, 300.800, -56.800, 291.200, -59.800, 298.400); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 306) - { - mg_move_to(270.500, 287.000); - mg_cubic_to(270.500, 287.000, 258.500, 277.000, 256.000, 273.500); - mg_cubic_to(256.000, 273.500, 269.500, 292.000, 269.500, 299.000); - mg_cubic_to(269.500, 299.000, 272.000, 291.500, 270.500, 287.000); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 307) - { - mg_move_to(276.000, 265.000); - mg_cubic_to(276.000, 265.000, 255.000, 250.000, 251.500, 242.500); - mg_cubic_to(251.500, 242.500, 278.000, 272.000, 278.000, 276.500); - mg_cubic_to(278.000, 276.500, 278.500, 267.500, 276.000, 265.000); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 308) - { - mg_move_to(293.000, 111.000); - mg_cubic_to(293.000, 111.000, 281.000, 103.000, 279.500, 105.000); - mg_cubic_to(279.500, 105.000, 290.000, 111.500, 292.500, 120.000); - mg_cubic_to(292.500, 120.000, 291.000, 111.000, 293.000, 111.000); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 309) - { - mg_move_to(301.500, 191.500); - mg_move_to(284.000, 179.500); - mg_cubic_to(284.000, 179.500, 303.000, 196.500, 303.500, 200.500); - mg_line_to(301.500, 191.500); - mg_close_path(); - mg_set_color_rgba(0.800, 0.800, 0.800, 1); - mg_fill(); - } - - if(!singlePath || singlePathIndex == 310) - { - mg_move_to(-89.250, 169.000); - mg_move_to(-67.250, 173.750); - } - if(!singlePath || singlePathIndex == 311) - { - mg_set_width(1); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 312) - { - mg_move_to(-39.000, 331.000); - mg_cubic_to(-39.000, 331.000, -39.500, 327.500, -48.500, 338.000); - } - if(!singlePath || singlePathIndex == 313) - { - mg_set_width(1); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 314) - { - mg_move_to(-33.500, 336.000); - mg_cubic_to(-33.500, 336.000, -31.500, 329.500, -38.000, 334.000); - } - if(!singlePath || singlePathIndex == 315) - { - mg_set_width(1); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - - if(!singlePath || singlePathIndex == 316) - { - mg_move_to(20.500, 344.500); - mg_cubic_to(20.500, 344.500, 22.000, 333.500, 10.500, 346.500); - } - if(!singlePath || singlePathIndex == 317) - { - mg_set_width(1); - mg_set_color_rgba(0.000, 0.000, 0.000, 1); - mg_stroke(); - } - + if(!singlePath || singlePathIndex == 0) + { + mg_move_to(-122.300, 84.285); + mg_cubic_to(-122.300, 84.285, -122.200, 86.179, -123.030, 86.160); + mg_cubic_to(-123.850, 86.141, -140.300, 38.066, -160.830, 40.309); + mg_cubic_to(-160.830, 40.309, -143.050, 32.956, -122.300, 84.285); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 1) + { + mg_set_width(0.17200001); + mg_move_to(-122.300, 84.285); + mg_cubic_to(-122.300, 84.285, -122.200, 86.179, -123.030, 86.160); + mg_cubic_to(-123.850, 86.141, -140.300, 38.066, -160.830, 40.309); + mg_cubic_to(-160.830, 40.309, -143.050, 32.956, -122.300, 84.285); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 2) + { + mg_move_to(-118.770, 81.262); + mg_cubic_to(-118.770, 81.262, -119.320, 83.078, -120.090, 82.779); + mg_cubic_to(-120.860, 82.481, -119.980, 31.675, -140.040, 26.801); + mg_cubic_to(-140.040, 26.801, -120.820, 25.937, -118.770, 81.262); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 3) + { + mg_set_width(0.17200001); + mg_move_to(-118.770, 81.262); + mg_cubic_to(-118.770, 81.262, -119.320, 83.078, -120.090, 82.779); + mg_cubic_to(-120.860, 82.481, -119.980, 31.675, -140.040, 26.801); + mg_cubic_to(-140.040, 26.801, -120.820, 25.937, -118.770, 81.262); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 4) + { + mg_move_to(-91.284, 123.590); + mg_cubic_to(-91.284, 123.590, -89.648, 124.550, -90.118, 125.230); + mg_cubic_to(-90.589, 125.900, -139.760, 113.100, -149.220, 131.460); + mg_cubic_to(-149.220, 131.460, -145.540, 112.570, -91.284, 123.590); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 5) + { + mg_set_width(0.17200001); + mg_move_to(-91.284, 123.590); + mg_cubic_to(-91.284, 123.590, -89.648, 124.550, -90.118, 125.230); + mg_cubic_to(-90.589, 125.900, -139.760, 113.100, -149.220, 131.460); + mg_cubic_to(-149.220, 131.460, -145.540, 112.570, -91.284, 123.590); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 6) + { + mg_move_to(-94.093, 133.800); + mg_cubic_to(-94.093, 133.800, -92.237, 134.200, -92.471, 134.990); + mg_cubic_to(-92.704, 135.780, -143.410, 139.120, -146.600, 159.520); + mg_cubic_to(-146.600, 159.520, -149.060, 140.440, -94.093, 133.800); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 7) + { + mg_set_width(0.17200001); + mg_move_to(-94.093, 133.800); + mg_cubic_to(-94.093, 133.800, -92.237, 134.200, -92.471, 134.990); + mg_cubic_to(-92.704, 135.780, -143.410, 139.120, -146.600, 159.520); + mg_cubic_to(-146.600, 159.520, -149.060, 140.440, -94.093, 133.800); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 8) + { + mg_move_to(-98.304, 128.280); + mg_cubic_to(-98.304, 128.280, -96.526, 128.940, -96.872, 129.690); + mg_cubic_to(-97.218, 130.440, -147.870, 126.350, -154.000, 146.060); + mg_cubic_to(-154.000, 146.060, -153.650, 126.820, -98.304, 128.280); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 9) + { + mg_set_width(0.17200001); + mg_move_to(-98.304, 128.280); + mg_cubic_to(-98.304, 128.280, -96.526, 128.940, -96.872, 129.690); + mg_cubic_to(-97.218, 130.440, -147.870, 126.350, -154.000, 146.060); + mg_cubic_to(-154.000, 146.060, -153.650, 126.820, -98.304, 128.280); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 10) + { + mg_move_to(-109.010, 110.070); + mg_cubic_to(-109.010, 110.070, -107.700, 111.450, -108.340, 111.970); + mg_cubic_to(-108.980, 112.490, -152.720, 86.634, -166.870, 101.680); + mg_cubic_to(-166.870, 101.680, -158.130, 84.533, -109.010, 110.070); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 11) + { + mg_set_width(0.17200001); + mg_move_to(-109.010, 110.070); + mg_cubic_to(-109.010, 110.070, -107.700, 111.450, -108.340, 111.970); + mg_cubic_to(-108.980, 112.490, -152.720, 86.634, -166.870, 101.680); + mg_cubic_to(-166.870, 101.680, -158.130, 84.533, -109.010, 110.070); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 12) + { + mg_move_to(-116.550, 114.260); + mg_cubic_to(-116.550, 114.260, -115.100, 115.480, -115.670, 116.070); + mg_cubic_to(-116.250, 116.660, -162.640, 95.922, -174.990, 112.470); + mg_cubic_to(-174.990, 112.470, -168.250, 94.447, -116.550, 114.260); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 13) + { + mg_set_width(0.17200001); + mg_move_to(-116.550, 114.260); + mg_cubic_to(-116.550, 114.260, -115.100, 115.480, -115.670, 116.070); + mg_cubic_to(-116.250, 116.660, -162.640, 95.922, -174.990, 112.470); + mg_cubic_to(-174.990, 112.470, -168.250, 94.447, -116.550, 114.260); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 14) + { + mg_move_to(-119.150, 118.340); + mg_cubic_to(-119.150, 118.340, -117.550, 119.340, -118.040, 120.010); + mg_cubic_to(-118.530, 120.670, -167.310, 106.450, -177.290, 124.520); + mg_cubic_to(-177.290, 124.520, -173.070, 105.750, -119.150, 118.340); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 15) + { + mg_set_width(0.17200001); + mg_move_to(-119.150, 118.340); + mg_cubic_to(-119.150, 118.340, -117.550, 119.340, -118.040, 120.010); + mg_cubic_to(-118.530, 120.670, -167.310, 106.450, -177.290, 124.520); + mg_cubic_to(-177.290, 124.520, -173.070, 105.750, -119.150, 118.340); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 16) + { + mg_move_to(-108.420, 118.950); + mg_cubic_to(-108.420, 118.950, -107.300, 120.480, -108.000, 120.920); + mg_cubic_to(-108.700, 121.350, -148.770, 90.102, -164.730, 103.210); + mg_cubic_to(-164.730, 103.210, -153.860, 87.326, -108.420, 118.950); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 17) + { + mg_set_width(0.17200001); + mg_move_to(-108.420, 118.950); + mg_cubic_to(-108.420, 118.950, -107.300, 120.480, -108.000, 120.920); + mg_cubic_to(-108.700, 121.350, -148.770, 90.102, -164.730, 103.210); + mg_cubic_to(-164.730, 103.210, -153.860, 87.326, -108.420, 118.950); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 18) + { + mg_move_to(-128.200, 90.000); + mg_cubic_to(-128.200, 90.000, -127.600, 91.800, -128.400, 92.000); + mg_cubic_to(-129.200, 92.200, -157.800, 50.200, -177.000, 57.800); + mg_cubic_to(-177.000, 57.800, -161.800, 46.000, -128.200, 90.000); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 19) + { + mg_set_width(0.17200001); + mg_move_to(-128.200, 90.000); + mg_cubic_to(-128.200, 90.000, -127.600, 91.800, -128.400, 92.000); + mg_cubic_to(-129.200, 92.200, -157.800, 50.200, -177.000, 57.800); + mg_cubic_to(-177.000, 57.800, -161.800, 46.000, -128.200, 90.000); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 20) + { + mg_move_to(-127.500, 96.979); + mg_cubic_to(-127.500, 96.979, -126.530, 98.608, -127.270, 98.975); + mg_cubic_to(-128.010, 99.343, -164.990, 64.499, -182.100, 76.061); + mg_cubic_to(-182.100, 76.061, -169.800, 61.261, -127.500, 96.979); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 21) + { + mg_set_width(0.17200001); + mg_move_to(-127.500, 96.979); + mg_cubic_to(-127.500, 96.979, -126.530, 98.608, -127.270, 98.975); + mg_cubic_to(-128.010, 99.343, -164.990, 64.499, -182.100, 76.061); + mg_cubic_to(-182.100, 76.061, -169.800, 61.261, -127.500, 96.979); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 22) + { + mg_move_to(-127.620, 101.350); + mg_cubic_to(-127.620, 101.350, -126.500, 102.880, -127.200, 103.320); + mg_cubic_to(-127.900, 103.750, -167.970, 72.502, -183.930, 85.607); + mg_cubic_to(-183.930, 85.607, -173.060, 69.726, -127.620, 101.350); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 23) + { + mg_set_width(0.17200001); + mg_move_to(-127.620, 101.350); + mg_cubic_to(-127.620, 101.350, -126.500, 102.880, -127.200, 103.320); + mg_cubic_to(-127.900, 103.750, -167.970, 72.502, -183.930, 85.607); + mg_cubic_to(-183.930, 85.607, -173.060, 69.726, -127.620, 101.350); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 24) + { + mg_move_to(-129.830, 103.060); + mg_cubic_to(-129.330, 109.110, -128.340, 115.680, -126.600, 118.800); + mg_cubic_to(-126.600, 118.800, -130.200, 131.200, -121.400, 144.400); + mg_cubic_to(-121.400, 144.400, -121.800, 151.600, -120.200, 154.800); + mg_cubic_to(-120.200, 154.800, -116.200, 163.200, -111.400, 164.000); + mg_cubic_to(-107.520, 164.650, -98.793, 167.720, -88.932, 169.120); + mg_cubic_to(-88.932, 169.120, -71.800, 183.200, -75.000, 196.000); + mg_cubic_to(-75.000, 196.000, -75.400, 212.400, -79.000, 214.000); + mg_cubic_to(-79.000, 214.000, -67.400, 202.800, -77.000, 219.600); + mg_line_to(-81.400, 238.400); + mg_cubic_to(-81.400, 238.400, -55.800, 216.800, -71.400, 235.200); + mg_line_to(-81.400, 261.200); + mg_cubic_to(-81.400, 261.200, -61.800, 242.800, -69.000, 251.200); + mg_line_to(-72.200, 260.000); + mg_cubic_to(-72.200, 260.000, -29.000, 232.800, -59.800, 262.400); + mg_cubic_to(-59.800, 262.400, -51.800, 258.800, -47.400, 261.600); + mg_cubic_to(-47.400, 261.600, -40.600, 260.400, -41.400, 262.000); + mg_cubic_to(-41.400, 262.000, -62.200, 272.400, -65.800, 290.800); + mg_cubic_to(-65.800, 290.800, -57.400, 280.800, -60.600, 291.600); + mg_line_to(-60.200, 303.200); + mg_cubic_to(-60.200, 303.200, -56.200, 281.600, -56.600, 319.200); + mg_cubic_to(-56.600, 319.200, -37.400, 301.200, -49.000, 322.000); + mg_line_to(-49.000, 338.800); + mg_cubic_to(-49.000, 338.800, -33.800, 322.400, -40.200, 335.200); + mg_cubic_to(-40.200, 335.200, -30.200, 326.400, -34.200, 341.600); + mg_cubic_to(-34.200, 341.600, -35.000, 352.000, -30.600, 340.800); + mg_cubic_to(-30.600, 340.800, -14.600, 310.200, -20.600, 336.400); + mg_cubic_to(-20.600, 336.400, -21.400, 355.600, -16.600, 340.800); + mg_cubic_to(-16.600, 340.800, -16.200, 351.200, -7.000, 358.400); + mg_cubic_to(-7.000, 358.400, -8.200, 307.600, 4.600, 343.600); + mg_line_to(8.600, 360.000); + mg_cubic_to(8.600, 360.000, 11.400, 350.800, 11.000, 345.600); + mg_line_to(19.000, 353.600); + mg_cubic_to(19.000, 353.600, 34.200, 330.800, 31.000, 344.000); + mg_cubic_to(31.000, 344.000, 23.400, 360.000, 25.000, 364.800); + mg_cubic_to(25.000, 364.800, 41.800, 330.000, 43.000, 328.400); + mg_cubic_to(43.000, 328.400, 41.000, 370.800, 51.800, 334.800); + mg_cubic_to(51.800, 334.800, 57.400, 346.800, 54.600, 351.200); + mg_cubic_to(54.600, 351.200, 62.600, 343.200, 61.800, 340.000); + mg_cubic_to(61.800, 340.000, 66.400, 331.800, 69.200, 345.400); + mg_cubic_to(69.200, 345.400, 71.000, 354.800, 72.600, 351.600); + mg_cubic_to(72.600, 351.600, 76.600, 375.600, 77.800, 352.800); + mg_cubic_to(77.800, 352.800, 79.400, 339.200, 72.200, 327.600); + mg_cubic_to(72.200, 327.600, 73.000, 324.400, 70.200, 320.400); + mg_cubic_to(70.200, 320.400, 83.800, 342.000, 76.600, 313.200); + mg_cubic_to(76.600, 313.200, 87.801, 321.200, 89.001, 321.200); + mg_cubic_to(89.001, 321.200, 75.400, 298.000, 84.200, 302.800); + mg_cubic_to(84.200, 302.800, 79.000, 292.400, 97.001, 304.400); + mg_cubic_to(97.001, 304.400, 81.000, 288.400, 98.601, 298.000); + mg_cubic_to(98.601, 298.000, 106.600, 304.400, 99.001, 294.400); + mg_cubic_to(99.001, 294.400, 84.600, 278.400, 106.600, 296.400); + mg_cubic_to(106.600, 296.400, 118.200, 312.800, 119.000, 315.600); + mg_cubic_to(119.000, 315.600, 109.000, 286.400, 104.600, 283.600); + mg_cubic_to(104.600, 283.600, 113.000, 247.200, 154.200, 262.800); + mg_cubic_to(154.200, 262.800, 161.000, 280.000, 165.400, 261.600); + mg_cubic_to(165.400, 261.600, 178.200, 255.200, 189.400, 282.800); + mg_cubic_to(189.400, 282.800, 193.400, 269.200, 192.600, 266.400); + mg_cubic_to(192.600, 266.400, 199.400, 267.600, 198.600, 266.400); + mg_cubic_to(198.600, 266.400, 211.800, 270.800, 213.000, 270.000); + mg_cubic_to(213.000, 270.000, 219.800, 276.800, 220.200, 273.200); + mg_cubic_to(220.200, 273.200, 229.400, 276.000, 227.400, 272.400); + mg_cubic_to(227.400, 272.400, 236.200, 288.000, 236.600, 291.600); + mg_line_to(239.000, 277.600); + mg_line_to(241.000, 280.400); + mg_cubic_to(241.000, 280.400, 242.600, 272.800, 241.800, 271.600); + mg_cubic_to(241.000, 270.400, 261.800, 278.400, 266.600, 299.200); + mg_line_to(268.600, 307.600); + mg_cubic_to(268.600, 307.600, 274.600, 292.800, 273.000, 288.800); + mg_cubic_to(273.000, 288.800, 278.200, 289.600, 278.600, 294.000); + mg_cubic_to(278.600, 294.000, 282.600, 270.800, 277.800, 264.800); + mg_cubic_to(277.800, 264.800, 282.200, 264.000, 283.400, 267.600); + mg_line_to(283.400, 260.400); + mg_cubic_to(283.400, 260.400, 290.600, 261.200, 290.600, 258.800); + mg_cubic_to(290.600, 258.800, 295.000, 254.800, 297.000, 259.600); + mg_cubic_to(297.000, 259.600, 284.600, 224.400, 303.000, 243.600); + mg_cubic_to(303.000, 243.600, 310.200, 254.400, 306.600, 235.600); + mg_cubic_to(303.000, 216.800, 299.000, 215.200, 303.800, 214.800); + mg_cubic_to(303.800, 214.800, 304.600, 211.200, 302.600, 209.600); + mg_cubic_to(300.600, 208.000, 303.800, 209.600, 303.800, 209.600); + mg_cubic_to(303.800, 209.600, 308.600, 213.600, 303.400, 191.600); + mg_cubic_to(303.400, 191.600, 309.800, 193.200, 297.800, 164.000); + mg_cubic_to(297.800, 164.000, 300.600, 161.600, 296.600, 153.200); + mg_cubic_to(296.600, 153.200, 304.600, 157.600, 307.400, 156.000); + mg_cubic_to(307.400, 156.000, 307.000, 154.400, 303.800, 150.400); + mg_cubic_to(303.800, 150.400, 282.200, 95.600, 302.600, 117.600); + mg_cubic_to(302.600, 117.600, 314.450, 131.150, 308.050, 108.350); + mg_cubic_to(308.050, 108.350, 298.940, 84.341, 299.720, 80.045); + mg_line_to(-129.830, 103.060); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 25) + { + mg_set_width(1); + mg_move_to(-129.830, 103.060); + mg_cubic_to(-129.330, 109.110, -128.340, 115.680, -126.600, 118.800); + mg_cubic_to(-126.600, 118.800, -130.200, 131.200, -121.400, 144.400); + mg_cubic_to(-121.400, 144.400, -121.800, 151.600, -120.200, 154.800); + mg_cubic_to(-120.200, 154.800, -116.200, 163.200, -111.400, 164.000); + mg_cubic_to(-107.520, 164.650, -98.793, 167.720, -88.932, 169.120); + mg_cubic_to(-88.932, 169.120, -71.800, 183.200, -75.000, 196.000); + mg_cubic_to(-75.000, 196.000, -75.400, 212.400, -79.000, 214.000); + mg_cubic_to(-79.000, 214.000, -67.400, 202.800, -77.000, 219.600); + mg_line_to(-81.400, 238.400); + mg_cubic_to(-81.400, 238.400, -55.800, 216.800, -71.400, 235.200); + mg_line_to(-81.400, 261.200); + mg_cubic_to(-81.400, 261.200, -61.800, 242.800, -69.000, 251.200); + mg_line_to(-72.200, 260.000); + mg_cubic_to(-72.200, 260.000, -29.000, 232.800, -59.800, 262.400); + mg_cubic_to(-59.800, 262.400, -51.800, 258.800, -47.400, 261.600); + mg_cubic_to(-47.400, 261.600, -40.600, 260.400, -41.400, 262.000); + mg_cubic_to(-41.400, 262.000, -62.200, 272.400, -65.800, 290.800); + mg_cubic_to(-65.800, 290.800, -57.400, 280.800, -60.600, 291.600); + mg_line_to(-60.200, 303.200); + mg_cubic_to(-60.200, 303.200, -56.200, 281.600, -56.600, 319.200); + mg_cubic_to(-56.600, 319.200, -37.400, 301.200, -49.000, 322.000); + mg_line_to(-49.000, 338.800); + mg_cubic_to(-49.000, 338.800, -33.800, 322.400, -40.200, 335.200); + mg_cubic_to(-40.200, 335.200, -30.200, 326.400, -34.200, 341.600); + mg_cubic_to(-34.200, 341.600, -35.000, 352.000, -30.600, 340.800); + mg_cubic_to(-30.600, 340.800, -14.600, 310.200, -20.600, 336.400); + mg_cubic_to(-20.600, 336.400, -21.400, 355.600, -16.600, 340.800); + mg_cubic_to(-16.600, 340.800, -16.200, 351.200, -7.000, 358.400); + mg_cubic_to(-7.000, 358.400, -8.200, 307.600, 4.600, 343.600); + mg_line_to(8.600, 360.000); + mg_cubic_to(8.600, 360.000, 11.400, 350.800, 11.000, 345.600); + mg_line_to(19.000, 353.600); + mg_cubic_to(19.000, 353.600, 34.200, 330.800, 31.000, 344.000); + mg_cubic_to(31.000, 344.000, 23.400, 360.000, 25.000, 364.800); + mg_cubic_to(25.000, 364.800, 41.800, 330.000, 43.000, 328.400); + mg_cubic_to(43.000, 328.400, 41.000, 370.800, 51.800, 334.800); + mg_cubic_to(51.800, 334.800, 57.400, 346.800, 54.600, 351.200); + mg_cubic_to(54.600, 351.200, 62.600, 343.200, 61.800, 340.000); + mg_cubic_to(61.800, 340.000, 66.400, 331.800, 69.200, 345.400); + mg_cubic_to(69.200, 345.400, 71.000, 354.800, 72.600, 351.600); + mg_cubic_to(72.600, 351.600, 76.600, 375.600, 77.800, 352.800); + mg_cubic_to(77.800, 352.800, 79.400, 339.200, 72.200, 327.600); + mg_cubic_to(72.200, 327.600, 73.000, 324.400, 70.200, 320.400); + mg_cubic_to(70.200, 320.400, 83.800, 342.000, 76.600, 313.200); + mg_cubic_to(76.600, 313.200, 87.801, 321.200, 89.001, 321.200); + mg_cubic_to(89.001, 321.200, 75.400, 298.000, 84.200, 302.800); + mg_cubic_to(84.200, 302.800, 79.000, 292.400, 97.001, 304.400); + mg_cubic_to(97.001, 304.400, 81.000, 288.400, 98.601, 298.000); + mg_cubic_to(98.601, 298.000, 106.600, 304.400, 99.001, 294.400); + mg_cubic_to(99.001, 294.400, 84.600, 278.400, 106.600, 296.400); + mg_cubic_to(106.600, 296.400, 118.200, 312.800, 119.000, 315.600); + mg_cubic_to(119.000, 315.600, 109.000, 286.400, 104.600, 283.600); + mg_cubic_to(104.600, 283.600, 113.000, 247.200, 154.200, 262.800); + mg_cubic_to(154.200, 262.800, 161.000, 280.000, 165.400, 261.600); + mg_cubic_to(165.400, 261.600, 178.200, 255.200, 189.400, 282.800); + mg_cubic_to(189.400, 282.800, 193.400, 269.200, 192.600, 266.400); + mg_cubic_to(192.600, 266.400, 199.400, 267.600, 198.600, 266.400); + mg_cubic_to(198.600, 266.400, 211.800, 270.800, 213.000, 270.000); + mg_cubic_to(213.000, 270.000, 219.800, 276.800, 220.200, 273.200); + mg_cubic_to(220.200, 273.200, 229.400, 276.000, 227.400, 272.400); + mg_cubic_to(227.400, 272.400, 236.200, 288.000, 236.600, 291.600); + mg_line_to(239.000, 277.600); + mg_line_to(241.000, 280.400); + mg_cubic_to(241.000, 280.400, 242.600, 272.800, 241.800, 271.600); + mg_cubic_to(241.000, 270.400, 261.800, 278.400, 266.600, 299.200); + mg_line_to(268.600, 307.600); + mg_cubic_to(268.600, 307.600, 274.600, 292.800, 273.000, 288.800); + mg_cubic_to(273.000, 288.800, 278.200, 289.600, 278.600, 294.000); + mg_cubic_to(278.600, 294.000, 282.600, 270.800, 277.800, 264.800); + mg_cubic_to(277.800, 264.800, 282.200, 264.000, 283.400, 267.600); + mg_line_to(283.400, 260.400); + mg_cubic_to(283.400, 260.400, 290.600, 261.200, 290.600, 258.800); + mg_cubic_to(290.600, 258.800, 295.000, 254.800, 297.000, 259.600); + mg_cubic_to(297.000, 259.600, 284.600, 224.400, 303.000, 243.600); + mg_cubic_to(303.000, 243.600, 310.200, 254.400, 306.600, 235.600); + mg_cubic_to(303.000, 216.800, 299.000, 215.200, 303.800, 214.800); + mg_cubic_to(303.800, 214.800, 304.600, 211.200, 302.600, 209.600); + mg_cubic_to(300.600, 208.000, 303.800, 209.600, 303.800, 209.600); + mg_cubic_to(303.800, 209.600, 308.600, 213.600, 303.400, 191.600); + mg_cubic_to(303.400, 191.600, 309.800, 193.200, 297.800, 164.000); + mg_cubic_to(297.800, 164.000, 300.600, 161.600, 296.600, 153.200); + mg_cubic_to(296.600, 153.200, 304.600, 157.600, 307.400, 156.000); + mg_cubic_to(307.400, 156.000, 307.000, 154.400, 303.800, 150.400); + mg_cubic_to(303.800, 150.400, 282.200, 95.600, 302.600, 117.600); + mg_cubic_to(302.600, 117.600, 314.450, 131.150, 308.050, 108.350); + mg_cubic_to(308.050, 108.350, 298.940, 84.341, 299.720, 80.045); + mg_line_to(-129.830, 103.060); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 26) + { + mg_move_to(299.720, 80.245); + mg_cubic_to(300.340, 80.426, 302.550, 81.550, 303.800, 83.200); + mg_cubic_to(303.800, 83.200, 310.600, 94.000, 305.400, 75.600); + mg_cubic_to(305.400, 75.600, 296.200, 46.800, 305.000, 58.000); + mg_cubic_to(305.000, 58.000, 311.000, 65.200, 307.800, 51.600); + mg_cubic_to(303.940, 35.173, 301.400, 28.800, 301.400, 28.800); + mg_cubic_to(301.400, 28.800, 313.000, 33.600, 286.200, -6.000); + mg_line_to(295.000, -2.400); + mg_cubic_to(295.000, -2.400, 275.400, -42.000, 253.800, -47.200); + mg_line_to(245.800, -53.200); + mg_cubic_to(245.800, -53.200, 284.200, -91.200, 271.400, -128.000); + mg_cubic_to(271.400, -128.000, 264.600, -133.200, 255.000, -124.000); + mg_cubic_to(255.000, -124.000, 248.600, -119.200, 242.600, -120.800); + mg_cubic_to(242.600, -120.800, 211.800, -119.600, 209.800, -119.600); + mg_cubic_to(207.800, -119.600, 173.000, -156.800, 107.400, -139.200); + mg_cubic_to(107.400, -139.200, 102.200, -137.200, 97.801, -138.400); + mg_cubic_to(97.801, -138.400, 79.400, -154.400, 30.600, -131.600); + mg_cubic_to(30.600, -131.600, 20.600, -129.600, 19.000, -129.600); + mg_cubic_to(17.400, -129.600, 14.600, -129.600, 6.600, -123.200); + mg_cubic_to(-1.400, -116.800, -1.800, -116.000, -3.800, -114.400); + mg_cubic_to(-3.800, -114.400, -20.200, -103.200, -25.000, -102.400); + mg_cubic_to(-25.000, -102.400, -36.600, -96.000, -41.000, -86.000); + mg_line_to(-44.600, -84.800); + mg_cubic_to(-44.600, -84.800, -46.200, -77.600, -46.600, -76.400); + mg_cubic_to(-46.600, -76.400, -51.400, -72.800, -52.200, -67.200); + mg_cubic_to(-52.200, -67.200, -61.000, -61.200, -60.600, -56.800); + mg_cubic_to(-60.600, -56.800, -62.200, -51.600, -63.000, -46.800); + mg_cubic_to(-63.000, -46.800, -70.200, -42.000, -69.400, -39.200); + mg_cubic_to(-69.400, -39.200, -77.000, -25.200, -75.800, -18.400); + mg_cubic_to(-75.800, -18.400, -82.200, -18.800, -85.000, -16.400); + mg_cubic_to(-85.000, -16.400, -85.800, -11.600, -87.400, -11.200); + mg_cubic_to(-87.400, -11.200, -90.200, -10.000, -87.800, -6.000); + mg_cubic_to(-87.800, -6.000, -89.400, -3.200, -89.800, -1.600); + mg_cubic_to(-89.800, -1.600, -89.000, 1.200, -93.400, 6.800); + mg_cubic_to(-93.400, 6.800, -99.800, 25.600, -97.800, 30.800); + mg_cubic_to(-97.800, 30.800, -97.400, 35.600, -100.200, 37.200); + mg_cubic_to(-100.200, 37.200, -103.800, 36.800, -95.400, 48.800); + mg_cubic_to(-95.400, 48.800, -94.600, 50.000, -97.800, 52.400); + mg_cubic_to(-97.800, 52.400, -115.000, 56.000, -117.400, 72.400); + mg_cubic_to(-117.400, 72.400, -131.000, 87.200, -131.000, 92.400); + mg_cubic_to(-131.000, 94.705, -130.730, 97.852, -130.030, 102.460); + mg_cubic_to(-130.030, 102.460, -130.600, 110.800, -103.000, 111.600); + mg_cubic_to(-75.400, 112.400, 299.720, 80.245, 299.720, 80.245); + mg_close_path(); + mg_set_color_rgba(0.800, 0.447, 0.149, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 27) + { + mg_set_width(1); + mg_move_to(299.720, 80.245); + mg_cubic_to(300.340, 80.426, 302.550, 81.550, 303.800, 83.200); + mg_cubic_to(303.800, 83.200, 310.600, 94.000, 305.400, 75.600); + mg_cubic_to(305.400, 75.600, 296.200, 46.800, 305.000, 58.000); + mg_cubic_to(305.000, 58.000, 311.000, 65.200, 307.800, 51.600); + mg_cubic_to(303.940, 35.173, 301.400, 28.800, 301.400, 28.800); + mg_cubic_to(301.400, 28.800, 313.000, 33.600, 286.200, -6.000); + mg_line_to(295.000, -2.400); + mg_cubic_to(295.000, -2.400, 275.400, -42.000, 253.800, -47.200); + mg_line_to(245.800, -53.200); + mg_cubic_to(245.800, -53.200, 284.200, -91.200, 271.400, -128.000); + mg_cubic_to(271.400, -128.000, 264.600, -133.200, 255.000, -124.000); + mg_cubic_to(255.000, -124.000, 248.600, -119.200, 242.600, -120.800); + mg_cubic_to(242.600, -120.800, 211.800, -119.600, 209.800, -119.600); + mg_cubic_to(207.800, -119.600, 173.000, -156.800, 107.400, -139.200); + mg_cubic_to(107.400, -139.200, 102.200, -137.200, 97.801, -138.400); + mg_cubic_to(97.801, -138.400, 79.400, -154.400, 30.600, -131.600); + mg_cubic_to(30.600, -131.600, 20.600, -129.600, 19.000, -129.600); + mg_cubic_to(17.400, -129.600, 14.600, -129.600, 6.600, -123.200); + mg_cubic_to(-1.400, -116.800, -1.800, -116.000, -3.800, -114.400); + mg_cubic_to(-3.800, -114.400, -20.200, -103.200, -25.000, -102.400); + mg_cubic_to(-25.000, -102.400, -36.600, -96.000, -41.000, -86.000); + mg_line_to(-44.600, -84.800); + mg_cubic_to(-44.600, -84.800, -46.200, -77.600, -46.600, -76.400); + mg_cubic_to(-46.600, -76.400, -51.400, -72.800, -52.200, -67.200); + mg_cubic_to(-52.200, -67.200, -61.000, -61.200, -60.600, -56.800); + mg_cubic_to(-60.600, -56.800, -62.200, -51.600, -63.000, -46.800); + mg_cubic_to(-63.000, -46.800, -70.200, -42.000, -69.400, -39.200); + mg_cubic_to(-69.400, -39.200, -77.000, -25.200, -75.800, -18.400); + mg_cubic_to(-75.800, -18.400, -82.200, -18.800, -85.000, -16.400); + mg_cubic_to(-85.000, -16.400, -85.800, -11.600, -87.400, -11.200); + mg_cubic_to(-87.400, -11.200, -90.200, -10.000, -87.800, -6.000); + mg_cubic_to(-87.800, -6.000, -89.400, -3.200, -89.800, -1.600); + mg_cubic_to(-89.800, -1.600, -89.000, 1.200, -93.400, 6.800); + mg_cubic_to(-93.400, 6.800, -99.800, 25.600, -97.800, 30.800); + mg_cubic_to(-97.800, 30.800, -97.400, 35.600, -100.200, 37.200); + mg_cubic_to(-100.200, 37.200, -103.800, 36.800, -95.400, 48.800); + mg_cubic_to(-95.400, 48.800, -94.600, 50.000, -97.800, 52.400); + mg_cubic_to(-97.800, 52.400, -115.000, 56.000, -117.400, 72.400); + mg_cubic_to(-117.400, 72.400, -131.000, 87.200, -131.000, 92.400); + mg_cubic_to(-131.000, 94.705, -130.730, 97.852, -130.030, 102.460); + mg_cubic_to(-130.030, 102.460, -130.600, 110.800, -103.000, 111.600); + mg_cubic_to(-75.400, 112.400, 299.720, 80.245, 299.720, 80.245); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 28) + { + mg_move_to(-115.600, 102.600); + mg_cubic_to(-140.600, 63.200, -126.200, 119.600, -126.200, 119.600); + mg_cubic_to(-117.400, 154.000, 12.200, 116.400, 12.200, 116.400); + mg_cubic_to(12.200, 116.400, 181.000, 86.000, 192.200, 82.000); + mg_cubic_to(203.400, 78.000, 298.600, 84.400, 298.600, 84.400); + mg_line_to(293.000, 67.600); + mg_cubic_to(228.200, 21.200, 209.000, 44.400, 195.400, 40.400); + mg_cubic_to(181.800, 36.400, 184.200, 46.000, 181.000, 46.800); + mg_cubic_to(177.800, 47.600, 138.600, 22.800, 132.200, 23.600); + mg_cubic_to(125.800, 24.400, 100.460, 0.649, 115.400, 32.400); + mg_cubic_to(131.400, 66.400, 57.000, 71.600, 40.200, 60.400); + mg_cubic_to(23.400, 49.200, 47.400, 78.800, 47.400, 78.800); + mg_cubic_to(65.800, 98.800, 31.400, 82.000, 31.400, 82.000); + mg_cubic_to(-3.000, 69.200, -27.000, 94.800, -30.200, 95.600); + mg_cubic_to(-33.400, 96.400, -38.200, 99.600, -39.000, 93.200); + mg_cubic_to(-39.800, 86.800, -47.310, 70.099, -79.000, 96.400); + mg_cubic_to(-99.000, 113.000, -112.800, 91.000, -112.800, 91.000); + mg_line_to(-115.600, 102.600); + mg_close_path(); + mg_set_color_rgba(0.800, 0.447, 0.149, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 29) + { + mg_move_to(133.510, 25.346); + mg_cubic_to(127.110, 26.146, 101.740, 2.407, 116.710, 34.146); + mg_cubic_to(133.310, 69.346, 58.310, 73.346, 41.510, 62.146); + mg_cubic_to(24.709, 50.946, 48.710, 80.546, 48.710, 80.546); + mg_cubic_to(67.110, 100.550, 32.709, 83.746, 32.709, 83.746); + mg_cubic_to(-1.691, 70.946, -25.691, 96.546, -28.891, 97.346); + mg_cubic_to(-32.091, 98.146, -36.891, 101.350, -37.691, 94.946); + mg_cubic_to(-38.491, 88.546, -45.870, 72.012, -77.691, 98.146); + mg_cubic_to(-98.927, 115.490, -112.420, 94.037, -112.420, 94.037); + mg_line_to(-115.620, 104.150); + mg_cubic_to(-140.620, 64.346, -125.550, 122.660, -125.550, 122.660); + mg_cubic_to(-116.740, 157.060, 13.510, 118.150, 13.510, 118.150); + mg_cubic_to(13.510, 118.150, 182.310, 87.746, 193.510, 83.746); + mg_cubic_to(204.710, 79.746, 299.040, 86.073, 299.040, 86.073); + mg_line_to(293.510, 68.764); + mg_cubic_to(228.710, 22.364, 210.310, 46.146, 196.710, 42.146); + mg_cubic_to(183.110, 38.146, 185.510, 47.746, 182.310, 48.546); + mg_cubic_to(179.110, 49.346, 139.910, 24.546, 133.510, 25.346); + mg_close_path(); + mg_set_color_rgba(0.910, 0.498, 0.227, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 30) + { + mg_move_to(134.820, 27.091); + mg_cubic_to(128.420, 27.891, 103.680, 3.862, 118.020, 35.891); + mg_cubic_to(134.220, 72.092, 59.619, 75.092, 42.819, 63.892); + mg_cubic_to(26.019, 52.692, 50.019, 82.292, 50.019, 82.292); + mg_cubic_to(68.419, 102.290, 34.019, 85.492, 34.019, 85.492); + mg_cubic_to(-0.381, 72.692, -24.382, 98.292, -27.582, 99.092); + mg_cubic_to(-30.782, 99.892, -35.582, 103.090, -36.382, 96.692); + mg_cubic_to(-37.182, 90.292, -44.430, 73.925, -76.382, 99.892); + mg_cubic_to(-98.855, 117.980, -112.040, 97.074, -112.040, 97.074); + mg_line_to(-115.640, 105.690); + mg_cubic_to(-139.440, 66.692, -124.890, 125.710, -124.890, 125.710); + mg_cubic_to(-116.090, 160.110, 14.820, 119.890, 14.820, 119.890); + mg_cubic_to(14.820, 119.890, 183.620, 89.492, 194.820, 85.492); + mg_cubic_to(206.020, 81.492, 299.470, 87.746, 299.470, 87.746); + mg_line_to(294.020, 69.928); + mg_cubic_to(229.220, 23.528, 211.620, 47.891, 198.020, 43.891); + mg_cubic_to(184.420, 39.891, 186.820, 49.491, 183.620, 50.292); + mg_cubic_to(180.420, 51.092, 141.220, 26.291, 134.820, 27.091); + mg_close_path(); + mg_set_color_rgba(0.918, 0.549, 0.302, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 31) + { + mg_move_to(136.130, 28.837); + mg_cubic_to(129.730, 29.637, 105.000, 5.605, 119.330, 37.637); + mg_cubic_to(136.130, 75.193, 60.394, 76.482, 44.128, 65.637); + mg_cubic_to(27.328, 54.437, 51.328, 84.037, 51.328, 84.037); + mg_cubic_to(69.728, 104.040, 35.328, 87.237, 35.328, 87.237); + mg_cubic_to(0.928, 74.437, -23.072, 100.040, -26.272, 100.840); + mg_cubic_to(-29.472, 101.640, -34.272, 104.840, -35.072, 98.437); + mg_cubic_to(-35.872, 92.037, -42.989, 75.839, -75.073, 101.640); + mg_cubic_to(-98.782, 120.470, -111.660, 100.110, -111.660, 100.110); + mg_line_to(-115.660, 107.240); + mg_cubic_to(-137.460, 70.437, -124.240, 128.760, -124.240, 128.760); + mg_cubic_to(-115.440, 163.160, 16.130, 121.640, 16.130, 121.640); + mg_cubic_to(16.130, 121.640, 184.930, 91.237, 196.130, 87.237); + mg_cubic_to(207.330, 83.237, 299.910, 89.419, 299.910, 89.419); + mg_line_to(294.530, 71.092); + mg_cubic_to(229.730, 24.691, 212.930, 49.637, 199.330, 45.637); + mg_cubic_to(185.730, 41.637, 188.130, 51.237, 184.930, 52.037); + mg_cubic_to(181.730, 52.837, 142.530, 28.037, 136.130, 28.837); + mg_close_path(); + mg_set_color_rgba(0.925, 0.600, 0.380, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 32) + { + mg_move_to(137.440, 30.583); + mg_cubic_to(131.040, 31.383, 106.810, 7.129, 120.640, 39.383); + mg_cubic_to(137.440, 78.583, 62.237, 78.583, 45.437, 67.383); + mg_cubic_to(28.637, 56.183, 52.637, 85.783, 52.637, 85.783); + mg_cubic_to(71.037, 105.780, 36.637, 88.983, 36.637, 88.983); + mg_cubic_to(2.237, 76.183, -21.763, 101.780, -24.963, 102.580); + mg_cubic_to(-28.163, 103.380, -32.963, 106.580, -33.763, 100.180); + mg_cubic_to(-34.563, 93.783, -41.548, 77.752, -73.763, 103.380); + mg_cubic_to(-98.709, 122.960, -111.270, 103.150, -111.270, 103.150); + mg_line_to(-115.670, 108.780); + mg_cubic_to(-135.470, 73.982, -123.580, 131.820, -123.580, 131.820); + mg_cubic_to(-114.780, 166.220, 17.440, 123.380, 17.440, 123.380); + mg_cubic_to(17.440, 123.380, 186.240, 92.983, 197.440, 88.983); + mg_cubic_to(208.640, 84.983, 300.350, 91.092, 300.350, 91.092); + mg_line_to(295.040, 72.255); + mg_cubic_to(230.240, 25.855, 214.240, 51.383, 200.640, 47.383); + mg_cubic_to(187.040, 43.383, 189.440, 52.983, 186.240, 53.783); + mg_cubic_to(183.040, 54.583, 143.840, 29.783, 137.440, 30.583); + mg_close_path(); + mg_set_color_rgba(0.933, 0.647, 0.459, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 33) + { + mg_move_to(138.750, 32.328); + mg_cubic_to(132.350, 33.128, 106.380, 9.677, 121.950, 41.128); + mg_cubic_to(141.150, 79.928, 63.546, 80.328, 46.746, 69.128); + mg_cubic_to(29.946, 57.928, 53.946, 87.528, 53.946, 87.528); + mg_cubic_to(72.346, 107.530, 37.946, 90.728, 37.946, 90.728); + mg_cubic_to(3.546, 77.928, -20.454, 103.530, -23.654, 104.330); + mg_cubic_to(-26.854, 105.130, -31.654, 108.330, -32.454, 101.930); + mg_cubic_to(-33.254, 95.528, -40.108, 79.665, -72.454, 105.130); + mg_cubic_to(-98.636, 125.460, -110.890, 106.180, -110.890, 106.180); + mg_line_to(-115.690, 110.330); + mg_cubic_to(-133.690, 77.128, -122.930, 134.870, -122.930, 134.870); + mg_cubic_to(-114.130, 169.270, 18.750, 125.130, 18.750, 125.130); + mg_cubic_to(18.750, 125.130, 187.550, 94.728, 198.750, 90.728); + mg_cubic_to(209.950, 86.728, 300.780, 92.764, 300.780, 92.764); + mg_line_to(295.550, 73.419); + mg_cubic_to(230.750, 27.019, 215.550, 53.128, 201.950, 49.128); + mg_cubic_to(188.350, 45.128, 190.750, 54.728, 187.550, 55.528); + mg_cubic_to(184.350, 56.328, 145.150, 31.528, 138.750, 32.328); + mg_close_path(); + mg_set_color_rgba(0.945, 0.698, 0.533, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 34) + { + mg_move_to(140.060, 34.073); + mg_cubic_to(133.660, 34.873, 107.310, 11.613, 123.260, 42.873); + mg_cubic_to(143.660, 82.874, 64.855, 82.074, 48.055, 70.874); + mg_cubic_to(31.255, 59.674, 55.255, 89.274, 55.255, 89.274); + mg_cubic_to(73.655, 109.270, 39.255, 92.474, 39.255, 92.474); + mg_cubic_to(4.855, 79.674, -19.145, 105.270, -22.345, 106.070); + mg_cubic_to(-25.545, 106.870, -30.345, 110.070, -31.145, 103.670); + mg_cubic_to(-31.945, 97.274, -38.668, 81.578, -71.145, 106.870); + mg_cubic_to(-98.564, 127.950, -110.510, 109.220, -110.510, 109.220); + mg_line_to(-115.710, 111.870); + mg_cubic_to(-131.710, 81.674, -122.270, 137.930, -122.270, 137.930); + mg_cubic_to(-113.470, 172.330, 20.050, 126.870, 20.050, 126.870); + mg_cubic_to(20.050, 126.870, 188.850, 96.474, 200.050, 92.474); + mg_cubic_to(211.250, 88.474, 301.210, 94.437, 301.210, 94.437); + mg_line_to(296.050, 74.583); + mg_cubic_to(231.250, 28.183, 216.850, 54.874, 203.250, 50.874); + mg_cubic_to(189.650, 46.873, 192.050, 56.474, 188.850, 57.274); + mg_cubic_to(185.650, 58.074, 146.450, 33.273, 140.050, 34.073); + mg_close_path(); + mg_set_color_rgba(0.953, 0.749, 0.612, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 35) + { + mg_move_to(141.360, 35.819); + mg_cubic_to(134.960, 36.619, 107.520, 13.944, 124.560, 44.619); + mg_cubic_to(146.560, 84.219, 66.164, 83.819, 49.364, 72.619); + mg_cubic_to(32.564, 61.419, 56.564, 91.019, 56.564, 91.019); + mg_cubic_to(74.964, 111.020, 40.564, 94.219, 40.564, 94.219); + mg_cubic_to(6.164, 81.419, -17.836, 107.020, -21.036, 107.820); + mg_cubic_to(-24.236, 108.620, -29.036, 111.820, -29.836, 105.420); + mg_cubic_to(-30.636, 99.019, -37.227, 83.492, -69.836, 108.620); + mg_cubic_to(-98.491, 130.440, -110.130, 112.260, -110.130, 112.260); + mg_line_to(-115.730, 113.420); + mg_cubic_to(-130.130, 85.019, -121.620, 140.980, -121.620, 140.980); + mg_cubic_to(-112.820, 175.380, 21.360, 128.620, 21.360, 128.620); + mg_cubic_to(21.360, 128.620, 190.160, 98.219, 201.360, 94.219); + mg_cubic_to(212.560, 90.219, 301.660, 96.110, 301.660, 96.110); + mg_line_to(296.560, 75.746); + mg_cubic_to(231.760, 29.346, 218.160, 56.619, 204.560, 52.619); + mg_cubic_to(190.960, 48.619, 193.360, 58.219, 190.160, 59.019); + mg_cubic_to(186.960, 59.819, 147.760, 35.019, 141.360, 35.819); + mg_close_path(); + mg_set_color_rgba(0.961, 0.800, 0.690, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 36) + { + mg_move_to(142.670, 37.565); + mg_cubic_to(136.270, 38.365, 108.830, 15.689, 125.870, 46.365); + mg_cubic_to(147.870, 85.965, 67.474, 85.565, 50.674, 74.365); + mg_cubic_to(33.874, 63.165, 57.874, 92.765, 57.874, 92.765); + mg_cubic_to(76.274, 112.760, 41.874, 95.965, 41.874, 95.965); + mg_cubic_to(7.473, 83.165, -16.527, 108.760, -19.727, 109.560); + mg_cubic_to(-22.927, 110.360, -27.727, 113.560, -28.527, 107.160); + mg_cubic_to(-29.327, 100.760, -35.786, 85.405, -68.527, 110.360); + mg_cubic_to(-98.418, 132.930, -109.740, 115.290, -109.740, 115.290); + mg_line_to(-115.740, 114.960); + mg_cubic_to(-129.350, 88.564, -120.960, 144.040, -120.960, 144.040); + mg_cubic_to(-112.160, 178.440, 22.670, 130.360, 22.670, 130.360); + mg_cubic_to(22.670, 130.360, 191.470, 99.965, 202.670, 95.965); + mg_cubic_to(213.870, 91.965, 302.090, 97.783, 302.090, 97.783); + mg_line_to(297.080, 76.910); + mg_cubic_to(232.270, 30.510, 219.470, 58.365, 205.870, 54.365); + mg_cubic_to(192.270, 50.365, 194.670, 59.965, 191.470, 60.765); + mg_cubic_to(188.270, 61.565, 149.070, 36.765, 142.670, 37.565); + mg_close_path(); + mg_set_color_rgba(0.973, 0.847, 0.769, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 37) + { + mg_move_to(143.980, 39.310); + mg_cubic_to(137.580, 40.110, 110.530, 17.223, 127.180, 48.110); + mg_cubic_to(149.180, 88.910, 68.783, 87.310, 51.983, 76.110); + mg_cubic_to(35.183, 64.910, 59.183, 94.510, 59.183, 94.510); + mg_cubic_to(77.583, 114.510, 43.183, 97.710, 43.183, 97.710); + mg_cubic_to(8.783, 84.910, -15.217, 110.510, -18.417, 111.310); + mg_cubic_to(-21.618, 112.110, -26.418, 115.310, -27.218, 108.910); + mg_cubic_to(-28.018, 102.510, -34.346, 87.318, -67.218, 112.110); + mg_cubic_to(-98.345, 135.420, -109.360, 118.330, -109.360, 118.330); + mg_line_to(-115.760, 116.510); + mg_cubic_to(-128.760, 92.510, -120.310, 147.090, -120.310, 147.090); + mg_cubic_to(-111.510, 181.490, 23.980, 132.110, 23.980, 132.110); + mg_cubic_to(23.980, 132.110, 192.780, 101.710, 203.980, 97.710); + mg_cubic_to(215.180, 93.710, 302.530, 99.456, 302.530, 99.456); + mg_line_to(297.580, 78.074); + mg_cubic_to(232.780, 31.673, 220.780, 60.110, 207.180, 56.110); + mg_cubic_to(193.580, 52.110, 195.980, 61.710, 192.780, 62.510); + mg_cubic_to(189.580, 63.310, 150.380, 38.510, 143.980, 39.310); + mg_close_path(); + mg_set_color_rgba(0.980, 0.898, 0.843, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 38) + { + mg_move_to(145.290, 41.055); + mg_cubic_to(138.890, 41.855, 112.920, 18.411, 128.490, 49.855); + mg_cubic_to(149.690, 92.656, 70.092, 89.056, 53.292, 77.856); + mg_cubic_to(36.492, 66.656, 60.492, 96.256, 60.492, 96.256); + mg_cubic_to(78.892, 116.260, 44.492, 99.456, 44.492, 99.456); + mg_cubic_to(10.092, 86.656, -13.908, 112.260, -17.108, 113.060); + mg_cubic_to(-20.308, 113.860, -25.108, 117.060, -25.908, 110.660); + mg_cubic_to(-26.708, 104.260, -32.905, 89.232, -65.908, 113.860); + mg_cubic_to(-98.273, 137.910, -108.980, 121.360, -108.980, 121.360); + mg_line_to(-115.780, 118.060); + mg_cubic_to(-128.580, 94.856, -119.650, 150.150, -119.650, 150.150); + mg_cubic_to(-110.850, 184.550, 25.290, 133.860, 25.290, 133.860); + mg_cubic_to(25.290, 133.860, 194.090, 103.460, 205.290, 99.456); + mg_cubic_to(216.490, 95.456, 302.960, 101.130, 302.960, 101.130); + mg_line_to(298.090, 79.237); + mg_cubic_to(233.290, 32.837, 222.090, 61.856, 208.490, 57.856); + mg_cubic_to(194.890, 53.855, 197.290, 63.456, 194.090, 64.256); + mg_cubic_to(190.890, 65.056, 151.690, 40.255, 145.290, 41.055); + mg_close_path(); + mg_set_color_rgba(0.988, 0.949, 0.922, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 39) + { + mg_move_to(-115.800, 119.600); + mg_cubic_to(-128.600, 97.600, -119.000, 153.200, -119.000, 153.200); + mg_cubic_to(-110.200, 187.600, 26.600, 135.600, 26.600, 135.600); + mg_cubic_to(26.600, 135.600, 195.400, 105.200, 206.600, 101.200); + mg_cubic_to(217.800, 97.200, 303.400, 102.800, 303.400, 102.800); + mg_line_to(298.600, 80.400); + mg_cubic_to(233.800, 34.000, 223.400, 63.600, 209.800, 59.600); + mg_cubic_to(196.200, 55.600, 198.600, 65.200, 195.400, 66.000); + mg_cubic_to(192.200, 66.800, 153.000, 42.000, 146.600, 42.800); + mg_cubic_to(140.200, 43.600, 114.980, 19.793, 129.800, 51.600); + mg_cubic_to(152.030, 99.307, 69.041, 89.227, 54.600, 79.600); + mg_cubic_to(37.800, 68.400, 61.800, 98.000, 61.800, 98.000); + mg_cubic_to(80.200, 118.000, 45.800, 101.200, 45.800, 101.200); + mg_cubic_to(11.400, 88.400, -12.600, 114.000, -15.800, 114.800); + mg_cubic_to(-19.000, 115.600, -23.800, 118.800, -24.600, 112.400); + mg_cubic_to(-25.400, 106.000, -31.465, 91.144, -64.600, 115.600); + mg_cubic_to(-98.200, 140.400, -108.600, 124.400, -108.600, 124.400); + mg_line_to(-115.800, 119.600); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 40) + { + mg_move_to(-74.200, 149.600); + mg_cubic_to(-74.200, 149.600, -81.400, 161.200, -60.600, 174.400); + mg_cubic_to(-60.600, 174.400, -59.200, 175.800, -77.200, 171.600); + mg_cubic_to(-77.200, 171.600, -83.400, 169.600, -85.000, 159.200); + mg_cubic_to(-85.000, 159.200, -89.800, 154.800, -94.600, 149.200); + mg_cubic_to(-99.400, 143.600, -74.200, 149.600, -74.200, 149.600); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 41) + { + mg_move_to(65.800, 102.000); + mg_cubic_to(65.800, 102.000, 83.498, 128.820, 82.900, 133.600); + mg_cubic_to(81.600, 144.000, 81.400, 153.600, 84.600, 157.600); + mg_cubic_to(87.801, 161.600, 96.601, 194.800, 96.601, 194.800); + mg_cubic_to(96.601, 194.800, 96.201, 196.000, 108.600, 158.000); + mg_cubic_to(108.600, 158.000, 120.200, 142.000, 100.200, 123.600); + mg_cubic_to(100.200, 123.600, 65.000, 94.800, 65.800, 102.000); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 42) + { + mg_move_to(-54.200, 176.400); + mg_cubic_to(-54.200, 176.400, -43.000, 183.600, -57.400, 214.800); + mg_line_to(-51.000, 212.400); + mg_cubic_to(-51.000, 212.400, -51.800, 223.600, -55.000, 226.000); + mg_line_to(-47.800, 222.800); + mg_cubic_to(-47.800, 222.800, -43.000, 230.800, -47.000, 235.600); + mg_cubic_to(-47.000, 235.600, -30.200, 243.600, -31.000, 250.000); + mg_cubic_to(-31.000, 250.000, -24.600, 242.000, -28.600, 235.600); + mg_cubic_to(-32.600, 229.200, -39.800, 233.200, -39.000, 214.800); + mg_line_to(-47.800, 218.000); + mg_cubic_to(-47.800, 218.000, -42.200, 209.200, -42.200, 202.800); + mg_line_to(-50.200, 205.200); + mg_cubic_to(-50.200, 205.200, -34.731, 178.620, -45.400, 177.200); + mg_cubic_to(-51.400, 176.400, -54.200, 176.400, -54.200, 176.400); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 43) + { + mg_move_to(-21.800, 193.200); + mg_cubic_to(-21.800, 193.200, -19.000, 188.800, -21.800, 189.600); + mg_cubic_to(-24.600, 190.400, -55.800, 205.200, -61.800, 214.800); + mg_cubic_to(-61.800, 214.800, -27.400, 190.400, -21.800, 193.200); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 44) + { + mg_move_to(-11.400, 201.200); + mg_cubic_to(-11.400, 201.200, -8.600, 196.800, -11.400, 197.600); + mg_cubic_to(-14.200, 198.400, -45.400, 213.200, -51.400, 222.800); + mg_cubic_to(-51.400, 222.800, -17.000, 198.400, -11.400, 201.200); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 45) + { + mg_move_to(1.800, 186.000); + mg_cubic_to(1.800, 186.000, 4.600, 181.600, 1.800, 182.400); + mg_cubic_to(-1.000, 183.200, -32.200, 198.000, -38.200, 207.600); + mg_cubic_to(-38.200, 207.600, -3.800, 183.200, 1.800, 186.000); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 46) + { + mg_move_to(-21.400, 229.600); + mg_cubic_to(-21.400, 229.600, -21.400, 223.600, -24.200, 224.400); + mg_cubic_to(-27.000, 225.200, -63.000, 242.800, -69.000, 252.400); + mg_cubic_to(-69.000, 252.400, -27.000, 226.800, -21.400, 229.600); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 47) + { + mg_move_to(-20.200, 218.800); + mg_cubic_to(-20.200, 218.800, -19.000, 214.000, -21.800, 214.800); + mg_cubic_to(-23.800, 214.800, -50.200, 226.400, -56.200, 236.000); + mg_cubic_to(-56.200, 236.000, -26.600, 214.400, -20.200, 218.800); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 48) + { + mg_move_to(-34.600, 266.400); + mg_move_to(-44.600, 274.000); + mg_cubic_to(-44.600, 274.000, -34.200, 266.400, -30.600, 267.600); + mg_cubic_to(-30.600, 267.600, -37.400, 278.800, -38.200, 284.000); + mg_cubic_to(-38.200, 284.000, -27.800, 271.200, -22.200, 271.600); + mg_cubic_to(-22.200, 271.600, -14.600, 272.000, -14.600, 282.800); + mg_cubic_to(-14.600, 282.800, -9.000, 272.400, -5.800, 272.800); + mg_cubic_to(-5.800, 272.800, -4.600, 279.200, -5.800, 286.000); + mg_cubic_to(-5.800, 286.000, -1.800, 278.400, 2.200, 280.000); + mg_cubic_to(2.200, 280.000, 8.600, 278.000, 7.800, 289.600); + mg_cubic_to(7.800, 289.600, 7.800, 300.000, 7.000, 302.800); + mg_cubic_to(7.000, 302.800, 12.600, 276.400, 15.000, 276.000); + mg_cubic_to(15.000, 276.000, 23.000, 274.800, 27.800, 283.600); + mg_cubic_to(27.800, 283.600, 23.800, 276.000, 28.600, 278.000); + mg_cubic_to(28.600, 278.000, 39.400, 279.600, 42.600, 286.400); + mg_cubic_to(42.600, 286.400, 35.800, 274.400, 41.400, 277.600); + mg_line_to(49.400, 284.000); + mg_cubic_to(49.400, 284.000, 57.800, 305.200, 59.800, 306.800); + mg_cubic_to(59.800, 306.800, 52.200, 285.200, 53.800, 285.200); + mg_cubic_to(53.800, 285.200, 51.800, 273.200, 57.000, 288.000); + mg_cubic_to(57.000, 288.000, 53.800, 274.000, 59.400, 274.800); + mg_cubic_to(65.000, 275.600, 69.400, 285.600, 77.800, 283.200); + mg_cubic_to(77.800, 283.200, 87.401, 288.800, 89.401, 219.600); + mg_line_to(-34.599, 266.400); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 49) + { + mg_move_to(-29.800, 173.600); + mg_cubic_to(-29.800, 173.600, -15.000, 167.600, 25.000, 173.600); + mg_cubic_to(25.000, 173.600, 32.200, 174.000, 39.000, 165.200); + mg_cubic_to(45.800, 156.400, 72.600, 149.200, 79.000, 151.200); + mg_line_to(88.601, 157.600); + mg_line_to(89.401, 158.800); + mg_cubic_to(89.401, 158.800, 101.800, 169.200, 102.200, 176.800); + mg_cubic_to(102.600, 184.400, 87.801, 232.400, 78.200, 248.400); + mg_cubic_to(68.600, 264.400, 59.000, 276.800, 39.800, 274.400); + mg_cubic_to(39.800, 274.400, 19.000, 270.400, -6.600, 274.400); + mg_cubic_to(-6.600, 274.400, -35.800, 272.800, -38.600, 264.800); + mg_cubic_to(-41.400, 256.800, -27.400, 241.600, -27.400, 241.600); + mg_cubic_to(-27.400, 241.600, -23.000, 233.200, -24.200, 218.800); + mg_cubic_to(-25.400, 204.400, -25.000, 176.400, -29.800, 173.600); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 50) + { + mg_move_to(-7.800, 175.600); + mg_cubic_to(0.600, 194.000, -29.000, 259.200, -29.000, 259.200); + mg_cubic_to(-31.000, 260.800, -16.340, 266.850, -6.200, 264.400); + mg_cubic_to(4.746, 261.760, 45.000, 266.000, 45.000, 266.000); + mg_cubic_to(68.600, 250.400, 81.400, 206.000, 81.400, 206.000); + mg_cubic_to(81.400, 206.000, 91.801, 182.000, 74.200, 178.800); + mg_cubic_to(56.600, 175.600, -7.800, 175.600, -7.800, 175.600); + mg_close_path(); + mg_set_color_rgba(0.898, 0.400, 0.549, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 51) + { + mg_move_to(-9.831, 206.500); + mg_cubic_to(-6.505, 193.710, -4.921, 181.910, -7.800, 175.600); + mg_cubic_to(-7.800, 175.600, 54.600, 182.000, 65.800, 161.200); + mg_cubic_to(70.041, 153.330, 84.801, 184.000, 84.400, 193.600); + mg_cubic_to(84.400, 193.600, 21.400, 208.000, 6.600, 196.800); + mg_line_to(-9.831, 206.500); + mg_close_path(); + mg_set_color_rgba(0.698, 0.196, 0.349, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 52) + { + mg_move_to(-5.400, 222.800); + mg_cubic_to(-5.400, 222.800, -3.400, 230.000, -5.800, 234.000); + mg_cubic_to(-5.800, 234.000, -7.400, 234.800, -8.600, 235.200); + mg_cubic_to(-8.600, 235.200, -7.400, 238.800, -1.400, 240.400); + mg_cubic_to(-1.400, 240.400, 0.600, 244.800, 3.000, 245.200); + mg_cubic_to(5.400, 245.600, 10.200, 251.200, 14.200, 250.000); + mg_cubic_to(18.200, 248.800, 29.400, 244.800, 29.400, 244.800); + mg_cubic_to(29.400, 244.800, 35.000, 241.600, 43.800, 245.200); + mg_cubic_to(43.800, 245.200, 46.175, 244.400, 46.600, 240.400); + mg_cubic_to(47.100, 235.700, 50.200, 232.000, 52.200, 230.000); + mg_cubic_to(54.200, 228.000, 63.800, 215.200, 62.600, 214.800); + mg_cubic_to(61.400, 214.400, -5.400, 222.800, -5.400, 222.800); + mg_close_path(); + mg_set_color_rgba(0.647, 0.149, 0.298, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 53) + { + mg_move_to(-9.800, 174.400); + mg_cubic_to(-9.800, 174.400, -12.600, 196.800, -9.400, 205.200); + mg_cubic_to(-6.200, 213.600, -7.000, 215.600, -7.800, 219.600); + mg_cubic_to(-8.600, 223.600, -4.200, 233.600, 1.400, 239.600); + mg_line_to(13.400, 241.200); + mg_cubic_to(13.400, 241.200, 28.600, 237.600, 37.800, 240.400); + mg_cubic_to(37.800, 240.400, 46.794, 241.740, 50.200, 226.800); + mg_cubic_to(50.200, 226.800, 55.000, 220.400, 62.200, 217.600); + mg_cubic_to(69.400, 214.800, 76.600, 173.200, 72.600, 165.200); + mg_cubic_to(68.600, 157.200, 54.200, 152.800, 38.200, 168.400); + mg_cubic_to(22.200, 184.000, 20.200, 167.200, -9.800, 174.400); + mg_close_path(); + mg_set_color_rgba(1.000, 0.447, 0.498, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 54) + { + mg_set_width(1); + mg_move_to(-9.800, 174.400); + mg_cubic_to(-9.800, 174.400, -12.600, 196.800, -9.400, 205.200); + mg_cubic_to(-6.200, 213.600, -7.000, 215.600, -7.800, 219.600); + mg_cubic_to(-8.600, 223.600, -4.200, 233.600, 1.400, 239.600); + mg_line_to(13.400, 241.200); + mg_cubic_to(13.400, 241.200, 28.600, 237.600, 37.800, 240.400); + mg_cubic_to(37.800, 240.400, 46.794, 241.740, 50.200, 226.800); + mg_cubic_to(50.200, 226.800, 55.000, 220.400, 62.200, 217.600); + mg_cubic_to(69.400, 214.800, 76.600, 173.200, 72.600, 165.200); + mg_cubic_to(68.600, 157.200, 54.200, 152.800, 38.200, 168.400); + mg_cubic_to(22.200, 184.000, 20.200, 167.200, -9.800, 174.400); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 55) + { + mg_move_to(-8.200, 249.200); + mg_cubic_to(-8.200, 249.200, -9.000, 247.200, -13.400, 246.800); + mg_cubic_to(-13.400, 246.800, -35.800, 243.200, -44.200, 230.800); + mg_cubic_to(-44.200, 230.800, -51.000, 225.200, -46.600, 236.800); + mg_cubic_to(-46.600, 236.800, -36.200, 257.200, -29.400, 260.000); + mg_cubic_to(-29.400, 260.000, -13.000, 264.000, -8.200, 249.200); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 0.800, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 56) + { + mg_set_width(0.5); + mg_move_to(-8.200, 249.200); + mg_cubic_to(-8.200, 249.200, -9.000, 247.200, -13.400, 246.800); + mg_cubic_to(-13.400, 246.800, -35.800, 243.200, -44.200, 230.800); + mg_cubic_to(-44.200, 230.800, -51.000, 225.200, -46.600, 236.800); + mg_cubic_to(-46.600, 236.800, -36.200, 257.200, -29.400, 260.000); + mg_cubic_to(-29.400, 260.000, -13.000, 264.000, -8.200, 249.200); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 57) + { + mg_move_to(71.742, 185.230); + mg_cubic_to(72.401, 177.320, 74.354, 168.710, 72.600, 165.200); + mg_cubic_to(66.154, 152.310, 49.181, 157.700, 38.200, 168.400); + mg_cubic_to(22.200, 184.000, 20.200, 167.200, -9.800, 174.400); + mg_cubic_to(-9.800, 174.400, -11.545, 188.360, -10.705, 198.380); + mg_cubic_to(-10.705, 198.380, 26.600, 186.800, 27.400, 192.400); + mg_cubic_to(27.400, 192.400, 29.000, 189.200, 38.200, 189.200); + mg_cubic_to(47.400, 189.200, 70.142, 188.030, 71.742, 185.230); + mg_close_path(); + mg_set_color_rgba(0.800, 0.247, 0.298, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 58) + { + mg_move_to(28.600, 175.200); + mg_cubic_to(28.600, 175.200, 33.400, 180.000, 29.800, 189.600); + mg_cubic_to(29.800, 189.600, 15.400, 205.600, 17.400, 219.600); + } + if(!singlePath || singlePathIndex == 59) + { + mg_set_width(2); + mg_set_color_rgba(0.647, 0.098, 0.149, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 60) + { + mg_move_to(-19.400, 260.000); + mg_cubic_to(-19.400, 260.000, -23.800, 247.200, -15.000, 254.000); + mg_line_to(-11.400, 257.600); + mg_cubic_to(-12.600, 259.200, -18.200, 263.200, -19.400, 260.000); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 0.800, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 61) + { + mg_set_width(0.5); + mg_move_to(-19.400, 260.000); + mg_cubic_to(-19.400, 260.000, -23.800, 247.200, -15.000, 254.000); + mg_line_to(-11.400, 257.600); + mg_cubic_to(-12.600, 259.200, -18.200, 263.200, -19.400, 260.000); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 62) + { + mg_move_to(-14.360, 261.200); + mg_cubic_to(-14.360, 261.200, -17.880, 250.960, -10.840, 256.400); + mg_line_to(-7.960, 259.280); + mg_cubic_to(-12.520, 260.560, -7.960, 263.120, -14.360, 261.200); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 0.800, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 63) + { + mg_set_width(0.5); + mg_move_to(-14.360, 261.200); + mg_cubic_to(-14.360, 261.200, -17.880, 250.960, -10.840, 256.400); + mg_line_to(-7.960, 259.280); + mg_cubic_to(-12.520, 260.560, -7.960, 263.120, -14.360, 261.200); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 64) + { + mg_move_to(-9.560, 261.200); + mg_cubic_to(-9.560, 261.200, -13.080, 250.960, -6.040, 256.400); + mg_line_to(-3.160, 259.280); + mg_cubic_to(-6.520, 260.560, -3.160, 263.120, -9.560, 261.200); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 0.800, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 65) + { + mg_set_width(0.5); + mg_move_to(-9.560, 261.200); + mg_cubic_to(-9.560, 261.200, -13.080, 250.960, -6.040, 256.400); + mg_line_to(-3.160, 259.280); + mg_cubic_to(-6.520, 260.560, -3.160, 263.120, -9.560, 261.200); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 66) + { + mg_move_to(-2.960, 261.400); + mg_cubic_to(-2.960, 261.400, -6.480, 251.160, 0.560, 256.600); + mg_cubic_to(0.560, 256.600, 4.943, 258.930, 3.441, 259.480); + mg_cubic_to(0.480, 260.560, 3.441, 263.320, -2.960, 261.400); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 0.800, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 67) + { + mg_set_width(0.5); + mg_move_to(-2.960, 261.400); + mg_cubic_to(-2.960, 261.400, -6.480, 251.160, 0.560, 256.600); + mg_cubic_to(0.560, 256.600, 4.943, 258.930, 3.441, 259.480); + mg_cubic_to(0.480, 260.560, 3.441, 263.320, -2.960, 261.400); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 68) + { + mg_move_to(3.520, 261.320); + mg_cubic_to(3.520, 261.320, 0.000, 251.080, 7.041, 256.520); + mg_line_to(9.921, 259.400); + mg_cubic_to(8.961, 260.680, 9.921, 263.240, 3.520, 261.320); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 0.800, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 69) + { + mg_set_width(0.5); + mg_move_to(3.520, 261.320); + mg_cubic_to(3.520, 261.320, 0.000, 251.080, 7.041, 256.520); + mg_line_to(9.921, 259.400); + mg_cubic_to(8.961, 260.680, 9.921, 263.240, 3.520, 261.320); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 70) + { + mg_move_to(10.200, 262.000); + mg_cubic_to(10.200, 262.000, 5.400, 249.600, 14.600, 256.000); + mg_line_to(18.200, 259.600); + mg_cubic_to(17.000, 261.200, 18.200, 264.400, 10.200, 262.000); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 0.800, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 71) + { + mg_set_width(0.5); + mg_move_to(10.200, 262.000); + mg_cubic_to(10.200, 262.000, 5.400, 249.600, 14.600, 256.000); + mg_line_to(18.200, 259.600); + mg_cubic_to(17.000, 261.200, 18.200, 264.400, 10.200, 262.000); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 72) + { + mg_move_to(-18.200, 244.800); + mg_cubic_to(-18.200, 244.800, -5.000, 242.000, 1.000, 245.200); + mg_cubic_to(1.000, 245.200, 7.000, 246.400, 8.200, 246.000); + mg_cubic_to(9.400, 245.600, 12.600, 245.200, 12.600, 245.200); + } + if(!singlePath || singlePathIndex == 73) + { + mg_set_width(2); + mg_set_color_rgba(0.647, 0.149, 0.298, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 74) + { + mg_move_to(15.800, 253.600); + mg_cubic_to(15.800, 253.600, 27.800, 240.000, 39.800, 244.400); + mg_cubic_to(46.816, 246.970, 45.800, 243.600, 46.600, 240.800); + mg_cubic_to(47.400, 238.000, 47.600, 233.800, 52.600, 230.800); + } + if(!singlePath || singlePathIndex == 75) + { + mg_set_width(2); + mg_set_color_rgba(0.647, 0.149, 0.298, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 76) + { + mg_move_to(33.000, 237.600); + mg_cubic_to(33.000, 237.600, 29.000, 226.800, 26.200, 239.600); + mg_cubic_to(23.400, 252.400, 20.200, 256.000, 18.600, 258.800); + mg_cubic_to(18.600, 258.800, 18.600, 264.000, 27.000, 263.600); + mg_cubic_to(27.000, 263.600, 37.800, 263.200, 38.200, 260.400); + mg_cubic_to(38.600, 257.600, 37.000, 246.000, 33.000, 237.600); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 0.800, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 77) + { + mg_set_width(0.5); + mg_move_to(33.000, 237.600); + mg_cubic_to(33.000, 237.600, 29.000, 226.800, 26.200, 239.600); + mg_cubic_to(23.400, 252.400, 20.200, 256.000, 18.600, 258.800); + mg_cubic_to(18.600, 258.800, 18.600, 264.000, 27.000, 263.600); + mg_cubic_to(27.000, 263.600, 37.800, 263.200, 38.200, 260.400); + mg_cubic_to(38.600, 257.600, 37.000, 246.000, 33.000, 237.600); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 78) + { + mg_move_to(47.000, 244.800); + mg_cubic_to(47.000, 244.800, 50.600, 242.400, 53.000, 243.600); + } + if(!singlePath || singlePathIndex == 79) + { + mg_set_width(2); + mg_set_color_rgba(0.647, 0.149, 0.298, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 80) + { + mg_move_to(53.500, 228.400); + mg_cubic_to(53.500, 228.400, 56.400, 223.500, 61.200, 222.700); + } + if(!singlePath || singlePathIndex == 81) + { + mg_set_width(2); + mg_set_color_rgba(0.647, 0.149, 0.298, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 82) + { + mg_move_to(-25.800, 265.200); + mg_cubic_to(-25.800, 265.200, -7.800, 268.400, -3.400, 266.800); + mg_line_to(-3.000, 268.800); + mg_line_to(-23.800, 267.600); + mg_cubic_to(-23.800, 267.600, -35.400, 262.000, -25.800, 265.200); + mg_close_path(); + mg_set_color_rgba(0.698, 0.698, 0.698, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 83) + { + mg_move_to(-11.800, 172.000); + mg_move_to(7.800, 172.800); + mg_cubic_to(7.800, 172.800, 15.000, 203.600, 11.400, 211.200); + mg_cubic_to(11.400, 211.200, 10.200, 214.000, 7.400, 208.400); + mg_cubic_to(7.400, 208.400, -11.000, 175.600, -14.200, 173.600); + mg_cubic_to(-17.400, 171.600, -13.000, 172.000, -11.800, 172.000); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 0.800, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 84) + { + mg_set_width(0.5); + mg_move_to(-11.800, 172.000); + mg_move_to(7.800, 172.800); + mg_cubic_to(7.800, 172.800, 15.000, 203.600, 11.400, 211.200); + mg_cubic_to(11.400, 211.200, 10.200, 214.000, 7.400, 208.400); + mg_cubic_to(7.400, 208.400, -11.000, 175.600, -14.200, 173.600); + mg_cubic_to(-17.400, 171.600, -13.000, 172.000, -11.800, 172.000); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 85) + { + mg_move_to(-88.900, 169.300); + mg_cubic_to(-88.900, 169.300, -80.000, 171.000, -67.400, 173.600); + mg_cubic_to(-67.400, 173.600, -62.600, 196.000, -59.400, 200.800); + mg_cubic_to(-56.200, 205.600, -59.800, 205.600, -63.400, 202.800); + mg_cubic_to(-67.000, 200.000, -81.800, 186.000, -83.800, 181.600); + mg_cubic_to(-85.800, 177.200, -88.900, 169.300, -88.900, 169.300); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 0.800, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 86) + { + mg_set_width(0.5); + mg_move_to(-88.900, 169.300); + mg_cubic_to(-88.900, 169.300, -80.000, 171.000, -67.400, 173.600); + mg_cubic_to(-67.400, 173.600, -62.600, 196.000, -59.400, 200.800); + mg_cubic_to(-56.200, 205.600, -59.800, 205.600, -63.400, 202.800); + mg_cubic_to(-67.000, 200.000, -81.800, 186.000, -83.800, 181.600); + mg_cubic_to(-85.800, 177.200, -88.900, 169.300, -88.900, 169.300); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 87) + { + mg_move_to(-67.039, 173.820); + mg_cubic_to(-67.039, 173.820, -61.239, 175.370, -60.230, 177.580); + mg_cubic_to(-59.222, 179.800, -61.432, 183.090, -61.432, 183.090); + mg_cubic_to(-61.432, 183.090, -62.432, 186.400, -63.634, 184.240); + mg_cubic_to(-64.836, 182.070, -67.708, 174.410, -67.039, 173.820); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 0.800, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 88) + { + mg_set_width(0.5); + mg_move_to(-67.039, 173.820); + mg_cubic_to(-67.039, 173.820, -61.239, 175.370, -60.230, 177.580); + mg_cubic_to(-59.222, 179.800, -61.432, 183.090, -61.432, 183.090); + mg_cubic_to(-61.432, 183.090, -62.432, 186.400, -63.634, 184.240); + mg_cubic_to(-64.836, 182.070, -67.708, 174.410, -67.039, 173.820); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 89) + { + mg_move_to(-67.000, 173.600); + mg_cubic_to(-67.000, 173.600, -63.400, 178.800, -59.800, 178.800); + mg_cubic_to(-56.200, 178.800, -55.818, 178.390, -53.000, 179.000); + mg_cubic_to(-48.400, 180.000, -48.800, 178.000, -42.200, 179.200); + mg_cubic_to(-39.560, 179.680, -37.000, 178.800, -34.200, 180.000); + mg_cubic_to(-31.400, 181.200, -28.200, 180.400, -27.000, 178.400); + mg_cubic_to(-25.800, 176.400, -21.000, 172.200, -21.000, 172.200); + mg_cubic_to(-21.000, 172.200, -33.800, 174.000, -36.600, 174.800); + mg_cubic_to(-36.600, 174.800, -59.000, 176.000, -67.000, 173.600); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 90) + { + mg_move_to(-22.400, 173.800); + mg_cubic_to(-22.400, 173.800, -28.850, 177.300, -29.250, 179.700); + mg_cubic_to(-29.650, 182.100, -24.000, 185.800, -24.000, 185.800); + mg_cubic_to(-24.000, 185.800, -21.250, 190.400, -20.650, 188.000); + mg_cubic_to(-20.050, 185.600, -21.600, 174.200, -22.400, 173.800); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 0.800, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 91) + { + mg_set_width(0.5); + mg_move_to(-22.400, 173.800); + mg_cubic_to(-22.400, 173.800, -28.850, 177.300, -29.250, 179.700); + mg_cubic_to(-29.650, 182.100, -24.000, 185.800, -24.000, 185.800); + mg_cubic_to(-24.000, 185.800, -21.250, 190.400, -20.650, 188.000); + mg_cubic_to(-20.050, 185.600, -21.600, 174.200, -22.400, 173.800); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 92) + { + mg_move_to(-59.885, 179.260); + mg_cubic_to(-59.885, 179.260, -52.878, 190.450, -52.661, 179.240); + mg_cubic_to(-52.661, 179.240, -52.104, 177.980, -53.864, 177.960); + mg_cubic_to(-59.939, 177.890, -58.418, 173.780, -59.885, 179.260); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 0.800, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 93) + { + mg_set_width(0.5); + mg_move_to(-59.885, 179.260); + mg_cubic_to(-59.885, 179.260, -52.878, 190.450, -52.661, 179.240); + mg_cubic_to(-52.661, 179.240, -52.104, 177.980, -53.864, 177.960); + mg_cubic_to(-59.939, 177.890, -58.418, 173.780, -59.885, 179.260); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 94) + { + mg_move_to(-52.707, 179.510); + mg_cubic_to(-52.707, 179.510, -44.786, 190.700, -45.422, 179.420); + mg_cubic_to(-45.422, 179.420, -45.415, 179.090, -47.168, 178.940); + mg_cubic_to(-51.915, 178.520, -51.570, 174.000, -52.707, 179.510); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 0.800, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 95) + { + mg_set_width(0.5); + mg_move_to(-52.707, 179.510); + mg_cubic_to(-52.707, 179.510, -44.786, 190.700, -45.422, 179.420); + mg_cubic_to(-45.422, 179.420, -45.415, 179.090, -47.168, 178.940); + mg_cubic_to(-51.915, 178.520, -51.570, 174.000, -52.707, 179.510); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 96) + { + mg_move_to(-45.494, 179.520); + mg_cubic_to(-45.494, 179.520, -37.534, 190.150, -38.203, 180.480); + mg_cubic_to(-38.203, 180.480, -38.084, 179.250, -39.738, 178.950); + mg_cubic_to(-43.630, 178.240, -43.841, 175.000, -45.494, 179.520); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 0.800, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 97) + { + mg_set_width(0.5); + mg_move_to(-45.494, 179.520); + mg_cubic_to(-45.494, 179.520, -37.534, 190.150, -38.203, 180.480); + mg_cubic_to(-38.203, 180.480, -38.084, 179.250, -39.738, 178.950); + mg_cubic_to(-43.630, 178.240, -43.841, 175.000, -45.494, 179.520); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 98) + { + mg_move_to(-38.618, 179.600); + mg_cubic_to(-38.618, 179.600, -30.718, 191.160, -30.370, 181.380); + mg_cubic_to(-30.370, 181.380, -28.726, 180.000, -30.472, 179.780); + mg_cubic_to(-36.290, 179.040, -35.492, 174.590, -38.618, 179.600); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 0.800, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 99) + { + mg_set_width(0.5); + mg_move_to(-38.618, 179.600); + mg_cubic_to(-38.618, 179.600, -30.718, 191.160, -30.370, 181.380); + mg_cubic_to(-30.370, 181.380, -28.726, 180.000, -30.472, 179.780); + mg_cubic_to(-36.290, 179.040, -35.492, 174.590, -38.618, 179.600); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 100) + { + mg_move_to(-74.792, 183.130); + mg_move_to(-82.450, 181.600); + mg_cubic_to(-85.050, 176.600, -87.150, 170.450, -87.150, 170.450); + mg_cubic_to(-87.150, 170.450, -80.800, 171.450, -68.300, 174.250); + mg_cubic_to(-68.300, 174.250, -67.424, 177.570, -65.952, 183.360); + mg_line_to(-74.792, 183.130); + mg_close_path(); + mg_set_color_rgba(0.898, 0.898, 0.698, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 101) + { + mg_move_to(-9.724, 178.470); + mg_cubic_to(-11.390, 175.960, -12.707, 174.210, -13.357, 173.800); + mg_cubic_to(-16.370, 171.920, -12.227, 172.290, -11.098, 172.290); + mg_line_to(7.356, 173.050); + mg_cubic_to(7.356, 173.050, 7.880, 175.290, 8.564, 178.680); + mg_cubic_to(8.564, 178.680, -1.524, 176.670, -9.724, 178.470); + mg_close_path(); + mg_set_color_rgba(0.898, 0.898, 0.698, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 102) + { + mg_move_to(43.880, 40.321); + mg_cubic_to(71.601, 44.281, 97.121, 8.641, 98.881, -1.040); + mg_cubic_to(100.640, -10.720, 90.521, -22.600, 90.521, -22.600); + mg_cubic_to(91.841, -25.680, 87.001, -39.760, 81.721, -49.000); + mg_cubic_to(76.441, -58.240, 60.540, -57.266, 43.000, -58.240); + mg_cubic_to(27.160, -59.120, 8.680, -35.800, 7.360, -34.040); + mg_cubic_to(6.040, -32.280, 12.200, 6.001, 13.520, 11.721); + mg_cubic_to(14.840, 17.441, 12.200, 43.841, 12.200, 43.841); + mg_cubic_to(46.440, 34.741, 16.160, 36.361, 43.880, 40.321); + mg_close_path(); + mg_set_color_rgba(0.800, 0.447, 0.149, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 103) + { + mg_move_to(8.088, -33.392); + mg_cubic_to(6.792, -31.664, 12.840, 5.921, 14.136, 11.537); + mg_cubic_to(15.432, 17.153, 12.840, 43.073, 12.840, 43.073); + mg_cubic_to(45.512, 34.193, 16.728, 35.729, 43.944, 39.617); + mg_cubic_to(71.161, 43.505, 96.217, 8.513, 97.945, -0.992); + mg_cubic_to(99.673, -10.496, 89.737, -22.160, 89.737, -22.160); + mg_cubic_to(91.033, -25.184, 86.281, -39.008, 81.097, -48.080); + mg_cubic_to(75.913, -57.152, 60.302, -56.195, 43.080, -57.152); + mg_cubic_to(27.528, -58.016, 9.384, -35.120, 8.088, -33.392); + mg_close_path(); + mg_set_color_rgba(0.918, 0.557, 0.318, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 104) + { + mg_move_to(8.816, -32.744); + mg_cubic_to(7.544, -31.048, 13.480, 5.841, 14.752, 11.353); + mg_cubic_to(16.024, 16.865, 13.480, 42.305, 13.480, 42.305); + mg_cubic_to(44.884, 33.145, 17.296, 35.097, 44.008, 38.913); + mg_cubic_to(70.721, 42.729, 95.313, 8.385, 97.009, -0.944); + mg_cubic_to(98.705, -10.272, 88.953, -21.720, 88.953, -21.720); + mg_cubic_to(90.225, -24.688, 85.561, -38.256, 80.473, -47.160); + mg_cubic_to(75.385, -56.064, 60.063, -55.125, 43.160, -56.064); + mg_cubic_to(27.896, -56.912, 10.088, -34.440, 8.816, -32.744); + mg_close_path(); + mg_set_color_rgba(0.937, 0.667, 0.486, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 105) + { + mg_move_to(9.544, -32.096); + mg_cubic_to(8.296, -30.432, 14.120, 5.761, 15.368, 11.169); + mg_cubic_to(16.616, 16.577, 14.120, 41.537, 14.120, 41.537); + mg_cubic_to(43.556, 32.497, 17.864, 34.465, 44.072, 38.209); + mg_cubic_to(70.281, 41.953, 94.409, 8.257, 96.073, -0.895); + mg_cubic_to(97.737, -10.048, 88.169, -21.280, 88.169, -21.280); + mg_cubic_to(89.417, -24.192, 84.841, -37.504, 79.849, -46.240); + mg_cubic_to(74.857, -54.976, 59.824, -54.055, 43.240, -54.976); + mg_cubic_to(28.264, -55.808, 10.792, -33.760, 9.544, -32.096); + mg_close_path(); + mg_set_color_rgba(0.957, 0.776, 0.659, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 106) + { + mg_move_to(10.272, -31.448); + mg_cubic_to(9.048, -29.816, 14.760, 5.681, 15.984, 10.985); + mg_cubic_to(17.208, 16.289, 14.760, 40.769, 14.760, 40.769); + mg_cubic_to(42.628, 31.849, 18.432, 33.833, 44.136, 37.505); + mg_cubic_to(69.841, 41.177, 93.505, 8.129, 95.137, -0.848); + mg_cubic_to(96.769, -9.824, 87.385, -20.840, 87.385, -20.840); + mg_cubic_to(88.609, -23.696, 84.121, -36.752, 79.225, -45.320); + mg_cubic_to(74.329, -53.888, 59.585, -52.985, 43.320, -53.888); + mg_cubic_to(28.632, -54.704, 11.496, -33.080, 10.272, -31.448); + mg_close_path(); + mg_set_color_rgba(0.976, 0.886, 0.827, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 107) + { + mg_move_to(44.200, 36.800); + mg_cubic_to(69.400, 40.400, 92.601, 8.000, 94.201, -0.800); + mg_cubic_to(95.801, -9.600, 86.601, -20.400, 86.601, -20.400); + mg_cubic_to(87.801, -23.200, 83.400, -36.000, 78.600, -44.400); + mg_cubic_to(73.800, -52.800, 59.346, -51.914, 43.400, -52.800); + mg_cubic_to(29.000, -53.600, 12.200, -32.400, 11.000, -30.800); + mg_cubic_to(9.800, -29.200, 15.400, 5.600, 16.600, 10.800); + mg_cubic_to(17.800, 16.000, 15.400, 40.000, 15.400, 40.000); + mg_cubic_to(40.900, 31.400, 19.000, 33.200, 44.200, 36.800); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 108) + { + mg_move_to(90.601, 2.800); + mg_cubic_to(90.601, 2.800, 62.800, 10.400, 51.200, 8.800); + mg_cubic_to(51.200, 8.800, 35.400, 2.200, 26.600, 24.000); + mg_cubic_to(26.600, 24.000, 23.000, 31.200, 21.000, 33.200); + mg_cubic_to(19.000, 35.200, 90.601, 2.800, 90.601, 2.800); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 109) + { + mg_move_to(94.401, 0.600); + mg_cubic_to(94.401, 0.600, 65.400, 12.800, 55.400, 12.400); + mg_cubic_to(55.400, 12.400, 39.000, 7.800, 30.600, 22.400); + mg_cubic_to(30.600, 22.400, 22.200, 31.600, 19.000, 33.200); + mg_cubic_to(19.000, 33.200, 18.600, 34.800, 25.000, 30.800); + mg_line_to(35.400, 36.000); + mg_cubic_to(35.400, 36.000, 50.200, 45.600, 59.800, 29.600); + mg_cubic_to(59.800, 29.600, 63.800, 18.400, 63.800, 16.400); + mg_cubic_to(63.800, 14.400, 85.000, 8.800, 86.601, 8.400); + mg_cubic_to(88.201, 8.000, 94.801, 3.800, 94.401, 0.600); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 110) + { + mg_move_to(47.000, 36.514); + mg_cubic_to(40.128, 36.514, 31.755, 32.649, 31.755, 26.400); + mg_cubic_to(31.755, 20.152, 40.128, 13.887, 47.000, 13.887); + mg_cubic_to(53.874, 13.887, 59.446, 18.952, 59.446, 25.200); + mg_cubic_to(59.446, 31.449, 53.874, 36.514, 47.000, 36.514); + mg_close_path(); + mg_set_color_rgba(0.600, 0.800, 0.196, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 111) + { + mg_move_to(43.377, 19.830); + mg_cubic_to(38.531, 20.552, 33.442, 22.055, 33.514, 21.839); + mg_cubic_to(35.054, 17.220, 41.415, 13.887, 47.000, 13.887); + mg_cubic_to(51.296, 13.887, 55.084, 15.865, 57.320, 18.875); + mg_cubic_to(57.320, 18.875, 52.004, 18.545, 43.377, 19.830); + mg_close_path(); + mg_set_color_rgba(0.396, 0.600, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 112) + { + mg_move_to(55.400, 19.600); + mg_cubic_to(55.400, 19.600, 51.000, 16.400, 51.000, 18.600); + mg_cubic_to(51.000, 18.600, 54.600, 23.000, 55.400, 19.600); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 113) + { + mg_move_to(45.400, 27.726); + mg_cubic_to(42.901, 27.726, 40.875, 25.700, 40.875, 23.200); + mg_cubic_to(40.875, 20.701, 42.901, 18.675, 45.400, 18.675); + mg_cubic_to(47.900, 18.675, 49.926, 20.701, 49.926, 23.200); + mg_cubic_to(49.926, 25.700, 47.900, 27.726, 45.400, 27.726); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 114) + { + mg_move_to(-58.600, 14.400); + mg_cubic_to(-58.600, 14.400, -61.800, -6.800, -59.400, -11.200); + mg_cubic_to(-59.400, -11.200, -48.600, -21.200, -49.000, -24.800); + mg_cubic_to(-49.000, -24.800, -49.400, -42.800, -50.600, -43.600); + mg_cubic_to(-51.800, -44.400, -59.400, -50.400, -65.400, -44.000); + mg_cubic_to(-65.400, -44.000, -75.800, -26.000, -75.000, -19.600); + mg_line_to(-75.000, -17.600); + mg_cubic_to(-75.000, -17.600, -82.600, -18.000, -84.200, -16.000); + mg_cubic_to(-84.200, -16.000, -85.400, -10.800, -86.600, -10.400); + mg_cubic_to(-86.600, -10.400, -89.400, -8.000, -87.400, -5.200); + mg_cubic_to(-87.400, -5.200, -89.400, -2.800, -89.000, 1.200); + mg_line_to(-81.400, 5.200); + mg_cubic_to(-81.400, 5.200, -79.400, 19.600, -68.600, 24.800); + mg_cubic_to(-63.764, 27.129, -60.600, 20.400, -58.600, 14.400); + mg_close_path(); + mg_set_color_rgba(0.800, 0.447, 0.149, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 115) + { + mg_move_to(-59.600, 12.560); + mg_cubic_to(-59.600, 12.560, -62.480, -6.520, -60.320, -10.480); + mg_cubic_to(-60.320, -10.480, -50.600, -19.480, -50.960, -22.720); + mg_cubic_to(-50.960, -22.720, -51.320, -38.920, -52.400, -39.640); + mg_cubic_to(-53.480, -40.360, -60.320, -45.760, -65.720, -40.000); + mg_cubic_to(-65.720, -40.000, -75.080, -23.800, -74.360, -18.040); + mg_line_to(-74.360, -16.240); + mg_cubic_to(-74.360, -16.240, -81.200, -16.600, -82.640, -14.800); + mg_cubic_to(-82.640, -14.800, -83.720, -10.120, -84.800, -9.760); + mg_cubic_to(-84.800, -9.760, -87.320, -7.600, -85.520, -5.080); + mg_cubic_to(-85.520, -5.080, -87.320, -2.920, -86.960, 0.680); + mg_line_to(-80.120, 4.280); + mg_cubic_to(-80.120, 4.280, -78.320, 17.240, -68.600, 21.920); + mg_cubic_to(-64.248, 24.015, -61.400, 17.960, -59.600, 12.560); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 116) + { + mg_move_to(-51.050, -42.610); + mg_cubic_to(-52.140, -43.470, -59.630, -49.240, -65.480, -43.000); + mg_cubic_to(-65.480, -43.000, -75.620, -25.450, -74.840, -19.210); + mg_line_to(-74.840, -17.260); + mg_cubic_to(-74.840, -17.260, -82.250, -17.650, -83.810, -15.700); + mg_cubic_to(-83.810, -15.700, -84.980, -10.630, -86.150, -10.240); + mg_cubic_to(-86.150, -10.240, -88.880, -7.900, -86.930, -5.170); + mg_cubic_to(-86.930, -5.170, -88.880, -2.830, -88.490, 1.070); + mg_line_to(-81.080, 4.970); + mg_cubic_to(-81.080, 4.970, -79.130, 19.010, -68.600, 24.080); + mg_cubic_to(-63.886, 26.350, -60.800, 19.790, -58.850, 13.940); + mg_cubic_to(-58.850, 13.940, -61.970, -6.730, -59.630, -11.020); + mg_cubic_to(-59.630, -11.020, -49.100, -20.770, -49.490, -24.280); + mg_cubic_to(-49.490, -24.280, -49.880, -41.830, -51.050, -42.610); + mg_close_path(); + mg_set_color_rgba(0.922, 0.584, 0.361, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 117) + { + mg_move_to(-51.500, -41.620); + mg_cubic_to(-52.480, -42.540, -59.860, -48.080, -65.560, -42.000); + mg_cubic_to(-65.560, -42.000, -75.440, -24.900, -74.680, -18.820); + mg_line_to(-74.680, -16.920); + mg_cubic_to(-74.680, -16.920, -81.900, -17.300, -83.420, -15.400); + mg_cubic_to(-83.420, -15.400, -84.560, -10.460, -85.700, -10.080); + mg_cubic_to(-85.700, -10.080, -88.360, -7.800, -86.460, -5.140); + mg_cubic_to(-86.460, -5.140, -88.360, -2.860, -87.980, 0.940); + mg_line_to(-80.760, 4.740); + mg_cubic_to(-80.760, 4.740, -78.860, 18.420, -68.600, 23.360); + mg_cubic_to(-64.006, 25.572, -61.000, 19.180, -59.100, 13.480); + mg_cubic_to(-59.100, 13.480, -62.140, -6.660, -59.860, -10.840); + mg_cubic_to(-59.860, -10.840, -49.600, -20.340, -49.980, -23.760); + mg_cubic_to(-49.980, -23.760, -50.360, -40.860, -51.500, -41.620); + mg_close_path(); + mg_set_color_rgba(0.949, 0.722, 0.573, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 118) + { + mg_move_to(-51.950, -40.630); + mg_cubic_to(-52.820, -41.610, -60.090, -46.920, -65.640, -41.000); + mg_cubic_to(-65.640, -41.000, -75.260, -24.350, -74.520, -18.430); + mg_line_to(-74.520, -16.580); + mg_cubic_to(-74.520, -16.580, -81.550, -16.950, -83.030, -15.100); + mg_cubic_to(-83.030, -15.100, -84.140, -10.290, -85.250, -9.920); + mg_cubic_to(-85.250, -9.920, -87.840, -7.700, -85.990, -5.110); + mg_cubic_to(-85.990, -5.110, -87.840, -2.890, -87.470, 0.810); + mg_line_to(-80.440, 4.510); + mg_cubic_to(-80.440, 4.510, -78.590, 17.830, -68.600, 22.640); + mg_cubic_to(-64.127, 24.794, -61.200, 18.570, -59.350, 13.020); + mg_cubic_to(-59.350, 13.020, -62.310, -6.590, -60.090, -10.660); + mg_cubic_to(-60.090, -10.660, -50.100, -19.910, -50.470, -23.240); + mg_cubic_to(-50.470, -23.240, -50.840, -39.890, -51.950, -40.630); + mg_close_path(); + mg_set_color_rgba(0.973, 0.863, 0.784, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 119) + { + mg_move_to(-59.600, 12.460); + mg_cubic_to(-59.600, 12.460, -62.480, -6.520, -60.320, -10.480); + mg_cubic_to(-60.320, -10.480, -50.600, -19.480, -50.960, -22.720); + mg_cubic_to(-50.960, -22.720, -51.320, -38.920, -52.400, -39.640); + mg_cubic_to(-53.160, -40.680, -60.320, -45.760, -65.720, -40.000); + mg_cubic_to(-65.720, -40.000, -75.080, -23.800, -74.360, -18.040); + mg_line_to(-74.360, -16.240); + mg_cubic_to(-74.360, -16.240, -81.200, -16.600, -82.640, -14.800); + mg_cubic_to(-82.640, -14.800, -83.720, -10.120, -84.800, -9.760); + mg_cubic_to(-84.800, -9.760, -87.320, -7.600, -85.520, -5.080); + mg_cubic_to(-85.520, -5.080, -87.320, -2.920, -86.960, 0.680); + mg_line_to(-80.120, 4.280); + mg_cubic_to(-80.120, 4.280, -78.320, 17.240, -68.600, 21.920); + mg_cubic_to(-64.248, 24.015, -61.400, 17.860, -59.600, 12.460); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 120) + { + mg_move_to(-62.700, 6.200); + mg_cubic_to(-62.700, 6.200, -84.300, -4.000, -85.200, -4.800); + mg_cubic_to(-85.200, -4.800, -76.100, 3.400, -75.300, 3.400); + mg_cubic_to(-74.500, 3.400, -62.700, 6.200, -62.700, 6.200); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 121) + { + mg_move_to(-79.800, 0.000); + mg_cubic_to(-79.800, 0.000, -61.400, 3.600, -61.400, 8.000); + mg_cubic_to(-61.400, 10.912, -61.643, 24.331, -67.000, 22.800); + mg_cubic_to(-75.400, 20.400, -71.800, 6.000, -79.800, 0.000); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 122) + { + mg_move_to(-71.400, 3.800); + mg_cubic_to(-71.400, 3.800, -62.422, 5.274, -61.400, 8.000); + mg_cubic_to(-60.800, 9.600, -60.137, 17.908, -65.600, 19.000); + mg_cubic_to(-70.152, 19.911, -72.382, 9.690, -71.400, 3.800); + mg_close_path(); + mg_set_color_rgba(0.600, 0.800, 0.196, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 123) + { + mg_move_to(14.595, 46.349); + mg_cubic_to(14.098, 44.607, 15.409, 44.738, 17.200, 44.200); + mg_cubic_to(19.200, 43.600, 31.400, 39.800, 32.200, 37.200); + mg_cubic_to(33.000, 34.600, 46.200, 39.000, 46.200, 39.000); + mg_cubic_to(48.000, 39.800, 52.400, 42.400, 52.400, 42.400); + mg_cubic_to(57.200, 43.600, 63.800, 44.000, 63.800, 44.000); + mg_cubic_to(66.200, 45.000, 69.600, 47.800, 69.600, 47.800); + mg_cubic_to(84.200, 58.000, 96.601, 50.800, 96.601, 50.800); + mg_cubic_to(116.600, 44.200, 110.600, 27.000, 110.600, 27.000); + mg_cubic_to(107.600, 18.000, 110.800, 14.600, 110.800, 14.600); + mg_cubic_to(111.000, 10.800, 118.200, 17.200, 118.200, 17.200); + mg_cubic_to(120.800, 21.400, 121.600, 26.400, 121.600, 26.400); + mg_cubic_to(129.600, 37.600, 126.200, 19.800, 126.200, 19.800); + mg_cubic_to(126.400, 18.800, 123.600, 15.200, 123.600, 14.000); + mg_cubic_to(123.600, 12.800, 121.800, 9.400, 121.800, 9.400); + mg_cubic_to(118.800, 6.000, 121.200, -1.000, 121.200, -1.000); + mg_cubic_to(123.000, -14.800, 120.800, -13.000, 120.800, -13.000); + mg_cubic_to(119.600, -14.800, 110.400, -4.800, 110.400, -4.800); + mg_cubic_to(108.200, -1.400, 102.200, 0.200, 102.200, 0.200); + mg_cubic_to(99.401, 2.000, 96.001, 0.600, 96.001, 0.600); + mg_cubic_to(93.401, 0.200, 87.801, 7.200, 87.801, 7.200); + mg_cubic_to(90.601, 7.000, 93.001, 11.400, 95.401, 11.600); + mg_cubic_to(97.801, 11.800, 99.601, 9.200, 101.200, 8.600); + mg_cubic_to(102.800, 8.000, 105.600, 13.800, 105.600, 13.800); + mg_cubic_to(106.000, 16.400, 100.400, 21.200, 100.400, 21.200); + mg_cubic_to(100.000, 25.800, 98.401, 24.200, 98.401, 24.200); + mg_cubic_to(95.401, 23.600, 94.201, 27.400, 93.201, 32.000); + mg_cubic_to(92.201, 36.600, 88.001, 37.000, 88.001, 37.000); + mg_cubic_to(86.401, 44.400, 85.200, 41.400, 85.200, 41.400); + mg_cubic_to(85.000, 35.800, 79.000, 41.600, 79.000, 41.600); + mg_cubic_to(77.800, 43.600, 73.200, 41.400, 73.200, 41.400); + mg_cubic_to(66.400, 39.400, 68.800, 37.400, 68.800, 37.400); + mg_cubic_to(70.600, 35.200, 81.800, 37.400, 81.800, 37.400); + mg_cubic_to(84.000, 35.800, 76.000, 31.800, 76.000, 31.800); + mg_cubic_to(75.400, 30.000, 76.400, 25.600, 76.400, 25.600); + mg_cubic_to(77.600, 22.400, 84.400, 16.800, 84.400, 16.800); + mg_cubic_to(93.801, 15.600, 91.001, 14.000, 91.001, 14.000); + mg_cubic_to(84.801, 8.800, 79.000, 16.400, 79.000, 16.400); + mg_cubic_to(76.800, 22.600, 59.400, 37.600, 59.400, 37.600); + mg_cubic_to(54.600, 41.000, 57.200, 34.200, 53.200, 37.600); + mg_cubic_to(49.200, 41.000, 28.600, 32.000, 28.600, 32.000); + mg_cubic_to(17.038, 30.807, 14.306, 46.549, 10.777, 43.429); + mg_cubic_to(10.777, 43.429, 16.195, 51.949, 14.595, 46.349); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 124) + { + mg_move_to(209.400, -120.000); + mg_cubic_to(209.400, -120.000, 183.800, -112.000, 181.000, -93.200); + mg_cubic_to(181.000, -93.200, 178.600, -70.400, 199.000, -52.800); + mg_cubic_to(199.000, -52.800, 199.400, -46.400, 201.400, -43.200); + mg_cubic_to(201.400, -43.200, 199.800, -38.400, 218.600, -46.000); + mg_line_to(245.800, -54.400); + mg_cubic_to(245.800, -54.400, 252.200, -56.800, 257.400, -65.600); + mg_cubic_to(262.600, -74.400, 277.800, -93.200, 274.200, -118.400); + mg_cubic_to(274.200, -118.400, 275.400, -129.600, 269.400, -130.000); + mg_cubic_to(269.400, -130.000, 261.000, -131.600, 253.800, -124.000); + mg_cubic_to(253.800, -124.000, 247.000, -120.800, 244.600, -121.200); + mg_line_to(209.400, -120.000); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 125) + { + mg_move_to(264.020, -120.990); + mg_cubic_to(264.020, -120.990, 266.120, -129.920, 261.280, -125.080); + mg_cubic_to(261.280, -125.080, 254.240, -119.360, 246.760, -119.360); + mg_cubic_to(246.760, -119.360, 232.240, -117.160, 227.840, -103.960); + mg_cubic_to(227.840, -103.960, 223.880, -77.120, 231.800, -71.400); + mg_cubic_to(231.800, -71.400, 236.640, -63.920, 243.680, -70.520); + mg_cubic_to(250.720, -77.120, 266.220, -107.350, 264.020, -120.990); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 126) + { + mg_move_to(263.650, -120.630); + mg_cubic_to(263.650, -120.630, 265.740, -129.380, 260.990, -124.620); + mg_cubic_to(260.990, -124.620, 254.070, -119.010, 246.730, -119.010); + mg_cubic_to(246.730, -119.010, 232.470, -116.850, 228.150, -103.890); + mg_cubic_to(228.150, -103.890, 224.260, -77.536, 232.040, -71.920); + mg_cubic_to(232.040, -71.920, 236.790, -64.576, 243.700, -71.056); + mg_cubic_to(250.620, -77.536, 265.810, -107.240, 263.650, -120.630); + mg_close_path(); + mg_set_color_rgba(0.196, 0.196, 0.196, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 127) + { + mg_move_to(263.270, -120.270); + mg_cubic_to(263.270, -120.270, 265.350, -128.830, 260.690, -124.170); + mg_cubic_to(260.690, -124.170, 253.910, -118.660, 246.700, -118.660); + mg_cubic_to(246.700, -118.660, 232.700, -116.540, 228.460, -103.820); + mg_cubic_to(228.460, -103.820, 224.650, -77.952, 232.280, -72.440); + mg_cubic_to(232.280, -72.440, 236.940, -65.232, 243.730, -71.592); + mg_cubic_to(250.510, -77.952, 265.390, -107.130, 263.270, -120.270); + mg_close_path(); + mg_set_color_rgba(0.400, 0.400, 0.400, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 128) + { + mg_move_to(262.900, -119.920); + mg_cubic_to(262.900, -119.920, 264.970, -128.290, 260.390, -123.710); + mg_cubic_to(260.390, -123.710, 253.740, -118.300, 246.660, -118.300); + mg_cubic_to(246.660, -118.300, 232.940, -116.220, 228.780, -103.740); + mg_cubic_to(228.780, -103.740, 225.030, -78.368, 232.520, -72.960); + mg_cubic_to(232.520, -72.960, 237.100, -65.888, 243.750, -72.128); + mg_cubic_to(250.410, -78.368, 264.980, -107.020, 262.900, -119.920); + mg_close_path(); + mg_set_color_rgba(0.600, 0.600, 0.600, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 129) + { + mg_move_to(262.530, -119.560); + mg_cubic_to(262.530, -119.560, 264.590, -127.740, 260.100, -123.260); + mg_cubic_to(260.100, -123.260, 253.570, -117.950, 246.630, -117.950); + mg_cubic_to(246.630, -117.950, 233.170, -115.910, 229.090, -103.670); + mg_cubic_to(229.090, -103.670, 225.420, -78.784, 232.760, -73.480); + mg_cubic_to(232.760, -73.480, 237.250, -66.544, 243.780, -72.664); + mg_cubic_to(250.300, -78.784, 264.570, -106.910, 262.530, -119.560); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 130) + { + mg_move_to(262.150, -119.200); + mg_cubic_to(262.150, -119.200, 264.200, -127.200, 259.800, -122.800); + mg_cubic_to(259.800, -122.800, 253.400, -117.600, 246.600, -117.600); + mg_cubic_to(246.600, -117.600, 233.400, -115.600, 229.400, -103.600); + mg_cubic_to(229.400, -103.600, 225.800, -79.200, 233.000, -74.000); + mg_cubic_to(233.000, -74.000, 237.400, -67.200, 243.800, -73.200); + mg_cubic_to(250.200, -79.200, 264.150, -106.800, 262.150, -119.200); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 131) + { + mg_move_to(50.600, 84.000); + mg_cubic_to(50.600, 84.000, 30.200, 64.800, 22.200, 64.000); + mg_cubic_to(22.200, 64.000, -12.200, 60.000, -27.000, 78.000); + mg_cubic_to(-27.000, 78.000, -9.400, 57.600, 18.200, 63.200); + mg_cubic_to(18.200, 63.200, -3.400, 58.800, -15.800, 62.000); + mg_line_to(-42.200, 76.000); + mg_line_to(-45.000, 80.800); + mg_cubic_to(-45.000, 80.800, -41.000, 66.000, -22.600, 60.000); + mg_cubic_to(-22.600, 60.000, 0.200, 55.200, 11.000, 60.000); + mg_cubic_to(11.000, 60.000, -10.600, 53.200, -20.600, 55.200); + mg_cubic_to(-20.600, 55.200, -51.000, 52.800, -63.800, 79.200); + mg_cubic_to(-63.800, 79.200, -59.800, 64.800, -45.000, 57.600); + mg_cubic_to(-45.000, 57.600, -31.400, 48.800, -11.000, 51.600); + mg_cubic_to(-11.000, 51.600, 3.400, 54.800, 8.600, 57.200); + mg_cubic_to(13.800, 59.600, 12.600, 56.800, 4.200, 52.000); + mg_cubic_to(4.200, 52.000, -1.400, 42.000, -15.400, 42.400); + mg_cubic_to(-15.400, 42.400, -58.200, 46.000, -68.600, 58.000); + mg_cubic_to(-68.600, 58.000, -55.000, 46.800, -44.600, 44.000); + mg_cubic_to(-44.600, 44.000, -22.200, 36.000, -13.800, 36.800); + mg_cubic_to(-13.800, 36.800, 11.000, 37.800, 18.600, 33.800); + mg_cubic_to(18.600, 33.800, 7.400, 38.800, 10.600, 42.000); + mg_cubic_to(13.800, 45.200, 20.600, 52.800, 20.600, 54.000); + mg_cubic_to(20.600, 55.200, 44.800, 77.300, 48.400, 81.700); + mg_line_to(50.600, 84.000); + mg_close_path(); + mg_set_color_rgba(0.600, 0.149, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 132) + { + mg_move_to(189.000, 278.000); + mg_cubic_to(189.000, 278.000, 173.500, 241.500, 161.000, 232.000); + mg_cubic_to(161.000, 232.000, 187.000, 248.000, 190.500, 266.000); + mg_cubic_to(190.500, 266.000, 190.500, 276.000, 189.000, 278.000); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 133) + { + mg_move_to(236.000, 285.500); + mg_cubic_to(236.000, 285.500, 209.500, 230.500, 191.000, 206.500); + mg_cubic_to(191.000, 206.500, 234.500, 244.000, 239.500, 270.500); + mg_line_to(240.000, 276.000); + mg_line_to(237.000, 273.500); + mg_cubic_to(237.000, 273.500, 236.500, 282.500, 236.000, 285.500); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 134) + { + mg_move_to(292.500, 237.000); + mg_cubic_to(292.500, 237.000, 230.000, 177.500, 228.500, 175.000); + mg_cubic_to(228.500, 175.000, 289.000, 241.000, 292.000, 248.500); + mg_cubic_to(292.000, 248.500, 290.000, 239.500, 292.500, 237.000); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 135) + { + mg_move_to(104.000, 280.500); + mg_cubic_to(104.000, 280.500, 123.500, 228.500, 142.500, 251.000); + mg_cubic_to(142.500, 251.000, 157.500, 261.000, 157.000, 264.000); + mg_cubic_to(157.000, 264.000, 153.000, 257.500, 135.000, 258.000); + mg_cubic_to(135.000, 258.000, 116.000, 255.000, 104.000, 280.500); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 136) + { + mg_move_to(294.500, 153.000); + mg_cubic_to(294.500, 153.000, 249.500, 124.500, 242.000, 123.000); + mg_cubic_to(230.190, 120.640, 291.500, 152.000, 296.500, 162.500); + mg_cubic_to(296.500, 162.500, 298.500, 160.000, 294.500, 153.000); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 137) + { + mg_move_to(143.800, 259.600); + mg_cubic_to(143.800, 259.600, 164.200, 257.600, 171.000, 250.800); + mg_line_to(175.400, 254.400); + mg_line_to(193.000, 216.000); + mg_line_to(196.600, 221.200); + mg_cubic_to(196.600, 221.200, 211.000, 206.400, 210.200, 198.400); + mg_cubic_to(209.400, 190.400, 223.000, 204.400, 223.000, 204.400); + mg_cubic_to(223.000, 204.400, 222.200, 192.800, 229.400, 199.600); + mg_cubic_to(229.400, 199.600, 227.000, 184.000, 235.400, 192.000); + mg_cubic_to(235.400, 192.000, 224.860, 161.840, 247.400, 187.600); + mg_cubic_to(253.000, 194.000, 248.600, 187.200, 248.600, 187.200); + mg_cubic_to(248.600, 187.200, 222.600, 139.200, 244.200, 153.600); + mg_cubic_to(244.200, 153.600, 246.200, 130.800, 245.000, 126.400); + mg_cubic_to(243.800, 122.000, 241.800, 99.600, 237.000, 94.400); + mg_cubic_to(232.200, 89.200, 237.400, 87.600, 243.000, 92.800); + mg_cubic_to(243.000, 92.800, 231.800, 68.800, 245.000, 80.800); + mg_cubic_to(245.000, 80.800, 241.400, 65.600, 237.000, 62.800); + mg_cubic_to(237.000, 62.800, 231.400, 45.600, 246.600, 56.400); + mg_cubic_to(246.600, 56.400, 242.200, 44.000, 239.000, 40.800); + mg_cubic_to(239.000, 40.800, 227.400, 13.200, 234.600, 18.000); + mg_line_to(239.000, 21.600); + mg_cubic_to(239.000, 21.600, 232.200, 7.600, 238.600, 12.000); + mg_cubic_to(245.000, 16.400, 245.000, 16.000, 245.000, 16.000); + mg_cubic_to(245.000, 16.000, 223.800, -17.200, 244.200, 0.400); + mg_cubic_to(244.200, 0.400, 236.040, -13.518, 232.600, -20.400); + mg_cubic_to(232.600, -20.400, 213.800, -40.800, 228.200, -34.400); + mg_line_to(233.000, -32.800); + mg_cubic_to(233.000, -32.800, 224.200, -42.800, 216.200, -44.400); + mg_cubic_to(208.200, -46.000, 218.600, -52.400, 225.000, -50.400); + mg_cubic_to(231.400, -48.400, 247.000, -40.800, 247.000, -40.800); + mg_cubic_to(247.000, -40.800, 259.800, -22.000, 263.800, -21.600); + mg_cubic_to(263.800, -21.600, 243.800, -29.200, 249.800, -21.200); + mg_cubic_to(249.800, -21.200, 264.200, -7.200, 257.000, -7.600); + mg_cubic_to(257.000, -7.600, 251.000, -0.400, 255.800, 8.400); + mg_cubic_to(255.800, 8.400, 237.340, -9.991, 252.200, 15.600); + mg_line_to(259.000, 32.000); + mg_cubic_to(259.000, 32.000, 234.600, 7.200, 245.800, 29.200); + mg_cubic_to(245.800, 29.200, 263.000, 52.800, 265.000, 53.200); + mg_cubic_to(267.000, 53.600, 271.400, 62.400, 271.400, 62.400); + mg_line_to(267.000, 60.400); + mg_line_to(272.200, 69.200); + mg_cubic_to(272.200, 69.200, 261.000, 57.200, 267.000, 70.400); + mg_line_to(272.600, 84.800); + mg_cubic_to(272.600, 84.800, 252.200, 62.800, 265.800, 92.400); + mg_cubic_to(265.800, 92.400, 249.400, 87.200, 258.200, 104.400); + mg_cubic_to(258.200, 104.400, 256.600, 120.400, 257.000, 125.600); + mg_cubic_to(257.400, 130.800, 258.600, 159.200, 254.200, 167.200); + mg_cubic_to(249.800, 175.200, 260.200, 194.400, 262.200, 198.400); + mg_cubic_to(264.200, 202.400, 267.800, 213.200, 259.000, 204.000); + mg_cubic_to(250.200, 194.800, 254.600, 200.400, 256.600, 209.200); + mg_cubic_to(258.600, 218.000, 264.600, 233.600, 263.800, 239.200); + mg_cubic_to(263.800, 239.200, 262.600, 240.400, 259.400, 236.800); + mg_cubic_to(259.400, 236.800, 244.600, 214.000, 246.200, 228.400); + mg_cubic_to(246.200, 228.400, 245.000, 236.400, 241.800, 245.200); + mg_cubic_to(241.800, 245.200, 238.600, 256.000, 238.600, 247.200); + mg_cubic_to(238.600, 247.200, 235.400, 230.400, 232.600, 238.000); + mg_cubic_to(229.800, 245.600, 226.200, 251.600, 223.400, 254.000); + mg_cubic_to(220.600, 256.400, 215.400, 233.600, 214.200, 244.000); + mg_cubic_to(214.200, 244.000, 202.200, 231.600, 197.400, 248.000); + mg_line_to(185.800, 264.400); + mg_cubic_to(185.800, 264.400, 185.400, 252.000, 184.200, 258.000); + mg_cubic_to(184.200, 258.000, 154.200, 264.000, 143.800, 259.600); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 138) + { + mg_move_to(109.400, -97.200); + mg_cubic_to(109.400, -97.200, 97.801, -105.200, 93.801, -104.800); + mg_cubic_to(89.801, -104.400, 121.400, -113.600, 162.600, -86.000); + mg_cubic_to(162.600, -86.000, 167.400, -83.200, 171.000, -83.600); + mg_cubic_to(171.000, -83.600, 174.200, -81.200, 171.400, -77.600); + mg_cubic_to(171.400, -77.600, 162.600, -68.000, 173.800, -56.800); + mg_cubic_to(173.800, -56.800, 192.200, -50.000, 186.600, -58.800); + mg_cubic_to(186.600, -58.800, 197.400, -54.800, 199.800, -50.800); + mg_cubic_to(202.200, -46.800, 201.000, -50.800, 201.000, -50.800); + mg_line_to(188.600, -63.200); + mg_cubic_to(188.600, -63.200, 183.400, -65.200, 180.600, -73.600); + mg_cubic_to(177.800, -82.000, 175.400, -92.000, 179.800, -95.200); + mg_cubic_to(179.800, -95.200, 175.800, -90.800, 176.600, -94.800); + mg_cubic_to(177.400, -98.800, 181.000, -102.400, 182.600, -102.800); + mg_cubic_to(184.200, -103.200, 200.600, -119.000, 207.400, -119.400); + mg_cubic_to(207.400, -119.400, 198.200, -118.000, 195.200, -119.000); + mg_cubic_to(192.200, -120.000, 165.600, -131.400, 159.600, -132.600); + mg_cubic_to(159.600, -132.600, 142.800, -139.200, 154.800, -137.200); + mg_cubic_to(154.800, -137.200, 190.600, -133.400, 208.800, -120.200); + mg_cubic_to(208.800, -120.200, 201.600, -128.600, 183.200, -135.600); + mg_cubic_to(183.200, -135.600, 161.000, -148.200, 125.800, -143.200); + mg_cubic_to(125.800, -143.200, 108.000, -140.000, 100.200, -138.200); + mg_cubic_to(100.200, -138.200, 97.601, -138.800, 97.001, -139.200); + mg_cubic_to(96.401, -139.600, 84.600, -148.600, 57.000, -141.600); + mg_cubic_to(57.000, -141.600, 40.000, -137.000, 31.400, -132.200); + mg_cubic_to(31.400, -132.200, 16.200, -131.000, 12.600, -127.800); + mg_cubic_to(12.600, -127.800, -6.000, -113.200, -8.000, -112.400); + mg_cubic_to(-10.000, -111.600, -21.400, -104.000, -22.200, -103.600); + mg_cubic_to(-22.200, -103.600, 2.400, -110.200, 4.800, -112.600); + mg_cubic_to(7.200, -115.000, 24.600, -117.600, 27.000, -116.200); + mg_cubic_to(29.400, -114.800, 37.800, -115.400, 28.200, -114.800); + mg_cubic_to(28.200, -114.800, 103.800, -100.000, 104.600, -98.000); + mg_cubic_to(105.400, -96.000, 109.400, -97.200, 109.400, -97.200); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 139) + { + mg_move_to(180.800, -106.400); + mg_cubic_to(180.800, -106.400, 170.600, -113.800, 168.600, -113.800); + mg_cubic_to(166.600, -113.800, 154.200, -124.000, 150.000, -123.600); + mg_cubic_to(145.800, -123.200, 133.600, -133.200, 106.200, -125.000); + mg_cubic_to(106.200, -125.000, 105.600, -127.000, 109.200, -127.800); + mg_cubic_to(109.200, -127.800, 115.600, -130.000, 116.000, -130.600); + mg_cubic_to(116.000, -130.600, 136.200, -134.800, 143.400, -131.200); + mg_cubic_to(143.400, -131.200, 152.600, -128.600, 158.800, -122.400); + mg_cubic_to(158.800, -122.400, 170.000, -119.200, 173.200, -120.200); + mg_cubic_to(173.200, -120.200, 182.000, -118.000, 182.400, -116.200); + mg_cubic_to(182.400, -116.200, 188.200, -113.200, 186.400, -110.600); + mg_cubic_to(186.400, -110.600, 186.800, -109.000, 180.800, -106.400); + mg_close_path(); + mg_set_color_rgba(0.800, 0.447, 0.149, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 140) + { + mg_move_to(168.330, -108.510); + mg_cubic_to(169.140, -107.880, 170.160, -107.780, 170.760, -106.970); + mg_cubic_to(171.000, -106.660, 170.710, -106.330, 170.390, -106.230); + mg_cubic_to(169.350, -105.920, 168.290, -106.490, 167.150, -105.900); + mg_cubic_to(166.750, -105.690, 166.110, -105.870, 165.550, -106.020); + mg_cubic_to(163.920, -106.460, 162.090, -106.490, 160.400, -105.800); + mg_cubic_to(158.420, -106.930, 156.060, -106.340, 153.980, -107.350); + mg_cubic_to(153.920, -107.370, 153.700, -107.030, 153.620, -107.050); + mg_cubic_to(150.580, -108.200, 146.830, -107.920, 144.400, -110.200); + mg_cubic_to(141.970, -110.610, 139.620, -111.070, 137.190, -111.750); + mg_cubic_to(135.370, -112.260, 133.960, -113.250, 132.340, -114.080); + mg_cubic_to(130.960, -114.790, 129.510, -115.310, 127.970, -115.690); + mg_cubic_to(126.110, -116.140, 124.280, -116.030, 122.390, -116.550); + mg_cubic_to(122.290, -116.570, 122.100, -116.230, 122.020, -116.250); + mg_cubic_to(121.700, -116.360, 121.400, -116.940, 121.230, -116.890); + mg_cubic_to(119.550, -116.370, 118.060, -117.340, 116.400, -117.000); + mg_cubic_to(115.220, -118.220, 113.500, -117.980, 111.950, -118.420); + mg_cubic_to(108.980, -119.270, 105.830, -118.000, 102.800, -119.000); + mg_cubic_to(106.910, -120.840, 111.600, -119.610, 115.660, -121.680); + mg_cubic_to(117.990, -122.860, 120.650, -121.760, 123.220, -122.520); + mg_cubic_to(123.710, -122.670, 124.400, -122.870, 124.800, -122.200); + mg_cubic_to(124.940, -122.340, 125.120, -122.570, 125.180, -122.550); + mg_cubic_to(127.620, -121.390, 129.940, -120.120, 132.420, -119.050); + mg_cubic_to(132.760, -118.900, 133.300, -119.140, 133.550, -118.930); + mg_cubic_to(135.070, -117.720, 137.010, -117.820, 138.400, -116.600); + mg_cubic_to(140.100, -117.100, 141.890, -116.720, 143.620, -117.350); + mg_cubic_to(143.700, -117.370, 143.930, -117.030, 143.960, -117.050); + mg_cubic_to(145.100, -117.800, 146.250, -117.530, 147.140, -117.230); + mg_cubic_to(147.480, -117.110, 148.140, -116.860, 148.450, -116.790); + mg_cubic_to(149.570, -116.520, 150.430, -116.040, 151.610, -115.850); + mg_cubic_to(151.720, -115.830, 151.910, -116.170, 151.980, -116.150); + mg_cubic_to(153.100, -115.710, 154.140, -115.760, 154.800, -114.600); + mg_cubic_to(154.940, -114.740, 155.100, -114.970, 155.180, -114.950); + mg_cubic_to(156.210, -114.610, 156.860, -113.850, 157.960, -113.610); + mg_cubic_to(158.440, -113.510, 159.060, -112.880, 159.630, -112.700); + mg_cubic_to(162.020, -111.970, 163.870, -110.440, 166.060, -109.550); + mg_cubic_to(166.820, -109.240, 167.700, -109.000, 168.330, -108.510); + mg_close_path(); + mg_set_color_rgba(0.800, 0.447, 0.149, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 141) + { + mg_move_to(91.696, -122.740); + mg_cubic_to(89.178, -124.460, 86.810, -125.570, 84.368, -127.360); + mg_cubic_to(84.187, -127.490, 83.827, -127.320, 83.625, -127.440); + mg_cubic_to(82.618, -128.050, 81.730, -128.630, 80.748, -129.330); + mg_cubic_to(80.209, -129.710, 79.388, -129.700, 78.880, -129.960); + mg_cubic_to(76.336, -131.250, 73.707, -131.810, 71.200, -133.000); + mg_cubic_to(71.882, -133.640, 73.004, -133.390, 73.600, -134.200); + mg_cubic_to(73.795, -133.920, 74.033, -133.640, 74.386, -133.830); + mg_cubic_to(76.064, -134.730, 77.914, -134.880, 79.590, -134.790); + mg_cubic_to(81.294, -134.700, 83.014, -134.400, 84.789, -134.120); + mg_cubic_to(85.096, -134.080, 85.295, -133.560, 85.618, -133.460); + mg_cubic_to(87.846, -132.800, 90.235, -133.320, 92.354, -132.480); + mg_cubic_to(93.945, -131.850, 95.515, -131.030, 96.754, -129.760); + mg_cubic_to(97.006, -129.500, 96.681, -129.190, 96.401, -129.000); + mg_cubic_to(96.789, -129.110, 97.062, -128.900, 97.173, -128.590); + mg_cubic_to(97.257, -128.350, 97.257, -128.050, 97.173, -127.810); + mg_cubic_to(97.061, -127.500, 96.782, -127.400, 96.408, -127.350); + mg_cubic_to(95.001, -127.160, 96.773, -128.540, 96.073, -128.090); + mg_cubic_to(94.800, -127.270, 95.546, -125.870, 94.801, -124.600); + mg_cubic_to(94.521, -124.790, 94.291, -125.010, 94.401, -125.400); + mg_cubic_to(94.635, -124.880, 94.033, -124.590, 93.865, -124.270); + mg_cubic_to(93.480, -123.550, 92.581, -122.130, 91.696, -122.740); + mg_close_path(); + mg_set_color_rgba(0.800, 0.447, 0.149, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 142) + { + mg_move_to(59.198, -115.390); + mg_cubic_to(56.044, -116.180, 52.994, -116.070, 49.978, -117.350); + mg_cubic_to(49.911, -117.370, 49.688, -117.030, 49.624, -117.050); + mg_cubic_to(48.258, -117.650, 47.340, -118.610, 46.264, -119.660); + mg_cubic_to(45.351, -120.550, 43.693, -120.160, 42.419, -120.650); + mg_cubic_to(42.095, -120.770, 41.892, -121.280, 41.591, -121.320); + mg_cubic_to(40.372, -121.480, 39.445, -122.430, 38.400, -123.000); + mg_cubic_to(40.736, -123.800, 43.147, -123.760, 45.609, -124.150); + mg_cubic_to(45.722, -124.170, 45.867, -123.840, 46.000, -123.840); + mg_cubic_to(46.136, -123.840, 46.266, -124.070, 46.400, -124.200); + mg_cubic_to(46.595, -123.920, 46.897, -123.590, 47.154, -123.850); + mg_cubic_to(47.702, -124.390, 48.258, -124.200, 48.798, -124.160); + mg_cubic_to(48.942, -124.150, 49.067, -123.840, 49.200, -123.840); + mg_cubic_to(49.336, -123.840, 49.467, -124.160, 49.600, -124.160); + mg_cubic_to(49.736, -124.160, 49.867, -123.840, 50.000, -123.840); + mg_cubic_to(50.136, -123.840, 50.266, -124.070, 50.400, -124.200); + mg_cubic_to(51.092, -123.420, 51.977, -123.970, 52.799, -123.790); + mg_cubic_to(53.837, -123.570, 54.104, -122.420, 55.178, -122.120); + mg_cubic_to(59.893, -120.820, 64.030, -118.670, 68.393, -116.580); + mg_cubic_to(68.700, -116.440, 68.910, -116.190, 68.800, -115.800); + mg_cubic_to(69.067, -115.800, 69.380, -115.890, 69.570, -115.760); + mg_cubic_to(70.628, -115.020, 71.669, -114.480, 72.366, -113.380); + mg_cubic_to(72.582, -113.040, 72.253, -112.630, 72.020, -112.680); + mg_cubic_to(67.591, -113.680, 63.585, -114.290, 59.198, -115.390); + mg_close_path(); + mg_set_color_rgba(0.800, 0.447, 0.149, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 143) + { + mg_move_to(45.338, -71.179); + mg_cubic_to(43.746, -72.398, 43.162, -74.429, 42.034, -76.221); + mg_cubic_to(41.820, -76.561, 42.094, -76.875, 42.411, -76.964); + mg_cubic_to(42.971, -77.123, 43.514, -76.645, 43.923, -76.443); + mg_cubic_to(45.668, -75.581, 47.203, -74.339, 49.200, -74.200); + mg_cubic_to(51.190, -71.966, 55.450, -71.581, 55.457, -68.200); + mg_cubic_to(55.458, -67.341, 54.030, -68.259, 53.600, -67.400); + mg_cubic_to(51.149, -68.403, 48.760, -68.300, 46.380, -69.767); + mg_cubic_to(45.763, -70.148, 46.093, -70.601, 45.338, -71.179); + mg_close_path(); + mg_set_color_rgba(0.800, 0.447, 0.149, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 144) + { + mg_move_to(17.800, -123.760); + mg_cubic_to(17.935, -123.760, 24.966, -123.520, 24.949, -123.410); + mg_cubic_to(24.904, -123.100, 17.174, -122.050, 16.810, -122.220); + mg_cubic_to(16.646, -122.300, 9.134, -119.870, 9.000, -120.000); + mg_cubic_to(9.268, -120.140, 17.534, -123.760, 17.800, -123.760); + mg_close_path(); + mg_set_color_rgba(0.800, 0.447, 0.149, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 145) + { + mg_move_to(33.200, -114.000); + mg_cubic_to(33.200, -114.000, 18.400, -112.200, 14.000, -111.000); + mg_cubic_to(9.600, -109.800, -9.000, -102.200, -12.000, -100.200); + mg_cubic_to(-12.000, -100.200, -25.400, -94.800, -42.400, -74.800); + mg_cubic_to(-42.400, -74.800, -34.800, -78.200, -32.600, -81.000); + mg_cubic_to(-32.600, -81.000, -19.000, -93.600, -19.200, -91.000); + mg_cubic_to(-19.200, -91.000, -7.000, -99.600, -7.600, -97.400); + mg_cubic_to(-7.600, -97.400, 16.800, -108.600, 14.800, -105.400); + mg_cubic_to(14.800, -105.400, 36.400, -110.000, 35.400, -108.000); + mg_cubic_to(35.400, -108.000, 54.200, -103.600, 51.400, -103.400); + mg_cubic_to(51.400, -103.400, 45.600, -102.200, 52.000, -98.600); + mg_cubic_to(52.000, -98.600, 48.600, -94.200, 43.200, -98.200); + mg_cubic_to(37.800, -102.200, 40.800, -100.000, 35.800, -99.000); + mg_cubic_to(35.800, -99.000, 33.200, -98.200, 28.600, -102.200); + mg_cubic_to(28.600, -102.200, 23.000, -106.800, 14.200, -103.200); + mg_cubic_to(14.200, -103.200, -16.400, -90.600, -18.400, -90.000); + mg_cubic_to(-18.400, -90.000, -22.000, -87.200, -24.400, -83.600); + mg_cubic_to(-24.400, -83.600, -30.200, -79.200, -33.200, -77.800); + mg_cubic_to(-33.200, -77.800, -46.000, -66.200, -47.200, -64.800); + mg_cubic_to(-47.200, -64.800, -50.600, -59.600, -51.400, -59.200); + mg_cubic_to(-51.400, -59.200, -45.000, -63.000, -43.000, -65.000); + mg_cubic_to(-43.000, -65.000, -29.000, -75.000, -23.600, -75.800); + mg_cubic_to(-23.600, -75.800, -19.200, -78.800, -18.400, -80.200); + mg_cubic_to(-18.400, -80.200, -4.000, -89.400, 0.200, -89.400); + mg_cubic_to(0.200, -89.400, 9.400, -84.200, 11.800, -91.200); + mg_cubic_to(11.800, -91.200, 17.600, -93.000, 23.200, -91.800); + mg_cubic_to(23.200, -91.800, 26.400, -94.400, 25.600, -96.600); + mg_cubic_to(25.600, -96.600, 27.200, -98.400, 28.200, -94.600); + mg_cubic_to(28.200, -94.600, 31.600, -91.000, 36.400, -93.000); + mg_cubic_to(36.400, -93.000, 40.400, -93.200, 38.400, -90.800); + mg_cubic_to(38.400, -90.800, 34.000, -87.000, 22.200, -86.800); + mg_cubic_to(22.200, -86.800, 9.800, -86.200, -6.600, -78.600); + mg_cubic_to(-6.600, -78.600, -36.400, -68.200, -45.600, -57.800); + mg_cubic_to(-45.600, -57.800, -52.000, -49.000, -57.400, -47.800); + mg_cubic_to(-57.400, -47.800, -63.200, -47.000, -69.200, -39.600); + mg_cubic_to(-69.200, -39.600, -59.400, -45.400, -50.400, -45.400); + mg_cubic_to(-50.400, -45.400, -46.400, -47.800, -50.200, -44.200); + mg_cubic_to(-50.200, -44.200, -53.800, -36.600, -52.200, -31.200); + mg_cubic_to(-52.200, -31.200, -52.800, -26.000, -53.600, -24.400); + mg_cubic_to(-53.600, -24.400, -61.400, -11.600, -61.400, -9.200); + mg_cubic_to(-61.400, -6.800, -60.200, 3.000, -59.800, 3.600); + mg_cubic_to(-59.400, 4.200, -60.800, 2.000, -57.000, 4.400); + mg_cubic_to(-53.200, 6.800, -50.400, 8.400, -49.600, 11.200); + mg_cubic_to(-48.800, 14.000, -51.600, 5.800, -51.800, 4.000); + mg_cubic_to(-52.000, 2.200, -56.200, -5.000, -55.400, -7.400); + mg_cubic_to(-55.400, -7.400, -54.400, -6.400, -53.600, -5.000); + mg_cubic_to(-53.600, -5.000, -54.200, -5.600, -53.600, -9.200); + mg_cubic_to(-53.600, -9.200, -52.800, -14.400, -51.400, -17.600); + mg_cubic_to(-50.000, -20.800, -48.000, -24.600, -47.600, -25.400); + mg_cubic_to(-47.200, -26.200, -47.200, -32.000, -45.800, -29.400); + mg_line_to(-42.400, -26.800); + mg_cubic_to(-42.400, -26.800, -45.200, -29.400, -43.000, -31.600); + mg_cubic_to(-43.000, -31.600, -44.000, -37.200, -42.200, -39.800); + mg_cubic_to(-42.200, -39.800, -35.200, -48.200, -33.600, -49.200); + mg_cubic_to(-32.000, -50.200, -33.400, -49.800, -33.400, -49.800); + mg_cubic_to(-33.400, -49.800, -27.400, -54.000, -33.200, -52.400); + mg_cubic_to(-33.200, -52.400, -37.200, -50.800, -40.200, -50.800); + mg_cubic_to(-40.200, -50.800, -47.800, -48.800, -43.800, -53.000); + mg_cubic_to(-39.800, -57.200, -29.800, -62.600, -26.000, -62.400); + mg_line_to(-25.200, -60.800); + mg_line_to(-14.000, -63.200); + mg_line_to(-15.200, -62.400); + mg_cubic_to(-15.200, -62.400, -15.400, -62.600, -11.200, -63.000); + mg_cubic_to(-7.000, -63.400, -1.200, -62.000, 0.200, -63.800); + mg_cubic_to(1.600, -65.600, 5.000, -66.600, 4.600, -65.200); + mg_cubic_to(4.200, -63.800, 4.000, -61.800, 4.000, -61.800); + mg_cubic_to(4.000, -61.800, 9.000, -67.600, 8.400, -65.400); + mg_cubic_to(7.800, -63.200, -0.400, -58.000, -1.800, -51.800); + mg_line_to(8.600, -60.000); + mg_line_to(12.200, -63.000); + mg_cubic_to(12.200, -63.000, 15.800, -60.800, 16.000, -62.400); + mg_cubic_to(16.200, -64.000, 20.800, -69.800, 22.000, -69.600); + mg_cubic_to(23.200, -69.400, 25.200, -72.200, 25.000, -69.600); + mg_cubic_to(24.800, -67.000, 32.400, -61.600, 32.400, -61.600); + mg_cubic_to(32.400, -61.600, 35.600, -63.400, 37.000, -62.000); + mg_cubic_to(38.400, -60.600, 42.600, -81.800, 42.600, -81.800); + mg_line_to(67.600, -92.400); + mg_line_to(111.200, -95.800); + mg_line_to(94.201, -102.600); + mg_line_to(33.200, -114.000); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 146) + { + mg_move_to(51.400, 85.000); + mg_cubic_to(51.400, 85.000, 36.400, 68.200, 28.000, 65.600); + mg_cubic_to(28.000, 65.600, 14.600, 58.800, -10.000, 66.600); + } + if(!singlePath || singlePathIndex == 147) + { + mg_set_width(2); + mg_set_color_rgba(0.298, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 148) + { + mg_move_to(24.800, 64.200); + mg_cubic_to(24.800, 64.200, -0.400, 56.200, -15.800, 60.400); + mg_cubic_to(-15.800, 60.400, -34.200, 62.400, -42.600, 76.200); + } + if(!singlePath || singlePathIndex == 149) + { + mg_set_width(2); + mg_set_color_rgba(0.298, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 150) + { + mg_move_to(21.200, 63.000); + mg_cubic_to(21.200, 63.000, 4.200, 55.800, -10.600, 53.600); + mg_cubic_to(-10.600, 53.600, -27.200, 51.000, -43.800, 58.200); + mg_cubic_to(-43.800, 58.200, -56.000, 64.200, -61.400, 74.400); + } + if(!singlePath || singlePathIndex == 151) + { + mg_set_width(2); + mg_set_color_rgba(0.298, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 152) + { + mg_move_to(22.200, 63.400); + mg_cubic_to(22.200, 63.400, 6.800, 52.400, 5.800, 51.000); + mg_cubic_to(5.800, 51.000, -1.200, 40.000, -14.200, 39.600); + mg_cubic_to(-14.200, 39.600, -35.600, 40.400, -52.800, 48.400); + } + if(!singlePath || singlePathIndex == 153) + { + mg_set_width(2); + mg_set_color_rgba(0.298, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 154) + { + mg_move_to(20.895, 54.407); + mg_cubic_to(22.437, 55.870, 49.400, 84.800, 49.400, 84.800); + mg_cubic_to(84.600, 121.400, 56.600, 87.200, 56.600, 87.200); + mg_cubic_to(49.000, 82.400, 39.800, 63.600, 39.800, 63.600); + mg_cubic_to(38.600, 60.800, 53.800, 70.800, 53.800, 70.800); + mg_cubic_to(57.800, 71.600, 71.400, 90.800, 71.400, 90.800); + mg_cubic_to(64.600, 88.400, 69.400, 95.600, 69.400, 95.600); + mg_cubic_to(72.200, 97.600, 92.601, 113.200, 92.601, 113.200); + mg_cubic_to(96.201, 117.200, 100.200, 118.800, 100.200, 118.800); + mg_cubic_to(114.200, 113.600, 107.800, 126.800, 107.800, 126.800); + mg_cubic_to(110.200, 133.600, 115.800, 122.000, 115.800, 122.000); + mg_cubic_to(127.000, 105.200, 110.600, 107.600, 110.600, 107.600); + mg_cubic_to(80.600, 110.400, 73.800, 94.400, 73.800, 94.400); + mg_cubic_to(71.400, 92.000, 80.200, 94.400, 80.200, 94.400); + mg_cubic_to(88.601, 96.400, 73.000, 82.000, 73.000, 82.000); + mg_cubic_to(75.400, 82.000, 84.600, 88.800, 84.600, 88.800); + mg_cubic_to(95.001, 98.000, 97.001, 96.000, 97.001, 96.000); + mg_cubic_to(115.000, 87.200, 125.400, 94.800, 125.400, 94.800); + mg_cubic_to(127.400, 96.400, 121.800, 103.200, 123.400, 108.400); + mg_cubic_to(125.000, 113.600, 129.800, 126.000, 129.800, 126.000); + mg_cubic_to(127.400, 127.600, 127.800, 138.400, 127.800, 138.400); + mg_cubic_to(144.600, 161.600, 135.000, 159.600, 135.000, 159.600); + mg_cubic_to(119.400, 159.200, 134.200, 166.800, 134.200, 166.800); + mg_cubic_to(137.400, 168.800, 146.200, 176.000, 146.200, 176.000); + mg_cubic_to(143.400, 174.800, 141.800, 180.000, 141.800, 180.000); + mg_cubic_to(146.600, 184.000, 143.800, 188.800, 143.800, 188.800); + mg_cubic_to(137.800, 190.000, 136.600, 194.000, 136.600, 194.000); + mg_cubic_to(143.400, 202.000, 133.400, 202.400, 133.400, 202.400); + mg_cubic_to(137.000, 206.800, 132.200, 218.800, 132.200, 218.800); + mg_cubic_to(127.400, 218.800, 121.000, 224.400, 121.000, 224.400); + mg_cubic_to(123.400, 229.200, 113.000, 234.800, 113.000, 234.800); + mg_cubic_to(104.600, 236.400, 107.400, 243.200, 107.400, 243.200); + mg_cubic_to(99.401, 249.200, 97.001, 265.200, 97.001, 265.200); + mg_cubic_to(96.201, 275.600, 93.801, 278.800, 99.001, 276.800); + mg_cubic_to(104.200, 274.800, 103.400, 262.400, 103.400, 262.400); + mg_cubic_to(98.601, 246.800, 141.400, 230.800, 141.400, 230.800); + mg_cubic_to(145.400, 229.200, 146.200, 224.000, 146.200, 224.000); + mg_cubic_to(148.200, 224.400, 157.000, 232.000, 157.000, 232.000); + mg_cubic_to(164.600, 243.200, 165.000, 234.000, 165.000, 234.000); + mg_cubic_to(166.200, 230.400, 164.600, 224.400, 164.600, 224.400); + mg_cubic_to(170.600, 202.800, 156.600, 196.400, 156.600, 196.400); + mg_cubic_to(146.600, 162.800, 160.600, 171.200, 160.600, 171.200); + mg_cubic_to(163.400, 176.800, 174.200, 182.000, 174.200, 182.000); + mg_line_to(177.800, 179.600); + mg_cubic_to(176.200, 174.800, 184.600, 168.800, 184.600, 168.800); + mg_cubic_to(187.400, 175.200, 193.400, 167.200, 193.400, 167.200); + mg_cubic_to(197.000, 142.800, 209.400, 157.200, 209.400, 157.200); + mg_cubic_to(213.400, 158.400, 214.600, 151.600, 214.600, 151.600); + mg_cubic_to(218.200, 141.200, 214.600, 127.600, 214.600, 127.600); + mg_cubic_to(218.200, 127.200, 227.800, 133.200, 227.800, 133.200); + mg_cubic_to(230.600, 129.600, 221.400, 112.800, 225.400, 115.200); + mg_cubic_to(229.400, 117.600, 233.800, 119.200, 233.800, 119.200); + mg_cubic_to(234.600, 117.200, 224.600, 104.800, 224.600, 104.800); + mg_cubic_to(220.200, 102.000, 215.000, 81.600, 215.000, 81.600); + mg_cubic_to(222.200, 85.200, 212.200, 70.000, 212.200, 70.000); + mg_cubic_to(212.200, 66.800, 218.200, 55.600, 218.200, 55.600); + mg_cubic_to(217.400, 48.800, 218.200, 49.200, 218.200, 49.200); + mg_cubic_to(221.000, 50.400, 229.000, 52.000, 222.200, 45.600); + mg_cubic_to(215.400, 39.200, 223.000, 34.400, 223.000, 34.400); + mg_cubic_to(227.400, 31.600, 213.800, 32.000, 213.800, 32.000); + mg_cubic_to(208.600, 27.600, 209.000, 23.600, 209.000, 23.600); + mg_cubic_to(217.000, 25.600, 202.600, 11.200, 200.200, 7.600); + mg_cubic_to(197.800, 4.000, 207.400, -1.200, 207.400, -1.200); + mg_cubic_to(220.600, -4.800, 209.000, -8.000, 209.000, -8.000); + mg_cubic_to(189.400, -7.600, 200.200, -18.400, 200.200, -18.400); + mg_cubic_to(206.200, -18.000, 204.600, -20.400, 204.600, -20.400); + mg_cubic_to(199.400, -21.600, 189.800, -28.000, 189.800, -28.000); + mg_cubic_to(185.800, -31.600, 189.400, -30.800, 189.400, -30.800); + mg_cubic_to(206.200, -29.600, 177.400, -40.800, 177.400, -40.800); + mg_cubic_to(185.400, -40.800, 167.400, -51.200, 167.400, -51.200); + mg_cubic_to(165.400, -52.800, 162.200, -60.400, 162.200, -60.400); + mg_cubic_to(156.200, -65.600, 151.400, -72.400, 151.400, -72.400); + mg_cubic_to(151.000, -76.800, 146.200, -81.600, 146.200, -81.600); + mg_cubic_to(134.600, -95.200, 129.000, -94.800, 129.000, -94.800); + mg_cubic_to(114.200, -98.400, 109.000, -97.600, 109.000, -97.600); + mg_line_to(56.200, -93.200); + mg_cubic_to(29.800, -80.400, 37.600, -59.400, 37.600, -59.400); + mg_cubic_to(44.000, -51.000, 53.200, -54.800, 53.200, -54.800); + mg_cubic_to(57.800, -61.000, 69.400, -58.800, 69.400, -58.800); + mg_cubic_to(89.801, -55.600, 87.201, -59.200, 87.201, -59.200); + mg_cubic_to(84.801, -63.800, 68.600, -70.000, 68.400, -70.600); + mg_cubic_to(68.200, -71.200, 59.400, -74.600, 59.400, -74.600); + mg_cubic_to(56.400, -75.800, 52.000, -85.000, 52.000, -85.000); + mg_cubic_to(48.800, -88.400, 64.600, -82.600, 64.600, -82.600); + mg_cubic_to(63.400, -81.600, 70.800, -77.600, 70.800, -77.600); + mg_cubic_to(88.201, -78.600, 98.801, -67.800, 98.801, -67.800); + mg_cubic_to(109.600, -51.200, 109.800, -59.400, 109.800, -59.400); + mg_cubic_to(112.600, -68.800, 100.800, -90.000, 100.800, -90.000); + mg_cubic_to(101.200, -92.000, 109.400, -85.400, 109.400, -85.400); + mg_cubic_to(110.800, -87.400, 111.600, -81.600, 111.600, -81.600); + mg_cubic_to(111.800, -79.200, 115.600, -71.200, 115.600, -71.200); + mg_cubic_to(118.400, -58.200, 122.000, -65.600, 122.000, -65.600); + mg_line_to(126.600, -56.200); + mg_cubic_to(128.000, -53.600, 122.000, -46.000, 122.000, -46.000); + mg_cubic_to(121.800, -43.200, 122.600, -43.400, 117.000, -35.800); + mg_cubic_to(111.400, -28.200, 114.800, -23.800, 114.800, -23.800); + mg_cubic_to(113.400, -17.200, 122.200, -17.600, 122.200, -17.600); + mg_cubic_to(124.800, -15.400, 128.200, -15.400, 128.200, -15.400); + mg_cubic_to(130.000, -13.400, 132.400, -14.000, 132.400, -14.000); + mg_cubic_to(134.000, -17.800, 140.200, -15.800, 140.200, -15.800); + mg_cubic_to(141.600, -18.200, 149.800, -18.600, 149.800, -18.600); + mg_cubic_to(150.800, -21.200, 151.200, -22.800, 154.600, -23.400); + mg_cubic_to(158.000, -24.000, 133.400, -67.000, 133.400, -67.000); + mg_cubic_to(139.800, -67.800, 131.600, -80.200, 131.600, -80.200); + mg_cubic_to(129.400, -86.800, 140.800, -72.200, 143.000, -70.800); + mg_cubic_to(145.200, -69.400, 146.200, -67.200, 144.600, -67.400); + mg_cubic_to(143.000, -67.600, 141.200, -65.400, 142.600, -65.200); + mg_cubic_to(144.000, -65.000, 157.000, -50.000, 160.400, -39.800); + mg_cubic_to(163.800, -29.600, 169.800, -25.600, 176.000, -19.600); + mg_cubic_to(182.200, -13.600, 181.400, 10.600, 181.400, 10.600); + mg_cubic_to(181.000, 19.400, 187.000, 30.000, 187.000, 30.000); + mg_cubic_to(189.000, 33.800, 184.800, 52.000, 184.800, 52.000); + mg_cubic_to(182.800, 54.200, 184.200, 55.000, 184.200, 55.000); + mg_cubic_to(185.200, 56.200, 192.000, 69.400, 192.000, 69.400); + mg_cubic_to(190.200, 69.200, 193.800, 72.800, 193.800, 72.800); + mg_cubic_to(199.000, 78.800, 192.600, 75.800, 192.600, 75.800); + mg_cubic_to(186.600, 74.200, 193.600, 84.000, 193.600, 84.000); + mg_cubic_to(194.800, 85.800, 185.800, 81.200, 185.800, 81.200); + mg_cubic_to(176.600, 80.600, 188.200, 87.800, 188.200, 87.800); + mg_cubic_to(196.800, 95.000, 185.400, 90.600, 185.400, 90.600); + mg_cubic_to(180.800, 88.800, 184.000, 95.600, 184.000, 95.600); + mg_cubic_to(187.200, 97.200, 204.400, 104.200, 204.400, 104.200); + mg_cubic_to(204.800, 108.000, 201.800, 113.000, 201.800, 113.000); + mg_cubic_to(202.200, 117.000, 200.000, 120.400, 200.000, 120.400); + mg_cubic_to(198.800, 128.600, 198.200, 129.400, 198.200, 129.400); + mg_cubic_to(194.000, 129.600, 186.600, 143.400, 186.600, 143.400); + mg_cubic_to(184.800, 146.000, 174.600, 158.000, 174.600, 158.000); + mg_cubic_to(172.600, 165.000, 154.600, 157.800, 154.600, 157.800); + mg_cubic_to(148.000, 161.200, 150.000, 157.800, 150.000, 157.800); + mg_cubic_to(149.600, 155.600, 154.400, 149.600, 154.400, 149.600); + mg_cubic_to(161.400, 147.000, 158.800, 136.200, 158.800, 136.200); + mg_cubic_to(162.800, 134.800, 151.600, 132.000, 151.800, 130.800); + mg_cubic_to(152.000, 129.600, 157.800, 128.200, 157.800, 128.200); + mg_cubic_to(165.800, 126.200, 161.400, 123.800, 161.400, 123.800); + mg_cubic_to(160.800, 119.800, 163.800, 114.200, 163.800, 114.200); + mg_cubic_to(175.400, 113.400, 163.800, 97.200, 163.800, 97.200); + mg_cubic_to(153.000, 89.600, 152.000, 83.800, 152.000, 83.800); + mg_cubic_to(164.600, 75.600, 156.400, 63.200, 156.600, 59.600); + mg_cubic_to(156.800, 56.000, 158.000, 34.400, 158.000, 34.400); + mg_cubic_to(156.000, 28.200, 153.000, 14.600, 153.000, 14.600); + mg_cubic_to(155.200, 9.400, 162.600, -3.200, 162.600, -3.200); + mg_cubic_to(165.400, -7.400, 174.200, -12.200, 172.000, -15.200); + mg_cubic_to(169.800, -18.200, 162.000, -16.400, 162.000, -16.400); + mg_cubic_to(154.200, -17.800, 154.800, -12.600, 154.800, -12.600); + mg_cubic_to(153.200, -11.600, 152.400, -6.600, 152.400, -6.600); + mg_cubic_to(151.680, 1.333, 142.800, 7.600, 142.800, 7.600); + mg_cubic_to(131.600, 13.800, 140.800, 17.800, 140.800, 17.800); + mg_cubic_to(146.800, 24.400, 137.000, 24.600, 137.000, 24.600); + mg_cubic_to(126.000, 22.800, 134.200, 33.000, 134.200, 33.000); + mg_cubic_to(145.000, 45.800, 142.000, 48.600, 142.000, 48.600); + mg_cubic_to(131.800, 49.600, 144.400, 58.800, 144.400, 58.800); + mg_cubic_to(144.400, 58.800, 143.600, 56.800, 143.800, 58.600); + mg_cubic_to(144.000, 60.400, 147.000, 64.600, 147.800, 66.600); + mg_cubic_to(148.600, 68.600, 144.600, 68.800, 144.600, 68.800); + mg_cubic_to(145.200, 78.400, 129.800, 74.200, 129.800, 74.200); + mg_line_to(128.200, 74.400); + mg_cubic_to(126.600, 74.600, 115.400, 73.800, 109.600, 71.600); + mg_cubic_to(103.800, 69.400, 97.001, 69.400, 97.001, 69.400); + mg_cubic_to(97.001, 69.400, 93.001, 71.200, 85.400, 71.000); + mg_cubic_to(77.800, 70.800, 69.800, 73.600, 69.800, 73.600); + mg_cubic_to(65.400, 73.200, 74.000, 68.800, 74.200, 69.000); + mg_cubic_to(74.400, 69.200, 80.000, 63.600, 72.000, 64.200); + mg_cubic_to(50.203, 65.835, 39.400, 55.600, 39.400, 55.600); + mg_cubic_to(37.400, 54.200, 34.800, 51.400, 34.800, 51.400); + mg_cubic_to(24.800, 49.400, 36.200, 63.800, 36.200, 63.800); + mg_cubic_to(37.400, 65.200, 36.000, 66.200, 36.000, 66.200); + mg_cubic_to(35.200, 64.600, 27.400, 59.200, 27.400, 59.200); + mg_cubic_to(24.589, 58.227, 23.226, 56.893, 20.895, 54.407); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 155) + { + mg_move_to(-3.000, 42.800); + mg_cubic_to(-3.000, 42.800, 8.600, 48.400, 11.200, 51.200); + mg_cubic_to(13.800, 54.000, 27.800, 65.400, 27.800, 65.400); + mg_cubic_to(27.800, 65.400, 22.400, 63.400, 19.800, 61.600); + mg_cubic_to(17.200, 59.800, 6.400, 51.600, 6.400, 51.600); + mg_cubic_to(6.400, 51.600, 2.600, 45.600, -3.000, 42.800); + mg_close_path(); + mg_set_color_rgba(0.298, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 156) + { + mg_move_to(-61.009, 11.603); + mg_cubic_to(-60.672, 11.455, -61.196, 8.743, -61.400, 8.200); + mg_cubic_to(-62.422, 5.474, -71.400, 4.000, -71.400, 4.000); + mg_cubic_to(-71.627, 5.365, -71.682, 6.961, -71.576, 8.599); + mg_cubic_to(-71.576, 8.599, -66.708, 14.118, -61.009, 11.603); + mg_close_path(); + mg_set_color_rgba(0.600, 0.800, 0.196, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 157) + { + mg_move_to(-61.009, 11.403); + mg_cubic_to(-61.458, 11.561, -61.024, 8.669, -61.200, 8.200); + mg_cubic_to(-62.222, 5.474, -71.400, 3.900, -71.400, 3.900); + mg_cubic_to(-71.627, 5.265, -71.682, 6.861, -71.576, 8.499); + mg_cubic_to(-71.576, 8.499, -67.308, 13.618, -61.009, 11.403); + mg_close_path(); + mg_set_color_rgba(0.396, 0.600, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 158) + { + mg_move_to(-65.400, 11.546); + mg_cubic_to(-66.025, 11.546, -66.531, 10.406, -66.531, 9.000); + mg_cubic_to(-66.531, 7.595, -66.025, 6.455, -65.400, 6.455); + mg_cubic_to(-64.775, 6.455, -64.268, 7.595, -64.268, 9.000); + mg_cubic_to(-64.268, 10.406, -64.775, 11.546, -65.400, 11.546); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 159) + { + mg_move_to(-65.400, 9.000); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 160) + { + mg_move_to(-111.000, 109.600); + mg_cubic_to(-111.000, 109.600, -116.600, 119.600, -91.800, 113.600); + mg_cubic_to(-91.800, 113.600, -77.800, 112.400, -75.400, 110.000); + mg_cubic_to(-74.200, 110.800, -65.834, 113.730, -63.000, 114.400); + mg_cubic_to(-56.200, 116.000, -47.800, 106.000, -47.800, 106.000); + mg_cubic_to(-47.800, 106.000, -43.200, 95.500, -40.400, 95.500); + mg_cubic_to(-37.600, 95.500, -40.800, 97.100, -40.800, 97.100); + mg_cubic_to(-40.800, 97.100, -47.400, 107.200, -47.000, 108.800); + mg_cubic_to(-47.000, 108.800, -52.200, 128.800, -68.200, 129.600); + mg_cubic_to(-68.200, 129.600, -84.350, 130.550, -83.000, 136.400); + mg_cubic_to(-83.000, 136.400, -74.200, 134.000, -71.800, 136.400); + mg_cubic_to(-71.800, 136.400, -61.000, 136.000, -69.000, 142.400); + mg_line_to(-75.800, 154.000); + mg_cubic_to(-75.800, 154.000, -75.660, 157.920, -85.800, 154.400); + mg_cubic_to(-95.600, 151.000, -105.900, 138.100, -105.900, 138.100); + mg_cubic_to(-105.900, 138.100, -121.850, 123.550, -111.000, 109.600); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 161) + { + mg_move_to(-112.200, 113.600); + mg_cubic_to(-112.200, 113.600, -114.200, 123.200, -77.400, 112.800); + mg_line_to(-70.600, 113.600); + mg_cubic_to(-68.200, 114.400, -56.200, 117.200, -54.200, 116.000); + mg_cubic_to(-54.200, 116.000, -61.400, 129.600, -73.000, 128.000); + mg_cubic_to(-73.000, 128.000, -86.200, 129.600, -85.800, 134.400); + mg_cubic_to(-85.800, 134.400, -81.800, 141.600, -77.000, 144.000); + mg_cubic_to(-77.000, 144.000, -74.200, 146.400, -74.600, 149.600); + mg_cubic_to(-75.000, 152.800, -77.800, 154.400, -79.800, 155.200); + mg_cubic_to(-81.800, 156.000, -85.000, 152.800, -86.600, 152.800); + mg_cubic_to(-88.200, 152.800, -96.600, 146.400, -101.000, 141.600); + mg_cubic_to(-105.400, 136.800, -113.800, 124.800, -113.400, 122.000); + mg_cubic_to(-113.000, 119.200, -112.200, 113.600, -112.200, 113.600); + mg_close_path(); + mg_set_color_rgba(0.898, 0.600, 0.600, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 162) + { + mg_move_to(-109.000, 131.050); + mg_cubic_to(-106.400, 135.000, -103.200, 139.200, -101.000, 141.600); + mg_cubic_to(-96.600, 146.400, -88.200, 152.800, -86.600, 152.800); + mg_cubic_to(-85.000, 152.800, -81.800, 156.000, -79.800, 155.200); + mg_cubic_to(-77.800, 154.400, -75.000, 152.800, -74.600, 149.600); + mg_cubic_to(-74.200, 146.400, -77.000, 144.000, -77.000, 144.000); + mg_cubic_to(-80.066, 142.470, -82.806, 138.980, -84.385, 136.650); + mg_cubic_to(-84.385, 136.650, -84.200, 139.200, -89.400, 138.400); + mg_cubic_to(-94.600, 137.600, -99.800, 134.800, -101.400, 131.600); + mg_cubic_to(-103.000, 128.400, -105.400, 126.000, -103.800, 129.600); + mg_cubic_to(-102.200, 133.200, -99.800, 136.800, -98.200, 137.200); + mg_cubic_to(-96.600, 137.600, -97.000, 138.800, -99.400, 138.400); + mg_cubic_to(-101.800, 138.000, -104.600, 137.600, -109.000, 132.400); + mg_close_path(); + mg_set_color_rgba(0.698, 0.396, 0.396, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 163) + { + mg_move_to(-111.600, 110.000); + mg_cubic_to(-111.600, 110.000, -109.800, 96.400, -108.600, 92.400); + mg_cubic_to(-108.600, 92.400, -109.400, 85.600, -107.000, 81.400); + mg_cubic_to(-104.600, 77.200, -102.600, 71.000, -99.600, 65.600); + mg_cubic_to(-96.600, 60.200, -96.400, 56.200, -92.400, 54.600); + mg_cubic_to(-88.400, 53.000, -82.400, 44.400, -79.600, 43.400); + mg_cubic_to(-76.800, 42.400, -77.000, 43.200, -77.000, 43.200); + mg_cubic_to(-77.000, 43.200, -70.200, 28.400, -56.600, 32.400); + mg_cubic_to(-56.600, 32.400, -72.800, 29.600, -57.000, 20.200); + mg_cubic_to(-57.000, 20.200, -61.800, 21.300, -58.500, 14.300); + mg_cubic_to(-56.299, 9.632, -56.800, 16.400, -67.800, 28.200); + mg_cubic_to(-67.800, 28.200, -72.800, 36.800, -78.000, 39.800); + mg_cubic_to(-83.200, 42.800, -95.200, 49.800, -96.400, 53.600); + mg_cubic_to(-97.600, 57.400, -100.800, 63.200, -102.800, 64.800); + mg_cubic_to(-104.800, 66.400, -107.600, 70.600, -108.000, 74.000); + mg_cubic_to(-108.000, 74.000, -109.200, 78.000, -110.600, 79.200); + mg_cubic_to(-112.000, 80.400, -112.200, 83.600, -112.200, 85.600); + mg_cubic_to(-112.200, 87.600, -114.200, 90.400, -114.000, 92.800); + mg_cubic_to(-114.000, 92.800, -113.200, 111.800, -113.600, 113.800); + mg_line_to(-111.600, 110.000); + mg_close_path(); + mg_set_color_rgba(0.600, 0.149, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 164) + { + mg_move_to(-120.200, 114.600); + mg_cubic_to(-120.200, 114.600, -122.200, 113.200, -126.600, 119.200); + mg_cubic_to(-126.600, 119.200, -119.300, 152.200, -119.300, 153.600); + mg_cubic_to(-119.300, 153.600, -118.200, 151.500, -119.500, 144.300); + mg_cubic_to(-120.800, 137.100, -121.700, 124.400, -121.700, 124.400); + mg_line_to(-120.200, 114.600); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 165) + { + mg_move_to(-98.600, 54.000); + mg_cubic_to(-98.600, 54.000, -116.200, 57.200, -115.800, 86.400); + mg_line_to(-116.600, 111.200); + mg_cubic_to(-116.600, 111.200, -117.800, 85.600, -119.000, 84.000); + mg_cubic_to(-120.200, 82.400, -116.200, 71.200, -119.400, 77.200); + mg_cubic_to(-119.400, 77.200, -133.400, 91.200, -125.400, 112.400); + mg_cubic_to(-125.400, 112.400, -123.900, 115.700, -126.900, 111.100); + mg_cubic_to(-126.900, 111.100, -131.500, 98.500, -130.400, 92.100); + mg_cubic_to(-130.400, 92.100, -130.200, 89.900, -128.300, 87.100); + mg_cubic_to(-128.300, 87.100, -119.700, 75.400, -117.000, 73.100); + mg_cubic_to(-117.000, 73.100, -115.200, 58.700, -99.800, 53.500); + mg_cubic_to(-99.800, 53.500, -94.100, 51.200, -98.600, 54.000); + mg_close_path(); + mg_set_color_rgba(0.600, 0.149, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 166) + { + mg_move_to(40.800, -12.200); + mg_cubic_to(41.460, -12.554, 41.451, -13.524, 42.031, -13.697); + mg_cubic_to(43.180, -14.041, 43.344, -15.108, 43.862, -15.892); + mg_cubic_to(44.735, -17.211, 44.928, -18.744, 45.510, -20.235); + mg_cubic_to(45.782, -20.935, 45.809, -21.890, 45.496, -22.550); + mg_cubic_to(44.322, -25.031, 43.620, -27.480, 42.178, -29.906); + mg_cubic_to(41.910, -30.356, 41.648, -31.150, 41.447, -31.748); + mg_cubic_to(40.984, -33.132, 39.727, -34.123, 38.867, -35.443); + mg_cubic_to(38.579, -35.884, 39.104, -36.809, 38.388, -36.893); + mg_cubic_to(37.491, -36.998, 36.042, -37.578, 35.809, -36.552); + mg_cubic_to(35.221, -33.965, 36.232, -31.442, 37.200, -29.000); + mg_cubic_to(36.418, -28.308, 36.752, -27.387, 36.904, -26.620); + mg_cubic_to(37.614, -23.014, 36.416, -19.662, 35.655, -16.188); + mg_cubic_to(35.632, -16.084, 35.974, -15.886, 35.946, -15.824); + mg_cubic_to(34.724, -13.138, 33.272, -10.693, 31.453, -8.312); + mg_cubic_to(30.695, -7.320, 29.823, -6.404, 29.326, -5.341); + mg_cubic_to(28.958, -4.554, 28.550, -3.588, 28.800, -2.600); + mg_cubic_to(25.365, 0.180, 23.115, 4.025, 20.504, 7.871); + mg_cubic_to(20.042, 8.551, 20.333, 9.760, 20.884, 10.029); + mg_cubic_to(21.697, 10.427, 22.653, 9.403, 23.123, 8.557); + mg_cubic_to(23.512, 7.859, 23.865, 7.209, 24.356, 6.566); + mg_cubic_to(24.489, 6.391, 24.310, 5.972, 24.445, 5.851); + mg_cubic_to(27.078, 3.504, 28.747, 0.568, 31.200, -1.800); + mg_cubic_to(33.150, -2.129, 34.687, -3.127, 36.435, -4.140); + mg_cubic_to(36.743, -4.319, 37.267, -4.070, 37.557, -4.265); + mg_cubic_to(39.310, -5.442, 39.308, -7.478, 39.414, -9.388); + mg_cubic_to(39.464, -10.272, 39.660, -11.589, 40.800, -12.200); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 167) + { + mg_move_to(31.959, -16.666); + mg_cubic_to(32.083, -16.743, 31.928, -17.166, 32.037, -17.382); + mg_cubic_to(32.199, -17.706, 32.602, -17.894, 32.764, -18.218); + mg_cubic_to(32.873, -18.434, 32.710, -18.814, 32.846, -18.956); + mg_cubic_to(35.179, -21.403, 35.436, -24.427, 34.400, -27.400); + mg_cubic_to(35.424, -28.020, 35.485, -29.282, 35.060, -30.129); + mg_cubic_to(34.207, -31.829, 34.014, -33.755, 33.039, -35.298); + mg_cubic_to(32.237, -36.567, 30.659, -37.811, 29.288, -36.508); + mg_cubic_to(28.867, -36.108, 28.546, -35.321, 28.824, -34.609); + mg_cubic_to(28.888, -34.446, 29.173, -34.300, 29.146, -34.218); + mg_cubic_to(29.039, -33.894, 28.493, -33.670, 28.487, -33.398); + mg_cubic_to(28.457, -31.902, 27.503, -30.391, 28.133, -29.062); + mg_cubic_to(28.905, -27.433, 29.724, -25.576, 30.400, -23.800); + mg_cubic_to(29.166, -21.684, 30.199, -19.235, 28.446, -17.358); + mg_cubic_to(28.310, -17.212, 28.319, -16.826, 28.441, -16.624); + mg_cubic_to(28.733, -16.138, 29.139, -15.732, 29.625, -15.440); + mg_cubic_to(29.827, -15.319, 30.175, -15.317, 30.375, -15.441); + mg_cubic_to(30.953, -15.803, 31.351, -16.290, 31.959, -16.666); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 168) + { + mg_move_to(94.771, -26.977); + mg_cubic_to(96.160, -25.185, 96.450, -22.390, 94.401, -21.000); + mg_cubic_to(94.951, -17.691, 98.302, -19.670, 100.400, -20.200); + mg_cubic_to(100.290, -20.588, 100.520, -20.932, 100.800, -20.937); + mg_cubic_to(101.860, -20.952, 102.540, -21.984, 103.600, -21.800); + mg_cubic_to(104.040, -23.357, 105.670, -24.059, 106.320, -25.439); + mg_cubic_to(108.040, -29.134, 107.450, -33.407, 104.870, -36.653); + mg_cubic_to(104.670, -36.907, 104.880, -37.424, 104.760, -37.786); + mg_cubic_to(104.000, -39.997, 101.940, -40.312, 100.000, -41.000); + mg_cubic_to(98.824, -44.875, 98.163, -48.906, 96.401, -52.600); + mg_cubic_to(94.787, -52.850, 94.089, -54.589, 92.752, -55.309); + mg_cubic_to(91.419, -56.028, 90.851, -54.449, 90.892, -53.403); + mg_cubic_to(90.899, -53.198, 91.351, -52.974, 91.181, -52.609); + mg_cubic_to(91.105, -52.445, 90.845, -52.334, 90.845, -52.200); + mg_cubic_to(90.846, -52.065, 91.067, -51.934, 91.201, -51.800); + mg_cubic_to(90.283, -50.980, 88.860, -50.503, 88.565, -49.358); + mg_cubic_to(87.611, -45.648, 90.184, -42.523, 91.852, -39.322); + mg_cubic_to(92.443, -38.187, 91.707, -36.916, 90.947, -35.708); + mg_cubic_to(90.509, -35.013, 90.617, -33.886, 90.893, -33.030); + mg_cubic_to(91.645, -30.699, 93.236, -28.960, 94.771, -26.977); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 169) + { + mg_move_to(57.611, -8.591); + mg_cubic_to(56.124, -6.740, 52.712, -4.171, 55.629, -2.243); + mg_cubic_to(55.823, -2.114, 56.193, -2.110, 56.366, -2.244); + mg_cubic_to(58.387, -3.809, 60.390, -4.712, 62.826, -5.294); + mg_cubic_to(62.950, -5.323, 63.224, -4.856, 63.593, -5.017); + mg_cubic_to(65.206, -5.720, 67.216, -5.662, 68.400, -7.000); + mg_cubic_to(72.167, -6.776, 75.732, -7.892, 79.123, -9.200); + mg_cubic_to(80.284, -9.648, 81.554, -10.207, 82.755, -10.709); + mg_cubic_to(84.131, -11.285, 85.335, -12.213, 86.447, -13.354); + mg_cubic_to(86.580, -13.490, 86.934, -13.400, 87.201, -13.400); + mg_cubic_to(87.161, -14.263, 88.123, -14.390, 88.370, -15.012); + mg_cubic_to(88.462, -15.244, 88.312, -15.640, 88.445, -15.742); + mg_cubic_to(90.583, -17.372, 91.503, -19.390, 90.334, -21.767); + mg_cubic_to(90.049, -22.345, 89.800, -22.963, 89.234, -23.439); + mg_cubic_to(88.149, -24.350, 87.047, -23.496, 86.000, -23.800); + mg_cubic_to(85.841, -23.172, 85.112, -23.344, 84.726, -23.146); + mg_cubic_to(83.867, -22.707, 82.534, -23.292, 81.675, -22.854); + mg_cubic_to(80.313, -22.159, 79.072, -21.990, 77.650, -21.613); + mg_cubic_to(77.338, -21.531, 76.560, -21.627, 76.400, -21.000); + mg_cubic_to(76.266, -21.134, 76.118, -21.368, 76.012, -21.346); + mg_cubic_to(74.104, -20.950, 72.844, -20.736, 71.543, -19.044); + mg_cubic_to(71.440, -18.911, 70.998, -19.090, 70.839, -18.955); + mg_cubic_to(69.882, -18.147, 69.477, -16.913, 68.376, -16.241); + mg_cubic_to(68.175, -16.118, 67.823, -16.286, 67.629, -16.157); + mg_cubic_to(66.983, -15.726, 66.616, -15.085, 65.974, -14.638); + mg_cubic_to(65.645, -14.409, 65.245, -14.734, 65.277, -14.990); + mg_cubic_to(65.522, -16.937, 66.175, -18.724, 65.600, -20.600); + mg_cubic_to(67.677, -23.120, 70.194, -25.069, 72.000, -27.800); + mg_cubic_to(72.015, -29.966, 72.707, -32.112, 72.594, -34.189); + mg_cubic_to(72.584, -34.382, 72.296, -35.115, 72.170, -35.462); + mg_cubic_to(71.858, -36.316, 72.764, -37.382, 71.920, -38.106); + mg_cubic_to(70.516, -39.309, 69.224, -38.433, 68.400, -37.000); + mg_cubic_to(66.562, -36.610, 64.496, -35.917, 62.918, -37.151); + mg_cubic_to(61.911, -37.938, 61.333, -38.844, 60.534, -39.900); + mg_cubic_to(59.549, -41.202, 59.884, -42.638, 59.954, -44.202); + mg_cubic_to(59.960, -44.330, 59.645, -44.466, 59.645, -44.600); + mg_cubic_to(59.646, -44.735, 59.866, -44.866, 60.000, -45.000); + mg_cubic_to(59.294, -45.626, 59.019, -46.684, 58.000, -47.000); + mg_cubic_to(58.305, -48.092, 57.629, -48.976, 56.758, -49.278); + mg_cubic_to(54.763, -49.969, 53.086, -48.057, 51.194, -47.984); + mg_cubic_to(50.680, -47.965, 50.213, -49.003, 49.564, -49.328); + mg_cubic_to(49.132, -49.544, 48.428, -49.577, 48.066, -49.311); + mg_cubic_to(47.378, -48.807, 46.789, -48.693, 46.031, -48.488); + mg_cubic_to(44.414, -48.052, 43.136, -46.958, 41.656, -46.103); + mg_cubic_to(40.171, -45.246, 39.216, -43.809, 38.136, -42.489); + mg_cubic_to(37.195, -41.337, 37.059, -38.923, 38.479, -38.423); + mg_cubic_to(40.322, -37.773, 41.626, -40.476, 43.592, -40.150); + mg_cubic_to(43.904, -40.099, 44.110, -39.788, 44.000, -39.400); + mg_cubic_to(44.389, -39.291, 44.607, -39.520, 44.800, -39.800); + mg_cubic_to(45.658, -38.781, 46.822, -38.444, 47.760, -37.571); + mg_cubic_to(48.730, -36.667, 50.476, -37.085, 51.491, -36.088); + mg_cubic_to(53.020, -34.586, 52.461, -31.905, 54.400, -30.600); + mg_cubic_to(53.814, -29.287, 53.207, -28.010, 52.872, -26.583); + mg_cubic_to(52.590, -25.377, 53.584, -24.180, 54.795, -24.271); + mg_cubic_to(56.053, -24.365, 56.315, -25.124, 56.800, -26.200); + mg_cubic_to(57.067, -25.933, 57.536, -25.636, 57.495, -25.420); + mg_cubic_to(57.038, -23.033, 56.011, -21.040, 55.553, -18.609); + mg_cubic_to(55.494, -18.292, 55.189, -18.090, 54.800, -18.200); + mg_cubic_to(54.332, -14.051, 50.280, -11.657, 47.735, -8.492); + mg_cubic_to(47.332, -7.990, 47.328, -6.741, 47.737, -6.338); + mg_cubic_to(49.140, -4.951, 51.100, -6.497, 52.800, -7.000); + mg_cubic_to(53.013, -8.206, 53.872, -9.148, 55.204, -9.092); + mg_cubic_to(55.460, -9.082, 55.695, -9.624, 56.019, -9.754); + mg_cubic_to(56.367, -9.892, 56.869, -9.668, 57.155, -9.866); + mg_cubic_to(58.884, -11.061, 60.292, -12.167, 62.030, -13.356); + mg_cubic_to(62.222, -13.487, 62.566, -13.328, 62.782, -13.436); + mg_cubic_to(63.107, -13.598, 63.294, -13.985, 63.617, -14.170); + mg_cubic_to(63.965, -14.370, 64.207, -14.080, 64.400, -13.800); + mg_cubic_to(63.754, -13.451, 63.750, -12.494, 63.168, -12.292); + mg_cubic_to(62.393, -12.024, 61.832, -11.511, 61.158, -11.064); + mg_cubic_to(60.866, -10.871, 60.207, -11.119, 60.103, -10.940); + mg_cubic_to(59.505, -9.912, 58.321, -9.474, 57.611, -8.591); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 170) + { + mg_move_to(2.200, -58.000); + mg_cubic_to(2.200, -58.000, -7.038, -60.872, -18.200, -35.200); + mg_cubic_to(-18.200, -35.200, -20.600, -30.000, -23.000, -28.000); + mg_cubic_to(-25.400, -26.000, -36.600, -22.400, -38.600, -18.400); + mg_line_to(-49.000, -2.400); + mg_cubic_to(-49.000, -2.400, -34.200, -18.400, -31.000, -20.800); + mg_cubic_to(-31.000, -20.800, -23.000, -29.200, -26.200, -22.400); + mg_cubic_to(-26.200, -22.400, -40.200, -11.600, -39.000, -2.400); + mg_cubic_to(-39.000, -2.400, -44.600, 12.000, -45.400, 14.000); + mg_cubic_to(-45.400, 14.000, -29.400, -18.000, -27.000, -19.200); + mg_cubic_to(-24.600, -20.400, -23.400, -20.400, -24.600, -16.800); + mg_cubic_to(-25.800, -13.200, -26.200, 3.200, -29.000, 5.200); + mg_cubic_to(-29.000, 5.200, -21.000, -15.200, -21.800, -18.400); + mg_cubic_to(-21.800, -18.400, -18.600, -22.000, -16.200, -16.800); + mg_line_to(-17.400, -0.800); + mg_line_to(-13.000, 11.200); + mg_cubic_to(-13.000, 11.200, -15.400, -0.000, -13.800, -15.600); + mg_cubic_to(-13.800, -15.600, -15.800, -26.000, -11.800, -20.400); + mg_cubic_to(-7.800, -14.800, 1.800, -8.800, 1.800, -4.000); + mg_cubic_to(1.800, -4.000, -3.400, -21.600, -12.600, -26.400); + mg_line_to(-16.600, -20.400); + mg_line_to(-17.800, -22.400); + mg_cubic_to(-17.800, -22.400, -21.400, -23.200, -17.000, -30.000); + mg_cubic_to(-12.600, -36.800, -13.000, -37.600, -13.000, -37.600); + mg_cubic_to(-13.000, -37.600, -6.600, -30.400, -5.000, -30.400); + mg_cubic_to(-5.000, -30.400, 8.200, -38.000, 9.400, -13.600); + mg_cubic_to(9.400, -13.600, 16.200, -28.000, 7.000, -34.800); + mg_cubic_to(7.000, -34.800, -7.800, -36.800, -6.600, -42.000); + mg_line_to(0.600, -54.400); + mg_cubic_to(4.200, -59.600, 2.600, -56.800, 2.600, -56.800); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 171) + { + mg_move_to(-17.800, -41.600); + mg_move_to(-33.800, -36.400); + mg_move_to(-41.000, -26.800); + mg_cubic_to(-41.000, -26.800, -23.800, -36.800, -19.800, -38.000); + mg_cubic_to(-15.800, -39.200, -17.800, -41.600, -17.800, -41.600); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 172) + { + mg_move_to(-57.800, -35.200); + mg_cubic_to(-57.800, -35.200, -59.800, -34.000, -60.200, -31.200); + mg_cubic_to(-60.600, -28.400, -63.000, -28.000, -62.200, -25.200); + mg_cubic_to(-61.400, -22.400, -59.400, -20.000, -59.400, -24.000); + mg_cubic_to(-59.400, -28.000, -57.800, -30.000, -57.000, -31.200); + mg_cubic_to(-56.200, -32.400, -54.600, -36.800, -57.800, -35.200); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 173) + { + mg_move_to(-66.600, 26.000); + mg_cubic_to(-66.600, 26.000, -75.000, 22.000, -78.200, 18.400); + mg_cubic_to(-81.400, 14.800, -80.948, 19.966, -85.800, 19.600); + mg_cubic_to(-91.647, 19.159, -90.600, 3.200, -90.600, 3.200); + mg_line_to(-94.600, 10.800); + mg_cubic_to(-94.600, 10.800, -95.800, 25.200, -87.800, 22.800); + mg_cubic_to(-83.893, 21.628, -82.600, 23.200, -84.200, 24.000); + mg_cubic_to(-85.800, 24.800, -78.600, 25.200, -81.400, 26.800); + mg_cubic_to(-84.200, 28.400, -69.800, 23.200, -72.200, 33.600); + mg_line_to(-66.600, 26.000); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 174) + { + mg_move_to(-79.200, 40.400); + mg_cubic_to(-79.200, 40.400, -94.600, 44.800, -98.200, 35.200); + mg_cubic_to(-98.200, 35.200, -103.000, 37.600, -100.800, 40.600); + mg_cubic_to(-98.600, 43.600, -97.400, 44.000, -97.400, 44.000); + mg_cubic_to(-97.400, 44.000, -92.000, 45.200, -92.600, 46.000); + mg_cubic_to(-93.200, 46.800, -95.600, 50.200, -95.600, 50.200); + mg_cubic_to(-95.600, 50.200, -85.400, 44.200, -79.200, 40.400); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 175) + { + mg_move_to(149.200, 118.600); + mg_cubic_to(148.770, 120.740, 147.100, 121.540, 145.200, 122.200); + mg_cubic_to(143.280, 121.240, 140.690, 118.140, 138.800, 120.200); + mg_cubic_to(138.330, 119.720, 137.550, 119.660, 137.200, 119.000); + mg_cubic_to(136.740, 118.100, 137.010, 117.060, 136.670, 116.260); + mg_cubic_to(136.120, 114.980, 135.420, 113.620, 135.600, 112.200); + mg_cubic_to(137.410, 111.490, 138.000, 109.580, 137.530, 107.820); + mg_cubic_to(137.460, 107.560, 137.030, 107.370, 137.230, 107.020); + mg_cubic_to(137.420, 106.690, 137.730, 106.470, 138.000, 106.200); + mg_cubic_to(137.870, 106.340, 137.720, 106.570, 137.610, 106.550); + mg_cubic_to(137.000, 106.440, 137.120, 105.800, 137.250, 105.420); + mg_cubic_to(137.840, 103.670, 139.850, 103.410, 141.200, 104.600); + mg_cubic_to(141.460, 104.040, 141.970, 104.230, 142.400, 104.200); + mg_cubic_to(142.350, 103.620, 142.760, 103.090, 142.960, 102.670); + mg_cubic_to(143.480, 101.580, 145.100, 102.680, 145.900, 102.070); + mg_cubic_to(146.980, 101.240, 148.040, 100.550, 149.120, 101.150); + mg_cubic_to(150.930, 102.160, 152.640, 103.370, 153.840, 105.120); + mg_cubic_to(154.410, 105.950, 154.650, 107.230, 154.590, 108.190); + mg_cubic_to(154.550, 108.840, 153.170, 108.480, 152.830, 109.410); + mg_cubic_to(152.180, 111.160, 154.020, 111.680, 154.770, 113.020); + mg_cubic_to(154.970, 113.370, 154.710, 113.670, 154.390, 113.770); + mg_cubic_to(153.980, 113.900, 153.200, 113.710, 153.330, 114.160); + mg_cubic_to(154.310, 117.350, 151.550, 118.030, 149.200, 118.600); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 176) + { + mg_move_to(139.600, 138.200); + mg_cubic_to(139.590, 136.460, 137.990, 134.710, 139.200, 133.000); + mg_cubic_to(139.340, 133.140, 139.470, 133.360, 139.600, 133.360); + mg_cubic_to(139.740, 133.360, 139.870, 133.140, 140.000, 133.000); + mg_cubic_to(141.500, 135.220, 145.150, 136.140, 145.010, 138.990); + mg_cubic_to(144.980, 139.440, 143.900, 140.360, 144.800, 141.000); + mg_cubic_to(142.990, 142.350, 142.930, 144.720, 142.000, 146.600); + mg_cubic_to(140.760, 146.320, 139.550, 145.950, 138.400, 145.400); + mg_cubic_to(138.750, 143.920, 138.640, 142.230, 139.460, 140.910); + mg_cubic_to(139.890, 140.210, 139.600, 139.130, 139.600, 138.200); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 177) + { + mg_move_to(-26.600, 129.200); + mg_cubic_to(-26.600, 129.200, -43.458, 139.340, -29.400, 124.000); + mg_cubic_to(-20.600, 114.400, -10.600, 108.800, -10.600, 108.800); + mg_cubic_to(-10.600, 108.800, -0.200, 104.400, 3.400, 103.200); + mg_cubic_to(7.000, 102.000, 22.200, 96.800, 25.400, 96.400); + mg_cubic_to(28.600, 96.000, 38.200, 92.000, 45.000, 96.000); + mg_cubic_to(51.800, 100.000, 59.800, 104.400, 59.800, 104.400); + mg_cubic_to(59.800, 104.400, 43.400, 96.000, 39.800, 98.400); + mg_cubic_to(36.200, 100.800, 29.000, 100.400, 23.000, 103.600); + mg_cubic_to(23.000, 103.600, 8.200, 108.000, 5.000, 110.000); + mg_cubic_to(1.800, 112.000, -8.600, 123.600, -10.200, 122.800); + mg_cubic_to(-11.800, 122.000, -9.800, 121.600, -8.600, 118.800); + mg_cubic_to(-7.400, 116.000, -9.400, 114.400, -17.400, 120.800); + mg_cubic_to(-25.400, 127.200, -26.600, 129.200, -26.600, 129.200); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 178) + { + mg_move_to(-19.195, 123.230); + mg_cubic_to(-19.195, 123.230, -17.785, 110.190, -9.307, 111.860); + mg_cubic_to(-9.307, 111.860, -1.081, 107.690, 1.641, 105.720); + mg_cubic_to(1.641, 105.720, 9.780, 104.020, 11.090, 103.400); + mg_cubic_to(29.569, 94.702, 44.288, 99.221, 44.835, 98.101); + mg_cubic_to(45.381, 96.982, 65.006, 104.100, 68.615, 108.180); + mg_cubic_to(69.006, 108.630, 58.384, 102.590, 48.686, 100.700); + mg_cubic_to(40.413, 99.083, 18.811, 100.940, 7.905, 106.480); + mg_cubic_to(4.932, 107.990, -4.013, 113.770, -6.544, 113.660); + mg_cubic_to(-9.075, 113.550, -19.195, 123.230, -19.195, 123.230); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 179) + { + mg_move_to(-23.000, 148.800); + mg_cubic_to(-23.000, 148.800, -38.200, 146.400, -21.400, 144.800); + mg_cubic_to(-21.400, 144.800, -3.400, 142.800, 0.600, 137.600); + mg_cubic_to(0.600, 137.600, 14.200, 128.400, 17.000, 128.000); + mg_cubic_to(19.800, 127.600, 49.800, 120.400, 50.200, 118.000); + mg_cubic_to(50.600, 115.600, 56.200, 115.600, 57.800, 116.400); + mg_cubic_to(59.400, 117.200, 58.600, 118.400, 55.800, 119.200); + mg_cubic_to(53.000, 120.000, 21.800, 136.400, 15.400, 137.600); + mg_cubic_to(9.000, 138.800, -2.600, 146.400, -7.400, 147.600); + mg_cubic_to(-12.200, 148.800, -23.000, 148.800, -23.000, 148.800); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 180) + { + mg_move_to(-3.480, 141.400); + mg_cubic_to(-3.480, 141.400, -12.062, 140.570, -3.461, 139.760); + mg_cubic_to(-3.461, 139.760, 5.355, 136.330, 7.403, 133.670); + mg_cubic_to(7.403, 133.670, 14.367, 128.960, 15.800, 128.750); + mg_cubic_to(17.234, 128.550, 31.194, 124.860, 31.399, 123.630); + mg_cubic_to(31.604, 122.400, 65.670, 109.820, 70.090, 113.010); + mg_cubic_to(73.001, 115.110, 63.100, 113.440, 53.466, 117.850); + mg_cubic_to(52.111, 118.470, 18.258, 133.050, 14.981, 133.670); + mg_cubic_to(11.704, 134.280, 5.765, 138.170, 3.307, 138.790); + mg_cubic_to(0.850, 139.400, -3.480, 141.400, -3.480, 141.400); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 181) + { + mg_move_to(-11.400, 143.600); + mg_cubic_to(-11.400, 143.600, -6.200, 143.200, -7.400, 144.800); + mg_cubic_to(-8.600, 146.400, -11.000, 145.600, -11.000, 145.600); + mg_line_to(-11.400, 143.600); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 182) + { + mg_move_to(-18.600, 145.200); + mg_cubic_to(-18.600, 145.200, -13.400, 144.800, -14.600, 146.400); + mg_cubic_to(-15.800, 148.000, -18.200, 147.200, -18.200, 147.200); + mg_line_to(-18.600, 145.200); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 183) + { + mg_move_to(-29.000, 146.800); + mg_cubic_to(-29.000, 146.800, -23.800, 146.400, -25.000, 148.000); + mg_cubic_to(-26.200, 149.600, -28.600, 148.800, -28.600, 148.800); + mg_line_to(-29.000, 146.800); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 184) + { + mg_move_to(-36.600, 147.600); + mg_cubic_to(-36.600, 147.600, -31.400, 147.200, -32.600, 148.800); + mg_cubic_to(-33.800, 150.400, -36.200, 149.600, -36.200, 149.600); + mg_line_to(-36.600, 147.600); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 185) + { + mg_move_to(1.800, 108.000); + mg_move_to(5.000, 109.600); + mg_cubic_to(3.800, 111.200, 0.600, 110.800, 0.600, 110.800); + mg_line_to(1.800, 108.000); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 186) + { + mg_move_to(-8.200, 113.600); + mg_cubic_to(-8.200, 113.600, -1.694, 111.460, -4.200, 114.800); + mg_cubic_to(-5.400, 116.400, -7.800, 115.600, -7.800, 115.600); + mg_line_to(-8.200, 113.600); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 187) + { + mg_move_to(-19.400, 118.400); + mg_cubic_to(-19.400, 118.400, -14.200, 118.000, -15.400, 119.600); + mg_cubic_to(-16.600, 121.200, -19.000, 120.400, -19.000, 120.400); + mg_line_to(-19.400, 118.400); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 188) + { + mg_move_to(-27.000, 124.400); + mg_cubic_to(-27.000, 124.400, -21.800, 124.000, -23.000, 125.600); + mg_cubic_to(-24.200, 127.200, -26.600, 126.400, -26.600, 126.400); + mg_line_to(-27.000, 124.400); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 189) + { + mg_move_to(-33.800, 129.200); + mg_cubic_to(-33.800, 129.200, -28.600, 128.800, -29.800, 130.400); + mg_cubic_to(-31.000, 132.000, -33.400, 131.200, -33.400, 131.200); + mg_line_to(-33.800, 129.200); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 190) + { + mg_move_to(5.282, 135.600); + mg_cubic_to(5.282, 135.600, 12.203, 135.070, 10.606, 137.200); + mg_cubic_to(9.009, 139.320, 5.814, 138.260, 5.814, 138.260); + mg_line_to(5.282, 135.600); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 191) + { + mg_move_to(15.682, 130.800); + mg_cubic_to(15.682, 130.800, 22.603, 130.270, 21.006, 132.400); + mg_cubic_to(19.409, 134.520, 16.214, 133.460, 16.214, 133.460); + mg_line_to(15.682, 130.800); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 192) + { + mg_move_to(26.482, 126.400); + mg_cubic_to(26.482, 126.400, 33.403, 125.870, 31.806, 128.000); + mg_cubic_to(30.209, 130.120, 27.014, 129.060, 27.014, 129.060); + mg_line_to(26.482, 126.400); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 193) + { + mg_move_to(36.882, 121.600); + mg_cubic_to(36.882, 121.600, 43.803, 121.070, 42.206, 123.200); + mg_cubic_to(40.609, 125.320, 37.414, 124.260, 37.414, 124.260); + mg_line_to(36.882, 121.600); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 194) + { + mg_move_to(9.282, 103.600); + mg_cubic_to(9.282, 103.600, 16.203, 103.070, 14.606, 105.200); + mg_cubic_to(13.009, 107.320, 9.014, 107.060, 9.014, 107.060); + mg_line_to(9.282, 103.600); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 195) + { + mg_move_to(19.282, 100.400); + mg_cubic_to(19.282, 100.400, 26.203, 99.866, 24.606, 102.000); + mg_cubic_to(23.009, 104.120, 18.614, 103.860, 18.614, 103.860); + mg_line_to(19.282, 100.400); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 196) + { + mg_move_to(-3.400, 140.400); + mg_cubic_to(-3.400, 140.400, 1.800, 140.000, 0.600, 141.600); + mg_cubic_to(-0.600, 143.200, -3.000, 142.400, -3.000, 142.400); + mg_line_to(-3.400, 140.400); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 197) + { + mg_move_to(-76.600, 41.200); + mg_cubic_to(-76.600, 41.200, -81.000, 50.000, -81.400, 53.200); + mg_cubic_to(-81.400, 53.200, -80.600, 44.400, -79.400, 42.400); + mg_cubic_to(-78.200, 40.400, -76.600, 41.200, -76.600, 41.200); + mg_close_path(); + mg_set_color_rgba(0.600, 0.149, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 198) + { + mg_move_to(-95.000, 55.200); + mg_cubic_to(-95.000, 55.200, -98.200, 69.600, -97.800, 72.400); + mg_cubic_to(-97.800, 72.400, -99.000, 60.800, -98.600, 59.600); + mg_cubic_to(-98.200, 58.400, -95.000, 55.200, -95.000, 55.200); + mg_close_path(); + mg_set_color_rgba(0.600, 0.149, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 199) + { + mg_move_to(-74.200, -19.400); + mg_move_to(-74.400, -16.200); + mg_move_to(-76.600, -16.000); + mg_cubic_to(-76.600, -16.000, -62.400, -3.400, -61.800, 4.200); + mg_cubic_to(-61.800, 4.200, -61.000, -4.000, -74.200, -19.400); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 200) + { + mg_move_to(-70.216, -18.135); + mg_cubic_to(-70.647, -18.551, -70.428, -19.296, -70.836, -19.556); + mg_cubic_to(-71.645, -20.072, -69.538, -20.129, -69.766, -20.845); + mg_cubic_to(-70.149, -22.051, -69.962, -22.072, -70.084, -23.348); + mg_cubic_to(-70.141, -23.946, -69.553, -25.486, -69.168, -25.926); + mg_cubic_to(-67.722, -27.578, -69.046, -30.510, -67.406, -32.061); + mg_cubic_to(-67.102, -32.350, -66.726, -32.902, -66.441, -33.320); + mg_cubic_to(-65.782, -34.283, -64.598, -34.771, -63.648, -35.599); + mg_cubic_to(-63.330, -35.875, -63.531, -36.702, -62.962, -36.610); + mg_cubic_to(-62.248, -36.495, -61.007, -36.625, -61.052, -35.784); + mg_cubic_to(-61.165, -33.664, -62.494, -31.944, -63.774, -30.276); + mg_cubic_to(-63.323, -29.572, -63.781, -28.937, -64.065, -28.380); + mg_cubic_to(-65.400, -25.760, -65.211, -22.919, -65.385, -20.079); + mg_cubic_to(-65.390, -19.994, -65.697, -19.916, -65.689, -19.863); + mg_cubic_to(-65.336, -17.528, -64.752, -15.329, -63.873, -13.100); + mg_cubic_to(-63.507, -12.170, -63.036, -11.275, -62.886, -10.348); + mg_cubic_to(-62.775, -9.662, -62.672, -8.829, -63.080, -8.124); + mg_cubic_to(-61.045, -5.234, -62.354, -2.583, -61.185, 0.948); + mg_cubic_to(-60.978, 1.573, -59.286, 3.487, -59.749, 3.326); + mg_cubic_to(-62.262, 2.455, -62.374, 2.057, -62.551, 1.304); + mg_cubic_to(-62.697, 0.681, -63.027, -0.696, -63.264, -1.298); + mg_cubic_to(-63.328, -1.462, -63.499, -3.346, -63.577, -3.468); + mg_cubic_to(-65.090, -5.850, -63.732, -5.674, -65.102, -8.032); + mg_cubic_to(-66.530, -8.712, -67.496, -9.816, -68.619, -10.978); + mg_cubic_to(-68.817, -11.182, -67.674, -11.906, -67.855, -12.119); + mg_cubic_to(-68.947, -13.408, -70.100, -14.175, -69.764, -15.668); + mg_cubic_to(-69.609, -16.358, -69.472, -17.415, -70.216, -18.135); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 201) + { + mg_move_to(-73.800, -16.400); + mg_cubic_to(-73.800, -16.400, -73.400, -9.600, -71.000, -8.000); + mg_cubic_to(-68.600, -6.400, -69.800, -7.200, -73.000, -8.400); + mg_cubic_to(-76.200, -9.600, -75.000, -10.400, -75.000, -10.400); + mg_cubic_to(-75.000, -10.400, -77.800, -10.000, -75.400, -8.000); + mg_cubic_to(-73.000, -6.000, -69.400, -3.600, -71.000, -3.600); + mg_cubic_to(-72.600, -3.600, -80.200, -7.600, -80.200, -10.400); + mg_cubic_to(-80.200, -13.200, -81.200, -17.300, -81.200, -17.300); + mg_cubic_to(-81.200, -17.300, -80.100, -18.100, -75.300, -18.000); + mg_cubic_to(-75.300, -18.000, -73.900, -17.300, -73.800, -16.400); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 202) + { + mg_move_to(-74.600, 2.200); + mg_cubic_to(-74.600, 2.200, -83.120, -0.591, -101.600, 2.800); + mg_cubic_to(-101.600, 2.800, -92.569, 0.722, -73.800, 3.000); + mg_cubic_to(-63.500, 4.250, -74.600, 2.200, -74.600, 2.200); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 203) + { + mg_set_width(0.1); + mg_move_to(-74.600, 2.200); + mg_cubic_to(-74.600, 2.200, -83.120, -0.591, -101.600, 2.800); + mg_cubic_to(-101.600, 2.800, -92.569, 0.722, -73.800, 3.000); + mg_cubic_to(-63.500, 4.250, -74.600, 2.200, -74.600, 2.200); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 204) + { + mg_move_to(-72.502, 2.129); + mg_cubic_to(-72.502, 2.129, -80.748, -1.389, -99.453, 0.392); + mg_cubic_to(-99.453, 0.392, -90.275, -0.897, -71.774, 2.995); + mg_cubic_to(-61.620, 5.131, -72.502, 2.129, -72.502, 2.129); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 205) + { + mg_set_width(0.1); + mg_move_to(-72.502, 2.129); + mg_cubic_to(-72.502, 2.129, -80.748, -1.389, -99.453, 0.392); + mg_cubic_to(-99.453, 0.392, -90.275, -0.897, -71.774, 2.995); + mg_cubic_to(-61.620, 5.131, -72.502, 2.129, -72.502, 2.129); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 206) + { + mg_move_to(-70.714, 2.222); + mg_cubic_to(-70.714, 2.222, -78.676, -1.899, -97.461, -1.514); + mg_cubic_to(-97.461, -1.514, -88.213, -2.118, -70.052, 3.140); + mg_cubic_to(-60.086, 6.025, -70.714, 2.222, -70.714, 2.222); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 207) + { + mg_set_width(0.1); + mg_move_to(-70.714, 2.222); + mg_cubic_to(-70.714, 2.222, -78.676, -1.899, -97.461, -1.514); + mg_cubic_to(-97.461, -1.514, -88.213, -2.118, -70.052, 3.140); + mg_cubic_to(-60.086, 6.025, -70.714, 2.222, -70.714, 2.222); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 208) + { + mg_move_to(-69.444, 2.445); + mg_cubic_to(-69.444, 2.445, -76.268, -1.862, -93.142, -2.960); + mg_cubic_to(-93.142, -2.960, -84.803, -2.790, -68.922, 3.319); + mg_cubic_to(-60.206, 6.672, -69.444, 2.445, -69.444, 2.445); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 209) + { + mg_set_width(0.1); + mg_move_to(-69.444, 2.445); + mg_cubic_to(-69.444, 2.445, -76.268, -1.862, -93.142, -2.960); + mg_cubic_to(-93.142, -2.960, -84.803, -2.790, -68.922, 3.319); + mg_cubic_to(-60.206, 6.672, -69.444, 2.445, -69.444, 2.445); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 210) + { + mg_move_to(45.840, 12.961); + mg_cubic_to(45.840, 12.961, 44.910, 13.605, 45.124, 12.424); + mg_cubic_to(45.339, 11.243, 73.547, -1.927, 77.161, -1.677); + mg_cubic_to(77.161, -1.677, 46.913, 11.529, 45.840, 12.961); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 211) + { + mg_set_width(0.1); + mg_move_to(45.840, 12.961); + mg_cubic_to(45.840, 12.961, 44.910, 13.605, 45.124, 12.424); + mg_cubic_to(45.339, 11.243, 73.547, -1.927, 77.161, -1.677); + mg_cubic_to(77.161, -1.677, 46.913, 11.529, 45.840, 12.961); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 212) + { + mg_move_to(42.446, 13.600); + mg_cubic_to(42.446, 13.600, 41.570, 14.315, 41.691, 13.121); + mg_cubic_to(41.812, 11.927, 68.899, -3.418, 72.521, -3.452); + mg_cubic_to(72.521, -3.452, 43.404, 12.089, 42.446, 13.600); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 213) + { + mg_set_width(0.1); + mg_move_to(42.446, 13.600); + mg_cubic_to(42.446, 13.600, 41.570, 14.315, 41.691, 13.121); + mg_cubic_to(41.812, 11.927, 68.899, -3.418, 72.521, -3.452); + mg_cubic_to(72.521, -3.452, 43.404, 12.089, 42.446, 13.600); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 214) + { + mg_move_to(39.160, 14.975); + mg_cubic_to(39.160, 14.975, 38.332, 15.747, 38.374, 14.547); + mg_cubic_to(38.416, 13.348, 58.233, -2.149, 68.045, -4.023); + mg_cubic_to(68.045, -4.023, 50.015, 4.104, 39.160, 14.975); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 215) + { + mg_set_width(0.1); + mg_move_to(39.160, 14.975); + mg_cubic_to(39.160, 14.975, 38.332, 15.747, 38.374, 14.547); + mg_cubic_to(38.416, 13.348, 58.233, -2.149, 68.045, -4.023); + mg_cubic_to(68.045, -4.023, 50.015, 4.104, 39.160, 14.975); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 216) + { + mg_move_to(36.284, 16.838); + mg_cubic_to(36.284, 16.838, 35.539, 17.532, 35.577, 16.453); + mg_cubic_to(35.615, 15.373, 53.449, 1.426, 62.280, -0.260); + mg_cubic_to(62.280, -0.260, 46.054, 7.054, 36.284, 16.838); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 217) + { + mg_set_width(0.1); + mg_move_to(36.284, 16.838); + mg_cubic_to(36.284, 16.838, 35.539, 17.532, 35.577, 16.453); + mg_cubic_to(35.615, 15.373, 53.449, 1.426, 62.280, -0.260); + mg_cubic_to(62.280, -0.260, 46.054, 7.054, 36.284, 16.838); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 218) + { + mg_move_to(4.600, 164.800); + mg_cubic_to(4.600, 164.800, -10.600, 162.400, 6.200, 160.800); + mg_cubic_to(6.200, 160.800, 24.200, 158.800, 28.200, 153.600); + mg_cubic_to(28.200, 153.600, 41.800, 144.400, 44.600, 144.000); + mg_cubic_to(47.400, 143.600, 63.800, 140.000, 64.200, 137.600); + mg_cubic_to(64.600, 135.200, 70.600, 132.800, 72.200, 133.600); + mg_cubic_to(73.800, 134.400, 73.800, 143.600, 71.000, 144.400); + mg_cubic_to(68.200, 145.200, 49.400, 152.400, 43.000, 153.600); + mg_cubic_to(36.600, 154.800, 25.000, 162.400, 20.200, 163.600); + mg_cubic_to(15.400, 164.800, 4.600, 164.800, 4.600, 164.800); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 219) + { + mg_move_to(77.600, 127.400); + mg_cubic_to(77.600, 127.400, 74.600, 129.000, 73.400, 131.600); + mg_cubic_to(73.400, 131.600, 67.000, 142.200, 52.800, 145.400); + mg_cubic_to(52.800, 145.400, 29.800, 154.400, 22.000, 156.400); + mg_cubic_to(22.000, 156.400, 8.600, 161.400, 1.200, 160.600); + mg_cubic_to(1.200, 160.600, -5.800, 160.800, 0.400, 162.400); + mg_cubic_to(0.400, 162.400, 20.600, 160.400, 24.000, 158.600); + mg_cubic_to(24.000, 158.600, 39.600, 153.400, 42.600, 150.800); + mg_cubic_to(45.600, 148.200, 63.800, 143.200, 66.000, 141.200); + mg_cubic_to(68.200, 139.200, 78.000, 130.800, 77.600, 127.400); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 220) + { + mg_move_to(18.882, 158.910); + mg_cubic_to(18.882, 158.910, 24.111, 158.680, 22.958, 160.230); + mg_cubic_to(21.805, 161.780, 19.357, 160.910, 19.357, 160.910); + mg_line_to(18.882, 158.910); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 221) + { + mg_move_to(11.680, 160.260); + mg_cubic_to(11.680, 160.260, 16.908, 160.040, 15.756, 161.590); + mg_cubic_to(14.603, 163.140, 12.155, 162.260, 12.155, 162.260); + mg_line_to(11.680, 160.260); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 222) + { + mg_move_to(1.251, 161.510); + mg_cubic_to(1.251, 161.510, 6.480, 161.280, 5.327, 162.830); + mg_cubic_to(4.174, 164.380, 1.726, 163.510, 1.726, 163.510); + mg_line_to(1.251, 161.510); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 223) + { + mg_move_to(-6.383, 162.060); + mg_cubic_to(-6.383, 162.060, -1.154, 161.830, -2.307, 163.380); + mg_cubic_to(-3.460, 164.930, -5.908, 164.050, -5.908, 164.050); + mg_line_to(-6.383, 162.060); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 224) + { + mg_move_to(35.415, 151.510); + mg_cubic_to(35.415, 151.510, 42.375, 151.210, 40.840, 153.270); + mg_cubic_to(39.306, 155.340, 36.047, 154.170, 36.047, 154.170); + mg_line_to(35.415, 151.510); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 225) + { + mg_move_to(45.730, 147.090); + mg_cubic_to(45.730, 147.090, 51.689, 143.790, 51.155, 148.850); + mg_cubic_to(50.885, 151.400, 46.362, 149.750, 46.362, 149.750); + mg_line_to(45.730, 147.090); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 226) + { + mg_move_to(54.862, 144.270); + mg_cubic_to(54.862, 144.270, 62.021, 140.570, 60.287, 146.040); + mg_cubic_to(59.509, 148.480, 55.493, 146.940, 55.493, 146.940); + mg_line_to(54.862, 144.270); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 227) + { + mg_move_to(64.376, 139.450); + mg_cubic_to(64.376, 139.450, 68.735, 134.550, 69.801, 141.210); + mg_cubic_to(70.207, 143.750, 65.008, 142.110, 65.008, 142.110); + mg_line_to(64.376, 139.450); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 228) + { + mg_move_to(26.834, 156.000); + mg_cubic_to(26.834, 156.000, 32.062, 155.770, 30.910, 157.320); + mg_cubic_to(29.757, 158.870, 27.308, 158.000, 27.308, 158.000); + mg_line_to(26.834, 156.000); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 229) + { + mg_move_to(62.434, 34.603); + mg_cubic_to(62.434, 34.603, 61.708, 35.268, 61.707, 34.197); + mg_cubic_to(61.707, 33.127, 79.191, 19.863, 88.034, 18.479); + mg_cubic_to(88.034, 18.479, 71.935, 25.208, 62.434, 34.603); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 230) + { + mg_set_width(0.1); + mg_move_to(62.434, 34.603); + mg_cubic_to(62.434, 34.603, 61.708, 35.268, 61.707, 34.197); + mg_cubic_to(61.707, 33.127, 79.191, 19.863, 88.034, 18.479); + mg_cubic_to(88.034, 18.479, 71.935, 25.208, 62.434, 34.603); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 231) + { + mg_move_to(65.400, 98.400); + mg_cubic_to(65.400, 98.400, 87.401, 120.800, 96.601, 124.400); + mg_cubic_to(96.601, 124.400, 105.800, 135.600, 101.800, 161.600); + mg_cubic_to(101.800, 161.600, 98.601, 169.200, 95.401, 148.400); + mg_cubic_to(95.401, 148.400, 98.601, 123.200, 87.401, 139.200); + mg_cubic_to(87.401, 139.200, 79.000, 129.300, 85.400, 129.600); + mg_cubic_to(85.400, 129.600, 88.601, 131.600, 89.001, 130.000); + mg_cubic_to(89.401, 128.400, 81.400, 114.800, 64.200, 100.400); + mg_cubic_to(47.000, 86.000, 65.400, 98.400, 65.400, 98.400); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 232) + { + mg_move_to(7.000, 137.200); + mg_cubic_to(7.000, 137.200, 6.800, 135.400, 8.600, 136.200); + mg_cubic_to(10.400, 137.000, 104.600, 143.200, 136.200, 167.200); + mg_cubic_to(136.200, 167.200, 91.001, 144.000, 7.000, 137.200); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 233) + { + mg_set_width(0.1); + mg_move_to(7.000, 137.200); + mg_cubic_to(7.000, 137.200, 6.800, 135.400, 8.600, 136.200); + mg_cubic_to(10.400, 137.000, 104.600, 143.200, 136.200, 167.200); + mg_cubic_to(136.200, 167.200, 91.001, 144.000, 7.000, 137.200); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 234) + { + mg_move_to(17.400, 132.800); + mg_cubic_to(17.400, 132.800, 17.200, 131.000, 19.000, 131.800); + mg_cubic_to(20.800, 132.600, 157.400, 131.600, 181.000, 164.000); + mg_cubic_to(181.000, 164.000, 159.000, 138.800, 17.400, 132.800); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 235) + { + mg_set_width(0.1); + mg_move_to(17.400, 132.800); + mg_cubic_to(17.400, 132.800, 17.200, 131.000, 19.000, 131.800); + mg_cubic_to(20.800, 132.600, 157.400, 131.600, 181.000, 164.000); + mg_cubic_to(181.000, 164.000, 159.000, 138.800, 17.400, 132.800); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 236) + { + mg_move_to(29.000, 128.800); + mg_cubic_to(29.000, 128.800, 28.800, 127.000, 30.600, 127.800); + mg_cubic_to(32.400, 128.600, 205.800, 115.600, 229.400, 148.000); + mg_cubic_to(229.400, 148.000, 219.800, 122.400, 29.000, 128.800); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 237) + { + mg_set_width(0.1); + mg_move_to(29.000, 128.800); + mg_cubic_to(29.000, 128.800, 28.800, 127.000, 30.600, 127.800); + mg_cubic_to(32.400, 128.600, 205.800, 115.600, 229.400, 148.000); + mg_cubic_to(229.400, 148.000, 219.800, 122.400, 29.000, 128.800); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 238) + { + mg_move_to(39.000, 124.000); + mg_cubic_to(39.000, 124.000, 38.800, 122.200, 40.600, 123.000); + mg_cubic_to(42.400, 123.800, 164.600, 85.200, 188.200, 117.600); + mg_cubic_to(188.200, 117.600, 174.800, 93.000, 39.000, 124.000); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 239) + { + mg_set_width(0.1); + mg_move_to(39.000, 124.000); + mg_cubic_to(39.000, 124.000, 38.800, 122.200, 40.600, 123.000); + mg_cubic_to(42.400, 123.800, 164.600, 85.200, 188.200, 117.600); + mg_cubic_to(188.200, 117.600, 174.800, 93.000, 39.000, 124.000); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 240) + { + mg_move_to(-19.000, 146.800); + mg_cubic_to(-19.000, 146.800, -19.200, 145.000, -17.400, 145.800); + mg_cubic_to(-15.600, 146.600, 2.200, 148.800, 4.200, 187.600); + mg_cubic_to(4.200, 187.600, -3.000, 145.600, -19.000, 146.800); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 241) + { + mg_set_width(0.1); + mg_move_to(-19.000, 146.800); + mg_cubic_to(-19.000, 146.800, -19.200, 145.000, -17.400, 145.800); + mg_cubic_to(-15.600, 146.600, 2.200, 148.800, 4.200, 187.600); + mg_cubic_to(4.200, 187.600, -3.000, 145.600, -19.000, 146.800); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 242) + { + mg_move_to(-27.800, 148.400); + mg_cubic_to(-27.800, 148.400, -28.000, 146.600, -26.200, 147.400); + mg_cubic_to(-24.400, 148.200, -10.200, 143.600, -13.000, 182.400); + mg_cubic_to(-13.000, 182.400, -11.800, 147.200, -27.800, 148.400); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 243) + { + mg_set_width(0.1); + mg_move_to(-27.800, 148.400); + mg_cubic_to(-27.800, 148.400, -28.000, 146.600, -26.200, 147.400); + mg_cubic_to(-24.400, 148.200, -10.200, 143.600, -13.000, 182.400); + mg_cubic_to(-13.000, 182.400, -11.800, 147.200, -27.800, 148.400); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 244) + { + mg_move_to(-35.800, 148.800); + mg_cubic_to(-35.800, 148.800, -36.000, 147.000, -34.200, 147.800); + mg_cubic_to(-32.400, 148.600, -17.000, 149.200, -29.400, 171.600); + mg_cubic_to(-29.400, 171.600, -19.800, 147.600, -35.800, 148.800); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 245) + { + mg_set_width(0.1); + mg_move_to(-35.800, 148.800); + mg_cubic_to(-35.800, 148.800, -36.000, 147.000, -34.200, 147.800); + mg_cubic_to(-32.400, 148.600, -17.000, 149.200, -29.400, 171.600); + mg_cubic_to(-29.400, 171.600, -19.800, 147.600, -35.800, 148.800); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 246) + { + mg_move_to(11.526, 104.460); + mg_cubic_to(11.526, 104.460, 11.082, 106.460, 12.631, 105.250); + mg_cubic_to(28.699, 92.622, 61.141, 33.720, 116.831, 28.086); + mg_cubic_to(116.831, 28.086, 78.519, 15.976, 11.531, 104.460); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 247) + { + mg_set_width(0.1); + mg_move_to(11.526, 104.460); + mg_cubic_to(11.526, 104.460, 11.082, 106.460, 12.631, 105.250); + mg_cubic_to(28.699, 92.622, 61.141, 33.720, 116.831, 28.086); + mg_cubic_to(116.831, 28.086, 78.519, 15.976, 11.531, 104.460); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 248) + { + mg_move_to(22.726, 102.660); + mg_cubic_to(22.726, 102.660, 21.363, 101.470, 23.231, 100.850); + mg_cubic_to(25.099, 100.220, 137.541, 27.720, 176.831, 35.686); + mg_cubic_to(176.831, 35.686, 149.721, 28.176, 22.731, 102.660); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 249) + { + mg_set_width(0.1); + mg_move_to(22.726, 102.660); + mg_cubic_to(22.726, 102.660, 21.363, 101.470, 23.231, 100.850); + mg_cubic_to(25.099, 100.220, 137.541, 27.720, 176.831, 35.686); + mg_cubic_to(176.831, 35.686, 149.721, 28.176, 22.731, 102.660); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 250) + { + mg_move_to(1.885, 108.770); + mg_cubic_to(1.885, 108.770, 1.376, 110.370, 3.087, 109.390); + mg_cubic_to(12.062, 104.270, 15.677, 47.059, 59.254, 45.804); + mg_cubic_to(59.254, 45.804, 26.843, 31.090, 1.885, 108.770); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 251) + { + mg_set_width(0.1); + mg_move_to(1.885, 108.770); + mg_cubic_to(1.885, 108.770, 1.376, 110.370, 3.087, 109.390); + mg_cubic_to(12.062, 104.270, 15.677, 47.059, 59.254, 45.804); + mg_cubic_to(59.254, 45.804, 26.843, 31.090, 1.885, 108.770); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 252) + { + mg_move_to(-18.038, 119.790); + mg_cubic_to(-18.038, 119.790, -19.115, 121.080, -17.162, 120.820); + mg_cubic_to(-6.916, 119.490, 14.489, 78.222, 58.928, 83.301); + mg_cubic_to(58.928, 83.301, 26.962, 68.955, -18.038, 119.790); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 253) + { + mg_set_width(0.1); + mg_move_to(-18.038, 119.790); + mg_cubic_to(-18.038, 119.790, -19.115, 121.080, -17.162, 120.820); + mg_cubic_to(-6.916, 119.490, 14.489, 78.222, 58.928, 83.301); + mg_cubic_to(58.928, 83.301, 26.962, 68.955, -18.038, 119.790); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 254) + { + mg_move_to(-6.800, 113.670); + mg_cubic_to(-6.800, 113.670, -7.611, 115.140, -5.742, 114.510); + mg_cubic_to(4.057, 111.240, 17.141, 66.625, 61.729, 63.078); + mg_cubic_to(61.729, 63.078, 27.603, 55.135, -6.800, 113.670); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 255) + { + mg_set_width(0.1); + mg_move_to(-6.800, 113.670); + mg_cubic_to(-6.800, 113.670, -7.611, 115.140, -5.742, 114.510); + mg_cubic_to(4.057, 111.240, 17.141, 66.625, 61.729, 63.078); + mg_cubic_to(61.729, 63.078, 27.603, 55.135, -6.800, 113.670); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 256) + { + mg_move_to(-25.078, 124.910); + mg_cubic_to(-25.078, 124.910, -25.951, 125.950, -24.369, 125.750); + mg_cubic_to(-16.070, 124.670, 1.268, 91.240, 37.264, 95.354); + mg_cubic_to(37.264, 95.354, 11.371, 83.734, -25.078, 124.910); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 257) + { + mg_set_width(0.1); + mg_move_to(-25.078, 124.910); + mg_cubic_to(-25.078, 124.910, -25.951, 125.950, -24.369, 125.750); + mg_cubic_to(-16.070, 124.670, 1.268, 91.240, 37.264, 95.354); + mg_cubic_to(37.264, 95.354, 11.371, 83.734, -25.078, 124.910); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 258) + { + mg_move_to(-32.677, 130.820); + mg_cubic_to(-32.677, 130.820, -33.682, 131.870, -32.091, 131.750); + mg_cubic_to(-27.923, 131.440, 2.715, 98.360, 21.183, 113.860); + mg_cubic_to(21.183, 113.860, 9.168, 95.139, -32.677, 130.820); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 259) + { + mg_set_width(0.1); + mg_move_to(-32.677, 130.820); + mg_cubic_to(-32.677, 130.820, -33.682, 131.870, -32.091, 131.750); + mg_cubic_to(-27.923, 131.440, 2.715, 98.360, 21.183, 113.860); + mg_cubic_to(21.183, 113.860, 9.168, 95.139, -32.677, 130.820); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 260) + { + mg_move_to(36.855, 98.898); + mg_cubic_to(36.855, 98.898, 35.654, 97.543, 37.586, 97.158); + mg_cubic_to(39.518, 96.774, 160.216, 39.061, 198.176, 51.927); + mg_cubic_to(198.176, 51.927, 172.236, 41.053, 36.856, 98.898); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 261) + { + mg_set_width(0.1); + mg_move_to(36.855, 98.898); + mg_cubic_to(36.855, 98.898, 35.654, 97.543, 37.586, 97.158); + mg_cubic_to(39.518, 96.774, 160.216, 39.061, 198.176, 51.927); + mg_cubic_to(198.176, 51.927, 172.236, 41.053, 36.856, 98.898); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 262) + { + mg_move_to(3.400, 163.200); + mg_cubic_to(3.400, 163.200, 3.200, 161.400, 5.000, 162.200); + mg_cubic_to(6.800, 163.000, 22.200, 163.600, 9.800, 186.000); + mg_cubic_to(9.800, 186.000, 19.400, 162.000, 3.400, 163.200); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 263) + { + mg_set_width(0.1); + mg_move_to(3.400, 163.200); + mg_cubic_to(3.400, 163.200, 3.200, 161.400, 5.000, 162.200); + mg_cubic_to(6.800, 163.000, 22.200, 163.600, 9.800, 186.000); + mg_cubic_to(9.800, 186.000, 19.400, 162.000, 3.400, 163.200); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 264) + { + mg_move_to(13.800, 161.600); + mg_cubic_to(13.800, 161.600, 13.600, 159.800, 15.400, 160.600); + mg_cubic_to(17.200, 161.400, 35.000, 163.600, 37.000, 202.400); + mg_cubic_to(37.000, 202.400, 29.800, 160.400, 13.800, 161.600); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 265) + { + mg_set_width(0.1); + mg_move_to(13.800, 161.600); + mg_cubic_to(13.800, 161.600, 13.600, 159.800, 15.400, 160.600); + mg_cubic_to(17.200, 161.400, 35.000, 163.600, 37.000, 202.400); + mg_cubic_to(37.000, 202.400, 29.800, 160.400, 13.800, 161.600); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 266) + { + mg_move_to(20.600, 160.000); + mg_cubic_to(20.600, 160.000, 20.400, 158.200, 22.200, 159.000); + mg_cubic_to(24.000, 159.800, 48.600, 163.200, 72.200, 195.600); + mg_cubic_to(72.200, 195.600, 36.600, 158.800, 20.600, 160.000); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 267) + { + mg_set_width(0.1); + mg_move_to(20.600, 160.000); + mg_cubic_to(20.600, 160.000, 20.400, 158.200, 22.200, 159.000); + mg_cubic_to(24.000, 159.800, 48.600, 163.200, 72.200, 195.600); + mg_cubic_to(72.200, 195.600, 36.600, 158.800, 20.600, 160.000); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 268) + { + mg_move_to(28.225, 157.970); + mg_cubic_to(28.225, 157.970, 27.788, 156.210, 29.678, 156.770); + mg_cubic_to(31.568, 157.320, 52.002, 155.420, 90.099, 189.600); + mg_cubic_to(90.099, 189.600, 43.924, 154.660, 28.225, 157.970); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 269) + { + mg_set_width(0.1); + mg_move_to(28.225, 157.970); + mg_cubic_to(28.225, 157.970, 27.788, 156.210, 29.678, 156.770); + mg_cubic_to(31.568, 157.320, 52.002, 155.420, 90.099, 189.600); + mg_cubic_to(90.099, 189.600, 43.924, 154.660, 28.225, 157.970); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 270) + { + mg_move_to(38.625, 153.570); + mg_cubic_to(38.625, 153.570, 38.188, 151.810, 40.078, 152.370); + mg_cubic_to(41.968, 152.920, 76.802, 157.420, 128.500, 192.400); + mg_cubic_to(128.500, 192.400, 54.324, 150.260, 38.625, 153.570); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 271) + { + mg_set_width(0.1); + mg_move_to(38.625, 153.570); + mg_cubic_to(38.625, 153.570, 38.188, 151.810, 40.078, 152.370); + mg_cubic_to(41.968, 152.920, 76.802, 157.420, 128.500, 192.400); + mg_cubic_to(128.500, 192.400, 54.324, 150.260, 38.625, 153.570); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 272) + { + mg_move_to(-1.800, 142.000); + mg_cubic_to(-1.800, 142.000, -2.000, 140.200, -0.200, 141.000); + mg_cubic_to(1.600, 141.800, 55.000, 144.400, 85.400, 171.200); + mg_cubic_to(85.400, 171.200, 50.499, 146.430, -1.800, 142.000); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 273) + { + mg_set_width(0.1); + mg_move_to(-1.800, 142.000); + mg_cubic_to(-1.800, 142.000, -2.000, 140.200, -0.200, 141.000); + mg_cubic_to(1.600, 141.800, 55.000, 144.400, 85.400, 171.200); + mg_cubic_to(85.400, 171.200, 50.499, 146.430, -1.800, 142.000); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 274) + { + mg_move_to(-11.800, 146.000); + mg_cubic_to(-11.800, 146.000, -12.000, 144.200, -10.200, 145.000); + mg_cubic_to(-8.400, 145.800, 16.200, 149.200, 39.800, 181.600); + mg_cubic_to(39.800, 181.600, 4.200, 144.800, -11.800, 146.000); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 275) + { + mg_set_width(0.1); + mg_move_to(-11.800, 146.000); + mg_cubic_to(-11.800, 146.000, -12.000, 144.200, -10.200, 145.000); + mg_cubic_to(-8.400, 145.800, 16.200, 149.200, 39.800, 181.600); + mg_cubic_to(39.800, 181.600, 4.200, 144.800, -11.800, 146.000); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 276) + { + mg_move_to(49.503, 148.960); + mg_cubic_to(49.503, 148.960, 48.938, 147.240, 50.864, 147.660); + mg_cubic_to(52.790, 148.070, 87.860, 150.000, 141.980, 181.100); + mg_cubic_to(141.980, 181.100, 64.317, 146.700, 49.503, 148.960); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 277) + { + mg_set_width(0.1); + mg_move_to(49.503, 148.960); + mg_cubic_to(49.503, 148.960, 48.938, 147.240, 50.864, 147.660); + mg_cubic_to(52.790, 148.070, 87.860, 150.000, 141.980, 181.100); + mg_cubic_to(141.980, 181.100, 64.317, 146.700, 49.503, 148.960); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 278) + { + mg_move_to(57.903, 146.560); + mg_cubic_to(57.903, 146.560, 57.338, 144.840, 59.264, 145.260); + mg_cubic_to(61.190, 145.670, 96.260, 147.600, 150.380, 178.700); + mg_cubic_to(150.380, 178.700, 73.317, 143.900, 57.903, 146.560); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 279) + { + mg_set_width(0.1); + mg_move_to(57.903, 146.560); + mg_cubic_to(57.903, 146.560, 57.338, 144.840, 59.264, 145.260); + mg_cubic_to(61.190, 145.670, 96.260, 147.600, 150.380, 178.700); + mg_cubic_to(150.380, 178.700, 73.317, 143.900, 57.903, 146.560); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 280) + { + mg_move_to(67.503, 141.560); + mg_cubic_to(67.503, 141.560, 66.938, 139.840, 68.864, 140.260); + mg_cubic_to(70.790, 140.670, 113.860, 145.000, 203.584, 179.300); + mg_cubic_to(203.584, 179.300, 82.924, 138.900, 67.504, 141.560); + mg_close_path(); + mg_set_color_rgba(1.000, 1.000, 1.000, 1); + mg_fill(); + } + if(!singlePath || singlePathIndex == 281) + { + mg_set_width(0.1); + mg_move_to(67.503, 141.560); + mg_cubic_to(67.503, 141.560, 66.938, 139.840, 68.864, 140.260); + mg_cubic_to(70.790, 140.670, 113.860, 145.000, 203.584, 179.300); + mg_cubic_to(203.584, 179.300, 82.924, 138.900, 67.504, 141.560); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 282) + { + mg_move_to(-43.800, 148.400); + mg_cubic_to(-43.800, 148.400, -38.600, 148.000, -39.800, 149.600); + mg_cubic_to(-41.000, 151.200, -43.400, 150.400, -43.400, 150.400); + mg_line_to(-43.800, 148.400); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 283) + { + mg_move_to(-13.000, 162.400); + mg_cubic_to(-13.000, 162.400, -7.800, 162.000, -9.000, 163.600); + mg_cubic_to(-10.200, 165.200, -12.600, 164.400, -12.600, 164.400); + mg_line_to(-13.000, 162.400); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 284) + { + mg_move_to(-21.800, 162.000); + mg_cubic_to(-21.800, 162.000, -16.600, 161.600, -17.800, 163.200); + mg_cubic_to(-19.000, 164.800, -21.400, 164.000, -21.400, 164.000); + mg_line_to(-21.800, 162.000); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 285) + { + mg_move_to(-117.170, 150.180); + mg_cubic_to(-117.170, 150.180, -112.120, 151.500, -113.780, 152.620); + mg_cubic_to(-115.440, 153.740, -117.450, 152.200, -117.450, 152.200); + mg_line_to(-117.170, 150.180); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 286) + { + mg_move_to(-115.170, 140.580); + mg_cubic_to(-115.170, 140.580, -110.120, 141.900, -111.780, 143.020); + mg_cubic_to(-113.440, 144.140, -115.450, 142.600, -115.450, 142.600); + mg_line_to(-115.170, 140.580); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 287) + { + mg_move_to(-122.370, 136.180); + mg_cubic_to(-122.370, 136.180, -117.320, 137.500, -118.980, 138.620); + mg_cubic_to(-120.640, 139.740, -122.650, 138.200, -122.650, 138.200); + mg_line_to(-122.370, 136.180); + mg_close_path(); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 288) + { + mg_move_to(-42.600, 211.200); + mg_move_to(-48.200, 213.200); + mg_cubic_to(-50.200, 213.200, -61.400, 216.800, -67.000, 226.800); + mg_cubic_to(-67.000, 226.800, -54.600, 217.200, -42.600, 211.200); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 289) + { + mg_move_to(45.116, 303.850); + mg_cubic_to(45.257, 304.100, 45.312, 304.520, 45.604, 304.540); + mg_cubic_to(46.262, 304.580, 47.495, 304.880, 47.370, 304.250); + mg_cubic_to(46.522, 299.940, 45.648, 295.000, 41.515, 293.200); + mg_cubic_to(40.876, 292.920, 39.434, 293.330, 39.360, 294.220); + mg_cubic_to(39.233, 295.740, 39.116, 297.090, 39.425, 298.550); + mg_cubic_to(39.725, 299.980, 41.883, 299.980, 42.800, 298.600); + mg_cubic_to(43.736, 300.270, 44.168, 302.120, 45.116, 303.850); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 290) + { + mg_move_to(34.038, 308.580); + mg_cubic_to(34.786, 309.990, 34.659, 311.850, 36.074, 312.420); + mg_cubic_to(36.814, 312.710, 38.664, 311.740, 38.246, 310.660); + mg_cubic_to(37.444, 308.600, 37.056, 306.360, 35.667, 304.550); + mg_cubic_to(35.467, 304.290, 35.707, 303.760, 35.547, 303.430); + mg_cubic_to(34.953, 302.210, 33.808, 301.470, 32.400, 301.800); + mg_cubic_to(31.285, 304.000, 32.433, 306.130, 33.955, 307.840); + mg_cubic_to(34.091, 307.990, 33.925, 308.370, 34.038, 308.580); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 291) + { + mg_move_to(-5.564, 303.390); + mg_cubic_to(-5.672, 303.010, -5.710, 302.550, -5.545, 302.230); + mg_cubic_to(-5.014, 301.200, -4.221, 300.080, -4.558, 299.050); + mg_cubic_to(-4.906, 298.000, -6.022, 298.180, -6.672, 298.750); + mg_cubic_to(-7.807, 299.740, -7.856, 301.570, -8.547, 302.930); + mg_cubic_to(-8.743, 303.310, -8.692, 303.890, -9.133, 304.280); + mg_cubic_to(-9.607, 304.700, -10.047, 306.220, -9.951, 306.790); + mg_cubic_to(-9.898, 307.110, -10.081, 317.010, -9.859, 316.750); + mg_cubic_to(-9.240, 316.020, -6.190, 306.280, -6.121, 305.390); + mg_cubic_to(-6.064, 304.660, -5.332, 304.200, -5.564, 303.390); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 292) + { + mg_move_to(-31.202, 296.600); + mg_cubic_to(-28.568, 294.100, -25.778, 291.140, -26.220, 287.430); + mg_cubic_to(-26.336, 286.450, -28.111, 286.980, -28.298, 287.820); + mg_cubic_to(-29.100, 291.450, -31.139, 294.110, -33.707, 296.500); + mg_cubic_to(-35.903, 298.550, -37.765, 304.890, -38.000, 305.400); + mg_cubic_to(-34.303, 300.140, -32.046, 297.400, -31.202, 296.600); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 293) + { + mg_move_to(-44.776, 290.640); + mg_cubic_to(-44.253, 290.260, -44.555, 289.770, -44.338, 289.440); + mg_cubic_to(-43.385, 287.980, -42.084, 286.740, -42.066, 285.000); + mg_cubic_to(-42.063, 284.720, -42.441, 284.410, -42.776, 284.640); + mg_cubic_to(-43.053, 284.820, -43.395, 284.950, -43.503, 285.080); + mg_cubic_to(-45.533, 287.530, -46.933, 290.200, -48.376, 293.010); + mg_cubic_to(-48.559, 293.370, -49.703, 297.860, -49.390, 297.970); + mg_cubic_to(-49.151, 298.060, -47.431, 293.880, -47.221, 293.760); + mg_cubic_to(-45.958, 293.080, -45.946, 291.460, -44.776, 290.640); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 294) + { + mg_move_to(-28.043, 310.180); + mg_cubic_to(-27.599, 309.310, -26.023, 308.110, -26.136, 307.220); + mg_cubic_to(-26.254, 306.290, -25.786, 304.850, -26.698, 305.540); + mg_cubic_to(-27.955, 306.480, -31.404, 307.830, -31.674, 313.640); + mg_cubic_to(-31.700, 314.210, -28.726, 311.520, -28.043, 310.180); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 295) + { + mg_move_to(-13.600, 293.000); + mg_cubic_to(-13.200, 292.330, -12.492, 292.810, -12.033, 292.540); + mg_cubic_to(-11.385, 292.170, -10.774, 291.610, -10.482, 290.960); + mg_cubic_to(-9.512, 288.820, -7.743, 287.000, -7.600, 284.600); + mg_cubic_to(-9.091, 283.200, -9.770, 285.240, -10.400, 286.200); + mg_cubic_to(-11.723, 284.550, -12.722, 286.430, -14.022, 286.950); + mg_cubic_to(-14.092, 286.980, -14.305, 286.630, -14.380, 286.660); + mg_cubic_to(-15.557, 287.100, -16.237, 288.180, -17.235, 288.960); + mg_cubic_to(-17.406, 289.090, -17.811, 288.910, -17.958, 289.050); + mg_cubic_to(-18.610, 289.650, -19.583, 289.980, -19.863, 290.660); + mg_cubic_to(-20.973, 293.360, -24.113, 295.460, -26.000, 303.000); + mg_cubic_to(-25.619, 303.910, -21.488, 296.360, -21.001, 295.660); + mg_cubic_to(-20.165, 294.460, -20.047, 297.320, -18.771, 296.660); + mg_cubic_to(-18.720, 296.630, -18.534, 296.870, -18.400, 297.000); + mg_cubic_to(-18.206, 296.720, -17.988, 296.490, -17.600, 296.600); + mg_cubic_to(-17.600, 296.200, -17.734, 295.640, -17.533, 295.490); + mg_cubic_to(-16.296, 294.510, -16.380, 293.440, -15.600, 292.200); + mg_cubic_to(-15.142, 292.990, -14.081, 292.270, -13.600, 293.000); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 296) + { + mg_move_to(46.200, 347.400); + mg_cubic_to(46.200, 347.400, 53.600, 327.000, 49.200, 315.800); + mg_cubic_to(49.200, 315.800, 60.600, 337.400, 56.000, 348.600); + mg_cubic_to(56.000, 348.600, 55.600, 338.200, 51.600, 333.200); + mg_cubic_to(51.600, 333.200, 47.600, 346.000, 46.200, 347.400); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 297) + { + mg_move_to(31.400, 344.800); + mg_cubic_to(31.400, 344.800, 36.800, 336.000, 28.800, 317.600); + mg_cubic_to(28.800, 317.600, 28.000, 338.000, 21.200, 349.000); + mg_cubic_to(21.200, 349.000, 35.400, 328.800, 31.400, 344.800); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 298) + { + mg_move_to(21.400, 342.800); + mg_cubic_to(21.400, 342.800, 21.200, 322.800, 21.600, 319.800); + mg_cubic_to(21.600, 319.800, 17.800, 336.400, 7.600, 346.000); + mg_cubic_to(7.600, 346.000, 22.000, 334.000, 21.400, 342.800); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 299) + { + mg_move_to(11.800, 310.800); + mg_cubic_to(11.800, 310.800, 17.800, 324.400, 7.800, 342.800); + mg_cubic_to(7.800, 342.800, 14.200, 330.600, 9.400, 323.600); + mg_cubic_to(9.400, 323.600, 12.000, 320.200, 11.800, 310.800); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 300) + { + mg_move_to(-7.400, 342.400); + mg_cubic_to(-7.400, 342.400, -8.400, 326.800, -6.600, 324.600); + mg_cubic_to(-6.600, 324.600, -6.400, 318.200, -6.800, 317.200); + mg_cubic_to(-6.800, 317.200, -2.800, 311.000, -2.600, 318.400); + mg_cubic_to(-2.600, 318.400, -1.200, 326.200, 1.600, 330.800); + mg_cubic_to(1.600, 330.800, 5.200, 336.200, 5.000, 342.600); + mg_cubic_to(5.000, 342.600, -5.000, 312.400, -7.400, 342.400); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 301) + { + mg_move_to(-11.000, 314.800); + mg_cubic_to(-11.000, 314.800, -17.600, 325.600, -19.400, 344.600); + mg_cubic_to(-19.400, 344.600, -20.800, 338.400, -17.000, 324.000); + mg_cubic_to(-17.000, 324.000, -12.800, 308.600, -11.000, 314.800); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 302) + { + mg_move_to(-32.800, 334.600); + mg_cubic_to(-32.800, 334.600, -27.800, 329.200, -26.400, 324.200); + mg_cubic_to(-26.400, 324.200, -22.800, 308.400, -29.200, 317.000); + mg_cubic_to(-29.200, 317.000, -29.000, 325.000, -37.200, 332.400); + mg_cubic_to(-37.200, 332.400, -32.400, 330.000, -32.800, 334.600); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 303) + { + mg_move_to(-38.600, 329.600); + mg_cubic_to(-38.600, 329.600, -35.200, 312.200, -34.400, 311.400); + mg_cubic_to(-34.400, 311.400, -32.600, 308.000, -35.400, 311.200); + mg_cubic_to(-35.400, 311.200, -44.200, 330.400, -48.200, 337.000); + mg_cubic_to(-48.200, 337.000, -40.200, 327.800, -38.600, 329.600); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 304) + { + mg_move_to(-44.400, 313.000); + mg_cubic_to(-44.400, 313.000, -32.800, 290.600, -54.600, 316.400); + mg_cubic_to(-54.600, 316.400, -43.600, 306.600, -44.400, 313.000); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 305) + { + mg_move_to(-59.800, 298.400); + mg_cubic_to(-59.800, 298.400, -55.000, 279.600, -52.400, 279.800); + mg_line_to(-50.800, 281.400); + mg_cubic_to(-50.800, 281.400, -56.800, 291.000, -56.200, 300.800); + mg_cubic_to(-56.200, 300.800, -56.800, 291.200, -59.800, 298.400); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 306) + { + mg_move_to(270.500, 287.000); + mg_cubic_to(270.500, 287.000, 258.500, 277.000, 256.000, 273.500); + mg_cubic_to(256.000, 273.500, 269.500, 292.000, 269.500, 299.000); + mg_cubic_to(269.500, 299.000, 272.000, 291.500, 270.500, 287.000); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 307) + { + mg_move_to(276.000, 265.000); + mg_cubic_to(276.000, 265.000, 255.000, 250.000, 251.500, 242.500); + mg_cubic_to(251.500, 242.500, 278.000, 272.000, 278.000, 276.500); + mg_cubic_to(278.000, 276.500, 278.500, 267.500, 276.000, 265.000); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 308) + { + mg_move_to(293.000, 111.000); + mg_cubic_to(293.000, 111.000, 281.000, 103.000, 279.500, 105.000); + mg_cubic_to(279.500, 105.000, 290.000, 111.500, 292.500, 120.000); + mg_cubic_to(292.500, 120.000, 291.000, 111.000, 293.000, 111.000); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 309) + { + mg_move_to(301.500, 191.500); + mg_move_to(284.000, 179.500); + mg_cubic_to(284.000, 179.500, 303.000, 196.500, 303.500, 200.500); + mg_line_to(301.500, 191.500); + mg_close_path(); + mg_set_color_rgba(0.800, 0.800, 0.800, 1); + mg_fill(); + } + + if(!singlePath || singlePathIndex == 310) + { + mg_move_to(-89.250, 169.000); + mg_move_to(-67.250, 173.750); + } + if(!singlePath || singlePathIndex == 311) + { + mg_set_width(1); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 312) + { + mg_move_to(-39.000, 331.000); + mg_cubic_to(-39.000, 331.000, -39.500, 327.500, -48.500, 338.000); + } + if(!singlePath || singlePathIndex == 313) + { + mg_set_width(1); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 314) + { + mg_move_to(-33.500, 336.000); + mg_cubic_to(-33.500, 336.000, -31.500, 329.500, -38.000, 334.000); + } + if(!singlePath || singlePathIndex == 315) + { + mg_set_width(1); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } + + if(!singlePath || singlePathIndex == 316) + { + mg_move_to(20.500, 344.500); + mg_cubic_to(20.500, 344.500, 22.000, 333.500, 10.500, 346.500); + } + if(!singlePath || singlePathIndex == 317) + { + mg_set_width(1); + mg_set_color_rgba(0.000, 0.000, 0.000, 1); + mg_stroke(); + } } diff --git a/sketches/triangleGL/main.c b/sketches/triangleGL/main.c index 07ee863..b2e41d6 100644 --- a/sketches/triangleGL/main.c +++ b/sketches/triangleGL/main.c @@ -1,163 +1,163 @@ -/************************************************************//** +/************************************************************/ /** * * @file: main.cpp * @author: Martin Fouilleul * @date: 30/07/2022 * @revision: * -*****************************************************************/ -#include -#include - -#define _USE_MATH_DEFINES //NOTE: necessary for MSVC -#include - -#define MG_INCLUDE_GL_API -#include"milepost.h" - -unsigned int program; - -const char* vshaderSource = - "#version 430\n" - "attribute vec4 vPosition;\n" - "uniform mat4 transform;\n" - "void main()\n" - "{\n" - " gl_Position = transform*vPosition;\n" - "}\n"; - -const char* fshaderSource = - "#version 430\n" - "precision mediump float;\n" - "void main()\n" - "{\n" - " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" - "}\n"; - -void compile_shader(GLuint shader, const char* source) -{ - glShaderSource(shader, 1, &source, 0); - glCompileShader(shader); - - int err = glGetError(); - if(err) - { - printf("gl error: %i\n", err); - } - - int status = 0; - glGetShaderiv(shader, GL_COMPILE_STATUS, &status); - if(!status) - { - char buffer[256]; - int size = 0; - glGetShaderInfoLog(shader, 256, &size, buffer); - printf("shader error: %.*s\n", size, buffer); - } -} - -int main() -{ - mp_init(); - - mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600}; - mp_window window = mp_window_create(rect, "test", 0); - - //NOTE: create surface - mg_surface surface = mg_surface_create_for_window(window, MG_GL); - - //NOTE: init shader and gl state - mg_surface_prepare(surface); - - GLuint vao; - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); - - GLuint vertexBuffer; - glGenBuffers(1, &vertexBuffer); - - GLfloat vertices[] = { - -0.866/2, -0.5/2, 0, 0.866/2, -0.5/2, 0, 0, 0.5, 0}; - - glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - - unsigned int vshader = glCreateShader(GL_VERTEX_SHADER); - unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER); - program = glCreateProgram(); - - compile_shader(vshader, vshaderSource); - compile_shader(fshader, fshaderSource); - - glAttachShader(program, vshader); - glAttachShader(program, fshader); - glLinkProgram(program); - - int status = 0; - glGetProgramiv(program, GL_LINK_STATUS, &status); - if(!status) - { - char buffer[256]; - int size = 0; - glGetProgramInfoLog(program, 256, &size, buffer); - printf("link error: %.*s\n", size, buffer); - } - - glUseProgram(program); - - mp_window_bring_to_front(window); -// mp_window_focus(window); - - while(!mp_should_quit()) - { - mp_pump_events(0); - mp_event* event = 0; - while((event = mp_next_event(mem_scratch())) != 0) - { - switch(event->type) - { - case MP_EVENT_WINDOW_CLOSE: - { - mp_request_quit(); - } break; - - default: - break; - } - } - - mg_surface_prepare(surface); - - glClearColor(0.3, 0.3, 1, 1); - glClear(GL_COLOR_BUFFER_BIT); - - static float alpha = 0; - //f32 aspect = frameSize.x/frameSize.y; - f32 aspect = 800/(f32)600; - - GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0, - -sinf(alpha)/aspect, cosf(alpha), 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1}; - - alpha += 2*M_PI/120; - - glUniformMatrix4fv(0, 1, false, matrix); - - - glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); - glEnableVertexAttribArray(0); - - glDrawArrays(GL_TRIANGLES, 0, 3); - - mg_surface_present(surface); - - mem_arena_clear(mem_scratch()); - } - - mp_terminate(); - - return(0); -} +*****************************************************************/ +#include +#include + +#define _USE_MATH_DEFINES //NOTE: necessary for MSVC +#include + +#define MG_INCLUDE_GL_API +#include "milepost.h" + +unsigned int program; + +const char* vshaderSource = + "#version 430\n" + "attribute vec4 vPosition;\n" + "uniform mat4 transform;\n" + "void main()\n" + "{\n" + " gl_Position = transform*vPosition;\n" + "}\n"; + +const char* fshaderSource = + "#version 430\n" + "precision mediump float;\n" + "void main()\n" + "{\n" + " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" + "}\n"; + +void compile_shader(GLuint shader, const char* source) +{ + glShaderSource(shader, 1, &source, 0); + glCompileShader(shader); + + int err = glGetError(); + if(err) + { + printf("gl error: %i\n", err); + } + + int status = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + if(!status) + { + char buffer[256]; + int size = 0; + glGetShaderInfoLog(shader, 256, &size, buffer); + printf("shader error: %.*s\n", size, buffer); + } +} + +int main() +{ + mp_init(); + + mp_rect rect = { .x = 100, .y = 100, .w = 800, .h = 600 }; + mp_window window = mp_window_create(rect, "test", 0); + + //NOTE: create surface + mg_surface surface = mg_surface_create_for_window(window, MG_GL); + + //NOTE: init shader and gl state + mg_surface_prepare(surface); + + GLuint vao; + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + + GLuint vertexBuffer; + glGenBuffers(1, &vertexBuffer); + + GLfloat vertices[] = { + -0.866 / 2, -0.5 / 2, 0, 0.866 / 2, -0.5 / 2, 0, 0, 0.5, 0 + }; + + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + + unsigned int vshader = glCreateShader(GL_VERTEX_SHADER); + unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER); + program = glCreateProgram(); + + compile_shader(vshader, vshaderSource); + compile_shader(fshader, fshaderSource); + + glAttachShader(program, vshader); + glAttachShader(program, fshader); + glLinkProgram(program); + + int status = 0; + glGetProgramiv(program, GL_LINK_STATUS, &status); + if(!status) + { + char buffer[256]; + int size = 0; + glGetProgramInfoLog(program, 256, &size, buffer); + printf("link error: %.*s\n", size, buffer); + } + + glUseProgram(program); + + mp_window_bring_to_front(window); + // mp_window_focus(window); + + while(!mp_should_quit()) + { + mp_pump_events(0); + mp_event* event = 0; + while((event = mp_next_event(mem_scratch())) != 0) + { + switch(event->type) + { + case MP_EVENT_WINDOW_CLOSE: + { + mp_request_quit(); + } + break; + + default: + break; + } + } + + mg_surface_prepare(surface); + + glClearColor(0.3, 0.3, 1, 1); + glClear(GL_COLOR_BUFFER_BIT); + + static float alpha = 0; + //f32 aspect = frameSize.x/frameSize.y; + f32 aspect = 800 / (f32)600; + + GLfloat matrix[] = { cosf(alpha) / aspect, sinf(alpha), 0, 0, + -sinf(alpha) / aspect, cosf(alpha), 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 }; + + alpha += 2 * M_PI / 120; + + glUniformMatrix4fv(0, 1, false, matrix); + + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(0); + + glDrawArrays(GL_TRIANGLES, 0, 3); + + mg_surface_present(surface); + + mem_arena_clear(mem_scratch()); + } + + mp_terminate(); + + return (0); +} diff --git a/sketches/triangleGLES/main.c b/sketches/triangleGLES/main.c index d66bfe2..076718c 100644 --- a/sketches/triangleGLES/main.c +++ b/sketches/triangleGLES/main.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: main.cpp * @author: Martin Fouilleul @@ -6,160 +6,160 @@ * @revision: * *****************************************************************/ -#include -#include -#include +#include +#include +#include #define _USE_MATH_DEFINES //NOTE: necessary for MSVC -#include +#include #define MG_INCLUDE_GL_API 1 -#include"milepost.h" +#include "milepost.h" unsigned int program; const char* vshaderSource = - //"#version 320 es\n" - "attribute vec4 vPosition;\n" - "uniform mat4 transform;\n" - "void main()\n" - "{\n" - " gl_Position = transform*vPosition;\n" - "}\n"; + //"#version 320 es\n" + "attribute vec4 vPosition;\n" + "uniform mat4 transform;\n" + "void main()\n" + "{\n" + " gl_Position = transform*vPosition;\n" + "}\n"; const char* fshaderSource = - //"#version 320 es\n" - "precision mediump float;\n" - "void main()\n" - "{\n" - " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" - "}\n"; + //"#version 320 es\n" + "precision mediump float;\n" + "void main()\n" + "{\n" + " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n" + "}\n"; void compile_shader(GLuint shader, const char* source) { - glShaderSource(shader, 1, &source, 0); - glCompileShader(shader); + glShaderSource(shader, 1, &source, 0); + glCompileShader(shader); - int err = glGetError(); - if(err) - { - printf("gl error: %i\n", err); - } + int err = glGetError(); + if(err) + { + printf("gl error: %i\n", err); + } - int status = 0; - glGetShaderiv(shader, GL_COMPILE_STATUS, &status); - if(!status) - { - char buffer[256]; - int size = 0; - glGetShaderInfoLog(shader, 256, &size, buffer); - printf("shader error: %.*s\n", size, buffer); - } + int status = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + if(!status) + { + char buffer[256]; + int size = 0; + glGetShaderInfoLog(shader, 256, &size, buffer); + printf("shader error: %.*s\n", size, buffer); + } } int main() { - mp_init(); + mp_init(); - mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600}; - mp_window window = mp_window_create(rect, "test", 0); + mp_rect rect = { .x = 100, .y = 100, .w = 800, .h = 600 }; + mp_window window = mp_window_create(rect, "test", 0); - //NOTE: create surface - mg_surface surface = mg_surface_create_for_window(window, MG_GLES); - mg_surface_prepare(surface); + //NOTE: create surface + mg_surface surface = mg_surface_create_for_window(window, MG_GLES); + mg_surface_prepare(surface); - //NOTE: init shader and gl state - GLuint vao; - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); + //NOTE: init shader and gl state + GLuint vao; + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); - GLuint vertexBuffer; - glGenBuffers(1, &vertexBuffer); + GLuint vertexBuffer; + glGenBuffers(1, &vertexBuffer); - GLfloat vertices[] = { - -0.866/2, -0.5/2, 0, 0.866/2, -0.5/2, 0, 0, 0.5, 0}; + GLfloat vertices[] = { + -0.866 / 2, -0.5 / 2, 0, 0.866 / 2, -0.5 / 2, 0, 0, 0.5, 0 + }; - glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + unsigned int vshader = glCreateShader(GL_VERTEX_SHADER); + unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER); + program = glCreateProgram(); - unsigned int vshader = glCreateShader(GL_VERTEX_SHADER); - unsigned int fshader = glCreateShader(GL_FRAGMENT_SHADER); - program = glCreateProgram(); + compile_shader(vshader, vshaderSource); + compile_shader(fshader, fshaderSource); - compile_shader(vshader, vshaderSource); - compile_shader(fshader, fshaderSource); + glAttachShader(program, vshader); + glAttachShader(program, fshader); + glLinkProgram(program); - glAttachShader(program, vshader); - glAttachShader(program, fshader); - glLinkProgram(program); + int status = 0; + glGetProgramiv(program, GL_LINK_STATUS, &status); + if(!status) + { + char buffer[256]; + int size = 0; + glGetProgramInfoLog(program, 256, &size, buffer); + printf("link error: %.*s\n", size, buffer); + } - int status = 0; - glGetProgramiv(program, GL_LINK_STATUS, &status); - if(!status) - { - char buffer[256]; - int size = 0; - glGetProgramInfoLog(program, 256, &size, buffer); - printf("link error: %.*s\n", size, buffer); - } + glUseProgram(program); - glUseProgram(program); + mp_window_bring_to_front(window); + // mp_window_focus(window); - mp_window_bring_to_front(window); -// mp_window_focus(window); + while(!mp_should_quit()) + { + mp_pump_events(0); + mp_event* event = 0; + while((event = mp_next_event(mem_scratch())) != 0) + { + switch(event->type) + { + case MP_EVENT_WINDOW_CLOSE: + { + mp_request_quit(); + } + break; - while(!mp_should_quit()) - { - mp_pump_events(0); - mp_event* event = 0; - while((event = mp_next_event(mem_scratch())) != 0) - { - switch(event->type) - { - case MP_EVENT_WINDOW_CLOSE: - { - mp_request_quit(); - } break; + default: + break; + } + } - default: - break; - } - } + // mg_surface_prepare(surface); -// mg_surface_prepare(surface); + glClearColor(0.3, 0.3, 1, 1); + glClear(GL_COLOR_BUFFER_BIT); - glClearColor(0.3, 0.3, 1, 1); - glClear(GL_COLOR_BUFFER_BIT); + static float alpha = 0; + //f32 aspect = frameSize.x/frameSize.y; + f32 aspect = 800 / (f32)600; - static float alpha = 0; - //f32 aspect = frameSize.x/frameSize.y; - f32 aspect = 800/(f32)600; + GLfloat matrix[] = { cosf(alpha) / aspect, sinf(alpha), 0, 0, + -sinf(alpha) / aspect, cosf(alpha), 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 }; - GLfloat matrix[] = {cosf(alpha)/aspect, sinf(alpha), 0, 0, - -sinf(alpha)/aspect, cosf(alpha), 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1}; + alpha += 2 * M_PI / 120; - alpha += 2*M_PI/120; + glUniformMatrix4fv(0, 1, false, matrix); - glUniformMatrix4fv(0, 1, false, matrix); + glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); + glEnableVertexAttribArray(0); + glDrawArrays(GL_TRIANGLES, 0, 3); - glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); - glEnableVertexAttribArray(0); + mg_surface_present(surface); - glDrawArrays(GL_TRIANGLES, 0, 3); + mem_arena_clear(mem_scratch()); + } - mg_surface_present(surface); + mg_surface_destroy(surface); + mp_window_destroy(window); + mp_terminate(); - mem_arena_clear(mem_scratch()); - } - - mg_surface_destroy(surface); - mp_window_destroy(window); - mp_terminate(); - - return(0); + return (0); } diff --git a/sketches/triangleMetal/main.m b/sketches/triangleMetal/main.m index 4000c6f..30296a2 100644 --- a/sketches/triangleMetal/main.m +++ b/sketches/triangleMetal/main.m @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: main.cpp * @author: Martin Fouilleul @@ -6,121 +6,122 @@ * @revision: * *****************************************************************/ -#include -#include +#include +#include #define _USE_MATH_DEFINES //NOTE: necessary for MSVC -#include +#include -#include"milepost.h" -#include"mtl_surface.h" +#include "milepost.h" +#include "mtl_surface.h" #define LOG_SUBSYSTEM "Main" -#import -#import +#import +#import -#include"vertex.h" +#include "vertex.h" -static const my_vertex triangle[3] = {{{250, -250},{1, 0, 0, 1}}, - {{-250, -250},{0, 1, 0, 1}}, - {{0, 250},{0, 0, 1, 1}}}; +static const my_vertex triangle[3] = { { { 250, -250 }, { 1, 0, 0, 1 } }, + { { -250, -250 }, { 0, 1, 0, 1 } }, + { { 0, 250 }, { 0, 0, 1, 1 } } }; int main() { - LogLevel(LOG_LEVEL_DEBUG); + LogLevel(LOG_LEVEL_DEBUG); - mp_init(); + mp_init(); - mp_rect rect = {.x = 100, .y = 100, .w = 800, .h = 600}; - mp_window window = mp_window_create(rect, "test", 0); + mp_rect rect = { .x = 100, .y = 100, .w = 800, .h = 600 }; + mp_window window = mp_window_create(rect, "test", 0); - //NOTE: create surface - mg_surface surface = mg_surface_create_for_window(window, MG_BACKEND_METAL); + //NOTE: create surface + mg_surface surface = mg_surface_create_for_window(window, MG_BACKEND_METAL); - //NOTE(martin): load the library - id device = MTLCreateSystemDefaultDevice(); + //NOTE(martin): load the library + id device = MTLCreateSystemDefaultDevice(); - str8 shaderPath = path_executable_relative(mem_scratch(), STR8("triangle_shader.metallib")); - const char* shaderPathCString = str8_to_cstring(mem_scratch(), shaderPath); - NSString* metalFileName = [[NSString alloc] initWithCString: shaderPathCString encoding: NSUTF8StringEncoding]; - NSError* err = 0; - id library = [device newLibraryWithFile: metalFileName error:&err]; - if(err != nil) - { - const char* errStr = [[err localizedDescription] UTF8String]; - printf("error : %s\n", errStr); - return(-1); - } - id vertexFunction = [library newFunctionWithName:@"VertexShader"]; - id fragmentFunction = [library newFunctionWithName:@"FragmentShader"]; + str8 shaderPath = path_executable_relative(mem_scratch(), STR8("triangle_shader.metallib")); + const char* shaderPathCString = str8_to_cstring(mem_scratch(), shaderPath); + NSString* metalFileName = [[NSString alloc] initWithCString:shaderPathCString encoding:NSUTF8StringEncoding]; + NSError* err = 0; + id library = [device newLibraryWithFile:metalFileName error:&err]; + if(err != nil) + { + const char* errStr = [[err localizedDescription] UTF8String]; + printf("error : %s\n", errStr); + return (-1); + } + id vertexFunction = [library newFunctionWithName:@"VertexShader"]; + id fragmentFunction = [library newFunctionWithName:@"FragmentShader"]; - //NOTE(martin): create a render pipeline - MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; - pipelineStateDescriptor.label = @"My simple pipeline"; - pipelineStateDescriptor.vertexFunction = vertexFunction; - pipelineStateDescriptor.fragmentFunction = fragmentFunction; + //NOTE(martin): create a render pipeline + MTLRenderPipelineDescriptor* pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; + pipelineStateDescriptor.label = @"My simple pipeline"; + pipelineStateDescriptor.vertexFunction = vertexFunction; + pipelineStateDescriptor.fragmentFunction = fragmentFunction; - CAMetalLayer* layer = mg_mtl_surface_layer(surface); - pipelineStateDescriptor.colorAttachments[0].pixelFormat = layer.pixelFormat; + CAMetalLayer* layer = mg_mtl_surface_layer(surface); + pipelineStateDescriptor.colorAttachments[0].pixelFormat = layer.pixelFormat; - id pipelineState = [device newRenderPipelineStateWithDescriptor: pipelineStateDescriptor error:&err]; - if(err != nil) - { - const char* errStr = [[err localizedDescription] UTF8String]; - printf("error : %s\n", errStr); - return(-1); - } + id pipelineState = [device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor error:&err]; + if(err != nil) + { + const char* errStr = [[err localizedDescription] UTF8String]; + printf("error : %s\n", errStr); + return (-1); + } - // start app + // start app - mp_window_bring_to_front(window); - mp_window_focus(window); + mp_window_bring_to_front(window); + mp_window_focus(window); - while(!mp_should_quit()) - { - mp_pump_events(0); - mp_event event = {0}; - while(mp_next_event(&event)) - { - switch(event.type) - { - case MP_EVENT_WINDOW_CLOSE: - { - mp_request_quit(); - } break; + while(!mp_should_quit()) + { + mp_pump_events(0); + mp_event event = { 0 }; + while(mp_next_event(&event)) + { + switch(event.type) + { + case MP_EVENT_WINDOW_CLOSE: + { + mp_request_quit(); + } + break; - default: - break; - } - } + default: + break; + } + } - vector_uint2 viewportSize; - viewportSize.x = 800; - viewportSize.y = 600; + vector_uint2 viewportSize; + viewportSize.x = 800; + viewportSize.y = 600; - mg_surface_prepare(surface); - id drawable = mg_mtl_surface_drawable(surface); - id commandBuffer = mg_mtl_surface_command_buffer(surface); + mg_surface_prepare(surface); + id drawable = mg_mtl_surface_drawable(surface); + id commandBuffer = mg_mtl_surface_command_buffer(surface); - MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]; - renderPassDescriptor.colorAttachments[0].texture = drawable.texture; - renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; - id encoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; + MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]; + renderPassDescriptor.colorAttachments[0].texture = drawable.texture; + renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; + id encoder = [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; - //Set the pipeline state - [encoder setRenderPipelineState:pipelineState]; + //Set the pipeline state + [encoder setRenderPipelineState:pipelineState]; - //Send data to the shader and add draw call - [encoder setVertexBytes: triangle length:sizeof(triangle) atIndex: vertexInputIndexVertices]; - [encoder setVertexBytes: &viewportSize length:sizeof(viewportSize) atIndex: vertexInputIndexViewportSize]; - [encoder drawPrimitives: MTLPrimitiveTypeTriangle vertexStart: 0 vertexCount: 3]; - [encoder endEncoding]; + //Send data to the shader and add draw call + [encoder setVertexBytes:triangle length:sizeof(triangle) atIndex:vertexInputIndexVertices]; + [encoder setVertexBytes:&viewportSize length:sizeof(viewportSize) atIndex:vertexInputIndexViewportSize]; + [encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:3]; + [encoder endEncoding]; - mg_surface_present(surface); - } + mg_surface_present(surface); + } - mp_terminate(); + mp_terminate(); - return(0); + return (0); } diff --git a/sketches/triangleMetal/vertex.h b/sketches/triangleMetal/vertex.h index d14cb6f..8ada2ab 100644 --- a/sketches/triangleMetal/vertex.h +++ b/sketches/triangleMetal/vertex.h @@ -2,16 +2,18 @@ #ifndef __VERTEX_H__ #define __VERTEX_H__ -#include +#include typedef struct { - vector_float2 pos; - vector_float4 col; + vector_float2 pos; + vector_float4 col; } my_vertex; -typedef enum { vertexInputIndexVertices = 0, - vertexInputIndexViewportSize = 1 } vertexInputIndex; - +typedef enum +{ + vertexInputIndexVertices = 0, + vertexInputIndexViewportSize = 1 +} vertexInputIndex; #endif //__VERTEX_H__ diff --git a/sketches/ui/main.c b/sketches/ui/main.c index d743057..c28a0d5 100644 --- a/sketches/ui/main.c +++ b/sketches/ui/main.c @@ -1,633 +1,632 @@ -/************************************************************//** +/************************************************************/ /** * * @file: main.cpp * @author: Martin Fouilleul * @date: 30/07/2022 * @revision: * -*****************************************************************/ -#include -#include -#include -#include - -#define _USE_MATH_DEFINES //NOTE: necessary for MSVC -#include - -#include"milepost.h" - -void debug_print_indent(int indent) -{ - for(int i=0; ipattern.l, selector, ui_selector, listElt) - { - switch(selector->kind) - { - case UI_SEL_ANY: - printf("any: "); - break; - - case UI_SEL_OWNER: - printf("owner: "); - break; - - case UI_SEL_TEXT: - printf("text='%.*s': ", (int)selector->text.len, selector->text.ptr); - break; - - case UI_SEL_TAG: - printf("tag=0x%llx: ", selector->tag.hash); - break; - - case UI_SEL_STATUS: - { - if(selector->status & UI_HOVER) - { - printf("hover: "); - } - if(selector->status & UI_ACTIVE) - { - printf("active: "); - } - if(selector->status & UI_DRAGGING) - { - printf("dragging: "); - } - } break; - - case UI_SEL_KEY: - printf("key=0x%llx: ", selector->key.hash); - break; - - default: - printf("unknown: "); - break; - } - } - printf("=> font size = %f\n", rule->style->fontSize); -} -void debug_print_size(ui_box* box, ui_axis axis, int indent) -{ - debug_print_indent(indent); - printf("size %s: ", axis == UI_AXIS_X ? "x" : "y"); - f32 value = box->targetStyle->size.c[axis].value; - switch(box->targetStyle->size.c[axis].kind) - { - case UI_SIZE_TEXT: - printf("text\n"); - break; - - case UI_SIZE_CHILDREN: - printf("children\n"); - break; - - case UI_SIZE_PARENT: - printf("parent: %f\n", value); - break; - - case UI_SIZE_PARENT_MINUS_PIXELS: - printf("parent minus pixels: %f\n", value); - break; - - case UI_SIZE_PIXELS: - printf("pixels: %f\n", value); - break; - } - -} - -void debug_print_styles(ui_box* box, int indent) -{ - debug_print_indent(indent); - printf("### box '%.*s'\n", (int)box->string.len, box->string.ptr); - indent++; - - debug_print_indent(indent); - printf("font size: %f\n", box->targetStyle->fontSize); - - debug_print_size(box, UI_AXIS_X, indent); - debug_print_size(box, UI_AXIS_Y, indent); - - if(!list_empty(&box->beforeRules)) - { - debug_print_indent(indent); - printf("before rules:\n"); - for_list(&box->beforeRules, rule, ui_style_rule, boxElt) - { - debug_print_indent(indent+1); - debug_print_rule(rule); - } - } - - if(!list_empty(&box->afterRules)) - { - debug_print_indent(indent); - printf("after rules:\n"); - for_list(&box->afterRules, rule, ui_style_rule, boxElt) - { - debug_print_indent(indent+1); - debug_print_rule(rule); - } - } - - if(!list_empty(&box->children)) - { - debug_print_indent(indent); - printf("children:\n"); - indent++; - for_list(&box->children, child, ui_box, listElt) - { - debug_print_styles(child, indent); - } - } -} - -mg_font create_font() -{ - //NOTE(martin): create font - str8 fontPath = path_executable_relative(mem_scratch(), STR8("../resources/OpenSansLatinSubset.ttf")); - char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath); - - FILE* fontFile = fopen(fontPathCString, "r"); - if(!fontFile) - { - log_error("Could not load font file '%s': %s\n", fontPathCString, strerror(errno)); - return(mg_font_nil()); - } - unsigned char* fontData = 0; - fseek(fontFile, 0, SEEK_END); - u32 fontDataSize = ftell(fontFile); - rewind(fontFile); - fontData = (unsigned char*)malloc(fontDataSize); - fread(fontData, 1, fontDataSize, fontFile); - fclose(fontFile); - - unicode_range ranges[5] = {UNICODE_RANGE_BASIC_LATIN, - UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT, - UNICODE_RANGE_LATIN_EXTENDED_A, - UNICODE_RANGE_LATIN_EXTENDED_B, - UNICODE_RANGE_SPECIALS}; - - mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges); - free(fontData); - - return(font); -} - -void widget_begin_view(char* str) -{ - ui_style_next(&(ui_style){.layout.axis = UI_AXIS_Y, - .layout.spacing = 10, - .layout.margin.x = 10, - .layout.margin.y = 10, - .layout.align.x = UI_ALIGN_CENTER, - .layout.align.y = UI_ALIGN_START}, - UI_STYLE_LAYOUT); - - ui_box_begin(str, UI_FLAG_DRAW_BORDER); - ui_label(str); - -} - -void widget_end_view(void) -{ - ui_box_end(); -} - -#define widget_view(s) defer_loop(widget_begin_view(s), widget_end_view()) - -int main() -{ - mp_init(); - mp_clock_init(); //TODO put that in mp_init()? - - ui_context context; - ui_init(&context); - ui_set_context(&context); - - mp_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610}; - mp_window window = mp_window_create(windowRect, "test", 0); - - mp_rect contentRect = mp_window_get_content_rect(window); - - //NOTE: create surface - mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS); - mg_surface_swap_interval(surface, 0); - - //TODO: create canvas - mg_canvas canvas = mg_canvas_create(); - - if(mg_canvas_is_nil(canvas)) - { - printf("Error: couldn't create canvas\n"); - return(-1); - } - - mg_font font = create_font(); - - mem_arena textArena = {0}; - mem_arena_init(&textArena); - - // start app - mp_window_bring_to_front(window); - mp_window_focus(window); - - while(!mp_should_quit()) - { - bool printDebugStyle = false; - - f64 startTime = mp_get_time(MP_CLOCK_MONOTONIC); - - mp_pump_events(0); - mp_event* event = 0; - while((event = mp_next_event(mem_scratch())) != 0) - { - ui_process_event(event); - - switch(event->type) - { - case MP_EVENT_WINDOW_CLOSE: - { - mp_request_quit(); - } break; - - - case MP_EVENT_KEYBOARD_KEY: - { - if(event->key.action == MP_KEY_PRESS && event->key.code == MP_KEY_P) - { - printDebugStyle = true; - } - } break; - - default: - break; - } - } - - //TEST UI - ui_style defaultStyle = {.bgColor = {0}, - .color = {1, 1, 1, 1}, - .font = font, - .fontSize = 16, - .borderColor = {1, 0, 0, 1}, - .borderSize = 2}; - - ui_style_mask defaultMask = UI_STYLE_BG_COLOR - | UI_STYLE_COLOR - | UI_STYLE_BORDER_COLOR - | UI_STYLE_BORDER_SIZE - | UI_STYLE_FONT - | UI_STYLE_FONT_SIZE; - - ui_flags debugFlags = UI_FLAG_DRAW_BORDER; - - ui_box* root = 0; - - mp_rect frameRect = mg_surface_get_frame(surface); - vec2 frameSize = {frameRect.w, frameRect.h}; - - ui_frame(frameSize, &defaultStyle, defaultMask) - { - root = ui_box_top(); - ui_style_match_before(ui_pattern_all(), &defaultStyle, defaultMask); - - ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, - .size.height = {UI_SIZE_PARENT, 1}, - .layout.axis = UI_AXIS_Y, - .layout.align.x = UI_ALIGN_CENTER, - .layout.align.y = UI_ALIGN_START, - .layout.spacing = 10, - .layout.margin.x = 10, - .layout.margin.y = 10, - .bgColor = {0.11, 0.11, 0.11, 1}}, - UI_STYLE_SIZE - | UI_STYLE_LAYOUT - | UI_STYLE_BG_COLOR); - - ui_container("background", UI_FLAG_DRAW_BACKGROUND) - { - ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, - .size.height = {UI_SIZE_CHILDREN}, - .layout.align.x = UI_ALIGN_CENTER}, - UI_STYLE_SIZE - |UI_STYLE_LAYOUT_ALIGN_X); - ui_container("title", debugFlags) - { - ui_style_next(&(ui_style){.fontSize = 26}, UI_STYLE_FONT_SIZE); - ui_label("Milepost UI Demo"); - - if(ui_box_sig(ui_box_top()).hovering) - { - ui_tooltip("tooltip") - { - ui_style_next(&(ui_style){.bgColor = {1, 0.99, 0.82, 1}}, - UI_STYLE_BG_COLOR); - - ui_container("background", UI_FLAG_DRAW_BACKGROUND) - { - ui_style_next(&(ui_style){.color = {0, 0, 0, 1}}, - UI_STYLE_COLOR); - - ui_label("That is a tooltip!"); - } - } - } - } - - ui_menu_bar("Menu bar") - { - ui_menu("Menu 1") - { - if(ui_menu_button("Option 1.1").pressed) - { - printf("Pressed option 1.1\n"); - } - ui_menu_button("Option 1.2"); - ui_menu_button("Option 1.3"); - ui_menu_button("Option 1.4"); - } - - ui_menu("Menu 2") - { - ui_menu_button("Option 2.1"); - ui_menu_button("Option 2.2"); - ui_menu_button("Option 2.3"); - ui_menu_button("Option 2.4"); - } - - ui_menu("Menu 3") - { - ui_menu_button("Option 3.1"); - ui_menu_button("Option 3.2"); - ui_menu_button("Option 3.3"); - ui_menu_button("Option 3.4"); - } - } - - ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, - .size.height = {UI_SIZE_PARENT, 1, 1}}, - UI_STYLE_SIZE); - - ui_style_next(&(ui_style){.layout.axis = UI_AXIS_X}, UI_STYLE_LAYOUT_AXIS); - ui_container("contents", debugFlags) - { - ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 0.5}, - .size.height = {UI_SIZE_PARENT, 1}, - .borderColor = {0, 0, 1, 1}}, - UI_STYLE_SIZE - |UI_STYLE_BORDER_COLOR); - - ui_container("left", debugFlags) - { - ui_style_next(&(ui_style){.layout.axis = UI_AXIS_X, - .layout.spacing = 10, - .layout.margin.x = 10, - .layout.margin.y = 10, - .size.width = {UI_SIZE_PARENT, 1}, - .size.height = {UI_SIZE_PARENT, 0.5}}, - UI_STYLE_LAYOUT_AXIS - |UI_STYLE_LAYOUT_SPACING - |UI_STYLE_LAYOUT_MARGIN_X - |UI_STYLE_LAYOUT_MARGIN_Y - |UI_STYLE_SIZE); - - ui_container("up", debugFlags) - { - ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 0.5}, - .size.height = {UI_SIZE_PARENT, 1}}, - UI_STYLE_SIZE); - widget_view("Buttons") - { - if(ui_button("Test Dialog").clicked) - { - char* options[] = {"Accept", "Reject"}; - int res = mp_alert_popup("test dialog", "dialog message", 2, options); - if(res >= 0) - { - printf("selected options %i: %s\n", res, options[res]); - } - else - { - printf("no options selected\n"); - } - } - - if(ui_button("Open").clicked) - { - char* filters[] = {"md"}; - str8 file = mp_open_dialog(mem_scratch(), "Open File", "C:\\Users", 1, filters, false); - printf("selected file %.*s\n", (int)file.len, file.ptr); - } - - if(ui_button("Save").clicked) - { - str8 file = mp_save_dialog(mem_scratch(), "Save File", "C:\\Users", 0, 0); - printf("selected file %.*s\n", (int)file.len, file.ptr); - } - } - - ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 0.5}, - .size.height = {UI_SIZE_PARENT, 1}}, - UI_STYLE_SIZE); - - - ui_pattern pattern = {0}; - ui_pattern_push(mem_scratch(), &pattern, (ui_selector){.kind = UI_SEL_TAG, .tag = ui_tag_make("checkbox")}); - ui_style_match_after(pattern, - &(ui_style){.bgColor = {0, 1, 0, 1}, - .color = {1, 1, 1, 1}}, - UI_STYLE_COLOR | UI_STYLE_BG_COLOR); - - widget_view("checkboxes") - { - static bool check1 = true; - static bool check2 = false; - static bool check3 = false; - - ui_checkbox("check1", &check1); - ui_checkbox("check2", &check2); - ui_checkbox("check3", &check3); - } - } - - ui_style_next(&(ui_style){.layout.axis = UI_AXIS_X, - .size.width = {UI_SIZE_PARENT, 1}, - .size.height = {UI_SIZE_PARENT, 0.5}}, - UI_STYLE_LAYOUT_AXIS - |UI_STYLE_SIZE); - - ui_container("down", debugFlags) - { - widget_view("Vertical Sliders") - { - ui_style_next(&(ui_style){.layout.axis = UI_AXIS_X, - .layout.spacing = 10}, - UI_STYLE_LAYOUT_AXIS - |UI_STYLE_LAYOUT_SPACING); - ui_container("contents", 0) - { - ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 20}, - .size.height = {UI_SIZE_PIXELS, 200}}, - UI_STYLE_SIZE); - static f32 slider1 = 0; - ui_slider("slider1", 0.2, &slider1); - - ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 20}, - .size.height = {UI_SIZE_PIXELS, 200}}, - UI_STYLE_SIZE); - static f32 slider2 = 0; - ui_slider("slider2", 0.2, &slider2); - - ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 20}, - .size.height = {UI_SIZE_PIXELS, 200}}, - UI_STYLE_SIZE); - static f32 slider3 = 0; - ui_slider("slider3", 0.2, &slider3); - } - } - - widget_view("Horizontal Sliders") - { - ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 200}, - .size.height = {UI_SIZE_PIXELS, 20}}, - UI_STYLE_SIZE); - static f32 slider1 = 0; - ui_slider("slider1", 0.2, &slider1); - - ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 200}, - .size.height = {UI_SIZE_PIXELS, 20}}, - UI_STYLE_SIZE); - static f32 slider2 = 0; - ui_slider("slider2", 0.2, &slider2); - - ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 200}, - .size.height = {UI_SIZE_PIXELS, 20}}, - UI_STYLE_SIZE); - static f32 slider3 = 0; - ui_slider("slider3", 0.2, &slider3); - } - } - } - - ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 0.5}, - .size.height = {UI_SIZE_PARENT, 1}}, - UI_STYLE_SIZE); - - ui_container("right", debugFlags) - { - - ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, - .size.height = {UI_SIZE_PARENT, 0.33}}, - UI_STYLE_SIZE); - widget_view("Text box") - { - ui_style_next(&(ui_style){.size.width = {UI_SIZE_PIXELS, 300}, - .size.height = {UI_SIZE_TEXT}}, - UI_STYLE_SIZE); - static str8 text = {0}; - ui_text_box_result res = ui_text_box("textbox", mem_scratch(), text); - if(res.changed) - { - mem_arena_clear(&textArena); - text = str8_push_copy(&textArena, res.text); - } - } - - ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, - .size.height = {UI_SIZE_PARENT, 0.33}}, - UI_STYLE_SIZE); - widget_view("Test") - { - ui_pattern pattern = {0}; - ui_pattern_push(mem_scratch(), &pattern, (ui_selector){.kind = UI_SEL_TEXT, .text = STR8("panel")}); - ui_style_match_after(pattern, &(ui_style){.bgColor = {0.3, 0.3, 1, 1}}, UI_STYLE_BG_COLOR); - - static int selected = 0; - str8 options[] = {STR8("option 1"), - STR8("option 2"), - STR8("long option 3"), - STR8("option 4"), - STR8("option 5")}; - ui_select_popup_info info = {.selectedIndex = selected, - .optionCount = 5, - .options = options}; - - ui_select_popup_info result = ui_select_popup("popup", &info); - selected = result.selectedIndex; - } - - ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, - .size.height = {UI_SIZE_PARENT, 0.33}}, - UI_STYLE_SIZE); - widget_view("Color") - { - ui_style_next(&(ui_style){.size.width = {UI_SIZE_PARENT, 1}, - .size.height = {UI_SIZE_PARENT, 0.7}, - .layout.axis = UI_AXIS_X}, - UI_STYLE_SIZE - |UI_STYLE_LAYOUT_AXIS); - - ui_panel("Panel", UI_FLAG_DRAW_BORDER) - { - ui_style_next(&(ui_style){.layout.axis = UI_AXIS_X}, - UI_STYLE_LAYOUT_AXIS); - ui_container("contents", 0) - { - ui_style_next(&(ui_style){.layout.spacing = 20}, - UI_STYLE_LAYOUT_SPACING); - ui_container("buttons", 0) - { - ui_button("Button A"); - ui_button("Button B"); - ui_button("Button C"); - ui_button("Button D"); - } - - ui_style_next(&(ui_style){.layout.axis = UI_AXIS_X, - .layout.spacing = 20}, - UI_STYLE_LAYOUT_SPACING - |UI_STYLE_LAYOUT_AXIS); - - ui_container("buttons2", 0) - { - ui_button("Button A"); - ui_button("Button B"); - ui_button("Button C"); - ui_button("Button D"); - } - } - } - } - - } - } - } - } - if(printDebugStyle) - { - debug_print_styles(root, 0); - } - - mg_surface_prepare(surface); - - ui_draw(); - - mg_render(surface, canvas); - mg_surface_present(surface); - - mem_arena_clear(mem_scratch()); - } - - mg_surface_destroy(surface); - mp_terminate(); - - return(0); -} +*****************************************************************/ +#include +#include +#include +#include + +#define _USE_MATH_DEFINES //NOTE: necessary for MSVC +#include + +#include "milepost.h" + +void debug_print_indent(int indent) +{ + for(int i = 0; i < indent; i++) + { + printf(" "); + } +} + +void debug_print_rule(ui_style_rule* rule) +{ + for_list(&rule->pattern.l, selector, ui_selector, listElt) + { + switch(selector->kind) + { + case UI_SEL_ANY: + printf("any: "); + break; + + case UI_SEL_OWNER: + printf("owner: "); + break; + + case UI_SEL_TEXT: + printf("text='%.*s': ", (int)selector->text.len, selector->text.ptr); + break; + + case UI_SEL_TAG: + printf("tag=0x%llx: ", selector->tag.hash); + break; + + case UI_SEL_STATUS: + { + if(selector->status & UI_HOVER) + { + printf("hover: "); + } + if(selector->status & UI_ACTIVE) + { + printf("active: "); + } + if(selector->status & UI_DRAGGING) + { + printf("dragging: "); + } + } + break; + + case UI_SEL_KEY: + printf("key=0x%llx: ", selector->key.hash); + break; + + default: + printf("unknown: "); + break; + } + } + printf("=> font size = %f\n", rule->style->fontSize); +} + +void debug_print_size(ui_box* box, ui_axis axis, int indent) +{ + debug_print_indent(indent); + printf("size %s: ", axis == UI_AXIS_X ? "x" : "y"); + f32 value = box->targetStyle->size.c[axis].value; + switch(box->targetStyle->size.c[axis].kind) + { + case UI_SIZE_TEXT: + printf("text\n"); + break; + + case UI_SIZE_CHILDREN: + printf("children\n"); + break; + + case UI_SIZE_PARENT: + printf("parent: %f\n", value); + break; + + case UI_SIZE_PARENT_MINUS_PIXELS: + printf("parent minus pixels: %f\n", value); + break; + + case UI_SIZE_PIXELS: + printf("pixels: %f\n", value); + break; + } +} + +void debug_print_styles(ui_box* box, int indent) +{ + debug_print_indent(indent); + printf("### box '%.*s'\n", (int)box->string.len, box->string.ptr); + indent++; + + debug_print_indent(indent); + printf("font size: %f\n", box->targetStyle->fontSize); + + debug_print_size(box, UI_AXIS_X, indent); + debug_print_size(box, UI_AXIS_Y, indent); + + if(!list_empty(&box->beforeRules)) + { + debug_print_indent(indent); + printf("before rules:\n"); + for_list(&box->beforeRules, rule, ui_style_rule, boxElt) + { + debug_print_indent(indent + 1); + debug_print_rule(rule); + } + } + + if(!list_empty(&box->afterRules)) + { + debug_print_indent(indent); + printf("after rules:\n"); + for_list(&box->afterRules, rule, ui_style_rule, boxElt) + { + debug_print_indent(indent + 1); + debug_print_rule(rule); + } + } + + if(!list_empty(&box->children)) + { + debug_print_indent(indent); + printf("children:\n"); + indent++; + for_list(&box->children, child, ui_box, listElt) + { + debug_print_styles(child, indent); + } + } +} + +mg_font create_font() +{ + //NOTE(martin): create font + str8 fontPath = path_executable_relative(mem_scratch(), STR8("../resources/OpenSansLatinSubset.ttf")); + char* fontPathCString = str8_to_cstring(mem_scratch(), fontPath); + + FILE* fontFile = fopen(fontPathCString, "r"); + if(!fontFile) + { + log_error("Could not load font file '%s': %s\n", fontPathCString, strerror(errno)); + return (mg_font_nil()); + } + unsigned char* fontData = 0; + fseek(fontFile, 0, SEEK_END); + u32 fontDataSize = ftell(fontFile); + rewind(fontFile); + fontData = (unsigned char*)malloc(fontDataSize); + fread(fontData, 1, fontDataSize, fontFile); + fclose(fontFile); + + unicode_range ranges[5] = { UNICODE_RANGE_BASIC_LATIN, + UNICODE_RANGE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT, + UNICODE_RANGE_LATIN_EXTENDED_A, + UNICODE_RANGE_LATIN_EXTENDED_B, + UNICODE_RANGE_SPECIALS }; + + mg_font font = mg_font_create_from_memory(fontDataSize, fontData, 5, ranges); + free(fontData); + + return (font); +} + +void widget_begin_view(char* str) +{ + ui_style_next(&(ui_style){ .layout.axis = UI_AXIS_Y, + .layout.spacing = 10, + .layout.margin.x = 10, + .layout.margin.y = 10, + .layout.align.x = UI_ALIGN_CENTER, + .layout.align.y = UI_ALIGN_START }, + UI_STYLE_LAYOUT); + + ui_box_begin(str, UI_FLAG_DRAW_BORDER); + ui_label(str); +} + +void widget_end_view(void) +{ + ui_box_end(); +} + +#define widget_view(s) defer_loop(widget_begin_view(s), widget_end_view()) + +int main() +{ + mp_init(); + mp_clock_init(); //TODO put that in mp_init()? + + ui_context context; + ui_init(&context); + ui_set_context(&context); + + mp_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 }; + mp_window window = mp_window_create(windowRect, "test", 0); + + mp_rect contentRect = mp_window_get_content_rect(window); + + //NOTE: create surface + mg_surface surface = mg_surface_create_for_window(window, MG_CANVAS); + mg_surface_swap_interval(surface, 0); + + //TODO: create canvas + mg_canvas canvas = mg_canvas_create(); + + if(mg_canvas_is_nil(canvas)) + { + printf("Error: couldn't create canvas\n"); + return (-1); + } + + mg_font font = create_font(); + + mem_arena textArena = { 0 }; + mem_arena_init(&textArena); + + // start app + mp_window_bring_to_front(window); + mp_window_focus(window); + + while(!mp_should_quit()) + { + bool printDebugStyle = false; + + f64 startTime = mp_get_time(MP_CLOCK_MONOTONIC); + + mp_pump_events(0); + mp_event* event = 0; + while((event = mp_next_event(mem_scratch())) != 0) + { + ui_process_event(event); + + switch(event->type) + { + case MP_EVENT_WINDOW_CLOSE: + { + mp_request_quit(); + } + break; + + case MP_EVENT_KEYBOARD_KEY: + { + if(event->key.action == MP_KEY_PRESS && event->key.code == MP_KEY_P) + { + printDebugStyle = true; + } + } + break; + + default: + break; + } + } + + //TEST UI + ui_style defaultStyle = { .bgColor = { 0 }, + .color = { 1, 1, 1, 1 }, + .font = font, + .fontSize = 16, + .borderColor = { 1, 0, 0, 1 }, + .borderSize = 2 }; + + ui_style_mask defaultMask = UI_STYLE_BG_COLOR + | UI_STYLE_COLOR + | UI_STYLE_BORDER_COLOR + | UI_STYLE_BORDER_SIZE + | UI_STYLE_FONT + | UI_STYLE_FONT_SIZE; + + ui_flags debugFlags = UI_FLAG_DRAW_BORDER; + + ui_box* root = 0; + + mp_rect frameRect = mg_surface_get_frame(surface); + vec2 frameSize = { frameRect.w, frameRect.h }; + + ui_frame(frameSize, &defaultStyle, defaultMask) + { + root = ui_box_top(); + ui_style_match_before(ui_pattern_all(), &defaultStyle, defaultMask); + + ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 1 }, + .size.height = { UI_SIZE_PARENT, 1 }, + .layout.axis = UI_AXIS_Y, + .layout.align.x = UI_ALIGN_CENTER, + .layout.align.y = UI_ALIGN_START, + .layout.spacing = 10, + .layout.margin.x = 10, + .layout.margin.y = 10, + .bgColor = { 0.11, 0.11, 0.11, 1 } }, + UI_STYLE_SIZE + | UI_STYLE_LAYOUT + | UI_STYLE_BG_COLOR); + + ui_container("background", UI_FLAG_DRAW_BACKGROUND) + { + ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 1 }, + .size.height = { UI_SIZE_CHILDREN }, + .layout.align.x = UI_ALIGN_CENTER }, + UI_STYLE_SIZE + | UI_STYLE_LAYOUT_ALIGN_X); + ui_container("title", debugFlags) + { + ui_style_next(&(ui_style){ .fontSize = 26 }, UI_STYLE_FONT_SIZE); + ui_label("Milepost UI Demo"); + + if(ui_box_sig(ui_box_top()).hovering) + { + ui_tooltip("tooltip") + { + ui_style_next(&(ui_style){ .bgColor = { 1, 0.99, 0.82, 1 } }, + UI_STYLE_BG_COLOR); + + ui_container("background", UI_FLAG_DRAW_BACKGROUND) + { + ui_style_next(&(ui_style){ .color = { 0, 0, 0, 1 } }, + UI_STYLE_COLOR); + + ui_label("That is a tooltip!"); + } + } + } + } + + ui_menu_bar("Menu bar") + { + ui_menu("Menu 1") + { + if(ui_menu_button("Option 1.1").pressed) + { + printf("Pressed option 1.1\n"); + } + ui_menu_button("Option 1.2"); + ui_menu_button("Option 1.3"); + ui_menu_button("Option 1.4"); + } + + ui_menu("Menu 2") + { + ui_menu_button("Option 2.1"); + ui_menu_button("Option 2.2"); + ui_menu_button("Option 2.3"); + ui_menu_button("Option 2.4"); + } + + ui_menu("Menu 3") + { + ui_menu_button("Option 3.1"); + ui_menu_button("Option 3.2"); + ui_menu_button("Option 3.3"); + ui_menu_button("Option 3.4"); + } + } + + ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 1 }, + .size.height = { UI_SIZE_PARENT, 1, 1 } }, + UI_STYLE_SIZE); + + ui_style_next(&(ui_style){ .layout.axis = UI_AXIS_X }, UI_STYLE_LAYOUT_AXIS); + ui_container("contents", debugFlags) + { + ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 0.5 }, + .size.height = { UI_SIZE_PARENT, 1 }, + .borderColor = { 0, 0, 1, 1 } }, + UI_STYLE_SIZE + | UI_STYLE_BORDER_COLOR); + + ui_container("left", debugFlags) + { + ui_style_next(&(ui_style){ .layout.axis = UI_AXIS_X, + .layout.spacing = 10, + .layout.margin.x = 10, + .layout.margin.y = 10, + .size.width = { UI_SIZE_PARENT, 1 }, + .size.height = { UI_SIZE_PARENT, 0.5 } }, + UI_STYLE_LAYOUT_AXIS + | UI_STYLE_LAYOUT_SPACING + | UI_STYLE_LAYOUT_MARGIN_X + | UI_STYLE_LAYOUT_MARGIN_Y + | UI_STYLE_SIZE); + + ui_container("up", debugFlags) + { + ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 0.5 }, + .size.height = { UI_SIZE_PARENT, 1 } }, + UI_STYLE_SIZE); + widget_view("Buttons") + { + if(ui_button("Test Dialog").clicked) + { + char* options[] = { "Accept", "Reject" }; + int res = mp_alert_popup("test dialog", "dialog message", 2, options); + if(res >= 0) + { + printf("selected options %i: %s\n", res, options[res]); + } + else + { + printf("no options selected\n"); + } + } + + if(ui_button("Open").clicked) + { + char* filters[] = { "md" }; + str8 file = mp_open_dialog(mem_scratch(), "Open File", "C:\\Users", 1, filters, false); + printf("selected file %.*s\n", (int)file.len, file.ptr); + } + + if(ui_button("Save").clicked) + { + str8 file = mp_save_dialog(mem_scratch(), "Save File", "C:\\Users", 0, 0); + printf("selected file %.*s\n", (int)file.len, file.ptr); + } + } + + ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 0.5 }, + .size.height = { UI_SIZE_PARENT, 1 } }, + UI_STYLE_SIZE); + + ui_pattern pattern = { 0 }; + ui_pattern_push(mem_scratch(), &pattern, (ui_selector){ .kind = UI_SEL_TAG, .tag = ui_tag_make("checkbox") }); + ui_style_match_after(pattern, + &(ui_style){ .bgColor = { 0, 1, 0, 1 }, + .color = { 1, 1, 1, 1 } }, + UI_STYLE_COLOR | UI_STYLE_BG_COLOR); + + widget_view("checkboxes") + { + static bool check1 = true; + static bool check2 = false; + static bool check3 = false; + + ui_checkbox("check1", &check1); + ui_checkbox("check2", &check2); + ui_checkbox("check3", &check3); + } + } + + ui_style_next(&(ui_style){ .layout.axis = UI_AXIS_X, + .size.width = { UI_SIZE_PARENT, 1 }, + .size.height = { UI_SIZE_PARENT, 0.5 } }, + UI_STYLE_LAYOUT_AXIS + | UI_STYLE_SIZE); + + ui_container("down", debugFlags) + { + widget_view("Vertical Sliders") + { + ui_style_next(&(ui_style){ .layout.axis = UI_AXIS_X, + .layout.spacing = 10 }, + UI_STYLE_LAYOUT_AXIS + | UI_STYLE_LAYOUT_SPACING); + ui_container("contents", 0) + { + ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PIXELS, 20 }, + .size.height = { UI_SIZE_PIXELS, 200 } }, + UI_STYLE_SIZE); + static f32 slider1 = 0; + ui_slider("slider1", 0.2, &slider1); + + ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PIXELS, 20 }, + .size.height = { UI_SIZE_PIXELS, 200 } }, + UI_STYLE_SIZE); + static f32 slider2 = 0; + ui_slider("slider2", 0.2, &slider2); + + ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PIXELS, 20 }, + .size.height = { UI_SIZE_PIXELS, 200 } }, + UI_STYLE_SIZE); + static f32 slider3 = 0; + ui_slider("slider3", 0.2, &slider3); + } + } + + widget_view("Horizontal Sliders") + { + ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PIXELS, 200 }, + .size.height = { UI_SIZE_PIXELS, 20 } }, + UI_STYLE_SIZE); + static f32 slider1 = 0; + ui_slider("slider1", 0.2, &slider1); + + ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PIXELS, 200 }, + .size.height = { UI_SIZE_PIXELS, 20 } }, + UI_STYLE_SIZE); + static f32 slider2 = 0; + ui_slider("slider2", 0.2, &slider2); + + ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PIXELS, 200 }, + .size.height = { UI_SIZE_PIXELS, 20 } }, + UI_STYLE_SIZE); + static f32 slider3 = 0; + ui_slider("slider3", 0.2, &slider3); + } + } + } + + ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 0.5 }, + .size.height = { UI_SIZE_PARENT, 1 } }, + UI_STYLE_SIZE); + + ui_container("right", debugFlags) + { + + ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 1 }, + .size.height = { UI_SIZE_PARENT, 0.33 } }, + UI_STYLE_SIZE); + widget_view("Text box") + { + ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PIXELS, 300 }, + .size.height = { UI_SIZE_TEXT } }, + UI_STYLE_SIZE); + static str8 text = { 0 }; + ui_text_box_result res = ui_text_box("textbox", mem_scratch(), text); + if(res.changed) + { + mem_arena_clear(&textArena); + text = str8_push_copy(&textArena, res.text); + } + } + + ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 1 }, + .size.height = { UI_SIZE_PARENT, 0.33 } }, + UI_STYLE_SIZE); + widget_view("Test") + { + ui_pattern pattern = { 0 }; + ui_pattern_push(mem_scratch(), &pattern, (ui_selector){ .kind = UI_SEL_TEXT, .text = STR8("panel") }); + ui_style_match_after(pattern, &(ui_style){ .bgColor = { 0.3, 0.3, 1, 1 } }, UI_STYLE_BG_COLOR); + + static int selected = 0; + str8 options[] = { STR8("option 1"), + STR8("option 2"), + STR8("long option 3"), + STR8("option 4"), + STR8("option 5") }; + ui_select_popup_info info = { .selectedIndex = selected, + .optionCount = 5, + .options = options }; + + ui_select_popup_info result = ui_select_popup("popup", &info); + selected = result.selectedIndex; + } + + ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 1 }, + .size.height = { UI_SIZE_PARENT, 0.33 } }, + UI_STYLE_SIZE); + widget_view("Color") + { + ui_style_next(&(ui_style){ .size.width = { UI_SIZE_PARENT, 1 }, + .size.height = { UI_SIZE_PARENT, 0.7 }, + .layout.axis = UI_AXIS_X }, + UI_STYLE_SIZE + | UI_STYLE_LAYOUT_AXIS); + + ui_panel("Panel", UI_FLAG_DRAW_BORDER) + { + ui_style_next(&(ui_style){ .layout.axis = UI_AXIS_X }, + UI_STYLE_LAYOUT_AXIS); + ui_container("contents", 0) + { + ui_style_next(&(ui_style){ .layout.spacing = 20 }, + UI_STYLE_LAYOUT_SPACING); + ui_container("buttons", 0) + { + ui_button("Button A"); + ui_button("Button B"); + ui_button("Button C"); + ui_button("Button D"); + } + + ui_style_next(&(ui_style){ .layout.axis = UI_AXIS_X, + .layout.spacing = 20 }, + UI_STYLE_LAYOUT_SPACING + | UI_STYLE_LAYOUT_AXIS); + + ui_container("buttons2", 0) + { + ui_button("Button A"); + ui_button("Button B"); + ui_button("Button C"); + ui_button("Button D"); + } + } + } + } + } + } + } + } + if(printDebugStyle) + { + debug_print_styles(root, 0); + } + + mg_surface_prepare(surface); + + ui_draw(); + + mg_render(surface, canvas); + mg_surface_present(surface); + + mem_arena_clear(mem_scratch()); + } + + mg_surface_destroy(surface); + mp_terminate(); + + return (0); +} diff --git a/src/app/app.c b/src/app/app.c index 76910d0..57c7776 100644 --- a/src/app/app.c +++ b/src/app/app.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: app.c * @author: Martin Fouilleul @@ -6,10 +6,10 @@ * @revision: * *****************************************************************/ -#include"platform/platform_debug.h" -#include"app_internal.h" +#include "app_internal.h" +#include "platform/platform_debug.h" -oc_app oc_appData = {0}; +oc_app oc_appData = { 0 }; //--------------------------------------------------------------- // Window handles @@ -17,63 +17,63 @@ oc_app oc_appData = {0}; void oc_init_window_handles() { - oc_list_init(&oc_appData.windowFreeList); - for(int i=0; i>32; - u32 generation = handle.h & 0xffffffff; - if(index >= OC_APP_MAX_WINDOWS) - { - return(0); - } - oc_window_data* window = &oc_appData.windowPool[index]; - if(window->generation != generation) - { - return(0); - } - else - { - return(window); - } + u32 index = handle.h >> 32; + u32 generation = handle.h & 0xffffffff; + if(index >= OC_APP_MAX_WINDOWS) + { + return (0); + } + oc_window_data* window = &oc_appData.windowPool[index]; + if(window->generation != generation) + { + return (0); + } + else + { + return (window); + } } oc_window oc_window_handle_from_ptr(oc_window_data* window) { - OC_DEBUG_ASSERT( (window - oc_appData.windowPool) >= 0 - && (window - oc_appData.windowPool) < OC_APP_MAX_WINDOWS); + OC_DEBUG_ASSERT((window - oc_appData.windowPool) >= 0 + && (window - oc_appData.windowPool) < OC_APP_MAX_WINDOWS); - u64 h = ((u64)(window - oc_appData.windowPool))<<32 - | ((u64)window->generation); + u64 h = ((u64)(window - oc_appData.windowPool)) << 32 + | ((u64)window->generation); - return((oc_window){h}); + return ((oc_window){ h }); } void oc_window_recycle_ptr(oc_window_data* window) { - window->generation++; - oc_list_push(&oc_appData.windowFreeList, &window->freeListElt); + window->generation++; + oc_list_push(&oc_appData.windowFreeList, &window->freeListElt); } //--------------------------------------------------------------- @@ -82,13 +82,13 @@ void oc_window_recycle_ptr(oc_window_data* window) static void oc_init_common() { - oc_init_window_handles(); - oc_ringbuffer_init(&oc_appData.eventQueue, 16); + oc_init_window_handles(); + oc_ringbuffer_init(&oc_appData.eventQueue, 16); } static void oc_terminate_common() { - oc_ringbuffer_cleanup(&oc_appData.eventQueue); + oc_ringbuffer_cleanup(&oc_appData.eventQueue); } //--------------------------------------------------------------- @@ -97,87 +97,87 @@ static void oc_terminate_common() void oc_queue_event(oc_event* event) { - oc_ringbuffer* queue = &oc_appData.eventQueue; + oc_ringbuffer* queue = &oc_appData.eventQueue; - if(oc_ringbuffer_write_available(queue) < sizeof(oc_event)) - { - oc_log_error("event queue full\n"); - } - else - { - bool error = false; - oc_ringbuffer_reserve(queue, sizeof(oc_event), (u8*)event); + if(oc_ringbuffer_write_available(queue) < sizeof(oc_event)) + { + oc_log_error("event queue full\n"); + } + else + { + bool error = false; + oc_ringbuffer_reserve(queue, sizeof(oc_event), (u8*)event); - if(event->type == OC_EVENT_PATHDROP) - { - oc_list_for(&event->paths.list, elt, oc_str8_elt, listElt) - { - oc_str8* path = &elt->string; - if(oc_ringbuffer_write_available(queue) < (sizeof(u64) + path->len)) - { - oc_log_error("event queue full\n"); - error = true; - break; - } - else - { - oc_ringbuffer_reserve(queue, sizeof(u64), (u8*)&path->len); - oc_ringbuffer_reserve(queue, path->len, (u8*)path->ptr); - } - } - } - if(error) - { - oc_ringbuffer_rewind(queue); - } - else - { - oc_ringbuffer_commit(queue); - } - } + if(event->type == OC_EVENT_PATHDROP) + { + oc_list_for(&event->paths.list, elt, oc_str8_elt, listElt) + { + oc_str8* path = &elt->string; + if(oc_ringbuffer_write_available(queue) < (sizeof(u64) + path->len)) + { + oc_log_error("event queue full\n"); + error = true; + break; + } + else + { + oc_ringbuffer_reserve(queue, sizeof(u64), (u8*)&path->len); + oc_ringbuffer_reserve(queue, path->len, (u8*)path->ptr); + } + } + } + if(error) + { + oc_ringbuffer_rewind(queue); + } + else + { + oc_ringbuffer_commit(queue); + } + } } oc_event* oc_next_event(oc_arena* arena) { - //NOTE: pop and return event from queue - oc_event* event = 0; - oc_ringbuffer* queue = &oc_appData.eventQueue; + //NOTE: pop and return event from queue + oc_event* event = 0; + oc_ringbuffer* queue = &oc_appData.eventQueue; - if(oc_ringbuffer_read_available(queue) >= sizeof(oc_event)) - { - event = oc_arena_push_type(arena, oc_event); - u64 read = oc_ringbuffer_read(queue, sizeof(oc_event), (u8*)event); - OC_DEBUG_ASSERT(read == sizeof(oc_event)); + if(oc_ringbuffer_read_available(queue) >= sizeof(oc_event)) + { + event = oc_arena_push_type(arena, oc_event); + u64 read = oc_ringbuffer_read(queue, sizeof(oc_event), (u8*)event); + OC_DEBUG_ASSERT(read == sizeof(oc_event)); - if(event->type == OC_EVENT_PATHDROP) - { - u64 pathCount = event->paths.eltCount; - event->paths = (oc_str8_list){0}; + if(event->type == OC_EVENT_PATHDROP) + { + u64 pathCount = event->paths.eltCount; + event->paths = (oc_str8_list){ 0 }; - for(int i=0; ipaths, oc_str8_from_buffer(len, buffer)); - } - } - } - return(event); + oc_str8_list_push(arena, &event->paths, oc_str8_from_buffer(len, buffer)); + } + } + } + return (event); } //--------------------------------------------------------------- @@ -186,32 +186,32 @@ oc_event* oc_next_event(oc_arena* arena) void oc_window_set_content_position(oc_window window, oc_vec2 position) { - oc_rect rect = oc_window_get_content_rect(window); - rect.x = position.x; - rect.y = position.y; - oc_window_set_content_rect(window, rect); + oc_rect rect = oc_window_get_content_rect(window); + rect.x = position.x; + rect.y = position.y; + oc_window_set_content_rect(window, rect); } void oc_window_set_content_size(oc_window window, oc_vec2 size) { - oc_rect rect = oc_window_get_content_rect(window); - rect.w = size.x; - rect.h = size.y; - oc_window_set_content_rect(window, rect); + oc_rect rect = oc_window_get_content_rect(window); + rect.w = size.x; + rect.h = size.y; + oc_window_set_content_rect(window, rect); } void oc_window_set_frame_position(oc_window window, oc_vec2 position) { - oc_rect frame = oc_window_get_frame_rect(window); - frame.x = position.x; - frame.y = position.y; - oc_window_set_frame_rect(window, frame); + oc_rect frame = oc_window_get_frame_rect(window); + frame.x = position.x; + frame.y = position.y; + oc_window_set_frame_rect(window, frame); } void oc_window_set_frame_size(oc_window window, oc_vec2 size) { - oc_rect frame = oc_window_get_frame_rect(window); - frame.w = size.x; - frame.h = size.y; - oc_window_set_frame_rect(window, frame); + oc_rect frame = oc_window_get_frame_rect(window); + frame.w = size.x; + frame.h = size.y; + oc_window_set_frame_rect(window, frame); } diff --git a/src/app/app.h b/src/app/app.h index 92d5ed2..297165a 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: platform_app.h * @author: Martin Fouilleul @@ -9,378 +9,396 @@ #ifndef __APP_H_ #define __APP_H_ -#include"util/typedefs.h" -#include"util/utf8.h" -#include"util/lists.h" -#include"util/memory.h" +#include "util/lists.h" +#include "util/memory.h" +#include "util/typedefs.h" +#include "util/utf8.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -//-------------------------------------------------------------------- -// Typedefs, enums and constants -//-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // Typedefs, enums and constants + //-------------------------------------------------------------------- -typedef struct oc_window { u64 h; } oc_window; + typedef struct oc_window + { + u64 h; + } oc_window; -typedef enum { OC_MOUSE_CURSOR_ARROW, - OC_MOUSE_CURSOR_RESIZE_0, - OC_MOUSE_CURSOR_RESIZE_90, - OC_MOUSE_CURSOR_RESIZE_45, - OC_MOUSE_CURSOR_RESIZE_135, - OC_MOUSE_CURSOR_TEXT } oc_mouse_cursor; + typedef enum + { + OC_MOUSE_CURSOR_ARROW, + OC_MOUSE_CURSOR_RESIZE_0, + OC_MOUSE_CURSOR_RESIZE_90, + OC_MOUSE_CURSOR_RESIZE_45, + OC_MOUSE_CURSOR_RESIZE_135, + OC_MOUSE_CURSOR_TEXT + } oc_mouse_cursor; -typedef i32 oc_window_style; -static const oc_window_style OC_WINDOW_STYLE_NO_TITLE = 0x01<<0, - OC_WINDOW_STYLE_FIXED_SIZE = 0x01<<1, - OC_WINDOW_STYLE_NO_CLOSE = 0x01<<2, - OC_WINDOW_STYLE_NO_MINIFY = 0x01<<3, - OC_WINDOW_STYLE_NO_FOCUS = 0x01<<4, - OC_WINDOW_STYLE_FLOAT = 0x01<<5, - OC_WINDOW_STYLE_POPUPMENU = 0x01<<6, - OC_WINDOW_STYLE_NO_BUTTONS = 0x01<<7; + typedef i32 oc_window_style; + static const oc_window_style OC_WINDOW_STYLE_NO_TITLE = 0x01 << 0, + OC_WINDOW_STYLE_FIXED_SIZE = 0x01 << 1, + OC_WINDOW_STYLE_NO_CLOSE = 0x01 << 2, + OC_WINDOW_STYLE_NO_MINIFY = 0x01 << 3, + OC_WINDOW_STYLE_NO_FOCUS = 0x01 << 4, + OC_WINDOW_STYLE_FLOAT = 0x01 << 5, + OC_WINDOW_STYLE_POPUPMENU = 0x01 << 6, + OC_WINDOW_STYLE_NO_BUTTONS = 0x01 << 7; -typedef enum { OC_EVENT_NONE, - OC_EVENT_KEYBOARD_MODS, //TODO: remove, keep only key? - OC_EVENT_KEYBOARD_KEY, - OC_EVENT_KEYBOARD_CHAR, - OC_EVENT_MOUSE_BUTTON, - OC_EVENT_MOUSE_MOVE, - OC_EVENT_MOUSE_WHEEL, - OC_EVENT_MOUSE_ENTER, - OC_EVENT_MOUSE_LEAVE, - OC_EVENT_WINDOW_RESIZE, - OC_EVENT_WINDOW_MOVE, - OC_EVENT_WINDOW_FOCUS, - OC_EVENT_WINDOW_UNFOCUS, - OC_EVENT_WINDOW_HIDE, // rename to minimize? - OC_EVENT_WINDOW_SHOW, // rename to restore? - OC_EVENT_WINDOW_CLOSE, - OC_EVENT_PATHDROP, - OC_EVENT_FRAME, - OC_EVENT_QUIT } oc_event_type; + typedef enum + { + OC_EVENT_NONE, + OC_EVENT_KEYBOARD_MODS, //TODO: remove, keep only key? + OC_EVENT_KEYBOARD_KEY, + OC_EVENT_KEYBOARD_CHAR, + OC_EVENT_MOUSE_BUTTON, + OC_EVENT_MOUSE_MOVE, + OC_EVENT_MOUSE_WHEEL, + OC_EVENT_MOUSE_ENTER, + OC_EVENT_MOUSE_LEAVE, + OC_EVENT_WINDOW_RESIZE, + OC_EVENT_WINDOW_MOVE, + OC_EVENT_WINDOW_FOCUS, + OC_EVENT_WINDOW_UNFOCUS, + OC_EVENT_WINDOW_HIDE, // rename to minimize? + OC_EVENT_WINDOW_SHOW, // rename to restore? + OC_EVENT_WINDOW_CLOSE, + OC_EVENT_PATHDROP, + OC_EVENT_FRAME, + OC_EVENT_QUIT + } oc_event_type; -typedef enum { OC_KEY_NO_ACTION, - OC_KEY_PRESS, - OC_KEY_RELEASE, - OC_KEY_REPEAT } oc_key_action; + typedef enum + { + OC_KEY_NO_ACTION, + OC_KEY_PRESS, + OC_KEY_RELEASE, + OC_KEY_REPEAT + } oc_key_action; -typedef enum { OC_KEY_UNKNOWN = 0, - OC_KEY_SPACE = 32, - OC_KEY_APOSTROPHE = 39, /* ' */ - OC_KEY_COMMA = 44, /* , */ - OC_KEY_MINUS = 45, // - - OC_KEY_PERIOD = 46, // . - OC_KEY_SLASH = 47, // / - OC_KEY_0 = 48, - OC_KEY_1 = 49, - OC_KEY_2 = 50, - OC_KEY_3 = 51, - OC_KEY_4 = 52, - OC_KEY_5 = 53, - OC_KEY_6 = 54, - OC_KEY_7 = 55, - OC_KEY_8 = 56, - OC_KEY_9 = 57, - OC_KEY_SEMICOLON = 59, // ; - OC_KEY_EQUAL = 61, // = - OC_KEY_A = 65, - OC_KEY_B = 66, - OC_KEY_C = 67, - OC_KEY_D = 68, - OC_KEY_E = 69, - OC_KEY_F = 70, - OC_KEY_G = 71, - OC_KEY_H = 72, - OC_KEY_I = 73, - OC_KEY_J = 74, - OC_KEY_K = 75, - OC_KEY_L = 76, - OC_KEY_M = 77, - OC_KEY_N = 78, - OC_KEY_O = 79, - OC_KEY_P = 80, - OC_KEY_Q = 81, - OC_KEY_R = 82, - OC_KEY_S = 83, - OC_KEY_T = 84, - OC_KEY_U = 85, - OC_KEY_V = 86, - OC_KEY_W = 87, - OC_KEY_X = 88, - OC_KEY_Y = 89, - OC_KEY_Z = 90, - OC_KEY_LEFT_BRACKET = 91, // [ - OC_KEY_BACKSLASH = 92, // \ */ - OC_KEY_RIGHT_BRACKET = 93, // ] - OC_KEY_GRAVE_ACCENT = 96, // ` - OC_KEY_WORLD_1 = 161, // non-US #1 - OC_KEY_WORLD_2 = 162, // non-US #2 - OC_KEY_ESCAPE = 256, - OC_KEY_ENTER = 257, - OC_KEY_TAB = 258, - OC_KEY_BACKSPACE = 259, - OC_KEY_INSERT = 260, - OC_KEY_DELETE = 261, - OC_KEY_RIGHT = 262, - OC_KEY_LEFT = 263, - OC_KEY_DOWN = 264, - OC_KEY_UP = 265, - OC_KEY_PAGE_UP = 266, - OC_KEY_PAGE_DOWN = 267, - OC_KEY_HOME = 268, - OC_KEY_END = 269, - OC_KEY_CAPS_LOCK = 280, - OC_KEY_SCROLL_LOCK = 281, - OC_KEY_NUM_LOCK = 282, - OC_KEY_PRINT_SCREEN = 283, - OC_KEY_PAUSE = 284, - OC_KEY_F1 = 290, - OC_KEY_F2 = 291, - OC_KEY_F3 = 292, - OC_KEY_F4 = 293, - OC_KEY_F5 = 294, - OC_KEY_F6 = 295, - OC_KEY_F7 = 296, - OC_KEY_F8 = 297, - OC_KEY_F9 = 298, - OC_KEY_F10 = 299, - OC_KEY_F11 = 300, - OC_KEY_F12 = 301, - OC_KEY_F13 = 302, - OC_KEY_F14 = 303, - OC_KEY_F15 = 304, - OC_KEY_F16 = 305, - OC_KEY_F17 = 306, - OC_KEY_F18 = 307, - OC_KEY_F19 = 308, - OC_KEY_F20 = 309, - OC_KEY_F21 = 310, - OC_KEY_F22 = 311, - OC_KEY_F23 = 312, - OC_KEY_F24 = 313, - OC_KEY_F25 = 314, - OC_KEY_KP_0 = 320, - OC_KEY_KP_1 = 321, - OC_KEY_KP_2 = 322, - OC_KEY_KP_3 = 323, - OC_KEY_KP_4 = 324, - OC_KEY_KP_5 = 325, - OC_KEY_KP_6 = 326, - OC_KEY_KP_7 = 327, - OC_KEY_KP_8 = 328, - OC_KEY_KP_9 = 329, - OC_KEY_KP_DECIMAL = 330, - OC_KEY_KP_DIVIDE = 331, - OC_KEY_KP_MULTIPLY = 332, - OC_KEY_KP_SUBTRACT = 333, - OC_KEY_KP_ADD = 334, - OC_KEY_KP_ENTER = 335, - OC_KEY_KP_EQUAL = 336, - OC_KEY_LEFT_SHIFT = 340, - OC_KEY_LEFT_CONTROL = 341, - OC_KEY_LEFT_ALT = 342, - OC_KEY_LEFT_SUPER = 343, - OC_KEY_RIGHT_SHIFT = 344, - OC_KEY_RIGHT_CONTROL = 345, - OC_KEY_RIGHT_ALT = 346, - OC_KEY_RIGHT_SUPER = 347, - OC_KEY_MENU = 348, - OC_KEY_COUNT } oc_key_code; + typedef enum + { + OC_KEY_UNKNOWN = 0, + OC_KEY_SPACE = 32, + OC_KEY_APOSTROPHE = 39, /* ' */ + OC_KEY_COMMA = 44, /* , */ + OC_KEY_MINUS = 45, // - + OC_KEY_PERIOD = 46, // . + OC_KEY_SLASH = 47, // / + OC_KEY_0 = 48, + OC_KEY_1 = 49, + OC_KEY_2 = 50, + OC_KEY_3 = 51, + OC_KEY_4 = 52, + OC_KEY_5 = 53, + OC_KEY_6 = 54, + OC_KEY_7 = 55, + OC_KEY_8 = 56, + OC_KEY_9 = 57, + OC_KEY_SEMICOLON = 59, // ; + OC_KEY_EQUAL = 61, // = + OC_KEY_A = 65, + OC_KEY_B = 66, + OC_KEY_C = 67, + OC_KEY_D = 68, + OC_KEY_E = 69, + OC_KEY_F = 70, + OC_KEY_G = 71, + OC_KEY_H = 72, + OC_KEY_I = 73, + OC_KEY_J = 74, + OC_KEY_K = 75, + OC_KEY_L = 76, + OC_KEY_M = 77, + OC_KEY_N = 78, + OC_KEY_O = 79, + OC_KEY_P = 80, + OC_KEY_Q = 81, + OC_KEY_R = 82, + OC_KEY_S = 83, + OC_KEY_T = 84, + OC_KEY_U = 85, + OC_KEY_V = 86, + OC_KEY_W = 87, + OC_KEY_X = 88, + OC_KEY_Y = 89, + OC_KEY_Z = 90, + OC_KEY_LEFT_BRACKET = 91, // [ + OC_KEY_BACKSLASH = 92, // \ */ + OC_KEY_RIGHT_BRACKET = 93, // ] + OC_KEY_GRAVE_ACCENT = 96, // ` + OC_KEY_WORLD_1 = 161, // non-US #1 + OC_KEY_WORLD_2 = 162, // non-US #2 + OC_KEY_ESCAPE = 256, + OC_KEY_ENTER = 257, + OC_KEY_TAB = 258, + OC_KEY_BACKSPACE = 259, + OC_KEY_INSERT = 260, + OC_KEY_DELETE = 261, + OC_KEY_RIGHT = 262, + OC_KEY_LEFT = 263, + OC_KEY_DOWN = 264, + OC_KEY_UP = 265, + OC_KEY_PAGE_UP = 266, + OC_KEY_PAGE_DOWN = 267, + OC_KEY_HOME = 268, + OC_KEY_END = 269, + OC_KEY_CAPS_LOCK = 280, + OC_KEY_SCROLL_LOCK = 281, + OC_KEY_NUM_LOCK = 282, + OC_KEY_PRINT_SCREEN = 283, + OC_KEY_PAUSE = 284, + OC_KEY_F1 = 290, + OC_KEY_F2 = 291, + OC_KEY_F3 = 292, + OC_KEY_F4 = 293, + OC_KEY_F5 = 294, + OC_KEY_F6 = 295, + OC_KEY_F7 = 296, + OC_KEY_F8 = 297, + OC_KEY_F9 = 298, + OC_KEY_F10 = 299, + OC_KEY_F11 = 300, + OC_KEY_F12 = 301, + OC_KEY_F13 = 302, + OC_KEY_F14 = 303, + OC_KEY_F15 = 304, + OC_KEY_F16 = 305, + OC_KEY_F17 = 306, + OC_KEY_F18 = 307, + OC_KEY_F19 = 308, + OC_KEY_F20 = 309, + OC_KEY_F21 = 310, + OC_KEY_F22 = 311, + OC_KEY_F23 = 312, + OC_KEY_F24 = 313, + OC_KEY_F25 = 314, + OC_KEY_KP_0 = 320, + OC_KEY_KP_1 = 321, + OC_KEY_KP_2 = 322, + OC_KEY_KP_3 = 323, + OC_KEY_KP_4 = 324, + OC_KEY_KP_5 = 325, + OC_KEY_KP_6 = 326, + OC_KEY_KP_7 = 327, + OC_KEY_KP_8 = 328, + OC_KEY_KP_9 = 329, + OC_KEY_KP_DECIMAL = 330, + OC_KEY_KP_DIVIDE = 331, + OC_KEY_KP_MULTIPLY = 332, + OC_KEY_KP_SUBTRACT = 333, + OC_KEY_KP_ADD = 334, + OC_KEY_KP_ENTER = 335, + OC_KEY_KP_EQUAL = 336, + OC_KEY_LEFT_SHIFT = 340, + OC_KEY_LEFT_CONTROL = 341, + OC_KEY_LEFT_ALT = 342, + OC_KEY_LEFT_SUPER = 343, + OC_KEY_RIGHT_SHIFT = 344, + OC_KEY_RIGHT_CONTROL = 345, + OC_KEY_RIGHT_ALT = 346, + OC_KEY_RIGHT_SUPER = 347, + OC_KEY_MENU = 348, + OC_KEY_COUNT + } oc_key_code; -typedef enum { - OC_KEYMOD_NONE = 0x00, - OC_KEYMOD_ALT = 0x01, - OC_KEYMOD_SHIFT = 0x02, - OC_KEYMOD_CTRL = 0x04, - OC_KEYMOD_CMD = 0x08, - OC_KEYMOD_MAIN_MODIFIER = 0x16 /* CMD on Mac, CTRL on Win32 */ } oc_keymod_flags; + typedef enum + { + OC_KEYMOD_NONE = 0x00, + OC_KEYMOD_ALT = 0x01, + OC_KEYMOD_SHIFT = 0x02, + OC_KEYMOD_CTRL = 0x04, + OC_KEYMOD_CMD = 0x08, + OC_KEYMOD_MAIN_MODIFIER = 0x16 /* CMD on Mac, CTRL on Win32 */ + } oc_keymod_flags; -typedef enum { - OC_MOUSE_LEFT = 0x00, - OC_MOUSE_RIGHT = 0x01, - OC_MOUSE_MIDDLE = 0x02, - OC_MOUSE_EXT1 = 0x03, - OC_MOUSE_EXT2 = 0x04, - OC_MOUSE_BUTTON_COUNT } oc_mouse_button; + typedef enum + { + OC_MOUSE_LEFT = 0x00, + OC_MOUSE_RIGHT = 0x01, + OC_MOUSE_MIDDLE = 0x02, + OC_MOUSE_EXT1 = 0x03, + OC_MOUSE_EXT2 = 0x04, + OC_MOUSE_BUTTON_COUNT + } oc_mouse_button; -typedef struct oc_key_event // keyboard and mouse buttons input -{ - oc_key_action action; - i32 code; - oc_keymod_flags mods; - char label[8]; - u8 labelLen; - int clickCount; -} oc_key_event; + typedef struct oc_key_event // keyboard and mouse buttons input + { + oc_key_action action; + i32 code; + oc_keymod_flags mods; + char label[8]; + u8 labelLen; + int clickCount; + } oc_key_event; -typedef struct oc_char_event // character input -{ - oc_utf32 codepoint; - char sequence[8]; - u8 seqLen; -} oc_char_event; + typedef struct oc_char_event // character input + { + oc_utf32 codepoint; + char sequence[8]; + u8 seqLen; + } oc_char_event; -typedef struct oc_mouse_event // mouse move/scroll -{ - f32 x; - f32 y; - f32 deltaX; - f32 deltaY; - oc_keymod_flags mods; -} oc_mouse_event; + typedef struct oc_mouse_event // mouse move/scroll + { + f32 x; + f32 y; + f32 deltaX; + f32 deltaY; + oc_keymod_flags mods; + } oc_mouse_event; -typedef struct oc_move_event // window resize / move -{ - oc_rect frame; - oc_rect content; -} oc_move_event; + typedef struct oc_move_event // window resize / move + { + oc_rect frame; + oc_rect content; + } oc_move_event; -typedef struct oc_event -{ - //TODO clipboard and path drop - oc_window window; - oc_event_type type; + typedef struct oc_event + { + //TODO clipboard and path drop + oc_window window; + oc_event_type type; - union - { - oc_key_event key; - oc_char_event character; - oc_mouse_event mouse; - oc_move_event move; - oc_str8_list paths; - }; + union + { + oc_key_event key; + oc_char_event character; + oc_mouse_event mouse; + oc_move_event move; + oc_str8_list paths; + }; -} oc_event; + } oc_event; //NOTE: these APIs are not directly available to Orca apps #if !defined(OC_PLATFORM_ORCA) || !(OC_PLATFORM_ORCA) -//-------------------------------------------------------------------- -// app management -//-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // app management + //-------------------------------------------------------------------- -ORCA_API void oc_init(void); -ORCA_API void oc_terminate(void); + ORCA_API void oc_init(void); + ORCA_API void oc_terminate(void); -ORCA_API bool oc_should_quit(void); -ORCA_API void oc_cancel_quit(void); -ORCA_API void oc_request_quit(void); + ORCA_API bool oc_should_quit(void); + ORCA_API void oc_cancel_quit(void); + ORCA_API void oc_request_quit(void); -ORCA_API void oc_set_cursor(oc_mouse_cursor cursor); + ORCA_API void oc_set_cursor(oc_mouse_cursor cursor); -//-------------------------------------------------------------------- -// Main loop and events handling -//-------------------------------------------------------------------- -/*NOTE: + //-------------------------------------------------------------------- + // Main loop and events handling + //-------------------------------------------------------------------- + /*NOTE: oc_pump_events() pumps system events into the event queue. A timeout of 0 polls for events, while a timeout of -1 blocks for events. A timeout > 0 blocks until new events are available or the timeout elapses. oc_next_event() get the next event from the event queue, allocating from the passed arena */ -ORCA_API void oc_pump_events(f64 timeout); -ORCA_API oc_event* oc_next_event(oc_arena* arena); + ORCA_API void oc_pump_events(f64 timeout); + ORCA_API oc_event* oc_next_event(oc_arena* arena); -typedef void(*oc_live_resize_callback)(oc_event event, void* data); -ORCA_API void oc_set_live_resize_callback(oc_live_resize_callback callback, void* data); + typedef void (*oc_live_resize_callback)(oc_event event, void* data); + ORCA_API void oc_set_live_resize_callback(oc_live_resize_callback callback, void* data); -//-------------------------------------------------------------------- -// window management -//-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // window management + //-------------------------------------------------------------------- -ORCA_API bool oc_window_handle_is_null(oc_window window); -ORCA_API oc_window oc_window_null_handle(void); + ORCA_API bool oc_window_handle_is_null(oc_window window); + ORCA_API oc_window oc_window_null_handle(void); -ORCA_API oc_window oc_window_create(oc_rect contentRect, oc_str8 title, oc_window_style style); -ORCA_API void oc_window_destroy(oc_window window); -ORCA_API void* oc_window_native_pointer(oc_window window); + ORCA_API oc_window oc_window_create(oc_rect contentRect, oc_str8 title, oc_window_style style); + ORCA_API void oc_window_destroy(oc_window window); + ORCA_API void* oc_window_native_pointer(oc_window window); -ORCA_API bool oc_window_should_close(oc_window window); -ORCA_API void oc_window_request_close(oc_window window); -ORCA_API void oc_window_cancel_close(oc_window window); + ORCA_API bool oc_window_should_close(oc_window window); + ORCA_API void oc_window_request_close(oc_window window); + ORCA_API void oc_window_cancel_close(oc_window window); -ORCA_API bool oc_window_is_hidden(oc_window window); -ORCA_API void oc_window_hide(oc_window window); -ORCA_API void oc_window_show(oc_window window); + ORCA_API bool oc_window_is_hidden(oc_window window); + ORCA_API void oc_window_hide(oc_window window); + ORCA_API void oc_window_show(oc_window window); -ORCA_API bool oc_window_is_minimized(oc_window window); -ORCA_API bool oc_window_is_maximized(oc_window window); -ORCA_API void oc_window_minimize(oc_window window); -ORCA_API void oc_window_maximize(oc_window window); -ORCA_API void oc_window_restore(oc_window window); + ORCA_API bool oc_window_is_minimized(oc_window window); + ORCA_API bool oc_window_is_maximized(oc_window window); + ORCA_API void oc_window_minimize(oc_window window); + ORCA_API void oc_window_maximize(oc_window window); + ORCA_API void oc_window_restore(oc_window window); -ORCA_API bool oc_window_has_focus(oc_window window); -ORCA_API void oc_window_focus(oc_window window); -ORCA_API void oc_window_unfocus(oc_window window); + ORCA_API bool oc_window_has_focus(oc_window window); + ORCA_API void oc_window_focus(oc_window window); + ORCA_API void oc_window_unfocus(oc_window window); -ORCA_API void oc_window_send_to_back(oc_window window); -ORCA_API void oc_window_bring_to_front(oc_window window); + ORCA_API void oc_window_send_to_back(oc_window window); + ORCA_API void oc_window_bring_to_front(oc_window window); -ORCA_API oc_rect oc_window_get_frame_rect(oc_window window); -ORCA_API void oc_window_set_frame_rect(oc_window window, oc_rect rect); -ORCA_API void oc_window_set_frame_position(oc_window window, oc_vec2 position); -ORCA_API void oc_window_set_frame_size(oc_window window, oc_vec2 size); + ORCA_API oc_rect oc_window_get_frame_rect(oc_window window); + ORCA_API void oc_window_set_frame_rect(oc_window window, oc_rect rect); + ORCA_API void oc_window_set_frame_position(oc_window window, oc_vec2 position); + ORCA_API void oc_window_set_frame_size(oc_window window, oc_vec2 size); -ORCA_API oc_rect oc_window_get_content_rect(oc_window window); -ORCA_API void oc_window_set_content_rect(oc_window window, oc_rect rect); -ORCA_API void oc_window_set_content_position(oc_window window, oc_vec2 position); -ORCA_API void oc_window_set_content_size(oc_window window, oc_vec2 size); + ORCA_API oc_rect oc_window_get_content_rect(oc_window window); + ORCA_API void oc_window_set_content_rect(oc_window window, oc_rect rect); + ORCA_API void oc_window_set_content_position(oc_window window, oc_vec2 position); + ORCA_API void oc_window_set_content_size(oc_window window, oc_vec2 size); -ORCA_API void oc_window_center(oc_window window); + ORCA_API void oc_window_center(oc_window window); -ORCA_API oc_rect oc_window_content_rect_for_frame_rect(oc_rect frameRect, oc_window_style style); -ORCA_API oc_rect oc_window_frame_rect_for_content_rect(oc_rect contentRect, oc_window_style style); + ORCA_API oc_rect oc_window_content_rect_for_frame_rect(oc_rect frameRect, oc_window_style style); + ORCA_API oc_rect oc_window_frame_rect_for_content_rect(oc_rect contentRect, oc_window_style style); -//--------------------------------------------------------------- -// Dispatching stuff to the main thread -//--------------------------------------------------------------- + //--------------------------------------------------------------- + // Dispatching stuff to the main thread + //--------------------------------------------------------------- -typedef i32 (*oc_dispatch_proc)(void* user); + typedef i32 (*oc_dispatch_proc)(void* user); -ORCA_API i32 oc_dispatch_on_main_thread_sync(oc_window main_window, oc_dispatch_proc proc, void* user); + ORCA_API i32 oc_dispatch_on_main_thread_sync(oc_window main_window, oc_dispatch_proc proc, void* user); -//-------------------------------------------------------------------- -// Clipboard -//-------------------------------------------------------------------- -ORCA_API void oc_clipboard_clear(void); + //-------------------------------------------------------------------- + // Clipboard + //-------------------------------------------------------------------- + ORCA_API void oc_clipboard_clear(void); -ORCA_API void oc_clipboard_set_string(oc_str8 string); -ORCA_API oc_str8 oc_clipboard_get_string(oc_arena* arena); -ORCA_API oc_str8 oc_clipboard_copy_string(oc_str8 backing); + ORCA_API void oc_clipboard_set_string(oc_str8 string); + ORCA_API oc_str8 oc_clipboard_get_string(oc_arena* arena); + ORCA_API oc_str8 oc_clipboard_copy_string(oc_str8 backing); -ORCA_API bool oc_clipboard_has_tag(const char* tag); -ORCA_API void oc_clipboard_set_data_for_tag(const char* tag, oc_str8 data); -ORCA_API oc_str8 oc_clipboard_get_data_for_tag(oc_arena* arena, const char* tag); + ORCA_API bool oc_clipboard_has_tag(const char* tag); + ORCA_API void oc_clipboard_set_data_for_tag(const char* tag, oc_str8 data); + ORCA_API oc_str8 oc_clipboard_get_data_for_tag(oc_arena* arena, const char* tag); -//-------------------------------------------------------------------- -// native open/save/alert windows -//-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // native open/save/alert windows + //-------------------------------------------------------------------- -ORCA_API oc_str8 oc_open_dialog(oc_arena* arena, - oc_str8 title, - oc_str8 defaultPath, - oc_str8_list filters, - bool directory); + ORCA_API oc_str8 oc_open_dialog(oc_arena* arena, + oc_str8 title, + oc_str8 defaultPath, + oc_str8_list filters, + bool directory); -ORCA_API oc_str8 oc_save_dialog(oc_arena* arena, - oc_str8 title, - oc_str8 defaultPath, - oc_str8_list filters); + ORCA_API oc_str8 oc_save_dialog(oc_arena* arena, + oc_str8 title, + oc_str8 defaultPath, + oc_str8_list filters); -ORCA_API int oc_alert_popup(oc_str8 title, - oc_str8 message, - oc_str8_list options); + ORCA_API int oc_alert_popup(oc_str8 title, + oc_str8 message, + oc_str8_list options); + //-------------------------------------------------------------------- + // file system stuff... //TODO: move elsewhere + //-------------------------------------------------------------------- + ORCA_API int oc_file_move(oc_str8 from, oc_str8 to); + ORCA_API int oc_file_remove(oc_str8 path); -//-------------------------------------------------------------------- -// file system stuff... //TODO: move elsewhere -//-------------------------------------------------------------------- -ORCA_API int oc_file_move(oc_str8 from, oc_str8 to); -ORCA_API int oc_file_remove(oc_str8 path); - -ORCA_API int oc_directory_create(oc_str8 path); - + ORCA_API int oc_directory_create(oc_str8 path); #endif // !defined(OC_PLATFORM_ORCA) || !(OC_PLATFORM_ORCA) @@ -388,5 +406,4 @@ ORCA_API int oc_directory_create(oc_str8 path); } // extern "C" #endif - #endif //__APP_H_ diff --git a/src/app/app_internal.h b/src/app/app_internal.h index 66a9fde..54b68d4 100644 --- a/src/app/app_internal.h +++ b/src/app/app_internal.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: app_internal.h * @author: Martin Fouilleul @@ -9,17 +9,17 @@ #ifndef __APP_INTERNAL_H_ #define __APP_INTERNAL_H_ -#include"app.h" +#include "app.h" -#include"platform/platform.h" -#include"util/ringbuffer.h" +#include "platform/platform.h" +#include "util/ringbuffer.h" #if OC_PLATFORM_WINDOWS - #include"win32_app.h" + #include "win32_app.h" #elif OC_PLATFORM_MACOS - #include"osx_app.h" + #include "osx_app.h" #else - #error "platform not supported yet" + #error "platform not supported yet" #endif //--------------------------------------------------------------- @@ -28,64 +28,65 @@ typedef struct oc_frame_stats { - f64 start; - f64 workTime; - f64 remainingTime; - f64 targetFramePeriod; + f64 start; + f64 workTime; + f64 remainingTime; + f64 targetFramePeriod; } oc_frame_stats; typedef struct oc_window_data { - oc_list_elt freeListElt; - u32 generation; + oc_list_elt freeListElt; + u32 generation; - oc_window_style style; + oc_window_style style; - bool shouldClose; //TODO could be in status flags - bool hidden; - bool minimized; + bool shouldClose; //TODO could be in status flags + bool hidden; + bool minimized; - OC_PLATFORM_WINDOW_DATA + OC_PLATFORM_WINDOW_DATA } oc_window_data; - //--------------------------------------------------------------- // Global App State //--------------------------------------------------------------- typedef struct oc_key_utf8 { - u8 labelLen; - char label[8]; + u8 labelLen; + char label[8]; } oc_key_utf8; - -enum { OC_APP_MAX_WINDOWS = 128 }; +enum +{ + OC_APP_MAX_WINDOWS = 128 +}; typedef struct oc_app { - bool init; - bool shouldQuit; - bool minimized; + bool init; + bool shouldQuit; + bool minimized; - oc_str8 pendingPathDrop; - oc_arena eventArena; + oc_str8 pendingPathDrop; + oc_arena eventArena; - oc_ringbuffer eventQueue; + oc_ringbuffer eventQueue; - oc_frame_stats frameStats; + oc_frame_stats frameStats; - oc_window_data windowPool[OC_APP_MAX_WINDOWS]; - oc_list windowFreeList; + oc_window_data windowPool[OC_APP_MAX_WINDOWS]; + oc_list windowFreeList; - oc_live_resize_callback liveResizeCallback; - void* liveResizeData; + oc_live_resize_callback liveResizeCallback; + void* liveResizeData; - oc_key_utf8 keyLabels[512]; - int keyCodes[512]; - int nativeKeys[OC_KEY_COUNT]; + oc_key_utf8 keyLabels[512]; + int keyCodes[512]; + int nativeKeys[OC_KEY_COUNT]; - OC_PLATFORM_APP_DATA + OC_PLATFORM_APP_DATA } oc_app; #endif // __APP_INTERNAL_H_ diff --git a/src/app/orca_app.c b/src/app/orca_app.c index cfeb123..fd349f0 100644 --- a/src/app/orca_app.c +++ b/src/app/orca_app.c @@ -1,4 +1,4 @@ -#include"orca.h" +#include "orca.h" //This is used to pass raw events from the runtime ORCA_EXPORT oc_event oc_rawEvent; diff --git a/src/app/osx_app.h b/src/app/osx_app.h index d578c1c..9fdb9ca 100644 --- a/src/app/osx_app.h +++ b/src/app/osx_app.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: osx_app.h * @author: Martin Fouilleul @@ -9,28 +9,28 @@ #ifndef __OSX_APP_H_ #define __OSX_APP_H_ -#include"app.h" -#include"graphics/graphics.h" +#include "app.h" +#include "graphics/graphics.h" #ifdef __OBJC__ - #import + #import #else - #define NSWindow void - #define NSView void - #define NSObject void - #define NSTimer void - #define NSCursor void - #define CALayer void - #define CAContext void + #define NSWindow void + #define NSView void + #define NSObject void + #define NSTimer void + #define NSCursor void + #define CALayer void + #define CAContext void #endif -#include +#include typedef struct oc_osx_window_data { - NSWindow* nsWindow; - NSView* nsView; - NSObject* nsWindowDelegate; + NSWindow* nsWindow; + NSView* nsView; + NSObject* nsWindowDelegate; } oc_osx_window_data; @@ -40,12 +40,12 @@ const u32 OC_APP_MAX_VIEWS = 128; typedef struct oc_osx_app_data { - NSTimer* frameTimer; - NSCursor* cursor; + NSTimer* frameTimer; + NSCursor* cursor; - TISInputSourceRef kbLayoutInputSource; - void* kbLayoutUnicodeData; - id kbLayoutListener; + TISInputSourceRef kbLayoutInputSource; + void* kbLayoutUnicodeData; + id kbLayoutListener; } oc_osx_app_data; @@ -55,33 +55,31 @@ typedef struct oc_osx_app_data // Surface layer //----------------------------------------------- #ifdef __OBJC__ - //NOTE: these private interfaces for surface sharing need to be declared explicitly here - typedef uint32_t CGSConnectionID; - CGSConnectionID CGSMainConnectionID(void); +//NOTE: these private interfaces for surface sharing need to be declared explicitly here +typedef uint32_t CGSConnectionID; +CGSConnectionID CGSMainConnectionID(void); - typedef uint32_t CAContextID; +typedef uint32_t CAContextID; - @interface CAContext : NSObject - { - } - + (id)contextWithCGSConnection:(CAContextID)contextId options:(NSDictionary*)optionsDict; - @property(readonly) CAContextID contextId; - @property(retain) CALayer *layer; - @end +@interface CAContext : NSObject +{ +} ++ (id)contextWithCGSConnection:(CAContextID)contextId options:(NSDictionary*)optionsDict; +@property(readonly) CAContextID contextId; +@property(retain) CALayer* layer; +@end - @interface CALayerHost : CALayer - { - } - @property CAContextID contextId; - @end +@interface CALayerHost : CALayer +{ +} +@property CAContextID contextId; +@end #endif typedef struct oc_layer { - CALayer* caLayer; - CAContext* caContext; + CALayer* caLayer; + CAContext* caContext; } oc_layer; - - #endif //__OSX_APP_H_ diff --git a/src/app/osx_app.m b/src/app/osx_app.m index e93d609..068d4ba 100644 --- a/src/app/osx_app.m +++ b/src/app/osx_app.m @@ -10,17 +10,17 @@ #import //CATransaction -#include // malloc/free +#include // malloc/free -#include"lists.h" -#include"ringbuffer.h" -#include"memory.h" -#include"macros.h" -#include"platform_debug.h" -#include"platform_clock.h" -#include"graphics/graphics_surface.h" +#include "graphics/graphics_surface.h" +#include "lists.h" +#include "macros.h" +#include "memory.h" +#include "platform_clock.h" +#include "platform_debug.h" +#include "ringbuffer.h" -#include"app.c" +#include "app.c" //-------------------------------------------------------------------- // mp window struct and utility functions @@ -28,307 +28,306 @@ static u32 oc_osx_get_window_style_mask(oc_window_style style) { - u32 mask = 0; - if(style & OC_WINDOW_STYLE_NO_TITLE) - { - mask = NSWindowStyleMaskBorderless; - } - else - { - mask = NSWindowStyleMaskTitled; - } + u32 mask = 0; + if(style & OC_WINDOW_STYLE_NO_TITLE) + { + mask = NSWindowStyleMaskBorderless; + } + else + { + mask = NSWindowStyleMaskTitled; + } - if(!(style & OC_WINDOW_STYLE_FIXED_SIZE)) - { - mask |= NSWindowStyleMaskResizable; - } - if(!(style & OC_WINDOW_STYLE_NO_CLOSE)) - { - mask |= NSWindowStyleMaskClosable; - } - if(!(style & OC_WINDOW_STYLE_NO_MINIFY)) - { - mask |= NSWindowStyleMaskMiniaturizable; - } - return(mask); + if(!(style & OC_WINDOW_STYLE_FIXED_SIZE)) + { + mask |= NSWindowStyleMaskResizable; + } + if(!(style & OC_WINDOW_STYLE_NO_CLOSE)) + { + mask |= NSWindowStyleMaskClosable; + } + if(!(style & OC_WINDOW_STYLE_NO_MINIFY)) + { + mask |= NSWindowStyleMaskMiniaturizable; + } + return (mask); } //--------------------------------------------------------------- static void oc_init_osx_keys() { - memset(oc_appData.keyCodes, OC_KEY_UNKNOWN, 256*sizeof(int)); + memset(oc_appData.keyCodes, OC_KEY_UNKNOWN, 256 * sizeof(int)); - oc_appData.keyCodes[0x1D] = OC_KEY_0; - oc_appData.keyCodes[0x12] = OC_KEY_1; - oc_appData.keyCodes[0x13] = OC_KEY_2; - oc_appData.keyCodes[0x14] = OC_KEY_3; - oc_appData.keyCodes[0x15] = OC_KEY_4; - oc_appData.keyCodes[0x17] = OC_KEY_5; - oc_appData.keyCodes[0x16] = OC_KEY_6; - oc_appData.keyCodes[0x1A] = OC_KEY_7; - oc_appData.keyCodes[0x1C] = OC_KEY_8; - oc_appData.keyCodes[0x19] = OC_KEY_9; - oc_appData.keyCodes[0x00] = OC_KEY_A; - oc_appData.keyCodes[0x0B] = OC_KEY_B; - oc_appData.keyCodes[0x08] = OC_KEY_C; - oc_appData.keyCodes[0x02] = OC_KEY_D; - oc_appData.keyCodes[0x0E] = OC_KEY_E; - oc_appData.keyCodes[0x03] = OC_KEY_F; - oc_appData.keyCodes[0x05] = OC_KEY_G; - oc_appData.keyCodes[0x04] = OC_KEY_H; - oc_appData.keyCodes[0x22] = OC_KEY_I; - oc_appData.keyCodes[0x26] = OC_KEY_J; - oc_appData.keyCodes[0x28] = OC_KEY_K; - oc_appData.keyCodes[0x25] = OC_KEY_L; - oc_appData.keyCodes[0x2E] = OC_KEY_M; - oc_appData.keyCodes[0x2D] = OC_KEY_N; - oc_appData.keyCodes[0x1F] = OC_KEY_O; - oc_appData.keyCodes[0x23] = OC_KEY_P; - oc_appData.keyCodes[0x0C] = OC_KEY_Q; - oc_appData.keyCodes[0x0F] = OC_KEY_R; - oc_appData.keyCodes[0x01] = OC_KEY_S; - oc_appData.keyCodes[0x11] = OC_KEY_T; - oc_appData.keyCodes[0x20] = OC_KEY_U; - oc_appData.keyCodes[0x09] = OC_KEY_V; - oc_appData.keyCodes[0x0D] = OC_KEY_W; - oc_appData.keyCodes[0x07] = OC_KEY_X; - oc_appData.keyCodes[0x10] = OC_KEY_Y; - oc_appData.keyCodes[0x06] = OC_KEY_Z; + oc_appData.keyCodes[0x1D] = OC_KEY_0; + oc_appData.keyCodes[0x12] = OC_KEY_1; + oc_appData.keyCodes[0x13] = OC_KEY_2; + oc_appData.keyCodes[0x14] = OC_KEY_3; + oc_appData.keyCodes[0x15] = OC_KEY_4; + oc_appData.keyCodes[0x17] = OC_KEY_5; + oc_appData.keyCodes[0x16] = OC_KEY_6; + oc_appData.keyCodes[0x1A] = OC_KEY_7; + oc_appData.keyCodes[0x1C] = OC_KEY_8; + oc_appData.keyCodes[0x19] = OC_KEY_9; + oc_appData.keyCodes[0x00] = OC_KEY_A; + oc_appData.keyCodes[0x0B] = OC_KEY_B; + oc_appData.keyCodes[0x08] = OC_KEY_C; + oc_appData.keyCodes[0x02] = OC_KEY_D; + oc_appData.keyCodes[0x0E] = OC_KEY_E; + oc_appData.keyCodes[0x03] = OC_KEY_F; + oc_appData.keyCodes[0x05] = OC_KEY_G; + oc_appData.keyCodes[0x04] = OC_KEY_H; + oc_appData.keyCodes[0x22] = OC_KEY_I; + oc_appData.keyCodes[0x26] = OC_KEY_J; + oc_appData.keyCodes[0x28] = OC_KEY_K; + oc_appData.keyCodes[0x25] = OC_KEY_L; + oc_appData.keyCodes[0x2E] = OC_KEY_M; + oc_appData.keyCodes[0x2D] = OC_KEY_N; + oc_appData.keyCodes[0x1F] = OC_KEY_O; + oc_appData.keyCodes[0x23] = OC_KEY_P; + oc_appData.keyCodes[0x0C] = OC_KEY_Q; + oc_appData.keyCodes[0x0F] = OC_KEY_R; + oc_appData.keyCodes[0x01] = OC_KEY_S; + oc_appData.keyCodes[0x11] = OC_KEY_T; + oc_appData.keyCodes[0x20] = OC_KEY_U; + oc_appData.keyCodes[0x09] = OC_KEY_V; + oc_appData.keyCodes[0x0D] = OC_KEY_W; + oc_appData.keyCodes[0x07] = OC_KEY_X; + oc_appData.keyCodes[0x10] = OC_KEY_Y; + oc_appData.keyCodes[0x06] = OC_KEY_Z; - oc_appData.keyCodes[0x27] = OC_KEY_APOSTROPHE; - oc_appData.keyCodes[0x2A] = OC_KEY_BACKSLASH; - oc_appData.keyCodes[0x2B] = OC_KEY_COMMA; - oc_appData.keyCodes[0x18] = OC_KEY_EQUAL; - oc_appData.keyCodes[0x32] = OC_KEY_GRAVE_ACCENT; - oc_appData.keyCodes[0x21] = OC_KEY_LEFT_BRACKET; - oc_appData.keyCodes[0x1B] = OC_KEY_MINUS; - oc_appData.keyCodes[0x2F] = OC_KEY_PERIOD; - oc_appData.keyCodes[0x1E] = OC_KEY_RIGHT_BRACKET; - oc_appData.keyCodes[0x29] = OC_KEY_SEMICOLON; - oc_appData.keyCodes[0x2C] = OC_KEY_SLASH; - oc_appData.keyCodes[0x0A] = OC_KEY_WORLD_1; + oc_appData.keyCodes[0x27] = OC_KEY_APOSTROPHE; + oc_appData.keyCodes[0x2A] = OC_KEY_BACKSLASH; + oc_appData.keyCodes[0x2B] = OC_KEY_COMMA; + oc_appData.keyCodes[0x18] = OC_KEY_EQUAL; + oc_appData.keyCodes[0x32] = OC_KEY_GRAVE_ACCENT; + oc_appData.keyCodes[0x21] = OC_KEY_LEFT_BRACKET; + oc_appData.keyCodes[0x1B] = OC_KEY_MINUS; + oc_appData.keyCodes[0x2F] = OC_KEY_PERIOD; + oc_appData.keyCodes[0x1E] = OC_KEY_RIGHT_BRACKET; + oc_appData.keyCodes[0x29] = OC_KEY_SEMICOLON; + oc_appData.keyCodes[0x2C] = OC_KEY_SLASH; + oc_appData.keyCodes[0x0A] = OC_KEY_WORLD_1; - oc_appData.keyCodes[0x33] = OC_KEY_BACKSPACE; - oc_appData.keyCodes[0x39] = OC_KEY_CAPS_LOCK; - oc_appData.keyCodes[0x75] = OC_KEY_DELETE; - oc_appData.keyCodes[0x7D] = OC_KEY_DOWN; - oc_appData.keyCodes[0x77] = OC_KEY_END; - oc_appData.keyCodes[0x24] = OC_KEY_ENTER; - oc_appData.keyCodes[0x35] = OC_KEY_ESCAPE; - oc_appData.keyCodes[0x7A] = OC_KEY_F1; - oc_appData.keyCodes[0x78] = OC_KEY_F2; - oc_appData.keyCodes[0x63] = OC_KEY_F3; - oc_appData.keyCodes[0x76] = OC_KEY_F4; - oc_appData.keyCodes[0x60] = OC_KEY_F5; - oc_appData.keyCodes[0x61] = OC_KEY_F6; - oc_appData.keyCodes[0x62] = OC_KEY_F7; - oc_appData.keyCodes[0x64] = OC_KEY_F8; - oc_appData.keyCodes[0x65] = OC_KEY_F9; - oc_appData.keyCodes[0x6D] = OC_KEY_F10; - oc_appData.keyCodes[0x67] = OC_KEY_F11; - oc_appData.keyCodes[0x6F] = OC_KEY_F12; - oc_appData.keyCodes[0x69] = OC_KEY_F13; - oc_appData.keyCodes[0x6B] = OC_KEY_F14; - oc_appData.keyCodes[0x71] = OC_KEY_F15; - oc_appData.keyCodes[0x6A] = OC_KEY_F16; - oc_appData.keyCodes[0x40] = OC_KEY_F17; - oc_appData.keyCodes[0x4F] = OC_KEY_F18; - oc_appData.keyCodes[0x50] = OC_KEY_F19; - oc_appData.keyCodes[0x5A] = OC_KEY_F20; - oc_appData.keyCodes[0x73] = OC_KEY_HOME; - oc_appData.keyCodes[0x72] = OC_KEY_INSERT; - oc_appData.keyCodes[0x7B] = OC_KEY_LEFT; - oc_appData.keyCodes[0x3A] = OC_KEY_LEFT_ALT; - oc_appData.keyCodes[0x3B] = OC_KEY_LEFT_CONTROL; - oc_appData.keyCodes[0x38] = OC_KEY_LEFT_SHIFT; - oc_appData.keyCodes[0x37] = OC_KEY_LEFT_SUPER; - oc_appData.keyCodes[0x6E] = OC_KEY_MENU; - oc_appData.keyCodes[0x47] = OC_KEY_NUM_LOCK; - oc_appData.keyCodes[0x79] = OC_KEY_PAGE_DOWN; - oc_appData.keyCodes[0x74] = OC_KEY_PAGE_UP; - oc_appData.keyCodes[0x7C] = OC_KEY_RIGHT; - oc_appData.keyCodes[0x3D] = OC_KEY_RIGHT_ALT; - oc_appData.keyCodes[0x3E] = OC_KEY_RIGHT_CONTROL; - oc_appData.keyCodes[0x3C] = OC_KEY_RIGHT_SHIFT; - oc_appData.keyCodes[0x36] = OC_KEY_RIGHT_SUPER; - oc_appData.keyCodes[0x31] = OC_KEY_SPACE; - oc_appData.keyCodes[0x30] = OC_KEY_TAB; - oc_appData.keyCodes[0x7E] = OC_KEY_UP; + oc_appData.keyCodes[0x33] = OC_KEY_BACKSPACE; + oc_appData.keyCodes[0x39] = OC_KEY_CAPS_LOCK; + oc_appData.keyCodes[0x75] = OC_KEY_DELETE; + oc_appData.keyCodes[0x7D] = OC_KEY_DOWN; + oc_appData.keyCodes[0x77] = OC_KEY_END; + oc_appData.keyCodes[0x24] = OC_KEY_ENTER; + oc_appData.keyCodes[0x35] = OC_KEY_ESCAPE; + oc_appData.keyCodes[0x7A] = OC_KEY_F1; + oc_appData.keyCodes[0x78] = OC_KEY_F2; + oc_appData.keyCodes[0x63] = OC_KEY_F3; + oc_appData.keyCodes[0x76] = OC_KEY_F4; + oc_appData.keyCodes[0x60] = OC_KEY_F5; + oc_appData.keyCodes[0x61] = OC_KEY_F6; + oc_appData.keyCodes[0x62] = OC_KEY_F7; + oc_appData.keyCodes[0x64] = OC_KEY_F8; + oc_appData.keyCodes[0x65] = OC_KEY_F9; + oc_appData.keyCodes[0x6D] = OC_KEY_F10; + oc_appData.keyCodes[0x67] = OC_KEY_F11; + oc_appData.keyCodes[0x6F] = OC_KEY_F12; + oc_appData.keyCodes[0x69] = OC_KEY_F13; + oc_appData.keyCodes[0x6B] = OC_KEY_F14; + oc_appData.keyCodes[0x71] = OC_KEY_F15; + oc_appData.keyCodes[0x6A] = OC_KEY_F16; + oc_appData.keyCodes[0x40] = OC_KEY_F17; + oc_appData.keyCodes[0x4F] = OC_KEY_F18; + oc_appData.keyCodes[0x50] = OC_KEY_F19; + oc_appData.keyCodes[0x5A] = OC_KEY_F20; + oc_appData.keyCodes[0x73] = OC_KEY_HOME; + oc_appData.keyCodes[0x72] = OC_KEY_INSERT; + oc_appData.keyCodes[0x7B] = OC_KEY_LEFT; + oc_appData.keyCodes[0x3A] = OC_KEY_LEFT_ALT; + oc_appData.keyCodes[0x3B] = OC_KEY_LEFT_CONTROL; + oc_appData.keyCodes[0x38] = OC_KEY_LEFT_SHIFT; + oc_appData.keyCodes[0x37] = OC_KEY_LEFT_SUPER; + oc_appData.keyCodes[0x6E] = OC_KEY_MENU; + oc_appData.keyCodes[0x47] = OC_KEY_NUM_LOCK; + oc_appData.keyCodes[0x79] = OC_KEY_PAGE_DOWN; + oc_appData.keyCodes[0x74] = OC_KEY_PAGE_UP; + oc_appData.keyCodes[0x7C] = OC_KEY_RIGHT; + oc_appData.keyCodes[0x3D] = OC_KEY_RIGHT_ALT; + oc_appData.keyCodes[0x3E] = OC_KEY_RIGHT_CONTROL; + oc_appData.keyCodes[0x3C] = OC_KEY_RIGHT_SHIFT; + oc_appData.keyCodes[0x36] = OC_KEY_RIGHT_SUPER; + oc_appData.keyCodes[0x31] = OC_KEY_SPACE; + oc_appData.keyCodes[0x30] = OC_KEY_TAB; + oc_appData.keyCodes[0x7E] = OC_KEY_UP; - oc_appData.keyCodes[0x52] = OC_KEY_KP_0; - oc_appData.keyCodes[0x53] = OC_KEY_KP_1; - oc_appData.keyCodes[0x54] = OC_KEY_KP_2; - oc_appData.keyCodes[0x55] = OC_KEY_KP_3; - oc_appData.keyCodes[0x56] = OC_KEY_KP_4; - oc_appData.keyCodes[0x57] = OC_KEY_KP_5; - oc_appData.keyCodes[0x58] = OC_KEY_KP_6; - oc_appData.keyCodes[0x59] = OC_KEY_KP_7; - oc_appData.keyCodes[0x5B] = OC_KEY_KP_8; - oc_appData.keyCodes[0x5C] = OC_KEY_KP_9; - oc_appData.keyCodes[0x45] = OC_KEY_KP_ADD; - oc_appData.keyCodes[0x41] = OC_KEY_KP_DECIMAL; - oc_appData.keyCodes[0x4B] = OC_KEY_KP_DIVIDE; - oc_appData.keyCodes[0x4C] = OC_KEY_KP_ENTER; - oc_appData.keyCodes[0x51] = OC_KEY_KP_EQUAL; - oc_appData.keyCodes[0x43] = OC_KEY_KP_MULTIPLY; - oc_appData.keyCodes[0x4E] = OC_KEY_KP_SUBTRACT; + oc_appData.keyCodes[0x52] = OC_KEY_KP_0; + oc_appData.keyCodes[0x53] = OC_KEY_KP_1; + oc_appData.keyCodes[0x54] = OC_KEY_KP_2; + oc_appData.keyCodes[0x55] = OC_KEY_KP_3; + oc_appData.keyCodes[0x56] = OC_KEY_KP_4; + oc_appData.keyCodes[0x57] = OC_KEY_KP_5; + oc_appData.keyCodes[0x58] = OC_KEY_KP_6; + oc_appData.keyCodes[0x59] = OC_KEY_KP_7; + oc_appData.keyCodes[0x5B] = OC_KEY_KP_8; + oc_appData.keyCodes[0x5C] = OC_KEY_KP_9; + oc_appData.keyCodes[0x45] = OC_KEY_KP_ADD; + oc_appData.keyCodes[0x41] = OC_KEY_KP_DECIMAL; + oc_appData.keyCodes[0x4B] = OC_KEY_KP_DIVIDE; + oc_appData.keyCodes[0x4C] = OC_KEY_KP_ENTER; + oc_appData.keyCodes[0x51] = OC_KEY_KP_EQUAL; + oc_appData.keyCodes[0x43] = OC_KEY_KP_MULTIPLY; + oc_appData.keyCodes[0x4E] = OC_KEY_KP_SUBTRACT; - memset(oc_appData.nativeKeys, 0, sizeof(int)*OC_KEY_COUNT); - for(int nativeKey=0; nativeKey<256; nativeKey++) - { - oc_key_code mpKey = oc_appData.keyCodes[nativeKey]; - if(mpKey) - { - oc_appData.nativeKeys[mpKey] = nativeKey; - } - } + memset(oc_appData.nativeKeys, 0, sizeof(int) * OC_KEY_COUNT); + for(int nativeKey = 0; nativeKey < 256; nativeKey++) + { + oc_key_code mpKey = oc_appData.keyCodes[nativeKey]; + if(mpKey) + { + oc_appData.nativeKeys[mpKey] = nativeKey; + } + } } static int oc_convert_osx_key(unsigned short nsCode) { - if(nsCode >= 265) - { - return(OC_KEY_UNKNOWN); - } - else - { - return(oc_appData.keyCodes[nsCode]); - } + if(nsCode >= 265) + { + return (OC_KEY_UNKNOWN); + } + else + { + return (oc_appData.keyCodes[nsCode]); + } } static oc_keymod_flags oc_convert_osx_mods(NSUInteger nsFlags) { - oc_keymod_flags mods = OC_KEYMOD_NONE; - if(nsFlags & NSEventModifierFlagShift) - { - mods |= OC_KEYMOD_SHIFT; - } - if(nsFlags & NSEventModifierFlagControl) - { - mods |= OC_KEYMOD_CTRL; - } - if(nsFlags & NSEventModifierFlagOption) - { - mods |= OC_KEYMOD_ALT; - } - if(nsFlags & NSEventModifierFlagCommand) - { - mods |= OC_KEYMOD_CMD; - mods |= OC_KEYMOD_MAIN_MODIFIER; - } - return(mods); + oc_keymod_flags mods = OC_KEYMOD_NONE; + if(nsFlags & NSEventModifierFlagShift) + { + mods |= OC_KEYMOD_SHIFT; + } + if(nsFlags & NSEventModifierFlagControl) + { + mods |= OC_KEYMOD_CTRL; + } + if(nsFlags & NSEventModifierFlagOption) + { + mods |= OC_KEYMOD_ALT; + } + if(nsFlags & NSEventModifierFlagCommand) + { + mods |= OC_KEYMOD_CMD; + mods |= OC_KEYMOD_MAIN_MODIFIER; + } + return (mods); } static void oc_update_keyboard_layout() { - if(oc_appData.osx.kbLayoutInputSource) - { - CFRelease(oc_appData.osx.kbLayoutInputSource); - oc_appData.osx.kbLayoutInputSource = 0; - oc_appData.osx.kbLayoutUnicodeData = nil; - } + if(oc_appData.osx.kbLayoutInputSource) + { + CFRelease(oc_appData.osx.kbLayoutInputSource); + oc_appData.osx.kbLayoutInputSource = 0; + oc_appData.osx.kbLayoutUnicodeData = nil; + } - oc_appData.osx.kbLayoutInputSource = TISCopyCurrentKeyboardLayoutInputSource(); - if(!oc_appData.osx.kbLayoutInputSource) - { - oc_log_error("Failed to load keyboard layout input source"); - } + oc_appData.osx.kbLayoutInputSource = TISCopyCurrentKeyboardLayoutInputSource(); + if(!oc_appData.osx.kbLayoutInputSource) + { + oc_log_error("Failed to load keyboard layout input source"); + } - oc_appData.osx.kbLayoutUnicodeData = TISGetInputSourceProperty(oc_appData.osx.kbLayoutInputSource, - kTISPropertyUnicodeKeyLayoutData); - if(!oc_appData.osx.kbLayoutUnicodeData) - { - oc_log_error("Failed to load keyboard layout unicode data"); - } + oc_appData.osx.kbLayoutUnicodeData = TISGetInputSourceProperty(oc_appData.osx.kbLayoutInputSource, + kTISPropertyUnicodeKeyLayoutData); + if(!oc_appData.osx.kbLayoutUnicodeData) + { + oc_log_error("Failed to load keyboard layout unicode data"); + } - memset(oc_appData.keyLabels, 0, sizeof(oc_key_utf8)*OC_KEY_COUNT); + memset(oc_appData.keyLabels, 0, sizeof(oc_key_utf8) * OC_KEY_COUNT); - for(int key=0; keylabelLen, keyInfo->label); - return(label); + oc_key_utf8* keyInfo = &(oc_appData.keyLabels[key]); + oc_str8 label = oc_str8_from_buffer(keyInfo->labelLen, keyInfo->label); + return (label); } oc_key_code oc_label_to_key(oc_str8 label) { - oc_key_code res = OC_KEY_UNKNOWN; - for(int key=0; key --(id)init; +- (id)init; @end @implementation OCAppDelegate --(id)init +- (id)init { - self = [super init]; - [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self - andSelector:@selector(handleAppleEvent:withReplyEvent:) - forEventClass:kInternetEventClass - andEventID:kAEGetURL]; + self = [super init]; + [[NSAppleEventManager sharedAppleEventManager] setEventHandler:self + andSelector:@selector(handleAppleEvent:withReplyEvent:) + forEventClass:kInternetEventClass + andEventID:kAEGetURL]; - return(self); + return (self); } -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender { - //NOTE: We set shouldQuit to true and send a Quit event - // We then return a value to cancel the direct termination because we still - // want to execte the code after oc_event_loop(). If the user didn't set shouldQuit to - // false, oc_event_loop() will exit, and the user can execute any cleanup needed and - // exit the program. + //NOTE: We set shouldQuit to true and send a Quit event + // We then return a value to cancel the direct termination because we still + // want to execte the code after oc_event_loop(). If the user didn't set shouldQuit to + // false, oc_event_loop() will exit, and the user can execute any cleanup needed and + // exit the program. - oc_appData.shouldQuit = true; - oc_event event = {}; - event.type = OC_EVENT_QUIT; - oc_queue_event(&event); + oc_appData.shouldQuit = true; + oc_event event = {}; + event.type = OC_EVENT_QUIT; + oc_queue_event(&event); - return(NSTerminateCancel); + return (NSTerminateCancel); } -- (void)applicationWillFinishLaunching:(NSNotification *)notification -{@autoreleasepool{ +- (void)applicationWillFinishLaunching:(NSNotification*)notification +{ + @autoreleasepool + { - //NOTE(martin): add a menu for quit, and a corresponding key equivalent. - // this allows to quit the application when there is no window - // left to catch our Cmd-Q key equivalent - NSMenu* bar = [[NSMenu alloc] init]; - [NSApp setMainMenu:bar]; + //NOTE(martin): add a menu for quit, and a corresponding key equivalent. + // this allows to quit the application when there is no window + // left to catch our Cmd-Q key equivalent + NSMenu* bar = [[NSMenu alloc] init]; + [NSApp setMainMenu:bar]; - NSMenuItem* appMenuItem = - [bar addItemWithTitle:@"" action:NULL keyEquivalent:@""]; - NSMenu* appMenu = [[NSMenu alloc] init]; - [appMenuItem setSubmenu:appMenu]; + NSMenuItem* appMenuItem = + [bar addItemWithTitle:@"" + action:NULL + keyEquivalent:@""]; + NSMenu* appMenu = [[NSMenu alloc] init]; + [appMenuItem setSubmenu:appMenu]; - [appMenu addItemWithTitle: @"Quit" - action: @selector(terminate:) - keyEquivalent: @"q"]; - -}} + [appMenu addItemWithTitle:@"Quit" + action:@selector(terminate:) + keyEquivalent:@"q"]; + } +} - (void)timerElapsed:(NSTimer*)timer { - oc_event event = {}; - event.type = OC_EVENT_FRAME; - oc_queue_event(&event); + oc_event event = {}; + event.type = OC_EVENT_FRAME; + oc_queue_event(&event); } -- (void)applicationDidFinishLaunching:(NSNotification *)notification -{@autoreleasepool{ - //WARN(martin): the order of these calls seem to matter a lot for properly showing the menu bar - // with other orderings, the menu doesn't display before the application is put out of - // focus and on focus again... This is flaky undocumented behaviour, so although it is - // fixed by the current ordering, we expect the problem to show up again in future - // versions of macOS. - - //NOTE(martin): send a dummy event to wake-up the run loop and exit from the run loop. - - NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined - location:NSMakePoint(0, 0) - modifierFlags:0 - timestamp:0 - windowNumber:0 - context:nil - subtype:0 - data1:0 - data2:0]; - - [NSApp postEvent:event atStart:YES]; - [NSApp stop:nil]; -}} - -- (BOOL)application:(NSApplication *)application openFile:(NSString *)filename +- (void)applicationDidFinishLaunching:(NSNotification*)notification { - oc_event event = {0}; - event.window = (oc_window){0}; - event.type = OC_EVENT_PATHDROP; + @autoreleasepool + { + //WARN(martin): the order of these calls seem to matter a lot for properly showing the menu bar + // with other orderings, the menu doesn't display before the application is put out of + // focus and on focus again... This is flaky undocumented behaviour, so although it is + // fixed by the current ordering, we expect the problem to show up again in future + // versions of macOS. - oc_arena* scratch = oc_scratch(); - oc_arena_scope scope = oc_arena_scope_begin(scratch); + //NOTE(martin): send a dummy event to wake-up the run loop and exit from the run loop. - oc_str8 path = oc_str8_push_cstring(scratch, [filename UTF8String]); - oc_str8_list_push(scratch, &event.paths, path); + NSEvent* event = [NSEvent otherEventWithType:NSEventTypeApplicationDefined + location:NSMakePoint(0, 0) + modifierFlags:0 + timestamp:0 + windowNumber:0 + context:nil + subtype:0 + data1:0 + data2:0]; - oc_queue_event(&event); + [NSApp postEvent:event atStart:YES]; + [NSApp stop:nil]; + } +} - oc_arena_scope_end(scope); +- (BOOL)application:(NSApplication*)application openFile:(NSString*)filename +{ + oc_event event = { 0 }; + event.window = (oc_window){ 0 }; + event.type = OC_EVENT_PATHDROP; - return(YES); + oc_arena* scratch = oc_scratch(); + oc_arena_scope scope = oc_arena_scope_begin(scratch); + + oc_str8 path = oc_str8_push_cstring(scratch, [filename UTF8String]); + oc_str8_list_push(scratch, &event.paths, path); + + oc_queue_event(&event); + + oc_arena_scope_end(scope); + + return (YES); } - (void)handleAppleEvent:(NSAppleEventDescriptor*)appleEvent withReplyEvent:(NSAppleEventDescriptor*)replyEvent { - NSString* nsPath = [[appleEvent paramDescriptorForKeyword:keyDirectObject] stringValue]; + NSString* nsPath = [[appleEvent paramDescriptorForKeyword:keyDirectObject] stringValue]; - oc_event event = {}; - event.window = (oc_window){0}; - event.type = OC_EVENT_PATHDROP; + oc_event event = {}; + event.window = (oc_window){ 0 }; + event.type = OC_EVENT_PATHDROP; - oc_arena* scratch = oc_scratch(); - oc_arena_scope scope = oc_arena_scope_begin(scratch); + oc_arena* scratch = oc_scratch(); + oc_arena_scope scope = oc_arena_scope_begin(scratch); - oc_str8 path = oc_str8_push_cstring(scratch, [nsPath UTF8String]); - oc_str8_list_push(scratch, &event.paths, path); + oc_str8 path = oc_str8_push_cstring(scratch, [nsPath UTF8String]); + oc_str8_list_push(scratch, &event.paths, path); - oc_queue_event(&event); + oc_queue_event(&event); - oc_arena_scope_end(scope); + oc_arena_scope_end(scope); } //TODO: drag and drop paths @@ -483,15 +492,18 @@ void oc_install_keyboard_layout_listener() //--------------------------------------------------------------- @implementation OCWindow -- (id)initWithWindowData:(oc_window_data*) window contentRect:(NSRect) rect styleMask:(uint32) style + +- (id)initWithWindowData:(oc_window_data*)window contentRect:(NSRect)rect styleMask:(uint32)style { - mpWindow = window; - return([self initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:NO]); + mpWindow = window; + return ([self initWithContentRect:rect styleMask:style backing:NSBackingStoreBuffered defer:NO]); } + - (BOOL)canBecomeKeyWindow { - return(!(mpWindow->style & OC_WINDOW_STYLE_NO_FOCUS)); + return (!(mpWindow->style & OC_WINDOW_STYLE_NO_FOCUS)); } + /* - (NSDragOperation)draggingEntered:(id )sender { @@ -579,127 +591,127 @@ void oc_install_keyboard_layout_listener() @interface OCWindowDelegate : NSObject { - oc_window_data* mpWindow; + oc_window_data* mpWindow; } -- (id)initWithWindowData:(oc_window_data*) window; +- (id)initWithWindowData:(oc_window_data*)window; @end @implementation OCWindowDelegate -- (id)initWithWindowData:(oc_window_data*) window +- (id)initWithWindowData:(oc_window_data*)window { - self = [super init]; - if(self != nil) - { - mpWindow = window; - } - return(self); + self = [super init]; + if(self != nil) + { + mpWindow = window; + } + return (self); } - (void)windowDidBecomeKey:(NSNotification*)notification { - oc_event event = {}; - event.window = oc_window_handle_from_ptr(mpWindow); - event.type = OC_EVENT_WINDOW_FOCUS; + oc_event event = {}; + event.window = oc_window_handle_from_ptr(mpWindow); + event.type = OC_EVENT_WINDOW_FOCUS; - mpWindow->hidden = false; + mpWindow->hidden = false; - oc_queue_event(&event); + oc_queue_event(&event); } - (void)windowDidResignKey:(NSNotification*)notification { - oc_event event = {}; - event.window = oc_window_handle_from_ptr(mpWindow); - event.type = OC_EVENT_WINDOW_UNFOCUS; + oc_event event = {}; + event.window = oc_window_handle_from_ptr(mpWindow); + event.type = OC_EVENT_WINDOW_UNFOCUS; - oc_queue_event(&event); + oc_queue_event(&event); } -- (void)windowDidMove:(NSNotification *)notification +- (void)windowDidMove:(NSNotification*)notification { - const NSRect contentRect = [[mpWindow->osx.nsWindow contentView] frame]; - const NSRect frameRect = [mpWindow->osx.nsWindow frame]; - NSScreen* screen = mpWindow->osx.nsWindow.screen; + const NSRect contentRect = [[mpWindow->osx.nsWindow contentView] frame]; + const NSRect frameRect = [mpWindow->osx.nsWindow frame]; + NSScreen* screen = mpWindow->osx.nsWindow.screen; - oc_event event = {}; - event.window = oc_window_handle_from_ptr(mpWindow); - event.type = OC_EVENT_WINDOW_MOVE; + oc_event event = {}; + event.window = oc_window_handle_from_ptr(mpWindow); + event.type = OC_EVENT_WINDOW_MOVE; - event.move.frame.x = frameRect.origin.x; - event.move.frame.y = screen.frame.size.height - frameRect.origin.y - frameRect.size.height; - event.move.frame.w = frameRect.size.width; - event.move.frame.h = frameRect.size.height; + event.move.frame.x = frameRect.origin.x; + event.move.frame.y = screen.frame.size.height - frameRect.origin.y - frameRect.size.height; + event.move.frame.w = frameRect.size.width; + event.move.frame.h = frameRect.size.height; - event.move.content.x = frameRect.origin.x + contentRect.origin.x; - event.move.content.y = screen.frame.size.height - frameRect.origin.y - contentRect.origin.y - contentRect.size.height; - event.move.content.w = contentRect.size.width; - event.move.content.h = contentRect.size.height; + event.move.content.x = frameRect.origin.x + contentRect.origin.x; + event.move.content.y = screen.frame.size.height - frameRect.origin.y - contentRect.origin.y - contentRect.size.height; + event.move.content.w = contentRect.size.width; + event.move.content.h = contentRect.size.height; - oc_queue_event(&event); + oc_queue_event(&event); } -- (void)windowDidResize:(NSNotification *)notification +- (void)windowDidResize:(NSNotification*)notification { - const NSRect contentRect = [[mpWindow->osx.nsWindow contentView] frame]; - const NSRect frameRect = [mpWindow->osx.nsWindow frame]; - NSScreen* screen = mpWindow->osx.nsWindow.screen; + const NSRect contentRect = [[mpWindow->osx.nsWindow contentView] frame]; + const NSRect frameRect = [mpWindow->osx.nsWindow frame]; + NSScreen* screen = mpWindow->osx.nsWindow.screen; - oc_event event = {}; - event.window = oc_window_handle_from_ptr(mpWindow); - event.type = OC_EVENT_WINDOW_RESIZE; + oc_event event = {}; + event.window = oc_window_handle_from_ptr(mpWindow); + event.type = OC_EVENT_WINDOW_RESIZE; - event.move.frame.x = frameRect.origin.x; - event.move.frame.y = screen.frame.size.height - frameRect.origin.y - frameRect.size.height; - event.move.frame.w = frameRect.size.width; - event.move.frame.h = frameRect.size.height; + event.move.frame.x = frameRect.origin.x; + event.move.frame.y = screen.frame.size.height - frameRect.origin.y - frameRect.size.height; + event.move.frame.w = frameRect.size.width; + event.move.frame.h = frameRect.size.height; - event.move.content.x = frameRect.origin.x + contentRect.origin.x; - event.move.content.y = screen.frame.size.height - frameRect.origin.y - contentRect.origin.y - contentRect.size.height; - event.move.content.w = contentRect.size.width; - event.move.content.h = contentRect.size.height; + event.move.content.x = frameRect.origin.x + contentRect.origin.x; + event.move.content.y = screen.frame.size.height - frameRect.origin.y - contentRect.origin.y - contentRect.size.height; + event.move.content.w = contentRect.size.width; + event.move.content.h = contentRect.size.height; - if(oc_appData.liveResizeCallback) - { - oc_appData.liveResizeCallback(event, oc_appData.liveResizeData); - } + if(oc_appData.liveResizeCallback) + { + oc_appData.liveResizeCallback(event, oc_appData.liveResizeData); + } - //TODO: also ensure we don't overflow the queue during live resize... - oc_queue_event(&event); + //TODO: also ensure we don't overflow the queue during live resize... + oc_queue_event(&event); } --(void)windowWillStartLiveResize:(NSNotification *)notification +- (void)windowWillStartLiveResize:(NSNotification*)notification { - //TODO + //TODO } --(void)windowDidEndLiveResize:(NSNotification *)notification +- (void)windowDidEndLiveResize:(NSNotification*)notification { - //TODO + //TODO } -- (void)windowWillClose:(NSNotification *)notification +- (void)windowWillClose:(NSNotification*)notification { - mpWindow->osx.nsWindow = nil; - [mpWindow->osx.nsView release]; - mpWindow->osx.nsView = nil; - [mpWindow->osx.nsWindowDelegate release]; - mpWindow->osx.nsWindowDelegate = nil; + mpWindow->osx.nsWindow = nil; + [mpWindow->osx.nsView release]; + mpWindow->osx.nsView = nil; + [mpWindow->osx.nsWindowDelegate release]; + mpWindow->osx.nsWindowDelegate = nil; - oc_window_recycle_ptr(mpWindow); + oc_window_recycle_ptr(mpWindow); } - (BOOL)windowShouldClose:(id)sender { - mpWindow->shouldClose = true; + mpWindow->shouldClose = true; - oc_event event = {}; - event.window = oc_window_handle_from_ptr(mpWindow); - event.type = OC_EVENT_WINDOW_CLOSE; + oc_event event = {}; + event.window = oc_window_handle_from_ptr(mpWindow); + event.type = OC_EVENT_WINDOW_CLOSE; - oc_queue_event(&event); + oc_queue_event(&event); - return(mpWindow->shouldClose); + return (mpWindow->shouldClose); } @end //@implementation OCWindowDelegate @@ -710,368 +722,367 @@ void oc_install_keyboard_layout_listener() @interface OCView : NSView { - oc_window_data* window; - NSTrackingArea* trackingArea; - NSMutableAttributedString* markedText; + oc_window_data* window; + NSTrackingArea* trackingArea; + NSMutableAttributedString* markedText; } -- (id)initWithWindowData:(oc_window_data*) mpWindow; +- (id)initWithWindowData:(oc_window_data*)mpWindow; @end @implementation OCView -- (id)initWithWindowData:(oc_window_data*) mpWindow +- (id)initWithWindowData:(oc_window_data*)mpWindow { - self = [super init]; - if(self != nil) - { - window = mpWindow; - mpWindow->osx.nsView = self; - [mpWindow->osx.nsView setWantsLayer:YES]; - mpWindow->osx.nsView.layerContentsRedrawPolicy = NSViewLayerContentsRedrawDuringViewResize; + self = [super init]; + if(self != nil) + { + window = mpWindow; + mpWindow->osx.nsView = self; + [mpWindow->osx.nsView setWantsLayer:YES]; + mpWindow->osx.nsView.layerContentsRedrawPolicy = NSViewLayerContentsRedrawDuringViewResize; - NSTrackingAreaOptions trackingOptions = NSTrackingMouseEnteredAndExited - | NSTrackingMouseMoved - | NSTrackingCursorUpdate - | NSTrackingActiveInActiveApp //TODO maybe change that to allow multi-window mouse events... - | NSTrackingEnabledDuringMouseDrag - | NSTrackingInVisibleRect - | NSTrackingAssumeInside ; + NSTrackingAreaOptions trackingOptions = NSTrackingMouseEnteredAndExited + | NSTrackingMouseMoved + | NSTrackingCursorUpdate + | NSTrackingActiveInActiveApp //TODO maybe change that to allow multi-window mouse events... + | NSTrackingEnabledDuringMouseDrag + | NSTrackingInVisibleRect + | NSTrackingAssumeInside; - trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] options:trackingOptions owner:self userInfo:nil]; - [self addTrackingArea:trackingArea]; - markedText = [[NSMutableAttributedString alloc] init]; - } - return(self); + trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] options:trackingOptions owner:self userInfo:nil]; + [self addTrackingArea:trackingArea]; + markedText = [[NSMutableAttributedString alloc] init]; + } + return (self); } - (void)dealloc { - [trackingArea release]; - [markedText release]; - [super dealloc]; + [trackingArea release]; + [markedText release]; + [super dealloc]; } --(void)drawRect:(NSRect)dirtyRect +- (void)drawRect:(NSRect)dirtyRect { - if(window->style & OC_WINDOW_STYLE_NO_TITLE) - { - [NSGraphicsContext saveGraphicsState]; - NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:[self frame] xRadius:5 yRadius:5]; - [path addClip]; - [[NSColor whiteColor] set]; - NSRectFill([self frame]); - } + if(window->style & OC_WINDOW_STYLE_NO_TITLE) + { + [NSGraphicsContext saveGraphicsState]; + NSBezierPath* path = [NSBezierPath bezierPathWithRoundedRect:[self frame] xRadius:5 yRadius:5]; + [path addClip]; + [[NSColor whiteColor] set]; + NSRectFill([self frame]); + } - if(window->style & OC_WINDOW_STYLE_NO_TITLE) - { - [NSGraphicsContext restoreGraphicsState]; - [window->osx.nsWindow invalidateShadow]; - } + if(window->style & OC_WINDOW_STYLE_NO_TITLE) + { + [NSGraphicsContext restoreGraphicsState]; + [window->osx.nsWindow invalidateShadow]; + } } - (BOOL)acceptsFirstReponder { - return(YES); + return (YES); } - (void)cursorUpdate:(NSEvent*)event { - if(oc_appData.osx.cursor) - { - [oc_appData.osx.cursor set]; - } - else - { - [[NSCursor arrowCursor] set]; - } + if(oc_appData.osx.cursor) + { + [oc_appData.osx.cursor set]; + } + else + { + [[NSCursor arrowCursor] set]; + } } static void oc_process_mouse_button(NSEvent* nsEvent, oc_window_data* window, oc_mouse_button button, oc_key_action action) { - oc_event event = {}; - event.window = oc_window_handle_from_ptr(window); - event.type = OC_EVENT_MOUSE_BUTTON; - event.key.action = action; - event.key.code = button; - event.key.mods = oc_convert_osx_mods([nsEvent modifierFlags]); - event.key.clickCount = [nsEvent clickCount]; + oc_event event = {}; + event.window = oc_window_handle_from_ptr(window); + event.type = OC_EVENT_MOUSE_BUTTON; + event.key.action = action; + event.key.code = button; + event.key.mods = oc_convert_osx_mods([nsEvent modifierFlags]); + event.key.clickCount = [nsEvent clickCount]; - oc_queue_event(&event); + oc_queue_event(&event); } -- (void)mouseDown:(NSEvent *)nsEvent +- (void)mouseDown:(NSEvent*)nsEvent { - oc_process_mouse_button(nsEvent, window, OC_MOUSE_LEFT, OC_KEY_PRESS); - [window->osx.nsWindow makeFirstResponder:self]; + oc_process_mouse_button(nsEvent, window, OC_MOUSE_LEFT, OC_KEY_PRESS); + [window->osx.nsWindow makeFirstResponder:self]; } - (void)mouseUp:(NSEvent*)nsEvent { - oc_process_mouse_button(nsEvent, window, OC_MOUSE_LEFT, OC_KEY_RELEASE); + oc_process_mouse_button(nsEvent, window, OC_MOUSE_LEFT, OC_KEY_RELEASE); } - (void)rightMouseDown:(NSEvent*)nsEvent { - oc_process_mouse_button(nsEvent, window, OC_MOUSE_RIGHT, OC_KEY_PRESS); + oc_process_mouse_button(nsEvent, window, OC_MOUSE_RIGHT, OC_KEY_PRESS); } - (void)rightMouseUp:(NSEvent*)nsEvent { - oc_process_mouse_button(nsEvent, window, OC_MOUSE_RIGHT, OC_KEY_RELEASE); + oc_process_mouse_button(nsEvent, window, OC_MOUSE_RIGHT, OC_KEY_RELEASE); } - (void)otherMouseDown:(NSEvent*)nsEvent { - oc_process_mouse_button(nsEvent, window, [nsEvent buttonNumber], OC_KEY_PRESS); + oc_process_mouse_button(nsEvent, window, [nsEvent buttonNumber], OC_KEY_PRESS); } - (void)otherMouseUp:(NSEvent*)nsEvent { - oc_process_mouse_button(nsEvent, window, [nsEvent buttonNumber], OC_KEY_RELEASE); + oc_process_mouse_button(nsEvent, window, [nsEvent buttonNumber], OC_KEY_RELEASE); } - (void)mouseDragged:(NSEvent*)nsEvent { - [self mouseMoved:nsEvent]; + [self mouseMoved:nsEvent]; } - (void)mouseMoved:(NSEvent*)nsEvent { - NSPoint p = [self convertPoint:[nsEvent locationInWindow] fromView:nil]; + NSPoint p = [self convertPoint:[nsEvent locationInWindow] fromView:nil]; - NSRect frame = [[window->osx.nsWindow contentView] frame]; - oc_event event = {}; - event.type = OC_EVENT_MOUSE_MOVE; - event.window = oc_window_handle_from_ptr(window); - event.mouse.x = p.x; - event.mouse.y = frame.size.height - p.y; - event.mouse.deltaX = [nsEvent deltaX]; - event.mouse.deltaY = [nsEvent deltaY]; - event.mouse.mods = oc_convert_osx_mods([nsEvent modifierFlags]); + NSRect frame = [[window->osx.nsWindow contentView] frame]; + oc_event event = {}; + event.type = OC_EVENT_MOUSE_MOVE; + event.window = oc_window_handle_from_ptr(window); + event.mouse.x = p.x; + event.mouse.y = frame.size.height - p.y; + event.mouse.deltaX = [nsEvent deltaX]; + event.mouse.deltaY = [nsEvent deltaY]; + event.mouse.mods = oc_convert_osx_mods([nsEvent modifierFlags]); - oc_queue_event(&event); + oc_queue_event(&event); } - (void)scrollWheel:(NSEvent*)nsEvent { - oc_event event = {}; - event.window = oc_window_handle_from_ptr(window); - event.type = OC_EVENT_MOUSE_WHEEL; + oc_event event = {}; + event.window = oc_window_handle_from_ptr(window); + event.type = OC_EVENT_MOUSE_WHEEL; - double factor = [nsEvent hasPreciseScrollingDeltas] ? 0.1 : 1.0; - event.mouse.x = 0; - event.mouse.y = 0; - event.mouse.deltaX = -[nsEvent scrollingDeltaX]*factor; - event.mouse.deltaY = -[nsEvent scrollingDeltaY]*factor; - event.mouse.mods = oc_convert_osx_mods([nsEvent modifierFlags]); + double factor = [nsEvent hasPreciseScrollingDeltas] ? 0.1 : 1.0; + event.mouse.x = 0; + event.mouse.y = 0; + event.mouse.deltaX = -[nsEvent scrollingDeltaX] * factor; + event.mouse.deltaY = -[nsEvent scrollingDeltaY] * factor; + event.mouse.mods = oc_convert_osx_mods([nsEvent modifierFlags]); - oc_queue_event(&event); + oc_queue_event(&event); } -- (void)mouseExited:(NSEvent *)nsEvent +- (void)mouseExited:(NSEvent*)nsEvent { - oc_event event = {}; - event.window = oc_window_handle_from_ptr(window); - event.type = OC_EVENT_MOUSE_LEAVE; - oc_queue_event(&event); + oc_event event = {}; + event.window = oc_window_handle_from_ptr(window); + event.type = OC_EVENT_MOUSE_LEAVE; + oc_queue_event(&event); } -- (void)mouseEntered:(NSEvent *)nsEvent +- (void)mouseEntered:(NSEvent*)nsEvent { - oc_event event = {}; - event.window = oc_window_handle_from_ptr(window); - event.type = OC_EVENT_MOUSE_ENTER; - oc_queue_event(&event); + oc_event event = {}; + event.window = oc_window_handle_from_ptr(window); + event.type = OC_EVENT_MOUSE_ENTER; + oc_queue_event(&event); } - (void)keyDown:(NSEvent*)nsEvent { - oc_key_action action = [nsEvent isARepeat] ? OC_KEY_REPEAT : OC_KEY_PRESS; + oc_key_action action = [nsEvent isARepeat] ? OC_KEY_REPEAT : OC_KEY_PRESS; - oc_event event = {}; - event.window = oc_window_handle_from_ptr(window); - event.type = OC_EVENT_KEYBOARD_KEY; - event.key.action = action; - event.key.code = oc_convert_osx_key([nsEvent keyCode]); - event.key.mods = oc_convert_osx_mods([nsEvent modifierFlags]); + oc_event event = {}; + event.window = oc_window_handle_from_ptr(window); + event.type = OC_EVENT_KEYBOARD_KEY; + event.key.action = action; + event.key.code = oc_convert_osx_key([nsEvent keyCode]); + event.key.mods = oc_convert_osx_mods([nsEvent modifierFlags]); - oc_str8 label = oc_key_to_label(event.key.code); - event.key.labelLen = label.len; - memcpy(event.key.label, label.ptr, label.len); + oc_str8 label = oc_key_to_label(event.key.code); + event.key.labelLen = label.len; + memcpy(event.key.label, label.ptr, label.len); - oc_queue_event(&event); + oc_queue_event(&event); - [self interpretKeyEvents:@[nsEvent]]; + [self interpretKeyEvents:@[ nsEvent ]]; } - (void)keyUp:(NSEvent*)nsEvent { - oc_event event = {}; - event.window = oc_window_handle_from_ptr(window); - event.type = OC_EVENT_KEYBOARD_KEY; - event.key.action = OC_KEY_RELEASE; - event.key.code = oc_convert_osx_key([nsEvent keyCode]); - event.key.mods = oc_convert_osx_mods([nsEvent modifierFlags]); + oc_event event = {}; + event.window = oc_window_handle_from_ptr(window); + event.type = OC_EVENT_KEYBOARD_KEY; + event.key.action = OC_KEY_RELEASE; + event.key.code = oc_convert_osx_key([nsEvent keyCode]); + event.key.mods = oc_convert_osx_mods([nsEvent modifierFlags]); - oc_queue_event(&event); + oc_queue_event(&event); } -- (void) flagsChanged:(NSEvent*)nsEvent +- (void)flagsChanged:(NSEvent*)nsEvent { - oc_event event = {}; - event.window = oc_window_handle_from_ptr(window); - event.type = OC_EVENT_KEYBOARD_MODS; - event.key.mods = oc_convert_osx_mods([nsEvent modifierFlags]); + oc_event event = {}; + event.window = oc_window_handle_from_ptr(window); + event.type = OC_EVENT_KEYBOARD_MODS; + event.key.mods = oc_convert_osx_mods([nsEvent modifierFlags]); - oc_queue_event(&event); + oc_queue_event(&event); } - (BOOL)performKeyEquivalent:(NSEvent*)nsEvent { - if([nsEvent modifierFlags] & NSEventModifierFlagCommand) - { - if([nsEvent charactersIgnoringModifiers] == [NSString stringWithUTF8String:"w"]) - { - [window->osx.nsWindow performClose:self]; - return(YES); - } - else if([nsEvent charactersIgnoringModifiers] == [NSString stringWithUTF8String:"q"]) - { - oc_appData.shouldQuit = true; + if([nsEvent modifierFlags] & NSEventModifierFlagCommand) + { + if([nsEvent charactersIgnoringModifiers] == [NSString stringWithUTF8String:"w"]) + { + [window->osx.nsWindow performClose:self]; + return (YES); + } + else if([nsEvent charactersIgnoringModifiers] == [NSString stringWithUTF8String:"q"]) + { + oc_appData.shouldQuit = true; - oc_event event = {}; - event.type = OC_EVENT_QUIT; + oc_event event = {}; + event.type = OC_EVENT_QUIT; - oc_queue_event(&event); + oc_queue_event(&event); - //[NSApp terminate:self]; - return(YES); - } - } + //[NSApp terminate:self]; + return (YES); + } + } - return([super performKeyEquivalent:nsEvent]); + return ([super performKeyEquivalent:nsEvent]); } - (BOOL)hasMarkedText { - return([markedText length] > 0); + return ([markedText length] > 0); } static const NSRange kEmptyRange = { NSNotFound, 0 }; - (NSRange)markedRange { - if([markedText length] > 0) - { - return(NSMakeRange(0, [markedText length] - 1)); - } - else - { - return(kEmptyRange); - } + if([markedText length] > 0) + { + return (NSMakeRange(0, [markedText length] - 1)); + } + else + { + return (kEmptyRange); + } } - (NSRange)selectedRange { - return(kEmptyRange); + return (kEmptyRange); } - (void)setMarkedText:(id)string selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange { - [markedText release]; + [markedText release]; - if([string isKindOfClass:[NSAttributedString class]]) - { - markedText = [[NSMutableAttributedString alloc] initWithAttributedString:string]; - } - else - { - markedText = [[NSMutableAttributedString alloc] initWithString:string]; - } + if([string isKindOfClass:[NSAttributedString class]]) + { + markedText = [[NSMutableAttributedString alloc] initWithAttributedString:string]; + } + else + { + markedText = [[NSMutableAttributedString alloc] initWithString:string]; + } } - (void)unmarkText { - [[markedText mutableString] setString:@""]; + [[markedText mutableString] setString:@""]; } - (NSArray*)validAttributesForMarkedText { - return([NSArray array]); + return ([NSArray array]); } - (NSAttributedString*)attributedSubstringForProposedRange:(NSRange)range actualRange:(NSRangePointer)actualRange { - return(nil); + return (nil); } - (NSUInteger)characterIndexForPoint:(NSPoint)point { - return(0); + return (0); } - (NSRect)firstRectForCharacterRange:(NSRange)range actualRange:(NSRangePointer)actualRange { - NSRect frame = [window->osx.nsView frame]; - return(NSMakeRect(frame.origin.x, frame.origin.y, 0.0, 0.0)); + NSRect frame = [window->osx.nsView frame]; + return (NSMakeRect(frame.origin.x, frame.origin.y, 0.0, 0.0)); } - (void)insertText:(id)string replacementRange:(NSRange)replacementRange { - NSString* characters; - NSEvent* nsEvent = [NSApp currentEvent]; - oc_keymod_flags mods = oc_convert_osx_mods([nsEvent modifierFlags]); + NSString* characters; + NSEvent* nsEvent = [NSApp currentEvent]; + oc_keymod_flags mods = oc_convert_osx_mods([nsEvent modifierFlags]); - if([string isKindOfClass:[NSAttributedString class]]) - { - characters = [string string]; - } - else - { - characters = (NSString*) string; - } + if([string isKindOfClass:[NSAttributedString class]]) + { + characters = [string string]; + } + else + { + characters = (NSString*)string; + } - NSRange range = NSMakeRange(0, [characters length]); - while (range.length) - { - oc_utf32 codepoint = 0; + NSRange range = NSMakeRange(0, [characters length]); + while(range.length) + { + oc_utf32 codepoint = 0; - if ([characters getBytes:&codepoint - maxLength:sizeof(codepoint) - usedLength:NULL - encoding:NSUTF32StringEncoding - options:0 - range:range - remainingRange:&range]) - { - if(codepoint >= 0xf700 && codepoint <= 0xf7ff) - { - continue; - } + if([characters getBytes:&codepoint + maxLength:sizeof(codepoint) + usedLength:NULL + encoding:NSUTF32StringEncoding + options:0 + range:range + remainingRange:&range]) + { + if(codepoint >= 0xf700 && codepoint <= 0xf7ff) + { + continue; + } - oc_event event = {}; - event.window = oc_window_handle_from_ptr(window); - event.type = OC_EVENT_KEYBOARD_CHAR; - event.character.codepoint = codepoint; + oc_event event = {}; + event.window = oc_window_handle_from_ptr(window); + event.type = OC_EVENT_KEYBOARD_CHAR; + event.character.codepoint = codepoint; - oc_str8 seq = oc_utf8_encode(event.character.sequence, event.character.codepoint); - event.character.seqLen = seq.len; + oc_str8 seq = oc_utf8_encode(event.character.sequence, event.character.codepoint); + event.character.seqLen = seq.len; - oc_queue_event(&event); - } - } - [self unmarkText]; + oc_queue_event(&event); + } + } + [self unmarkText]; } - (void)doCommandBySelector:(SEL)selector { } - @end //@implementation OCView //*************************************************************** @@ -1083,468 +1094,525 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; //--------------------------------------------------------------- void oc_init() -{@autoreleasepool { - if(!oc_appData.init) - { - memset(&oc_appData, 0, sizeof(oc_appData)); +{ + @autoreleasepool + { + if(!oc_appData.init) + { + memset(&oc_appData, 0, sizeof(oc_appData)); - oc_arena_init(&oc_appData.eventArena); + oc_arena_init(&oc_appData.eventArena); - oc_clock_init(); + oc_clock_init(); - oc_init_osx_keys(); - oc_update_keyboard_layout(); - oc_install_keyboard_layout_listener(); + oc_init_osx_keys(); + oc_update_keyboard_layout(); + oc_install_keyboard_layout_listener(); - oc_init_window_handles(); + oc_init_window_handles(); - oc_ringbuffer_init(&oc_appData.eventQueue, 16); + oc_ringbuffer_init(&oc_appData.eventQueue, 16); - [OCApplication sharedApplication]; - OCAppDelegate* delegate = [[OCAppDelegate alloc] init]; - [NSApp setDelegate: delegate]; + [OCApplication sharedApplication]; + OCAppDelegate* delegate = [[OCAppDelegate alloc] init]; + [NSApp setDelegate:delegate]; - [NSThread detachNewThreadSelector:@selector(noOpThread:) - toTarget:NSApp - withObject:nil]; + [NSThread detachNewThreadSelector:@selector(noOpThread:) + toTarget:NSApp + withObject:nil]; - oc_appData.init = true; + oc_appData.init = true; - [NSApp run]; - [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - [NSApp activateIgnoringOtherApps:YES]; - - } -}} + [NSApp run]; + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + [NSApp activateIgnoringOtherApps:YES]; + } + } +} void oc_terminate() { - //TODO: proper app data cleanup (eg delegate, etc) - if(oc_appData.init) - { - oc_arena_cleanup(&oc_appData.eventArena); - oc_appData = (oc_app){0}; - } + //TODO: proper app data cleanup (eg delegate, etc) + if(oc_appData.init) + { + oc_arena_cleanup(&oc_appData.eventArena); + oc_appData = (oc_app){ 0 }; + } } bool oc_should_quit() { - return(oc_appData.shouldQuit); + return (oc_appData.shouldQuit); } void oc_do_quit() { - oc_appData.shouldQuit = true; + oc_appData.shouldQuit = true; } void oc_cancel_quit() { - oc_appData.shouldQuit = false; + oc_appData.shouldQuit = false; } void oc_request_quit() { - oc_appData.shouldQuit = true; - oc_event event = {}; - event.type = OC_EVENT_QUIT; - oc_queue_event(&event); + oc_appData.shouldQuit = true; + oc_event event = {}; + event.type = OC_EVENT_QUIT; + oc_queue_event(&event); } void oc_set_cursor(oc_mouse_cursor cursor) { - switch(cursor) - { - case OC_MOUSE_CURSOR_ARROW: - { - oc_appData.osx.cursor = [NSCursor arrowCursor]; - } break; - case OC_MOUSE_CURSOR_RESIZE_0: - { - oc_appData.osx.cursor = [[NSCursor class] performSelector:@selector(_windowResizeEastWestCursor)]; - } break; - case OC_MOUSE_CURSOR_RESIZE_90: - { - oc_appData.osx.cursor = [[NSCursor class] performSelector:@selector(_windowResizeNorthSouthCursor)]; - } break; - case OC_MOUSE_CURSOR_RESIZE_45: - { - oc_appData.osx.cursor = [[NSCursor class] performSelector:@selector(_windowResizeNorthEastSouthWestCursor)]; - } break; - case OC_MOUSE_CURSOR_RESIZE_135: - { - oc_appData.osx.cursor = [[NSCursor class] performSelector:@selector(_windowResizeNorthWestSouthEastCursor)]; - } break; - case OC_MOUSE_CURSOR_TEXT: - { - oc_appData.osx.cursor = [NSCursor IBeamCursor]; - } break; - } - [oc_appData.osx.cursor set]; + switch(cursor) + { + case OC_MOUSE_CURSOR_ARROW: + { + oc_appData.osx.cursor = [NSCursor arrowCursor]; + } + break; + case OC_MOUSE_CURSOR_RESIZE_0: + { + oc_appData.osx.cursor = [[NSCursor class] performSelector:@selector(_windowResizeEastWestCursor)]; + } + break; + case OC_MOUSE_CURSOR_RESIZE_90: + { + oc_appData.osx.cursor = [[NSCursor class] performSelector:@selector(_windowResizeNorthSouthCursor)]; + } + break; + case OC_MOUSE_CURSOR_RESIZE_45: + { + oc_appData.osx.cursor = [[NSCursor class] performSelector:@selector(_windowResizeNorthEastSouthWestCursor)]; + } + break; + case OC_MOUSE_CURSOR_RESIZE_135: + { + oc_appData.osx.cursor = [[NSCursor class] performSelector:@selector(_windowResizeNorthWestSouthEastCursor)]; + } + break; + case OC_MOUSE_CURSOR_TEXT: + { + oc_appData.osx.cursor = [NSCursor IBeamCursor]; + } + break; + } + [oc_appData.osx.cursor set]; } void oc_clipboard_clear() -{@autoreleasepool{ - NSPasteboard* pb = [NSPasteboard generalPasteboard]; - [pb clearContents]; -}} +{ + @autoreleasepool + { + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + [pb clearContents]; + } +} void oc_clipboard_set_string(oc_str8 string) -{@autoreleasepool{ +{ + @autoreleasepool + { - NSString* nsString = [[NSString alloc] initWithBytes:string.ptr length:string.len encoding:NSUTF8StringEncoding]; - NSPasteboard* pb = [NSPasteboard generalPasteboard]; - [pb writeObjects:[[NSArray alloc] initWithObjects:nsString, nil]]; -}} + NSString* nsString = [[NSString alloc] initWithBytes:string.ptr length:string.len encoding:NSUTF8StringEncoding]; + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + [pb writeObjects:[[NSArray alloc] initWithObjects:nsString, nil]]; + } +} oc_str8 oc_clipboard_copy_string(oc_str8 backing) -{@autoreleasepool{ - //WARN(martin): maxSize includes space for a null terminator +{ + @autoreleasepool + { + //WARN(martin): maxSize includes space for a null terminator - NSPasteboard* pb = [NSPasteboard generalPasteboard]; - NSString* nsString = [pb stringForType:NSPasteboardTypeString]; - const char* cString = [nsString UTF8String]; - u32 len = oc_min(backing.len-1, strlen(cString)); //length without null terminator - strncpy(backing.ptr, cString, backing.len-1); - backing.ptr[len] = '\0'; + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + NSString* nsString = [pb stringForType:NSPasteboardTypeString]; + const char* cString = [nsString UTF8String]; + u32 len = oc_min(backing.len - 1, strlen(cString)); //length without null terminator + strncpy(backing.ptr, cString, backing.len - 1); + backing.ptr[len] = '\0'; - oc_str8 result = oc_str8_slice(backing, 0, len); - return(result); -}} + oc_str8 result = oc_str8_slice(backing, 0, len); + return (result); + } +} oc_str8 oc_clipboard_get_string(oc_arena* arena) -{@autoreleasepool{ - //WARN(martin): maxSize includes space for a null terminator +{ + @autoreleasepool + { + //WARN(martin): maxSize includes space for a null terminator - NSPasteboard* pb = [NSPasteboard generalPasteboard]; - NSString* nsString = [pb stringForType:NSPasteboardTypeString]; - const char* cString = [nsString UTF8String]; - oc_str8 result = oc_str8_push_cstring(arena, cString); - return(result); -}} + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + NSString* nsString = [pb stringForType:NSPasteboardTypeString]; + const char* cString = [nsString UTF8String]; + oc_str8 result = oc_str8_push_cstring(arena, cString); + return (result); + } +} bool oc_clipboard_has_tag(const char* tag) -{@autoreleasepool{ +{ + @autoreleasepool + { - NSString* tagString = [[NSString alloc] initWithUTF8String: tag]; - NSArray* tagArray = [NSArray arrayWithObjects: tagString, nil]; + NSString* tagString = [[NSString alloc] initWithUTF8String:tag]; + NSArray* tagArray = [NSArray arrayWithObjects:tagString, nil]; - NSPasteboard* pb = [NSPasteboard generalPasteboard]; - NSString* available = [pb availableTypeFromArray: tagArray]; + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + NSString* available = [pb availableTypeFromArray:tagArray]; - return(available != nil); -}} + return (available != nil); + } +} void oc_clipboard_set_data_for_tag(const char* tag, oc_str8 string) -{@autoreleasepool{ +{ + @autoreleasepool + { - NSString* tagString = [[NSString alloc] initWithUTF8String: tag]; - NSArray* tagArray = [NSArray arrayWithObjects: tagString, nil]; - NSData* nsData = [NSData dataWithBytes:string.ptr length:string.len]; + NSString* tagString = [[NSString alloc] initWithUTF8String:tag]; + NSArray* tagArray = [NSArray arrayWithObjects:tagString, nil]; + NSData* nsData = [NSData dataWithBytes:string.ptr length:string.len]; - NSPasteboard* pb = [NSPasteboard generalPasteboard]; - [pb addTypes: tagArray owner:nil]; - [pb setData: nsData forType: tagString]; -}} + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + [pb addTypes:tagArray owner:nil]; + [pb setData:nsData forType:tagString]; + } +} oc_str8 oc_clipboard_get_data_for_tag(oc_arena* arena, const char* tag) -{@autoreleasepool{ +{ + @autoreleasepool + { - NSString* tagString = [[NSString alloc] initWithUTF8String: tag]; - - NSPasteboard* pb = [NSPasteboard generalPasteboard]; - NSData* nsData = [pb dataForType: tagString]; - oc_str8 result = oc_str8_push_buffer(arena, [nsData length], (char*)[nsData bytes]); - return(result); -}} + NSString* tagString = [[NSString alloc] initWithUTF8String:tag]; + NSPasteboard* pb = [NSPasteboard generalPasteboard]; + NSData* nsData = [pb dataForType:tagString]; + oc_str8 result = oc_str8_push_buffer(arena, [nsData length], (char*)[nsData bytes]); + return (result); + } +} //--------------------------------------------------------------- // Window public API //--------------------------------------------------------------- oc_window oc_window_create(oc_rect contentRect, oc_str8 title, oc_window_style style) -{@autoreleasepool{ - oc_window_data* window = oc_window_alloc(); - if(!window) - { - oc_log_error("Could not allocate window data\n"); - return((oc_window){0}); - } +{ + @autoreleasepool + { + oc_window_data* window = oc_window_alloc(); + if(!window) + { + oc_log_error("Could not allocate window data\n"); + return ((oc_window){ 0 }); + } - window->style = style; - window->shouldClose = false; - window->hidden = true; + window->style = style; + window->shouldClose = false; + window->hidden = true; - u32 styleMask = oc_osx_get_window_style_mask(style); + u32 styleMask = oc_osx_get_window_style_mask(style); - NSRect screenRect = [[NSScreen mainScreen] frame]; - NSRect rect = NSMakeRect(contentRect.x, - screenRect.size.height - contentRect.y - contentRect.h, - contentRect.w, - contentRect.h); + NSRect screenRect = [[NSScreen mainScreen] frame]; + NSRect rect = NSMakeRect(contentRect.x, + screenRect.size.height - contentRect.y - contentRect.h, + contentRect.w, + contentRect.h); - window->osx.nsWindow = [[OCWindow alloc] initWithWindowData: window contentRect:rect styleMask:styleMask]; - window->osx.nsWindowDelegate = [[OCWindowDelegate alloc] initWithWindowData:window]; + window->osx.nsWindow = [[OCWindow alloc] initWithWindowData:window contentRect:rect styleMask:styleMask]; + window->osx.nsWindowDelegate = [[OCWindowDelegate alloc] initWithWindowData:window]; - [window->osx.nsWindow setDelegate:(id)window->osx.nsWindowDelegate]; + [window->osx.nsWindow setDelegate:(id)window->osx.nsWindowDelegate]; + [window->osx.nsWindow setTitle:[[NSString alloc] initWithBytes:(void*)title.ptr length:title.len encoding:NSUTF8StringEncoding]]; + if(style & OC_WINDOW_STYLE_NO_TITLE) + { + [window->osx.nsWindow setOpaque:NO]; + [window->osx.nsWindow setBackgroundColor:[NSColor clearColor]]; + [window->osx.nsWindow setHasShadow:YES]; + } + if(style & OC_WINDOW_STYLE_FLOAT) + { + [window->osx.nsWindow setLevel:NSFloatingWindowLevel]; + [window->osx.nsWindow setHidesOnDeactivate:YES]; + } + if(style & OC_WINDOW_STYLE_NO_BUTTONS) + { + [[window->osx.nsWindow standardWindowButton:NSWindowCloseButton] setHidden:YES]; + [[window->osx.nsWindow standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES]; + [[window->osx.nsWindow standardWindowButton:NSWindowZoomButton] setHidden:YES]; + } - [window->osx.nsWindow setTitle:[[NSString alloc] initWithBytes:(void*)title.ptr length: title.len encoding: NSUTF8StringEncoding]]; + OCView* view = [[OCView alloc] initWithWindowData:window]; + [view setCanDrawConcurrently:YES]; - if(style & OC_WINDOW_STYLE_NO_TITLE) - { - [window->osx.nsWindow setOpaque:NO]; - [window->osx.nsWindow setBackgroundColor:[NSColor clearColor]]; - [window->osx.nsWindow setHasShadow:YES]; - } - if(style & OC_WINDOW_STYLE_FLOAT) - { - [window->osx.nsWindow setLevel:NSFloatingWindowLevel]; - [window->osx.nsWindow setHidesOnDeactivate:YES]; - } - if(style & OC_WINDOW_STYLE_NO_BUTTONS) - { - [[window->osx.nsWindow standardWindowButton:NSWindowCloseButton] setHidden:YES]; - [[window->osx.nsWindow standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES]; - [[window->osx.nsWindow standardWindowButton:NSWindowZoomButton] setHidden:YES]; - } + [window->osx.nsWindow setContentView:view]; + [window->osx.nsWindow makeFirstResponder:view]; + [window->osx.nsWindow setAcceptsMouseMovedEvents:YES]; - OCView* view = [[OCView alloc] initWithWindowData:window]; - [view setCanDrawConcurrently: YES]; + oc_window windowHandle = oc_window_handle_from_ptr(window); - [window->osx.nsWindow setContentView:view]; - [window->osx.nsWindow makeFirstResponder:view]; - [window->osx.nsWindow setAcceptsMouseMovedEvents:YES]; - - - oc_window windowHandle = oc_window_handle_from_ptr(window); - - return(windowHandle); -}//autoreleasepool + return (windowHandle); + } //autoreleasepool } void oc_window_destroy(oc_window window) -{@autoreleasepool{ - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - [windowData->osx.nsWindow orderOut:nil]; +{ + @autoreleasepool + { + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + [windowData->osx.nsWindow orderOut:nil]; - [windowData->osx.nsWindow setDelegate:nil]; - [windowData->osx.nsWindowDelegate release]; - windowData->osx.nsWindowDelegate = nil; + [windowData->osx.nsWindow setDelegate:nil]; + [windowData->osx.nsWindowDelegate release]; + windowData->osx.nsWindowDelegate = nil; - [windowData->osx.nsView release]; - windowData->osx.nsView = nil; + [windowData->osx.nsView release]; + windowData->osx.nsView = nil; - [windowData->osx.nsWindow close]; //also release the window + [windowData->osx.nsWindow close]; //also release the window - oc_window_recycle_ptr(windowData); - } -} // autoreleasepool + oc_window_recycle_ptr(windowData); + } + } // autoreleasepool } bool oc_window_should_close(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - return(windowData->shouldClose); - } - else - { - return(false); - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + return (windowData->shouldClose); + } + else + { + return (false); + } } void oc_window_cancel_close(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - windowData->shouldClose = false; - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + windowData->shouldClose = false; + } } void oc_window_request_close(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - [windowData->osx.nsWindow close]; - //NOTE(martin): this will call our window delegate willClose method - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + [windowData->osx.nsWindow close]; + //NOTE(martin): this will call our window delegate willClose method + } } void* oc_window_native_pointer(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - return((__bridge void*)windowData->osx.nsWindow); - } - else - { - return(0); - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + return ((__bridge void*)windowData->osx.nsWindow); + } + else + { + return (0); + } } void oc_window_center(oc_window window) -{@autoreleasepool{ - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - [windowData->osx.nsWindow center]; - } -}} +{ + @autoreleasepool + { + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + [windowData->osx.nsWindow center]; + } + } +} bool oc_window_is_hidden(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - return(windowData->hidden); - } - else - { - return(false); - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + return (windowData->hidden); + } + else + { + return (false); + } } bool oc_window_is_focused(oc_window window) -{@autoreleasepool{ - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - return([windowData->osx.nsWindow isKeyWindow]); - } - else - { - return(false); - } -}} +{ + @autoreleasepool + { + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + return ([windowData->osx.nsWindow isKeyWindow]); + } + else + { + return (false); + } + } +} void oc_window_hide(oc_window window) -{@autoreleasepool{ - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - windowData->hidden = true; - [windowData->osx.nsWindow orderOut:nil]; - } -}} +{ + @autoreleasepool + { + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + windowData->hidden = true; + [windowData->osx.nsWindow orderOut:nil]; + } + } +} void oc_window_focus(oc_window window) -{@autoreleasepool{ - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - [windowData->osx.nsWindow makeKeyWindow]; - } -}} +{ + @autoreleasepool + { + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + [windowData->osx.nsWindow makeKeyWindow]; + } + } +} void oc_window_send_to_back(oc_window window) -{@autoreleasepool{ - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - [windowData->osx.nsWindow orderBack:nil]; - } -}} +{ + @autoreleasepool + { + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + [windowData->osx.nsWindow orderBack:nil]; + } + } +} void oc_window_bring_to_front(oc_window window) -{@autoreleasepool{ - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - windowData->hidden = false; - [windowData->osx.nsWindow orderFront:nil]; - } -}} +{ + @autoreleasepool + { + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + windowData->hidden = false; + [windowData->osx.nsWindow orderFront:nil]; + } + } +} void oc_window_bring_to_front_and_focus(oc_window window) { - oc_window_bring_to_front(window); - oc_window_focus(window); + oc_window_bring_to_front(window); + oc_window_focus(window); } oc_rect oc_window_get_frame_rect(oc_window window) { - oc_rect rect = {0}; - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - NSRect frameRect = windowData->osx.nsWindow.frame; - NSScreen* screen = windowData->osx.nsWindow.screen; + oc_rect rect = { 0 }; + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + NSRect frameRect = windowData->osx.nsWindow.frame; + NSScreen* screen = windowData->osx.nsWindow.screen; - rect = (oc_rect){ - frameRect.origin.x, - screen.frame.size.height - frameRect.origin.y - frameRect.size.height, - frameRect.size.width, - frameRect.size.height - }; - } - return(rect); + rect = (oc_rect){ + frameRect.origin.x, + screen.frame.size.height - frameRect.origin.y - frameRect.size.height, + frameRect.size.width, + frameRect.size.height + }; + } + return (rect); } void oc_window_set_frame_rect(oc_window window, oc_rect rect) -{@autoreleasepool{ - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - NSScreen* screen = windowData->osx.nsWindow.screen; - NSRect frameRect = { - rect.x, - screen.frame.size.height - rect.y - rect.h, - rect.w, - rect.h - }; - [windowData->osx.nsWindow setFrame:frameRect display:YES]; - } -}} +{ + @autoreleasepool + { + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + NSScreen* screen = windowData->osx.nsWindow.screen; + NSRect frameRect = { + rect.x, + screen.frame.size.height - rect.y - rect.h, + rect.w, + rect.h + }; + [windowData->osx.nsWindow setFrame:frameRect display:YES]; + } + } +} oc_rect oc_window_get_content_rect(oc_window window) -{@autoreleasepool{ - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - NSScreen* screen = [windowData->osx.nsWindow screen]; - NSView* view = [windowData->osx.nsWindow contentView]; - NSRect contentRect = [windowData->osx.nsWindow convertRectToScreen: view.frame]; +{ + @autoreleasepool + { + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + NSScreen* screen = [windowData->osx.nsWindow screen]; + NSView* view = [windowData->osx.nsWindow contentView]; + NSRect contentRect = [windowData->osx.nsWindow convertRectToScreen:view.frame]; - oc_rect rect = { - contentRect.origin.x, - screen.frame.size.height - contentRect.origin.y - contentRect.size.height, - contentRect.size.width, - contentRect.size.height}; + oc_rect rect = { + contentRect.origin.x, + screen.frame.size.height - contentRect.origin.y - contentRect.size.height, + contentRect.size.width, + contentRect.size.height + }; - return(rect); - } - else - { - return((oc_rect){}); - } -}} + return (rect); + } + else + { + return ((oc_rect){}); + } + } +} void oc_window_set_content_rect(oc_window window, oc_rect rect) -{@autoreleasepool{ +{ + @autoreleasepool + { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - NSScreen* screen = [windowData->osx.nsWindow screen]; - NSRect contentRect = { - rect.x, - screen.frame.size.height - rect.y - rect.h, - rect.w, - rect.h - }; + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + NSScreen* screen = [windowData->osx.nsWindow screen]; + NSRect contentRect = { + rect.x, + screen.frame.size.height - rect.y - rect.h, + rect.w, + rect.h + }; - NSRect frameRect = [windowData->osx.nsWindow frameRectForContentRect: contentRect]; - [windowData->osx.nsWindow setFrame:frameRect display:YES]; - } -}} + NSRect frameRect = [windowData->osx.nsWindow frameRectForContentRect:contentRect]; + [windowData->osx.nsWindow setFrame:frameRect display:YES]; + } + } +} //-------------------------------------------------------------------- // platform surface @@ -1552,138 +1620,165 @@ void oc_window_set_content_rect(oc_window window, oc_rect rect) void* oc_osx_surface_native_layer(oc_surface_data* surface) { - return((void*)surface->layer.caLayer); + return ((void*)surface->layer.caLayer); } oc_vec2 oc_osx_surface_contents_scaling(oc_surface_data* surface) -{@autoreleasepool{ - f32 contentsScale = [surface->layer.caLayer contentsScale]; - oc_vec2 res = {contentsScale, contentsScale}; - return(res); -}} +{ + @autoreleasepool + { + f32 contentsScale = [surface->layer.caLayer contentsScale]; + oc_vec2 res = { contentsScale, contentsScale }; + return (res); + } +} oc_vec2 oc_osx_surface_get_size(oc_surface_data* surface) -{@autoreleasepool{ - CGRect bounds = surface->layer.caLayer.bounds; - oc_vec2 res = {bounds.size.width, bounds.size.height}; - return(res); -}} +{ + @autoreleasepool + { + CGRect bounds = surface->layer.caLayer.bounds; + oc_vec2 res = { bounds.size.width, bounds.size.height }; + return (res); + } +} bool oc_osx_surface_get_hidden(oc_surface_data* surface) -{@autoreleasepool{ - return([surface->layer.caLayer isHidden]); -}} +{ + @autoreleasepool + { + return ([surface->layer.caLayer isHidden]); + } +} void oc_osx_surface_set_hidden(oc_surface_data* surface, bool hidden) -{@autoreleasepool{ - [CATransaction begin]; - [CATransaction setDisableActions:YES]; - [surface->layer.caLayer setHidden:hidden]; - [CATransaction commit]; -}} +{ + @autoreleasepool + { + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + [surface->layer.caLayer setHidden:hidden]; + [CATransaction commit]; + } +} void oc_surface_cleanup(oc_surface_data* surface) -{@autoreleasepool{ - [surface->layer.caLayer release]; -}} +{ + @autoreleasepool + { + [surface->layer.caLayer release]; + } +} void oc_surface_init_for_window(oc_surface_data* surface, oc_window_data* window) -{@autoreleasepool{ - surface->nativeLayer = oc_osx_surface_native_layer; - surface->contentsScaling = oc_osx_surface_contents_scaling; - surface->getSize = oc_osx_surface_get_size; - surface->getHidden = oc_osx_surface_get_hidden; - surface->setHidden = oc_osx_surface_set_hidden; +{ + @autoreleasepool + { + surface->nativeLayer = oc_osx_surface_native_layer; + surface->contentsScaling = oc_osx_surface_contents_scaling; + surface->getSize = oc_osx_surface_get_size; + surface->getHidden = oc_osx_surface_get_hidden; + surface->setHidden = oc_osx_surface_set_hidden; - surface->layer.caLayer = [[CALayer alloc] init]; - [surface->layer.caLayer retain]; + surface->layer.caLayer = [[CALayer alloc] init]; + [surface->layer.caLayer retain]; - NSRect frame = [[window->osx.nsWindow contentView] frame]; - CGSize size = frame.size; - surface->layer.caLayer.frame = (CGRect){{0, 0}, size}; - surface->layer.caLayer.contentsScale = window->osx.nsView.layer.contentsScale; + NSRect frame = [[window->osx.nsWindow contentView] frame]; + CGSize size = frame.size; + surface->layer.caLayer.frame = (CGRect){ { 0, 0 }, size }; + surface->layer.caLayer.contentsScale = window->osx.nsView.layer.contentsScale; - surface->layer.caLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; + surface->layer.caLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; - [window->osx.nsView.layer addSublayer: surface->layer.caLayer]; -}} + [window->osx.nsView.layer addSublayer:surface->layer.caLayer]; + } +} //------------------------------------------------------------------------------------------------ // Remote surfaces //------------------------------------------------------------------------------------------------ oc_surface_id oc_osx_surface_remote_id(oc_surface_data* surface) { - oc_surface_id remoteID = 0; - if(surface->layer.caContext) - { - @autoreleasepool - { - remoteID = (oc_surface_id)[surface->layer.caContext contextId]; - } - } - return(remoteID); + oc_surface_id remoteID = 0; + if(surface->layer.caContext) + { + @autoreleasepool + { + remoteID = (oc_surface_id)[surface->layer.caContext contextId]; + } + } + return (remoteID); } void oc_surface_init_remote(oc_surface_data* surface, u32 width, u32 height) -{@autoreleasepool{ +{ + @autoreleasepool + { - surface->nativeLayer = oc_osx_surface_native_layer; - surface->contentsScaling = oc_osx_surface_contents_scaling; - surface->getSize = oc_osx_surface_get_size; - surface->getHidden = oc_osx_surface_get_hidden; - surface->setHidden = oc_osx_surface_set_hidden; - surface->remoteID = oc_osx_surface_remote_id; + surface->nativeLayer = oc_osx_surface_native_layer; + surface->contentsScaling = oc_osx_surface_contents_scaling; + surface->getSize = oc_osx_surface_get_size; + surface->getHidden = oc_osx_surface_get_hidden; + surface->setHidden = oc_osx_surface_set_hidden; + surface->remoteID = oc_osx_surface_remote_id; - surface->layer.caLayer = [[CALayer alloc] init]; - [surface->layer.caLayer retain]; - [surface->layer.caLayer setFrame: (CGRect){{0, 0}, {width, height}}]; + surface->layer.caLayer = [[CALayer alloc] init]; + [surface->layer.caLayer retain]; + [surface->layer.caLayer setFrame:(CGRect){ { 0, 0 }, { width, height } }]; - NSDictionary* dict = [[NSDictionary alloc] init]; - CGSConnectionID connectionID = CGSMainConnectionID(); - surface->layer.caContext = [CAContext contextWithCGSConnection: connectionID options: dict]; - [surface->layer.caContext retain]; - [surface->layer.caContext setLayer:surface->layer.caLayer]; -}} + NSDictionary* dict = [[NSDictionary alloc] init]; + CGSConnectionID connectionID = CGSMainConnectionID(); + surface->layer.caContext = [CAContext contextWithCGSConnection:connectionID options:dict]; + [surface->layer.caContext retain]; + [surface->layer.caContext setLayer:surface->layer.caLayer]; + } +} void oc_osx_surface_host_connect(oc_surface_data* surface, oc_surface_id remoteID) -{@autoreleasepool{ - [(CALayerHost*)surface->layer.caLayer setContextId: (CAContextID)remoteID]; -}} +{ + @autoreleasepool + { + [(CALayerHost*)surface->layer.caLayer setContextId:(CAContextID)remoteID]; + } +} void oc_surface_init_host(oc_surface_data* surface, oc_window_data* window) -{@autoreleasepool{ +{ + @autoreleasepool + { - surface->api = OC_HOST; - surface->nativeLayer = oc_osx_surface_native_layer; - surface->contentsScaling = oc_osx_surface_contents_scaling; - surface->getSize = oc_osx_surface_get_size; - surface->getHidden = oc_osx_surface_get_hidden; - surface->setHidden = oc_osx_surface_set_hidden; - surface->hostConnect = oc_osx_surface_host_connect; + surface->api = OC_HOST; + surface->nativeLayer = oc_osx_surface_native_layer; + surface->contentsScaling = oc_osx_surface_contents_scaling; + surface->getSize = oc_osx_surface_get_size; + surface->getHidden = oc_osx_surface_get_hidden; + surface->setHidden = oc_osx_surface_set_hidden; + surface->hostConnect = oc_osx_surface_host_connect; - surface->layer.caLayer = [[CALayerHost alloc] init]; - [surface->layer.caLayer retain]; + surface->layer.caLayer = [[CALayerHost alloc] init]; + [surface->layer.caLayer retain]; - NSRect frame = [[window->osx.nsWindow contentView] frame]; - CGSize size = frame.size; - [surface->layer.caLayer setFrame: (CGRect){{0, 0}, size}]; + NSRect frame = [[window->osx.nsWindow contentView] frame]; + CGSize size = frame.size; + [surface->layer.caLayer setFrame:(CGRect){ { 0, 0 }, size }]; - [window->osx.nsView.layer addSublayer: surface->layer.caLayer]; -}} + [window->osx.nsView.layer addSublayer:surface->layer.caLayer]; + } +} oc_surface_data* oc_osx_surface_create_host(oc_window windowHandle) { - oc_surface_data* surface = 0; - oc_window_data* window = oc_window_ptr_from_handle(windowHandle); - if(window) - { - surface = oc_malloc_type(oc_surface_data); - if(surface) - { - oc_surface_init_host(surface, window); - } - } - return(surface); + oc_surface_data* surface = 0; + oc_window_data* window = oc_window_ptr_from_handle(windowHandle); + if(window) + { + surface = oc_malloc_type(oc_surface_data); + if(surface) + { + oc_surface_init_host(surface, window); + } + } + return (surface); } //-------------------------------------------------------------------- @@ -1759,23 +1854,24 @@ void oc_view_set_frame(oc_view viewHandle, oc_rect frame) void oc_set_target_fps(u32 fps) { - oc_appData.frameStats.targetFramePeriod = 1./(f64)fps; - oc_appData.frameStats.workTime = 0; - oc_appData.frameStats.remainingTime = 0; + oc_appData.frameStats.targetFramePeriod = 1. / (f64)fps; + oc_appData.frameStats.workTime = 0; + oc_appData.frameStats.remainingTime = 0; - if(oc_appData.osx.frameTimer) - { - [oc_appData.osx.frameTimer invalidate]; - } + if(oc_appData.osx.frameTimer) + { + [oc_appData.osx.frameTimer invalidate]; + } - oc_appData.osx.frameTimer = [NSTimer timerWithTimeInterval: oc_appData.frameStats.targetFramePeriod - target: [NSApp delegate] - selector:@selector(timerElapsed:) - userInfo:nil - repeats:YES]; + oc_appData.osx.frameTimer = [NSTimer timerWithTimeInterval:oc_appData.frameStats.targetFramePeriod + target:[NSApp delegate] + selector:@selector(timerElapsed:) + userInfo:nil + repeats:YES]; - [[NSRunLoop currentRunLoop] addTimer:oc_appData.osx.frameTimer forMode:NSRunLoopCommonModes]; + [[NSRunLoop currentRunLoop] addTimer:oc_appData.osx.frameTimer forMode:NSRunLoopCommonModes]; } + /* void oc_begin_frame() { @@ -1811,72 +1907,71 @@ void oc_end_frame() void oc_set_live_resize_callback(oc_live_resize_callback callback, void* data) { - oc_appData.liveResizeCallback = callback; - oc_appData.liveResizeData = data; + oc_appData.liveResizeCallback = callback; + oc_appData.liveResizeData = data; } - void oc_pump_events(f64 timeout) { - @autoreleasepool - { - bool accumulate = false; - NSDate* date = 0; - if(timeout > 0) - { - date = [NSDate dateWithTimeIntervalSinceNow: (double) timeout]; - } - else if(timeout == 0) - { - date = [NSDate distantPast]; - accumulate = true; - } - else - { - date = [NSDate distantFuture]; - } + @autoreleasepool + { + bool accumulate = false; + NSDate* date = 0; + if(timeout > 0) + { + date = [NSDate dateWithTimeIntervalSinceNow:(double)timeout]; + } + else if(timeout == 0) + { + date = [NSDate distantPast]; + accumulate = true; + } + else + { + date = [NSDate distantFuture]; + } - for(;;) - { - NSEvent* event = [NSApp nextEventMatchingMask: NSEventMaskAny - untilDate:date - inMode: NSDefaultRunLoopMode - dequeue: YES]; + for(;;) + { + NSEvent* event = [NSApp nextEventMatchingMask:NSEventMaskAny + untilDate:date + inMode:NSDefaultRunLoopMode + dequeue:YES]; - if(event != nil) - { - [NSApp sendEvent:event]; + if(event != nil) + { + [NSApp sendEvent:event]; - if(!accumulate) - { - break; - } - } - else - { - break; - } - } - } + if(!accumulate) + { + break; + } + } + else + { + break; + } + } + } } i32 oc_dispatch_on_main_thread_sync(oc_window main_window, oc_dispatch_proc proc, void* user) { - __block i32 result = 0; - dispatch_block_t block = ^{ - result = proc(user); - }; + __block i32 result = 0; + dispatch_block_t block = ^{ + result = proc(user); + }; - if([NSThread isMainThread]) - { - block(); - } - else - { - dispatch_sync(dispatch_get_main_queue(), block); - } + if([NSThread isMainThread]) + { + block(); + } + else + { + dispatch_sync(dispatch_get_main_queue(), block); + } - return(result); + return (result); } //-------------------------------------------------------------------- @@ -1889,73 +1984,73 @@ oc_str8 oc_open_dialog(oc_arena* arena, oc_str8_list filters, bool directory) { - @autoreleasepool - { - NSWindow *keyWindow = [NSApp keyWindow]; + @autoreleasepool + { + NSWindow* keyWindow = [NSApp keyWindow]; - NSOpenPanel* dialog = [NSOpenPanel openPanel] ; - [dialog setLevel:CGShieldingWindowLevel()]; + NSOpenPanel* dialog = [NSOpenPanel openPanel]; + [dialog setLevel:CGShieldingWindowLevel()]; - if(filters.eltCount) - { - NSMutableArray * fileTypesArray = [NSMutableArray array]; + if(filters.eltCount) + { + NSMutableArray* fileTypesArray = [NSMutableArray array]; - oc_list_for(&filters.list, elt, oc_str8_elt, listElt) - { - oc_str8 string = elt->string; - NSString * filter = [[NSString alloc] initWithBytes:string.ptr length:string.len encoding:NSUTF8StringEncoding]; - [fileTypesArray addObject:filter]; - } - [dialog setAllowedFileTypes:fileTypesArray]; - } - // Enable options in the dialog. - if(directory) - { - [dialog setCanChooseDirectories:YES]; - } - else - { - [dialog setCanChooseFiles:YES]; - } + oc_list_for(&filters.list, elt, oc_str8_elt, listElt) + { + oc_str8 string = elt->string; + NSString* filter = [[NSString alloc] initWithBytes:string.ptr length:string.len encoding:NSUTF8StringEncoding]; + [fileTypesArray addObject:filter]; + } + [dialog setAllowedFileTypes:fileTypesArray]; + } + // Enable options in the dialog. + if(directory) + { + [dialog setCanChooseDirectories:YES]; + } + else + { + [dialog setCanChooseFiles:YES]; + } + [dialog setAllowsMultipleSelection:FALSE]; - [dialog setAllowsMultipleSelection:FALSE]; + NSString* nsPath = 0; + ; + if(defaultPath.len) + { + nsPath = [[NSString alloc] initWithBytes:defaultPath.ptr length:defaultPath.len encoding:NSUTF8StringEncoding]; + } + else + { + nsPath = [NSString stringWithUTF8String:"~"]; + } + nsPath = [nsPath stringByExpandingTildeInPath]; - NSString* nsPath = 0;; - if(defaultPath.len) - { - nsPath = [[NSString alloc] initWithBytes: defaultPath.ptr length: defaultPath.len encoding: NSUTF8StringEncoding]; - } - else - { - nsPath = [NSString stringWithUTF8String: "~"]; - } - nsPath = [nsPath stringByExpandingTildeInPath]; + [dialog setDirectoryURL:[NSURL fileURLWithPath:nsPath]]; - [dialog setDirectoryURL:[NSURL fileURLWithPath:nsPath]]; + // Display the dialog box. If the OK pressed, + // process the files. - // Display the dialog box. If the OK pressed, - // process the files. + if([dialog runModal] == NSModalResponseOK) + { + // Gets list of all files selected + NSArray* files = [dialog URLs]; + //TODO: Loop through the files and process them. - if( [dialog runModal] == NSModalResponseOK ) - { - // Gets list of all files selected - NSArray *files = [dialog URLs]; - //TODO: Loop through the files and process them. + const char* result = [[[files objectAtIndex:0] path] UTF8String]; - const char* result = [[[files objectAtIndex:0] path] UTF8String]; + oc_str8 path = oc_str8_push_cstring(arena, result); + [keyWindow makeKeyWindow]; - oc_str8 path = oc_str8_push_cstring(arena, result); - [keyWindow makeKeyWindow]; - - return(path); - } - else - { - [keyWindow makeKeyWindow]; - return((oc_str8){0, 0}); - } - } + return (path); + } + else + { + [keyWindow makeKeyWindow]; + return ((oc_str8){ 0, 0 }); + } + } } oc_str8 oc_save_dialog(oc_arena* arena, @@ -1963,155 +2058,165 @@ oc_str8 oc_save_dialog(oc_arena* arena, oc_str8 defaultPath, oc_str8_list filters) { - @autoreleasepool - { - NSWindow *keyWindow = [NSApp keyWindow]; + @autoreleasepool + { + NSWindow* keyWindow = [NSApp keyWindow]; - NSSavePanel* dialog = [NSSavePanel savePanel] ; - [dialog setLevel:CGShieldingWindowLevel()]; + NSSavePanel* dialog = [NSSavePanel savePanel]; + [dialog setLevel:CGShieldingWindowLevel()]; - if(filters.eltCount) - { - NSMutableArray * fileTypesArray = [NSMutableArray array]; + if(filters.eltCount) + { + NSMutableArray* fileTypesArray = [NSMutableArray array]; - oc_list_for(&filters.list, elt, oc_str8_elt, listElt) - { - oc_str8 string = elt->string; - NSString * filter = [[NSString alloc] initWithBytes:string.ptr length:string.len encoding:NSUTF8StringEncoding]; - [fileTypesArray addObject:filter]; - } - [dialog setAllowedFileTypes:fileTypesArray]; - } + oc_list_for(&filters.list, elt, oc_str8_elt, listElt) + { + oc_str8 string = elt->string; + NSString* filter = [[NSString alloc] initWithBytes:string.ptr length:string.len encoding:NSUTF8StringEncoding]; + [fileTypesArray addObject:filter]; + } + [dialog setAllowedFileTypes:fileTypesArray]; + } - NSString* nsPath = 0;; - if(defaultPath.len) - { - nsPath = [[NSString alloc] initWithBytes: defaultPath.ptr length: defaultPath.len encoding: NSUTF8StringEncoding]; - } - else - { - nsPath = [NSString stringWithUTF8String: "~"]; - } - nsPath = [nsPath stringByExpandingTildeInPath]; + NSString* nsPath = 0; + ; + if(defaultPath.len) + { + nsPath = [[NSString alloc] initWithBytes:defaultPath.ptr length:defaultPath.len encoding:NSUTF8StringEncoding]; + } + else + { + nsPath = [NSString stringWithUTF8String:"~"]; + } + nsPath = [nsPath stringByExpandingTildeInPath]; - [dialog setDirectoryURL:[NSURL fileURLWithPath:nsPath]]; + [dialog setDirectoryURL:[NSURL fileURLWithPath:nsPath]]; - // Display the dialog box. If the OK pressed, - // process the files. + // Display the dialog box. If the OK pressed, + // process the files. - if( [dialog runModal] == NSModalResponseOK ) - { - // Gets list of all files selected - NSURL *files = [dialog URL]; - // Loop through the files and process them. + if([dialog runModal] == NSModalResponseOK) + { + // Gets list of all files selected + NSURL* files = [dialog URL]; + // Loop through the files and process them. - const char* result = [[files path] UTF8String]; + const char* result = [[files path] UTF8String]; - oc_str8 path = oc_str8_push_cstring(arena, result); - [keyWindow makeKeyWindow]; - return(path); - } - else - { - [keyWindow makeKeyWindow]; - return((oc_str8){0, 0}); - } - } + oc_str8 path = oc_str8_push_cstring(arena, result); + [keyWindow makeKeyWindow]; + return (path); + } + else + { + [keyWindow makeKeyWindow]; + return ((oc_str8){ 0, 0 }); + } + } } int oc_alert_popup(oc_str8 title, oc_str8 message, oc_str8_list options) { - __block int result = 0; + __block int result = 0; - dispatch_block_t block = ^{ - @autoreleasepool - { - NSWindow *keyWindow = [NSApp keyWindow]; + dispatch_block_t block = ^{ + @autoreleasepool + { + NSWindow* keyWindow = [NSApp keyWindow]; - NSAlert* alert = [[NSAlert alloc] init]; - NSString* string; + NSAlert* alert = [[NSAlert alloc] init]; + NSString* string; - oc_list_for_reverse((oc_list*)&options.list, elt, oc_str8_elt, listElt) - { - string = [[NSString alloc] initWithBytes:elt->string.ptr length:elt->string.len encoding: NSUTF8StringEncoding]; - [alert addButtonWithTitle:string]; - [string release]; - } - string = [[NSString alloc] initWithBytes:title.ptr length:title.len encoding: NSUTF8StringEncoding]; - [alert setMessageText:string]; - [string release]; + oc_list_for_reverse((oc_list*)&options.list, elt, oc_str8_elt, listElt) + { + string = [[NSString alloc] initWithBytes:elt->string.ptr length:elt->string.len encoding:NSUTF8StringEncoding]; + [alert addButtonWithTitle:string]; + [string release]; + } + string = [[NSString alloc] initWithBytes:title.ptr length:title.len encoding:NSUTF8StringEncoding]; + [alert setMessageText:string]; + [string release]; - string = [[NSString alloc] initWithBytes: message.ptr length: message.len encoding: NSUTF8StringEncoding]; - [alert setInformativeText:string]; - [string release]; + string = [[NSString alloc] initWithBytes:message.ptr length:message.len encoding:NSUTF8StringEncoding]; + [alert setInformativeText:string]; + [string release]; - [alert setAlertStyle:NSAlertStyleWarning]; - result = options.eltCount - ([alert runModal]-NSAlertFirstButtonReturn) - 1; - [keyWindow makeKeyWindow]; - } - }; + [alert setAlertStyle:NSAlertStyleWarning]; + result = options.eltCount - ([alert runModal] - NSAlertFirstButtonReturn) - 1; + [keyWindow makeKeyWindow]; + } + }; - if([NSThread isMainThread]) - { - block(); - } - else - { - dispatch_sync(dispatch_get_main_queue(), block); - } - return(result); + if([NSThread isMainThread]) + { + block(); + } + else + { + dispatch_sync(dispatch_get_main_queue(), block); + } + return (result); } - //-------------------------------------------------------------------- // file system stuff... //TODO: move elsewhere //-------------------------------------------------------------------- int oc_file_move(oc_str8 from, oc_str8 to) -{@autoreleasepool{ - NSString* nsFrom = [[NSString alloc] initWithBytes:from.ptr length:from.len encoding: NSUTF8StringEncoding]; - NSString* nsTo = [[NSString alloc] initWithBytes:to.ptr length:to.len encoding: NSUTF8StringEncoding]; - NSError* err; - if([[NSFileManager defaultManager] moveItemAtPath:nsFrom toPath:nsTo error:&err] == YES) - { - return(0); - } - else - { - return(-1); - } -}} +{ + @autoreleasepool + { + NSString* nsFrom = [[NSString alloc] initWithBytes:from.ptr length:from.len encoding:NSUTF8StringEncoding]; + NSString* nsTo = [[NSString alloc] initWithBytes:to.ptr length:to.len encoding:NSUTF8StringEncoding]; + NSError* err; + if([[NSFileManager defaultManager] moveItemAtPath:nsFrom toPath:nsTo error:&err] == YES) + { + return (0); + } + else + { + return (-1); + } + } +} int oc_file_remove(oc_str8 path) -{@autoreleasepool{ - NSString* nsPath = [[NSString alloc] initWithBytes:path.ptr length:path.len encoding: NSUTF8StringEncoding]; - NSError* err; - if([[NSFileManager defaultManager] removeItemAtPath:nsPath error:&err] == YES) - { - return(0); - } - else - { - return(-1); - } -}} +{ + @autoreleasepool + { + NSString* nsPath = [[NSString alloc] initWithBytes:path.ptr length:path.len encoding:NSUTF8StringEncoding]; + NSError* err; + if([[NSFileManager defaultManager] removeItemAtPath:nsPath error:&err] == YES) + { + return (0); + } + else + { + return (-1); + } + } +} int oc_directory_create(oc_str8 path) -{@autoreleasepool{ +{ + @autoreleasepool + { - NSString* nsPath = [[NSString alloc] initWithBytes:path.ptr length:path.len encoding: NSUTF8StringEncoding]; - NSError* err; - if([[NSFileManager defaultManager] createDirectoryAtPath: nsPath - withIntermediateDirectories: YES - attributes:nil - error:&err] == YES) - { - return(0); - } - else - { - return(-1); - } -}} + NSString* nsPath = [[NSString alloc] initWithBytes:path.ptr length:path.len encoding:NSUTF8StringEncoding]; + NSError* err; + if([[NSFileManager defaultManager] createDirectoryAtPath:nsPath + withIntermediateDirectories:YES + attributes:nil + error:&err] + == YES) + { + return (0); + } + else + { + return (-1); + } + } +} diff --git a/src/app/win32_app.c b/src/app/win32_app.c index 8677a0f..df6c4ff 100644 --- a/src/app/win32_app.c +++ b/src/app/win32_app.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: win32_app.c * @author: Martin Fouilleul @@ -7,15 +7,15 @@ * *****************************************************************/ -#include -#include"app.c" -#include"platform/platform_thread.h" +#include "app.c" +#include "platform/platform_thread.h" +#include void oc_init_keys() { - memset(oc_appData.keyCodes, OC_KEY_UNKNOWN, 256*sizeof(int)); + memset(oc_appData.keyCodes, OC_KEY_UNKNOWN, 256 * sizeof(int)); - oc_appData.keyCodes[0x00B] = OC_KEY_0; + oc_appData.keyCodes[0x00B] = OC_KEY_0; oc_appData.keyCodes[0x002] = OC_KEY_1; oc_appData.keyCodes[0x003] = OC_KEY_2; oc_appData.keyCodes[0x004] = OC_KEY_3; @@ -134,428 +134,451 @@ void oc_init_keys() oc_appData.keyCodes[0x037] = OC_KEY_KP_MULTIPLY; oc_appData.keyCodes[0x04A] = OC_KEY_KP_SUBTRACT; - memset(oc_appData.nativeKeys, 0, sizeof(int)*OC_KEY_COUNT); - for(int nativeKey=0; nativeKey<256; nativeKey++) - { - oc_key_code mpKey = oc_appData.keyCodes[nativeKey]; - if(mpKey) - { - oc_appData.nativeKeys[mpKey] = nativeKey; - } - } + memset(oc_appData.nativeKeys, 0, sizeof(int) * OC_KEY_COUNT); + for(int nativeKey = 0; nativeKey < 256; nativeKey++) + { + oc_key_code mpKey = oc_appData.keyCodes[nativeKey]; + if(mpKey) + { + oc_appData.nativeKeys[mpKey] = nativeKey; + } + } } void oc_init() { - if(!oc_appData.init) - { - memset(&oc_appData, 0, sizeof(oc_appData)); + if(!oc_appData.init) + { + memset(&oc_appData, 0, sizeof(oc_appData)); - oc_init_common(); - oc_init_keys(); + oc_init_common(); + oc_init_keys(); - oc_appData.win32.savedConsoleCodePage = GetConsoleOutputCP(); - SetConsoleOutputCP(CP_UTF8); + oc_appData.win32.savedConsoleCodePage = GetConsoleOutputCP(); + SetConsoleOutputCP(CP_UTF8); - DWORD mode; - GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &mode); - mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; - SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), mode); + DWORD mode; + GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &mode); + mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; + SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), mode); - SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); + SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); - u32 wheelScrollLines = 3; - SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &wheelScrollLines, 0); - oc_appData.win32.wheelScrollLines = wheelScrollLines; - } + u32 wheelScrollLines = 3; + SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &wheelScrollLines, 0); + oc_appData.win32.wheelScrollLines = wheelScrollLines; + } } void oc_terminate() { - if(oc_appData.init) - { - SetConsoleOutputCP(oc_appData.win32.savedConsoleCodePage); + if(oc_appData.init) + { + SetConsoleOutputCP(oc_appData.win32.savedConsoleCodePage); - oc_terminate_common(); - oc_appData = (oc_app){0}; - } + oc_terminate_common(); + oc_appData = (oc_app){ 0 }; + } } static oc_key_code oc_convert_win32_key(int code) { - return(oc_appData.keyCodes[code]); + return (oc_appData.keyCodes[code]); } static oc_keymod_flags oc_get_mod_keys() { - oc_keymod_flags mods = 0; - if(GetKeyState(VK_SHIFT) & 0x8000) - { - mods |= OC_KEYMOD_SHIFT; - } - if(GetKeyState(VK_CONTROL) & 0x8000) - { - mods |= OC_KEYMOD_CTRL; - mods |= OC_KEYMOD_MAIN_MODIFIER; - } - if(GetKeyState(VK_MENU) & 0x8000) - { - mods |= OC_KEYMOD_ALT; - } - if((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) & 0x8000) - { - mods |= OC_KEYMOD_CMD; - } - return(mods); + oc_keymod_flags mods = 0; + if(GetKeyState(VK_SHIFT) & 0x8000) + { + mods |= OC_KEYMOD_SHIFT; + } + if(GetKeyState(VK_CONTROL) & 0x8000) + { + mods |= OC_KEYMOD_CTRL; + mods |= OC_KEYMOD_MAIN_MODIFIER; + } + if(GetKeyState(VK_MENU) & 0x8000) + { + mods |= OC_KEYMOD_ALT; + } + if((GetKeyState(VK_LWIN) | GetKeyState(VK_RWIN)) & 0x8000) + { + mods |= OC_KEYMOD_CMD; + } + return (mods); } static void oc_win32_process_mouse_event(oc_window_data* window, oc_key_action action, oc_key_code button) { - if(action == OC_KEY_PRESS) - { - if(!oc_appData.win32.mouseCaptureMask) - { - SetCapture(window->win32.hWnd); - } - oc_appData.win32.mouseCaptureMask |= (1<win32.hWnd); + } + oc_appData.win32.mouseCaptureMask |= (1 << button); + } + else if(action == OC_KEY_RELEASE) + { + oc_appData.win32.mouseCaptureMask &= ~(1 << button); + if(!oc_appData.win32.mouseCaptureMask) + { + ReleaseCapture(); + } + } - //TODO click/double click + //TODO click/double click - oc_event event = {0}; - event.window = oc_window_handle_from_ptr(window); - event.type = OC_EVENT_MOUSE_BUTTON; - event.key.action = action; - event.key.code = button; - event.key.mods = oc_get_mod_keys(); + oc_event event = { 0 }; + event.window = oc_window_handle_from_ptr(window); + event.type = OC_EVENT_MOUSE_BUTTON; + event.key.action = action; + event.key.code = button; + event.key.mods = oc_get_mod_keys(); - oc_queue_event(&event); + oc_queue_event(&event); } static void oc_win32_process_wheel_event(oc_window_data* window, f32 x, f32 y) { - oc_event event = {0}; - event.window = oc_window_handle_from_ptr(window); - event.type = OC_EVENT_MOUSE_WHEEL; - // Borrowed from https://source.chromium.org/chromium/chromium/src/+/3e1a26c44c024d97dc9a4c09bbc6a2365398ca2c:ui/events/blink/web_input_event_builders_win.cc;l=318-330 - f32 scrollMultiplier = oc_appData.win32.wheelScrollLines * 100.0 / 3.0; - event.mouse.deltaX = x / WHEEL_DELTA * scrollMultiplier; - event.mouse.deltaY = -y / WHEEL_DELTA * scrollMultiplier; - event.mouse.mods = oc_get_mod_keys(); + oc_event event = { 0 }; + event.window = oc_window_handle_from_ptr(window); + event.type = OC_EVENT_MOUSE_WHEEL; + // Borrowed from https://source.chromium.org/chromium/chromium/src/+/3e1a26c44c024d97dc9a4c09bbc6a2365398ca2c:ui/events/blink/web_input_event_builders_win.cc;l=318-330 + f32 scrollMultiplier = oc_appData.win32.wheelScrollLines * 100.0 / 3.0; + event.mouse.deltaX = x / WHEEL_DELTA * scrollMultiplier; + event.mouse.deltaY = -y / WHEEL_DELTA * scrollMultiplier; + event.mouse.mods = oc_get_mod_keys(); - oc_queue_event(&event); + oc_queue_event(&event); } static void oc_win32_update_child_layers(oc_window_data* window) { - RECT clientRect; - GetClientRect(window->win32.hWnd, &clientRect); - POINT point = {0}; - ClientToScreen(window->win32.hWnd, &point); + RECT clientRect; + GetClientRect(window->win32.hWnd, &clientRect); + POINT point = { 0 }; + ClientToScreen(window->win32.hWnd, &point); - int clientWidth = (clientRect.right - clientRect.left); - int clientHeight = (clientRect.bottom - clientRect.top); + int clientWidth = (clientRect.right - clientRect.left); + int clientHeight = (clientRect.bottom - clientRect.top); - HWND insertAfter = window->win32.hWnd; + HWND insertAfter = window->win32.hWnd; - oc_list_for(&window->win32.layers, layer, oc_layer, listElt) - { - SetWindowPos(layer->hWnd, - insertAfter, - point.x, - point.y, - clientWidth, - clientHeight, - SWP_NOACTIVATE|SWP_NOOWNERZORDER|SWP_NOZORDER); + oc_list_for(&window->win32.layers, layer, oc_layer, listElt) + { + SetWindowPos(layer->hWnd, + insertAfter, + point.x, + point.y, + clientWidth, + clientHeight, + SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER); - insertAfter = layer->hWnd; - } + insertAfter = layer->hWnd; + } } LRESULT oc_win32_win_proc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam) { - LRESULT result = 0; + LRESULT result = 0; - oc_window_data* mpWindow = GetPropW(windowHandle, L"MilePost"); - //TODO: put messages in queue + oc_window_data* mpWindow = GetPropW(windowHandle, L"MilePost"); + //TODO: put messages in queue - bool handled = true; + bool handled = true; - switch(message) - { - case WM_CLOSE: - { - oc_event event = {0}; - event.window = oc_window_handle_from_ptr(mpWindow); - event.type = OC_EVENT_WINDOW_CLOSE; - oc_queue_event(&event); - } break; + switch(message) + { + case WM_CLOSE: + { + oc_event event = { 0 }; + event.window = oc_window_handle_from_ptr(mpWindow); + event.type = OC_EVENT_WINDOW_CLOSE; + oc_queue_event(&event); + } + break; - case WM_DPICHANGED: - { - u32 dpi = HIWORD(wParam); - RECT rect = *(RECT*)lParam; + case WM_DPICHANGED: + { + u32 dpi = HIWORD(wParam); + RECT rect = *(RECT*)lParam; - SetWindowPos(mpWindow->win32.hWnd, - HWND_TOP, - rect.left, - rect.top, - rect.right - rect.left, - rect.bottom - rect.top, - SWP_NOACTIVATE | SWP_NOZORDER); + SetWindowPos(mpWindow->win32.hWnd, + HWND_TOP, + rect.left, + rect.top, + rect.right - rect.left, + rect.bottom - rect.top, + SWP_NOACTIVATE | SWP_NOZORDER); - //TODO: send a message + //TODO: send a message + } + break; - } break; + //TODO: enter/exit size & move + case WM_WINDOWPOSCHANGED: + { + oc_win32_update_child_layers(mpWindow); + result = DefWindowProc(windowHandle, message, wParam, lParam); + } + break; - //TODO: enter/exit size & move - case WM_WINDOWPOSCHANGED: - { - oc_win32_update_child_layers(mpWindow); - result = DefWindowProc(windowHandle, message, wParam, lParam); - } break; + case WM_SIZING: + case WM_MOVING: + { + RECT* rect = (RECT*)lParam; - case WM_SIZING: - case WM_MOVING: - { - RECT* rect = (RECT*)lParam; + oc_event event = { 0 }; + event.type = message == WM_SIZING ? OC_EVENT_WINDOW_RESIZE : OC_EVENT_WINDOW_MOVE; + event.window = oc_window_handle_from_ptr(mpWindow); - oc_event event = {0}; - event.type = message == WM_SIZING ? OC_EVENT_WINDOW_RESIZE : OC_EVENT_WINDOW_MOVE; - event.window = oc_window_handle_from_ptr(mpWindow); + event.move.frame = oc_window_get_frame_rect(event.window); + event.move.content = oc_window_get_content_rect(event.window); - event.move.frame = oc_window_get_frame_rect(event.window); - event.move.content = oc_window_get_content_rect(event.window); + oc_queue_event(&event); - oc_queue_event(&event); + oc_win32_update_child_layers(mpWindow); + } + break; - oc_win32_update_child_layers(mpWindow); - } break; + case WM_SETFOCUS: + { + oc_event event = { 0 }; + event.window = oc_window_handle_from_ptr(mpWindow); + event.type = OC_EVENT_WINDOW_FOCUS; + oc_queue_event(&event); + } + break; - case WM_SETFOCUS: - { - oc_event event = {0}; - event.window = oc_window_handle_from_ptr(mpWindow); - event.type = OC_EVENT_WINDOW_FOCUS; - oc_queue_event(&event); - } break; + case WM_KILLFOCUS: + { + oc_event event = { 0 }; + event.window = oc_window_handle_from_ptr(mpWindow); + event.type = OC_EVENT_WINDOW_UNFOCUS; + oc_queue_event(&event); + } + break; - case WM_KILLFOCUS: - { - oc_event event = {0}; - event.window = oc_window_handle_from_ptr(mpWindow); - event.type = OC_EVENT_WINDOW_UNFOCUS; - oc_queue_event(&event); - } break; + case WM_SIZE: + { + bool minimized = (wParam == SIZE_MINIMIZED); + if(minimized != mpWindow->minimized) + { + mpWindow->minimized = minimized; - case WM_SIZE: - { - bool minimized = (wParam == SIZE_MINIMIZED); - if(minimized != mpWindow->minimized) - { - mpWindow->minimized = minimized; + oc_event event = { 0 }; + event.window = oc_window_handle_from_ptr(mpWindow); - oc_event event = {0}; - event.window = oc_window_handle_from_ptr(mpWindow); + if(minimized) + { + event.type = OC_EVENT_WINDOW_HIDE; + } + else if(mpWindow->minimized) + { + event.type = OC_EVENT_WINDOW_SHOW; + } + oc_queue_event(&event); + } + } + break; - if(minimized) - { - event.type = OC_EVENT_WINDOW_HIDE; - } - else if(mpWindow->minimized) - { - event.type = OC_EVENT_WINDOW_SHOW; - } - oc_queue_event(&event); - } - } break; + case WM_LBUTTONDOWN: + { + oc_win32_process_mouse_event(mpWindow, OC_KEY_PRESS, OC_MOUSE_LEFT); + } + break; - case WM_LBUTTONDOWN: - { - oc_win32_process_mouse_event(mpWindow, OC_KEY_PRESS, OC_MOUSE_LEFT); - } break; + case WM_RBUTTONDOWN: + { + oc_win32_process_mouse_event(mpWindow, OC_KEY_PRESS, OC_MOUSE_RIGHT); + } + break; - case WM_RBUTTONDOWN: - { - oc_win32_process_mouse_event(mpWindow, OC_KEY_PRESS, OC_MOUSE_RIGHT); - } break; + case WM_MBUTTONDOWN: + { + oc_win32_process_mouse_event(mpWindow, OC_KEY_PRESS, OC_MOUSE_MIDDLE); + } + break; - case WM_MBUTTONDOWN: - { - oc_win32_process_mouse_event(mpWindow, OC_KEY_PRESS, OC_MOUSE_MIDDLE); - } break; + case WM_LBUTTONUP: + { + oc_win32_process_mouse_event(mpWindow, OC_KEY_RELEASE, OC_MOUSE_LEFT); + } + break; - case WM_LBUTTONUP: - { - oc_win32_process_mouse_event(mpWindow, OC_KEY_RELEASE, OC_MOUSE_LEFT); - } break; + case WM_RBUTTONUP: + { + oc_win32_process_mouse_event(mpWindow, OC_KEY_RELEASE, OC_MOUSE_RIGHT); + } + break; - case WM_RBUTTONUP: - { - oc_win32_process_mouse_event(mpWindow, OC_KEY_RELEASE, OC_MOUSE_RIGHT); - } break; + case WM_MBUTTONUP: + { + oc_win32_process_mouse_event(mpWindow, OC_KEY_RELEASE, OC_MOUSE_MIDDLE); + } + break; - case WM_MBUTTONUP: - { - oc_win32_process_mouse_event(mpWindow, OC_KEY_RELEASE, OC_MOUSE_MIDDLE); - } break; + case WM_MOUSEMOVE: + { + RECT rect; + GetClientRect(mpWindow->win32.hWnd, &rect); - case WM_MOUSEMOVE: - { - RECT rect; - GetClientRect(mpWindow->win32.hWnd, &rect); + u32 dpi = GetDpiForWindow(mpWindow->win32.hWnd); + f32 scaling = (f32)dpi / 96.; - u32 dpi = GetDpiForWindow(mpWindow->win32.hWnd); - f32 scaling = (f32)dpi/96.; + oc_event event = { 0 }; + event.window = oc_window_handle_from_ptr(mpWindow); + event.type = OC_EVENT_MOUSE_MOVE; + event.mouse.x = LOWORD(lParam) / scaling; + event.mouse.y = HIWORD(lParam) / scaling; - oc_event event = {0}; - event.window = oc_window_handle_from_ptr(mpWindow); - event.type = OC_EVENT_MOUSE_MOVE; - event.mouse.x = LOWORD(lParam) / scaling; - event.mouse.y = HIWORD(lParam) / scaling; + if(oc_appData.win32.mouseTracked || oc_appData.win32.mouseCaptureMask) + { + event.mouse.deltaX = event.mouse.x - oc_appData.win32.lastMousePos.x; + event.mouse.deltaY = event.mouse.y - oc_appData.win32.lastMousePos.y; + } + oc_appData.win32.lastMousePos = (oc_vec2){ event.mouse.x, event.mouse.y }; - if(oc_appData.win32.mouseTracked || oc_appData.win32.mouseCaptureMask) - { - event.mouse.deltaX = event.mouse.x - oc_appData.win32.lastMousePos.x; - event.mouse.deltaY = event.mouse.y - oc_appData.win32.lastMousePos.y; - } - oc_appData.win32.lastMousePos = (oc_vec2){event.mouse.x, event.mouse.y}; + if(!oc_appData.win32.mouseTracked) + { + oc_appData.win32.mouseTracked = true; - if(!oc_appData.win32.mouseTracked) - { - oc_appData.win32.mouseTracked = true; + TRACKMOUSEEVENT track; + memset(&track, 0, sizeof(track)); + track.cbSize = sizeof(track); + track.dwFlags = TME_LEAVE; + track.hwndTrack = mpWindow->win32.hWnd; + TrackMouseEvent(&track); - TRACKMOUSEEVENT track; - memset(&track, 0, sizeof(track)); - track.cbSize = sizeof(track); - track.dwFlags = TME_LEAVE; - track.hwndTrack = mpWindow->win32.hWnd; - TrackMouseEvent(&track); + oc_event enter = { .window = event.window, + .type = OC_EVENT_MOUSE_ENTER, + .mouse.x = event.mouse.x, + .mouse.y = event.mouse.y }; + oc_queue_event(&enter); + } - oc_event enter = {.window = event.window, - .type = OC_EVENT_MOUSE_ENTER, - .mouse.x = event.mouse.x, - .mouse.y = event.mouse.y}; - oc_queue_event(&enter); - } + oc_queue_event(&event); + } + break; - oc_queue_event(&event); - } break; + case WM_MOUSELEAVE: + { + oc_appData.win32.mouseTracked = false; - case WM_MOUSELEAVE: - { - oc_appData.win32.mouseTracked = false; + oc_event event = { 0 }; + event.window = oc_window_handle_from_ptr(mpWindow); + event.type = OC_EVENT_MOUSE_LEAVE; + oc_queue_event(&event); + } + break; - oc_event event = {0}; - event.window = oc_window_handle_from_ptr(mpWindow); - event.type = OC_EVENT_MOUSE_LEAVE; - oc_queue_event(&event); - } break; + case WM_MOUSEWHEEL: + { + oc_win32_process_wheel_event(mpWindow, 0, (float)((i16)HIWORD(wParam))); + } + break; - case WM_MOUSEWHEEL: - { - oc_win32_process_wheel_event(mpWindow, 0, (float)((i16)HIWORD(wParam))); - } break; + case WM_MOUSEHWHEEL: + { + oc_win32_process_wheel_event(mpWindow, (float)((i16)HIWORD(wParam)), 0); + } + break; - case WM_MOUSEHWHEEL: - { - oc_win32_process_wheel_event(mpWindow, (float)((i16)HIWORD(wParam)), 0); - } break; + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + { + // Need to pass these through to the normal event handler to handle system shortcuts like Alt+F4. + // Same for WM_SYSKEYUP + if(message == WM_SYSKEYDOWN) + { + handled = false; + } - case WM_KEYDOWN: - case WM_SYSKEYDOWN: - { - // Need to pass these through to the normal event handler to handle system shortcuts like Alt+F4. - // Same for WM_SYSKEYUP - if (message == WM_SYSKEYDOWN) - { - handled = false; - } + oc_event event = { 0 }; + event.window = oc_window_handle_from_ptr(mpWindow); + event.type = OC_EVENT_KEYBOARD_KEY; + event.key.action = (lParam & 0x40000000) ? OC_KEY_REPEAT : OC_KEY_PRESS; + event.key.code = oc_convert_win32_key(HIWORD(lParam) & 0x1ff); + event.key.mods = oc_get_mod_keys(); + oc_queue_event(&event); + } + break; - oc_event event = {0}; - event.window = oc_window_handle_from_ptr(mpWindow); - event.type = OC_EVENT_KEYBOARD_KEY; - event.key.action = (lParam & 0x40000000) ? OC_KEY_REPEAT : OC_KEY_PRESS; - event.key.code = oc_convert_win32_key(HIWORD(lParam) & 0x1ff); - event.key.mods = oc_get_mod_keys(); - oc_queue_event(&event); - } break; + case WM_KEYUP: + case WM_SYSKEYUP: + { + if(message == WM_SYSKEYUP) + { + handled = false; + } - case WM_KEYUP: - case WM_SYSKEYUP: - { - if (message == WM_SYSKEYUP) - { - handled = false; - } + oc_event event = { 0 }; + event.window = oc_window_handle_from_ptr(mpWindow); + event.type = OC_EVENT_KEYBOARD_KEY; + event.key.action = OC_KEY_RELEASE; + event.key.code = oc_convert_win32_key(HIWORD(lParam) & 0x1ff); + event.key.mods = oc_get_mod_keys(); + oc_queue_event(&event); + } + break; - oc_event event = {0}; - event.window = oc_window_handle_from_ptr(mpWindow); - event.type = OC_EVENT_KEYBOARD_KEY; - event.key.action = OC_KEY_RELEASE; - event.key.code = oc_convert_win32_key(HIWORD(lParam) & 0x1ff); - event.key.mods = oc_get_mod_keys(); - oc_queue_event(&event); - } break; + case WM_CHAR: + { + if((u32)wParam >= 32) + { + oc_event event = { 0 }; + event.window = oc_window_handle_from_ptr(mpWindow); + event.type = OC_EVENT_KEYBOARD_CHAR; + event.character.codepoint = (oc_utf32)wParam; + oc_str8 seq = oc_utf8_encode(event.character.sequence, event.character.codepoint); + event.character.seqLen = seq.len; + oc_queue_event(&event); + } + } + break; - case WM_CHAR: - { - if((u32)wParam >= 32) - { - oc_event event = {0}; - event.window = oc_window_handle_from_ptr(mpWindow); - event.type = OC_EVENT_KEYBOARD_CHAR; - event.character.codepoint = (oc_utf32)wParam; - oc_str8 seq = oc_utf8_encode(event.character.sequence, event.character.codepoint); - event.character.seqLen = seq.len; - oc_queue_event(&event); - } - } break; + case WM_SETTINGCHANGE: + { + if((u32)wParam == SPI_SETWHEELSCROLLLINES) + { + u32 wheelScrollLines; + if(SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &wheelScrollLines, 0) != 0) + { + oc_appData.win32.wheelScrollLines = wheelScrollLines; + } + } + } + break; - case WM_SETTINGCHANGE: - { - if((u32)wParam == SPI_SETWHEELSCROLLLINES) - { - u32 wheelScrollLines; - if(SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &wheelScrollLines, 0) != 0) { - oc_appData.win32.wheelScrollLines = wheelScrollLines; - } - } - } break; + case WM_DROPFILES: + { + //TODO + } + break; - case WM_DROPFILES: - { - //TODO - } break; + case OC_WM_USER_DISPATCH_PROC: + { + oc_dispatch_proc proc = (oc_dispatch_proc)wParam; + void* user = (void*)lParam; + result = proc(user); + } + break; - case OC_WM_USER_DISPATCH_PROC: - { - oc_dispatch_proc proc = (oc_dispatch_proc)wParam; - void* user = (void*)lParam; - result = proc(user); - } break; + default: + { + handled = false; + } + break; + } - default: - { - handled = false; - } break; - } + if(handled == false) + { + result = DefWindowProc(windowHandle, message, wParam, lParam); + } - if (handled == false) - { - result = DefWindowProc(windowHandle, message, wParam, lParam); - } - - - return(result); + return (result); } //-------------------------------------------------------------------- @@ -564,46 +587,46 @@ LRESULT oc_win32_win_proc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM bool oc_should_quit() { - return(oc_appData.shouldQuit); + return (oc_appData.shouldQuit); } void oc_cancel_quit() { - oc_appData.shouldQuit = false; + oc_appData.shouldQuit = false; } void oc_request_quit() { - oc_appData.shouldQuit = true; + oc_appData.shouldQuit = true; } void oc_pump_events(f64 timeout) { - MSG message; + MSG message; - if(timeout < 0) - { - WaitMessage(); - } - else if(timeout > 0) - { - MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD) (timeout * 1e3), QS_ALLEVENTS); - } + if(timeout < 0) + { + WaitMessage(); + } + else if(timeout > 0) + { + MsgWaitForMultipleObjects(0, NULL, FALSE, (DWORD)(timeout * 1e3), QS_ALLEVENTS); + } - while(PeekMessage(&message, 0, 0, 0, PM_REMOVE)) - { - TranslateMessage(&message); - DispatchMessage(&message); - } + while(PeekMessage(&message, 0, 0, 0, PM_REMOVE)) + { + TranslateMessage(&message); + DispatchMessage(&message); + } } i32 oc_dispatch_on_main_thread_sync(oc_window main_window, oc_dispatch_proc proc, void* user) { - oc_window_data* window_data = oc_window_ptr_from_handle(main_window); - OC_DEBUG_ASSERT(window_data != NULL); + oc_window_data* window_data = oc_window_ptr_from_handle(main_window); + OC_DEBUG_ASSERT(window_data != NULL); - LRESULT result = SendMessage(window_data->win32.hWnd, OC_WM_USER_DISPATCH_PROC, (WPARAM)proc, (LPARAM)user); - return result; + LRESULT result = SendMessage(window_data->win32.hWnd, OC_WM_USER_DISPATCH_PROC, (WPARAM)proc, (LPARAM)user); + return result; } //-------------------------------------------------------------------- @@ -613,686 +636,686 @@ i32 oc_dispatch_on_main_thread_sync(oc_window main_window, oc_dispatch_proc proc //WARN: the following header pulls in objbase.h (even with WIN32_LEAN_AND_MEAN), which // #defines interface to struct... so make sure to #undef interface since it's a // name we want to be able to use throughout the codebase -#include +#include #undef interface oc_window oc_window_create(oc_rect rect, oc_str8 title, oc_window_style style) { - WNDCLASS windowClass = {.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC, - .lpfnWndProc = oc_win32_win_proc, - .hInstance = GetModuleHandleW(NULL), - .lpszClassName = "ApplicationWindowClass", - .hCursor = LoadCursor(0, IDC_ARROW)}; + WNDCLASS windowClass = { .style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC, + .lpfnWndProc = oc_win32_win_proc, + .hInstance = GetModuleHandleW(NULL), + .lpszClassName = "ApplicationWindowClass", + .hCursor = LoadCursor(0, IDC_ARROW) }; - if(!RegisterClass(&windowClass)) - { - //TODO: error - goto quit; - } + if(!RegisterClass(&windowClass)) + { + //TODO: error + goto quit; + } - u32 dpiX, dpiY; - HMONITOR monitor = MonitorFromPoint((POINT){rect.x, rect.y}, MONITOR_DEFAULTTOPRIMARY); - GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY); + u32 dpiX, dpiY; + HMONITOR monitor = MonitorFromPoint((POINT){ rect.x, rect.y }, MONITOR_DEFAULTTOPRIMARY); + GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY); - f32 scaleX = (f32)dpiX/96.; - f32 scaleY = (f32)dpiY/96.; + f32 scaleX = (f32)dpiX / 96.; + f32 scaleY = (f32)dpiY / 96.; - RECT frame = { - rect.x * scaleX, - rect.y * scaleY, - (rect.x + rect.w)*scaleX, - (rect.y + rect.h)*scaleY - }; + RECT frame = { + rect.x * scaleX, + rect.y * scaleY, + (rect.x + rect.w) * scaleX, + (rect.y + rect.h) * scaleY + }; - DWORD winStyle = WS_OVERLAPPEDWINDOW; - AdjustWindowRect(&frame, winStyle, FALSE); + DWORD winStyle = WS_OVERLAPPEDWINDOW; + AdjustWindowRect(&frame, winStyle, FALSE); - oc_arena_scope scratch = oc_scratch_begin(); - const char* titleCString = oc_str8_to_cstring(scratch.arena, title); + oc_arena_scope scratch = oc_scratch_begin(); + const char* titleCString = oc_str8_to_cstring(scratch.arena, title); - HWND windowHandle = CreateWindow("ApplicationWindowClass", titleCString, - winStyle, - frame.left, frame.top, - frame.right-frame.left, - frame.bottom-frame.top, - 0, 0, windowClass.hInstance, 0); + HWND windowHandle = CreateWindow("ApplicationWindowClass", titleCString, + winStyle, + frame.left, frame.top, + frame.right - frame.left, + frame.bottom - frame.top, + 0, 0, windowClass.hInstance, 0); - oc_scratch_end(scratch); + oc_scratch_end(scratch); - if(!windowHandle) - { - //TODO: error - goto quit; - } + if(!windowHandle) + { + //TODO: error + goto quit; + } - UpdateWindow(windowHandle); + UpdateWindow(windowHandle); - //TODO: return wrapped window - quit:; - oc_window_data* window = oc_window_alloc(); - window->win32.hWnd = windowHandle; - window->win32.layers = (oc_list){0}; +//TODO: return wrapped window +quit:; + oc_window_data* window = oc_window_alloc(); + window->win32.hWnd = windowHandle; + window->win32.layers = (oc_list){ 0 }; - SetPropW(windowHandle, L"MilePost", window); + SetPropW(windowHandle, L"MilePost", window); - return(oc_window_handle_from_ptr(window)); + return (oc_window_handle_from_ptr(window)); } void oc_window_destroy(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - DestroyWindow(windowData->win32.hWnd); - //TODO: check when to unregister class + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + DestroyWindow(windowData->win32.hWnd); + //TODO: check when to unregister class - oc_window_recycle_ptr(windowData); - } + oc_window_recycle_ptr(windowData); + } } void* oc_window_native_pointer(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - return(windowData->win32.hWnd); - } - else - { - return(0); - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + return (windowData->win32.hWnd); + } + else + { + return (0); + } } bool oc_window_should_close(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - return(windowData->shouldClose); - } - else - { - return(false); - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + return (windowData->shouldClose); + } + else + { + return (false); + } } void oc_window_request_close(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - windowData->shouldClose = true; - PostMessage(windowData->win32.hWnd, WM_CLOSE, 0, 0); - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + windowData->shouldClose = true; + PostMessage(windowData->win32.hWnd, WM_CLOSE, 0, 0); + } } void oc_window_cancel_close(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - windowData->shouldClose = false; - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + windowData->shouldClose = false; + } } - bool oc_window_is_hidden(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - return(IsWindowVisible(windowData->win32.hWnd)); - } - else - { - return(false); - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + return (IsWindowVisible(windowData->win32.hWnd)); + } + else + { + return (false); + } } void oc_window_hide(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - ShowWindow(windowData->win32.hWnd, SW_HIDE); - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + ShowWindow(windowData->win32.hWnd, SW_HIDE); + } } void oc_window_show(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - ShowWindow(windowData->win32.hWnd, SW_NORMAL); - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + ShowWindow(windowData->win32.hWnd, SW_NORMAL); + } } bool oc_window_is_minimized(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - return(windowData->minimized); - } - else - { - return(false); - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + return (windowData->minimized); + } + else + { + return (false); + } } void oc_window_minimize(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - ShowWindow(windowData->win32.hWnd, SW_MINIMIZE); - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + ShowWindow(windowData->win32.hWnd, SW_MINIMIZE); + } } void oc_window_maximize(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - ShowWindow(windowData->win32.hWnd, SW_MAXIMIZE); - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + ShowWindow(windowData->win32.hWnd, SW_MAXIMIZE); + } } void oc_window_restore(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - ShowWindow(windowData->win32.hWnd, SW_RESTORE); - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + ShowWindow(windowData->win32.hWnd, SW_RESTORE); + } } bool oc_window_has_focus(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - return(GetActiveWindow() == windowData->win32.hWnd); - } - else - { - return(false); - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + return (GetActiveWindow() == windowData->win32.hWnd); + } + else + { + return (false); + } } void oc_window_focus(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - SetFocus(windowData->win32.hWnd); - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + SetFocus(windowData->win32.hWnd); + } } void oc_window_unfocus(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - SetFocus(0); - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + SetFocus(0); + } } void oc_window_send_to_back(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - SetWindowPos(windowData->win32.hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + SetWindowPos(windowData->win32.hWnd, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + } } void oc_window_bring_to_front(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - if(!IsWindowVisible(windowData->win32.hWnd)) - { - ShowWindow(windowData->win32.hWnd, SW_NORMAL); - } - SetWindowPos(windowData->win32.hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); - } + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + if(!IsWindowVisible(windowData->win32.hWnd)) + { + ShowWindow(windowData->win32.hWnd, SW_NORMAL); + } + SetWindowPos(windowData->win32.hWnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); + } } oc_rect oc_window_get_frame_rect(oc_window window) { - oc_rect rect = {0}; - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - //NOTE: GetWindowRect() includes the drop shadow, which we don't want, so we call - // DwmGetWindowAttribute() instead. - // Note that contrary to what the GetWindowRect() docs suggests when mentionning - // this, DwmGetWindowAttributes() _does_ seem to adjust for DPI. - u32 dpi = GetDpiForWindow(windowData->win32.hWnd); - f32 scale = (float)dpi/96.; + oc_rect rect = { 0 }; + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + //NOTE: GetWindowRect() includes the drop shadow, which we don't want, so we call + // DwmGetWindowAttribute() instead. + // Note that contrary to what the GetWindowRect() docs suggests when mentionning + // this, DwmGetWindowAttributes() _does_ seem to adjust for DPI. + u32 dpi = GetDpiForWindow(windowData->win32.hWnd); + f32 scale = (float)dpi / 96.; - RECT frame; - HRESULT res = DwmGetWindowAttribute(windowData->win32.hWnd, - DWMWA_EXTENDED_FRAME_BOUNDS, - &frame, - sizeof(RECT)); - if(res == S_OK) - { - rect = (oc_rect){ - frame.left / scale, - frame.top / scale, - (frame.right - frame.left)/scale, - (frame.bottom - frame.top)/scale}; - } - } - return(rect); + RECT frame; + HRESULT res = DwmGetWindowAttribute(windowData->win32.hWnd, + DWMWA_EXTENDED_FRAME_BOUNDS, + &frame, + sizeof(RECT)); + if(res == S_OK) + { + rect = (oc_rect){ + frame.left / scale, + frame.top / scale, + (frame.right - frame.left) / scale, + (frame.bottom - frame.top) / scale + }; + } + } + return (rect); } static oc_rect oc_win32_get_drop_shadow_offsets(HWND hWnd) { - RECT frameIncludingShadow; - RECT frameExcludingShadow; + RECT frameIncludingShadow; + RECT frameExcludingShadow; - GetWindowRect(hWnd, &frameIncludingShadow); - DwmGetWindowAttribute(hWnd, - DWMWA_EXTENDED_FRAME_BOUNDS, - &frameExcludingShadow, - sizeof(RECT)); + GetWindowRect(hWnd, &frameIncludingShadow); + DwmGetWindowAttribute(hWnd, + DWMWA_EXTENDED_FRAME_BOUNDS, + &frameExcludingShadow, + sizeof(RECT)); - oc_rect extents = { - .x = frameIncludingShadow.left - frameExcludingShadow.left, - .y = frameIncludingShadow.top - frameExcludingShadow.top, - .w = frameIncludingShadow.right - frameExcludingShadow.right, - .h = frameIncludingShadow.bottom- frameExcludingShadow.bottom - }; + oc_rect extents = { + .x = frameIncludingShadow.left - frameExcludingShadow.left, + .y = frameIncludingShadow.top - frameExcludingShadow.top, + .w = frameIncludingShadow.right - frameExcludingShadow.right, + .h = frameIncludingShadow.bottom - frameExcludingShadow.bottom + }; - return(extents); + return (extents); } void oc_window_set_frame_rect(oc_window window, oc_rect rect) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - u32 dpi = GetDpiForWindow(windowData->win32.hWnd); - f32 scale = (float)dpi/96.; + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + u32 dpi = GetDpiForWindow(windowData->win32.hWnd); + f32 scale = (float)dpi / 96.; - //NOTE compute the size of the drop shadow to add it in setwindowpos - oc_rect shadowOffsets = oc_win32_get_drop_shadow_offsets(windowData->win32.hWnd); + //NOTE compute the size of the drop shadow to add it in setwindowpos + oc_rect shadowOffsets = oc_win32_get_drop_shadow_offsets(windowData->win32.hWnd); - RECT frame = { - rect.x * scale + shadowOffsets.x, - rect.y * scale + shadowOffsets.y, - (rect.x + rect.w)*scale + shadowOffsets.w, - (rect.y + rect.h)*scale + shadowOffsets.h - }; + RECT frame = { + rect.x * scale + shadowOffsets.x, + rect.y * scale + shadowOffsets.y, + (rect.x + rect.w) * scale + shadowOffsets.w, + (rect.y + rect.h) * scale + shadowOffsets.h + }; - SetWindowPos(windowData->win32.hWnd, - HWND_TOP, - frame.left, - frame.top, - frame.right - frame.left, - frame.bottom - frame.top, - SWP_NOZORDER|SWP_NOACTIVATE); - } + SetWindowPos(windowData->win32.hWnd, + HWND_TOP, + frame.left, + frame.top, + frame.right - frame.left, + frame.bottom - frame.top, + SWP_NOZORDER | SWP_NOACTIVATE); + } } oc_rect oc_window_get_content_rect(oc_window window) { - oc_rect rect = {0}; - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - RECT client; - if(GetClientRect(windowData->win32.hWnd, &client)) - { - u32 dpi = GetDpiForWindow(windowData->win32.hWnd); - f32 scale = (float)dpi/96.; + oc_rect rect = { 0 }; + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + RECT client; + if(GetClientRect(windowData->win32.hWnd, &client)) + { + u32 dpi = GetDpiForWindow(windowData->win32.hWnd); + f32 scale = (float)dpi / 96.; - POINT origin = {0, 0}; - ClientToScreen(windowData->win32.hWnd, &origin); + POINT origin = { 0, 0 }; + ClientToScreen(windowData->win32.hWnd, &origin); - rect = (oc_rect){ - origin.x/scale, - origin.y/scale, - (client.right - client.left)/scale, - (client.bottom - client.top)/scale}; - } - } - return(rect); + rect = (oc_rect){ + origin.x / scale, + origin.y / scale, + (client.right - client.left) / scale, + (client.bottom - client.top) / scale + }; + } + } + return (rect); } void oc_window_set_content_rect(oc_window window, oc_rect rect) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - u32 dpi = GetDpiForWindow(windowData->win32.hWnd); - f32 scale = (float)dpi/96.; + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + u32 dpi = GetDpiForWindow(windowData->win32.hWnd); + f32 scale = (float)dpi / 96.; - RECT frame = { - rect.x * scale, - rect.y * scale, - (rect.x + rect.w)*scale, - (rect.y + rect.h)*scale}; + RECT frame = { + rect.x * scale, + rect.y * scale, + (rect.x + rect.w) * scale, + (rect.y + rect.h) * scale + }; - DWORD style = GetWindowLong(windowData->win32.hWnd, GWL_STYLE); - BOOL menu = (GetMenu(windowData->win32.hWnd) != NULL); - AdjustWindowRect(&frame, style, menu); + DWORD style = GetWindowLong(windowData->win32.hWnd, GWL_STYLE); + BOOL menu = (GetMenu(windowData->win32.hWnd) != NULL); + AdjustWindowRect(&frame, style, menu); - SetWindowPos(windowData->win32.hWnd, - HWND_TOP, - frame.left, - frame.top, - frame.right - frame.left, - frame.bottom - frame.top, - SWP_NOZORDER|SWP_NOACTIVATE); - } + SetWindowPos(windowData->win32.hWnd, + HWND_TOP, + frame.left, + frame.top, + frame.right - frame.left, + frame.bottom - frame.top, + SWP_NOZORDER | SWP_NOACTIVATE); + } } void oc_window_center(oc_window window) { - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { - oc_rect frame = oc_window_get_frame_rect(window); + oc_rect frame = oc_window_get_frame_rect(window); - HMONITOR monitor = MonitorFromWindow(windowData->win32.hWnd, MONITOR_DEFAULTTOPRIMARY); - if(monitor) - { - MONITORINFO monitorInfo = {.cbSize = sizeof(MONITORINFO)}; - GetMonitorInfoW(monitor, &monitorInfo); + HMONITOR monitor = MonitorFromWindow(windowData->win32.hWnd, MONITOR_DEFAULTTOPRIMARY); + if(monitor) + { + MONITORINFO monitorInfo = { .cbSize = sizeof(MONITORINFO) }; + GetMonitorInfoW(monitor, &monitorInfo); - int dpiX, dpiY; - GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY); - f32 scaleX = dpiX/96.; - f32 scaleY = dpiY/96.; + int dpiX, dpiY; + GetDpiForMonitor(monitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY); + f32 scaleX = dpiX / 96.; + f32 scaleY = dpiY / 96.; - f32 monX = monitorInfo.rcWork.left/scaleX; - f32 monY = monitorInfo.rcWork.top/scaleY; - f32 monW = (monitorInfo.rcWork.right - monitorInfo.rcWork.left)/scaleX; - f32 monH = (monitorInfo.rcWork.bottom - monitorInfo.rcWork.top)/scaleY; + f32 monX = monitorInfo.rcWork.left / scaleX; + f32 monY = monitorInfo.rcWork.top / scaleY; + f32 monW = (monitorInfo.rcWork.right - monitorInfo.rcWork.left) / scaleX; + f32 monH = (monitorInfo.rcWork.bottom - monitorInfo.rcWork.top) / scaleY; - frame.x = monX + 0.5*(monW - frame.w); - frame.y = monY + 0.5*(monH - frame.h); + frame.x = monX + 0.5 * (monW - frame.w); + frame.y = monY + 0.5 * (monH - frame.h); - oc_window_set_frame_rect(window, frame); - } - } + oc_window_set_frame_rect(window, frame); + } + } } - //-------------------------------------------------------------------------------- // clipboard functions //-------------------------------------------------------------------------------- void oc_clipboard_clear(void) { - if(OpenClipboard(NULL)) - { - EmptyClipboard(); - CloseClipboard(); - } + if(OpenClipboard(NULL)) + { + EmptyClipboard(); + CloseClipboard(); + } } void oc_clipboard_set_string(oc_str8 string) { - if(OpenClipboard(NULL)) - { - EmptyClipboard(); + if(OpenClipboard(NULL)) + { + EmptyClipboard(); - int wideCount = MultiByteToWideChar(CP_UTF8, 0, string.ptr, string.len, 0, 0); - HANDLE handle = GlobalAlloc(GMEM_MOVEABLE, (wideCount+1)*sizeof(wchar_t)); - if(handle) - { - char* memory = GlobalLock(handle); - if(memory) - { - MultiByteToWideChar(CP_UTF8, 0, string.ptr, string.len, (wchar_t*)memory, wideCount); - ((wchar_t*)memory)[wideCount] = '\0'; + int wideCount = MultiByteToWideChar(CP_UTF8, 0, string.ptr, string.len, 0, 0); + HANDLE handle = GlobalAlloc(GMEM_MOVEABLE, (wideCount + 1) * sizeof(wchar_t)); + if(handle) + { + char* memory = GlobalLock(handle); + if(memory) + { + MultiByteToWideChar(CP_UTF8, 0, string.ptr, string.len, (wchar_t*)memory, wideCount); + ((wchar_t*)memory)[wideCount] = '\0'; - GlobalUnlock(handle); - SetClipboardData(CF_UNICODETEXT, handle); - } - } - CloseClipboard(); - } + GlobalUnlock(handle); + SetClipboardData(CF_UNICODETEXT, handle); + } + } + CloseClipboard(); + } } oc_str8 oc_clipboard_get_string(oc_arena* arena) { - oc_str8 string = {0}; + oc_str8 string = { 0 }; - if(OpenClipboard(NULL)) - { - HANDLE handle = GetClipboardData(CF_UNICODETEXT); - if(handle) - { - char* memory = GlobalLock(handle); - if(memory) - { - u64 size = WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)memory, -1, 0, 0, 0, 0); - if(size) - { - string.ptr = oc_arena_push(arena, size); - string.len = size - 1; - WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)memory, -1, string.ptr, size, 0, 0); - GlobalUnlock(handle); - } - } - } - CloseClipboard(); - } - return(string); + if(OpenClipboard(NULL)) + { + HANDLE handle = GetClipboardData(CF_UNICODETEXT); + if(handle) + { + char* memory = GlobalLock(handle); + if(memory) + { + u64 size = WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)memory, -1, 0, 0, 0, 0); + if(size) + { + string.ptr = oc_arena_push(arena, size); + string.len = size - 1; + WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)memory, -1, string.ptr, size, 0, 0); + GlobalUnlock(handle); + } + } + } + CloseClipboard(); + } + return (string); } oc_str8 oc_clipboard_copy_string(oc_str8 backing) { - //TODO - return((oc_str8){0}); + //TODO + return ((oc_str8){ 0 }); } - //-------------------------------------------------------------------------------- // win32 surfaces //-------------------------------------------------------------------------------- -#include"graphics/graphics_surface.h" +#include "graphics/graphics_surface.h" oc_vec2 oc_win32_surface_contents_scaling(oc_surface_data* surface) { - u32 dpi = GetDpiForWindow(surface->layer.hWnd); - oc_vec2 contentsScaling = (oc_vec2){(float)dpi/96., (float)dpi/96.}; - return(contentsScaling); + u32 dpi = GetDpiForWindow(surface->layer.hWnd); + oc_vec2 contentsScaling = (oc_vec2){ (float)dpi / 96., (float)dpi / 96. }; + return (contentsScaling); } oc_vec2 oc_win32_surface_get_size(oc_surface_data* surface) { - oc_vec2 size = {0}; - RECT rect; - if(GetClientRect(surface->layer.hWnd, &rect)) - { - u32 dpi = GetDpiForWindow(surface->layer.hWnd); - f32 scale = (float)dpi/96.; - size = (oc_vec2){(rect.right - rect.left)/scale, (rect.bottom - rect.top)/scale}; - } - return(size); + oc_vec2 size = { 0 }; + RECT rect; + if(GetClientRect(surface->layer.hWnd, &rect)) + { + u32 dpi = GetDpiForWindow(surface->layer.hWnd); + f32 scale = (float)dpi / 96.; + size = (oc_vec2){ (rect.right - rect.left) / scale, (rect.bottom - rect.top) / scale }; + } + return (size); } bool oc_win32_surface_get_hidden(oc_surface_data* surface) { - bool hidden = !IsWindowVisible(surface->layer.hWnd); - return(hidden); + bool hidden = !IsWindowVisible(surface->layer.hWnd); + return (hidden); } void oc_win32_surface_set_hidden(oc_surface_data* surface, bool hidden) { - ShowWindow(surface->layer.hWnd, hidden ? SW_HIDE : SW_NORMAL); + ShowWindow(surface->layer.hWnd, hidden ? SW_HIDE : SW_NORMAL); } void* oc_win32_surface_native_layer(oc_surface_data* surface) { - return((void*)surface->layer.hWnd); + return ((void*)surface->layer.hWnd); } oc_surface_id oc_win32_surface_remote_id(oc_surface_data* surface) { - return((oc_surface_id)surface->layer.hWnd); + return ((oc_surface_id)surface->layer.hWnd); } void oc_win32_surface_host_connect(oc_surface_data* surface, oc_surface_id remoteID) { - HWND dstWnd = surface->layer.hWnd; - HWND srcWnd = (HWND)remoteID; + HWND dstWnd = surface->layer.hWnd; + HWND srcWnd = (HWND)remoteID; - RECT dstRect; - GetClientRect(dstWnd, &dstRect); + RECT dstRect; + GetClientRect(dstWnd, &dstRect); - SetParent(srcWnd, dstWnd); - ShowWindow(srcWnd, SW_NORMAL); + SetParent(srcWnd, dstWnd); + ShowWindow(srcWnd, SW_NORMAL); - SetWindowPos(srcWnd, - HWND_TOP, - 0, - 0, - dstRect.right - dstRect.left, - dstRect.bottom - dstRect.top, - SWP_NOACTIVATE | SWP_NOZORDER); + SetWindowPos(srcWnd, + HWND_TOP, + 0, + 0, + dstRect.right - dstRect.left, + dstRect.bottom - dstRect.top, + SWP_NOACTIVATE | SWP_NOZORDER); } void oc_surface_cleanup(oc_surface_data* surface) { - oc_list_remove(&surface->layer.parent->win32.layers, &surface->layer.listElt); - DestroyWindow(surface->layer.hWnd); + oc_list_remove(&surface->layer.parent->win32.layers, &surface->layer.listElt); + DestroyWindow(surface->layer.hWnd); } LRESULT LayerWinProc(HWND windowHandle, UINT message, WPARAM wParam, LPARAM lParam) { - if(message == WM_NCHITTEST) - { - return(HTTRANSPARENT); - } - else - { - return(DefWindowProc(windowHandle, message, wParam, lParam)); - } + if(message == WM_NCHITTEST) + { + return (HTTRANSPARENT); + } + else + { + return (DefWindowProc(windowHandle, message, wParam, lParam)); + } } void oc_surface_init_for_window(oc_surface_data* surface, oc_window_data* window) { - surface->contentsScaling = oc_win32_surface_contents_scaling; - surface->getSize = oc_win32_surface_get_size; - surface->getHidden = oc_win32_surface_get_hidden; - surface->setHidden = oc_win32_surface_set_hidden; - surface->nativeLayer = oc_win32_surface_native_layer; + surface->contentsScaling = oc_win32_surface_contents_scaling; + surface->getSize = oc_win32_surface_get_size; + surface->getHidden = oc_win32_surface_get_hidden; + surface->setHidden = oc_win32_surface_set_hidden; + surface->nativeLayer = oc_win32_surface_native_layer; - //NOTE(martin): create a child window for the surface - WNDCLASS layerWindowClass = {.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC, - .lpfnWndProc = LayerWinProc, - .hInstance = GetModuleHandleW(NULL), - .lpszClassName = "layer_window_class", - .hCursor = LoadCursor(0, IDC_ARROW)}; + //NOTE(martin): create a child window for the surface + WNDCLASS layerWindowClass = { .style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC, + .lpfnWndProc = LayerWinProc, + .hInstance = GetModuleHandleW(NULL), + .lpszClassName = "layer_window_class", + .hCursor = LoadCursor(0, IDC_ARROW) }; - RegisterClass(&layerWindowClass); + RegisterClass(&layerWindowClass); - RECT parentRect; - GetClientRect(window->win32.hWnd, &parentRect); - POINT point = {0}; - ClientToScreen(window->win32.hWnd, &point); + RECT parentRect; + GetClientRect(window->win32.hWnd, &parentRect); + POINT point = { 0 }; + ClientToScreen(window->win32.hWnd, &point); - int clientWidth = parentRect.right - parentRect.left; - int clientHeight = parentRect.bottom - parentRect.top; + int clientWidth = parentRect.right - parentRect.left; + int clientHeight = parentRect.bottom - parentRect.top; - surface->layer.hWnd = CreateWindow("layer_window_class", "layer", - WS_POPUP | WS_VISIBLE, - point.x, point.y, clientWidth, clientHeight, - window->win32.hWnd, - 0, - layerWindowClass.hInstance, - 0); + surface->layer.hWnd = CreateWindow("layer_window_class", "layer", + WS_POPUP | WS_VISIBLE, + point.x, point.y, clientWidth, clientHeight, + window->win32.hWnd, + 0, + layerWindowClass.hInstance, + 0); - HRGN region = CreateRectRgn(0, 0, -1, -1); + HRGN region = CreateRectRgn(0, 0, -1, -1); - DWM_BLURBEHIND bb = {0}; - bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; - bb.hRgnBlur = region; - bb.fEnable = TRUE; + DWM_BLURBEHIND bb = { 0 }; + bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION; + bb.hRgnBlur = region; + bb.fEnable = TRUE; - HRESULT res = DwmEnableBlurBehindWindow(surface->layer.hWnd, &bb); + HRESULT res = DwmEnableBlurBehindWindow(surface->layer.hWnd, &bb); - DeleteObject(region); - if(res != S_OK) - { - oc_log_error("couldn't enable blur behind\n"); - } + DeleteObject(region); + if(res != S_OK) + { + oc_log_error("couldn't enable blur behind\n"); + } - surface->layer.parent = window; - oc_list_append(&window->win32.layers, &surface->layer.listElt); + surface->layer.parent = window; + oc_list_append(&window->win32.layers, &surface->layer.listElt); } void oc_surface_init_remote(oc_surface_data* surface, u32 width, u32 height) { - surface->contentsScaling = oc_win32_surface_contents_scaling; - surface->getSize = oc_win32_surface_get_size; - surface->getHidden = oc_win32_surface_get_hidden; - surface->setHidden = oc_win32_surface_set_hidden; - surface->nativeLayer = oc_win32_surface_native_layer; - surface->remoteID = oc_win32_surface_remote_id; + surface->contentsScaling = oc_win32_surface_contents_scaling; + surface->getSize = oc_win32_surface_get_size; + surface->getHidden = oc_win32_surface_get_hidden; + surface->setHidden = oc_win32_surface_set_hidden; + surface->nativeLayer = oc_win32_surface_native_layer; + surface->remoteID = oc_win32_surface_remote_id; - WNDCLASS layerWindowClass = {.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC, - .lpfnWndProc = DefWindowProc, - .hInstance = GetModuleHandleW(NULL), - .lpszClassName = "server_layer_window_class", - .hCursor = LoadCursor(0, IDC_ARROW)}; + WNDCLASS layerWindowClass = { .style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC, + .lpfnWndProc = DefWindowProc, + .hInstance = GetModuleHandleW(NULL), + .lpszClassName = "server_layer_window_class", + .hCursor = LoadCursor(0, IDC_ARROW) }; - RegisterClass(&layerWindowClass); + RegisterClass(&layerWindowClass); - //NOTE(martin): create a temporary parent window. This seems like a necessary hack, because if layer window is created as - // a normal window first, and then parented to the client window, it breaks resizing the parent - // window for some reason... - HWND tmpParent = CreateWindow("server_layer_window_class", "layerParent", - WS_OVERLAPPED, - 0, 0, width, height, - 0, - 0, - layerWindowClass.hInstance, - 0); + //NOTE(martin): create a temporary parent window. This seems like a necessary hack, because if layer window is created as + // a normal window first, and then parented to the client window, it breaks resizing the parent + // window for some reason... + HWND tmpParent = CreateWindow("server_layer_window_class", "layerParent", + WS_OVERLAPPED, + 0, 0, width, height, + 0, + 0, + layerWindowClass.hInstance, + 0); - //NOTE: create the layer window - surface->layer.hWnd = CreateWindowEx(WS_EX_NOACTIVATE, - "server_layer_window_class", "layer", - WS_CHILD, - 0, 0, width, height, - tmpParent, - 0, - layerWindowClass.hInstance, - 0); + //NOTE: create the layer window + surface->layer.hWnd = CreateWindowEx(WS_EX_NOACTIVATE, + "server_layer_window_class", "layer", + WS_CHILD, + 0, 0, width, height, + tmpParent, + 0, + layerWindowClass.hInstance, + 0); - //NOTE: unparent it and destroy tmp parent - SetParent(surface->layer.hWnd, 0); - DestroyWindow(tmpParent); + //NOTE: unparent it and destroy tmp parent + SetParent(surface->layer.hWnd, 0); + DestroyWindow(tmpParent); } oc_surface_data* oc_win32_surface_create_host(oc_window window) { - oc_surface_data* surface = 0; - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - surface = oc_malloc_type(oc_surface_data); - if(surface) - { - memset(surface, 0, sizeof(oc_surface_data)); - oc_surface_init_for_window(surface, windowData); + oc_surface_data* surface = 0; + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + surface = oc_malloc_type(oc_surface_data); + if(surface) + { + memset(surface, 0, sizeof(oc_surface_data)); + oc_surface_init_for_window(surface, windowData); - surface->api = OC_HOST; - surface->hostConnect = oc_win32_surface_host_connect; - } - } - return(surface); + surface->api = OC_HOST; + surface->hostConnect = oc_win32_surface_host_connect; + } + } + return (surface); } //-------------------------------------------------------------------- @@ -1303,259 +1326,257 @@ oc_surface_data* oc_win32_surface_create_host(oc_window window) // requires filters which pair a "descriptive" name with an extension #define interface struct -#include -#include +#include +#include #undef interface - oc_str8 oc_open_dialog(oc_arena* arena, oc_str8 title, oc_str8 defaultPath, oc_str8_list filters, bool directory) { - oc_str8 res = {0}; - HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); - if(SUCCEEDED(hr)) - { - IFileOpenDialog* dialog = 0; - hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_ALL, &IID_IFileOpenDialog, (void**)&dialog); - if(SUCCEEDED(hr)) - { - if(directory) - { - FILEOPENDIALOGOPTIONS opt; - dialog->lpVtbl->GetOptions(dialog, &opt); - dialog->lpVtbl->SetOptions(dialog, opt | FOS_PICKFOLDERS); - } + oc_str8 res = { 0 }; + HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + if(SUCCEEDED(hr)) + { + IFileOpenDialog* dialog = 0; + hr = CoCreateInstance(&CLSID_FileOpenDialog, NULL, CLSCTX_ALL, &IID_IFileOpenDialog, (void**)&dialog); + if(SUCCEEDED(hr)) + { + if(directory) + { + FILEOPENDIALOGOPTIONS opt; + dialog->lpVtbl->GetOptions(dialog, &opt); + dialog->lpVtbl->SetOptions(dialog, opt | FOS_PICKFOLDERS); + } - if(filters.eltCount) - { - oc_arena_scope tmp = oc_arena_scope_begin(arena); - COMDLG_FILTERSPEC* filterSpecs = oc_arena_push_array(arena, COMDLG_FILTERSPEC, filters.eltCount); + if(filters.eltCount) + { + oc_arena_scope tmp = oc_arena_scope_begin(arena); + COMDLG_FILTERSPEC* filterSpecs = oc_arena_push_array(arena, COMDLG_FILTERSPEC, filters.eltCount); - int i = 0; - oc_list_for(&filters.list, elt, oc_str8_elt, listElt) - { - oc_str8_list list = {0}; - oc_str8_list_push(arena, &list, OC_STR8("*.")); - oc_str8_list_push(arena, &list, elt->string); - oc_str8 filter = oc_str8_list_join(arena, list); + int i = 0; + oc_list_for(&filters.list, elt, oc_str8_elt, listElt) + { + oc_str8_list list = { 0 }; + oc_str8_list_push(arena, &list, OC_STR8("*.")); + oc_str8_list_push(arena, &list, elt->string); + oc_str8 filter = oc_str8_list_join(arena, list); - int filterWideSize = 1 + MultiByteToWideChar(CP_UTF8, 0, filter.ptr, filter.len, NULL, 0); - filterSpecs[i].pszSpec = oc_arena_push_array(arena, wchar_t, filterWideSize); - MultiByteToWideChar(CP_UTF8, 0, filter.ptr, filter.len, (LPWSTR)filterSpecs[i].pszSpec, filterWideSize); - ((LPWSTR)(filterSpecs[i].pszSpec))[filterWideSize-1] = 0; + int filterWideSize = 1 + MultiByteToWideChar(CP_UTF8, 0, filter.ptr, filter.len, NULL, 0); + filterSpecs[i].pszSpec = oc_arena_push_array(arena, wchar_t, filterWideSize); + MultiByteToWideChar(CP_UTF8, 0, filter.ptr, filter.len, (LPWSTR)filterSpecs[i].pszSpec, filterWideSize); + ((LPWSTR)(filterSpecs[i].pszSpec))[filterWideSize - 1] = 0; - filterSpecs[i].pszName = filterSpecs[i].pszSpec; - i++; - } + filterSpecs[i].pszName = filterSpecs[i].pszSpec; + i++; + } - hr = dialog->lpVtbl->SetFileTypes(dialog, i, filterSpecs); + hr = dialog->lpVtbl->SetFileTypes(dialog, i, filterSpecs); - oc_arena_scope_end(tmp); - } + oc_arena_scope_end(tmp); + } - if(defaultPath.len) - { - oc_arena_scope tmp = oc_arena_scope_begin(arena); - int pathWideSize = MultiByteToWideChar(CP_UTF8, 0, defaultPath.ptr, defaultPath.len, NULL, 0); - LPWSTR pathWide = oc_arena_push_array(arena, wchar_t, pathWideSize+1); - MultiByteToWideChar(CP_UTF8, 0, defaultPath.ptr, defaultPath.len, pathWide, pathWideSize); - pathWide[pathWideSize] = '\0'; + if(defaultPath.len) + { + oc_arena_scope tmp = oc_arena_scope_begin(arena); + int pathWideSize = MultiByteToWideChar(CP_UTF8, 0, defaultPath.ptr, defaultPath.len, NULL, 0); + LPWSTR pathWide = oc_arena_push_array(arena, wchar_t, pathWideSize + 1); + MultiByteToWideChar(CP_UTF8, 0, defaultPath.ptr, defaultPath.len, pathWide, pathWideSize); + pathWide[pathWideSize] = '\0'; - IShellItem* item = 0; - hr = SHCreateItemFromParsingName(pathWide, NULL, &IID_IShellItem, (void**)&item); - if(SUCCEEDED(hr)) - { - hr = dialog->lpVtbl->SetFolder(dialog, item); - item->lpVtbl->Release(item); - } - oc_arena_scope_end(tmp); - } + IShellItem* item = 0; + hr = SHCreateItemFromParsingName(pathWide, NULL, &IID_IShellItem, (void**)&item); + if(SUCCEEDED(hr)) + { + hr = dialog->lpVtbl->SetFolder(dialog, item); + item->lpVtbl->Release(item); + } + oc_arena_scope_end(tmp); + } - hr = dialog->lpVtbl->Show(dialog, NULL); - if(SUCCEEDED(hr)) - { - IShellItem* item; - hr = dialog->lpVtbl->GetResult(dialog, &item); - if(SUCCEEDED(hr)) - { - PWSTR filePath; - hr = item->lpVtbl->GetDisplayName(item, SIGDN_FILESYSPATH, &filePath); + hr = dialog->lpVtbl->Show(dialog, NULL); + if(SUCCEEDED(hr)) + { + IShellItem* item; + hr = dialog->lpVtbl->GetResult(dialog, &item); + if(SUCCEEDED(hr)) + { + PWSTR filePath; + hr = item->lpVtbl->GetDisplayName(item, SIGDN_FILESYSPATH, &filePath); - if(SUCCEEDED(hr)) - { - int oc_utf8Size = WideCharToMultiByte(CP_UTF8, 0, filePath, -1, NULL, 0, NULL, NULL); - if(oc_utf8Size > 0) - { - res.ptr = oc_arena_push(arena, oc_utf8Size); - res.len = oc_utf8Size-1; - WideCharToMultiByte(CP_UTF8, 0, filePath, -1, res.ptr, oc_utf8Size, NULL, NULL); - } - CoTaskMemFree(filePath); - } - item->lpVtbl->Release(item); - } - } - } - } - CoUninitialize(); - return(res); + if(SUCCEEDED(hr)) + { + int oc_utf8Size = WideCharToMultiByte(CP_UTF8, 0, filePath, -1, NULL, 0, NULL, NULL); + if(oc_utf8Size > 0) + { + res.ptr = oc_arena_push(arena, oc_utf8Size); + res.len = oc_utf8Size - 1; + WideCharToMultiByte(CP_UTF8, 0, filePath, -1, res.ptr, oc_utf8Size, NULL, NULL); + } + CoTaskMemFree(filePath); + } + item->lpVtbl->Release(item); + } + } + } + } + CoUninitialize(); + return (res); } oc_str8 oc_save_dialog(oc_arena* arena, - oc_str8 title, - oc_str8 defaultPath, - oc_str8_list filters) + oc_str8 title, + oc_str8 defaultPath, + oc_str8_list filters) { - oc_str8 res = {0}; - HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); - if(SUCCEEDED(hr)) - { - IFileOpenDialog* dialog = 0; - hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_ALL, &IID_IFileSaveDialog, (void**)&dialog); - if(SUCCEEDED(hr)) - { - if(filters.eltCount) - { - oc_arena_scope tmp = oc_arena_scope_begin(arena); - COMDLG_FILTERSPEC* filterSpecs = oc_arena_push_array(arena, COMDLG_FILTERSPEC, filters.eltCount); + oc_str8 res = { 0 }; + HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + if(SUCCEEDED(hr)) + { + IFileOpenDialog* dialog = 0; + hr = CoCreateInstance(&CLSID_FileSaveDialog, NULL, CLSCTX_ALL, &IID_IFileSaveDialog, (void**)&dialog); + if(SUCCEEDED(hr)) + { + if(filters.eltCount) + { + oc_arena_scope tmp = oc_arena_scope_begin(arena); + COMDLG_FILTERSPEC* filterSpecs = oc_arena_push_array(arena, COMDLG_FILTERSPEC, filters.eltCount); - int i = 0; - oc_list_for(&filters.list, elt, oc_str8_elt, listElt) - { - oc_str8_list list = {0}; - oc_str8_list_push(arena, &list, OC_STR8("*.")); - oc_str8_list_push(arena, &list, elt->string); - oc_str8 filter = oc_str8_list_join(arena, list); + int i = 0; + oc_list_for(&filters.list, elt, oc_str8_elt, listElt) + { + oc_str8_list list = { 0 }; + oc_str8_list_push(arena, &list, OC_STR8("*.")); + oc_str8_list_push(arena, &list, elt->string); + oc_str8 filter = oc_str8_list_join(arena, list); - int filterWideSize = 1 + MultiByteToWideChar(CP_UTF8, 0, filter.ptr, filter.len, NULL, 0); - filterSpecs[i].pszSpec = oc_arena_push_array(arena, wchar_t, filterWideSize); - MultiByteToWideChar(CP_UTF8, 0, filter.ptr, filter.len, (LPWSTR)filterSpecs[i].pszSpec, filterWideSize); - ((LPWSTR)(filterSpecs[i].pszSpec))[filterWideSize-1] = 0; + int filterWideSize = 1 + MultiByteToWideChar(CP_UTF8, 0, filter.ptr, filter.len, NULL, 0); + filterSpecs[i].pszSpec = oc_arena_push_array(arena, wchar_t, filterWideSize); + MultiByteToWideChar(CP_UTF8, 0, filter.ptr, filter.len, (LPWSTR)filterSpecs[i].pszSpec, filterWideSize); + ((LPWSTR)(filterSpecs[i].pszSpec))[filterWideSize - 1] = 0; - filterSpecs[i].pszName = filterSpecs[i].pszSpec; - i++; - } + filterSpecs[i].pszName = filterSpecs[i].pszSpec; + i++; + } - hr = dialog->lpVtbl->SetFileTypes(dialog, i, filterSpecs); + hr = dialog->lpVtbl->SetFileTypes(dialog, i, filterSpecs); - oc_arena_scope_end(tmp); - } + oc_arena_scope_end(tmp); + } - if(defaultPath.len) - { - oc_arena_scope tmp = oc_arena_scope_begin(arena); - int pathWideSize = MultiByteToWideChar(CP_UTF8, 0, defaultPath.ptr, defaultPath.len, NULL, 0); - LPWSTR pathWide = oc_arena_push_array(arena, wchar_t, pathWideSize + 1); - MultiByteToWideChar(CP_UTF8, 0, defaultPath.ptr, defaultPath.len, pathWide, pathWideSize); - pathWide[pathWideSize] = '\0'; + if(defaultPath.len) + { + oc_arena_scope tmp = oc_arena_scope_begin(arena); + int pathWideSize = MultiByteToWideChar(CP_UTF8, 0, defaultPath.ptr, defaultPath.len, NULL, 0); + LPWSTR pathWide = oc_arena_push_array(arena, wchar_t, pathWideSize + 1); + MultiByteToWideChar(CP_UTF8, 0, defaultPath.ptr, defaultPath.len, pathWide, pathWideSize); + pathWide[pathWideSize] = '\0'; - IShellItem* item = 0; - hr = SHCreateItemFromParsingName(pathWide, NULL, &IID_IShellItem, (void**)&item); - if(SUCCEEDED(hr)) - { - hr = dialog->lpVtbl->SetFolder(dialog, item); - item->lpVtbl->Release(item); - } - oc_arena_scope_end(tmp); - } + IShellItem* item = 0; + hr = SHCreateItemFromParsingName(pathWide, NULL, &IID_IShellItem, (void**)&item); + if(SUCCEEDED(hr)) + { + hr = dialog->lpVtbl->SetFolder(dialog, item); + item->lpVtbl->Release(item); + } + oc_arena_scope_end(tmp); + } - hr = dialog->lpVtbl->Show(dialog, NULL); - if(SUCCEEDED(hr)) - { - IShellItem* item; - hr = dialog->lpVtbl->GetResult(dialog, &item); - if(SUCCEEDED(hr)) - { - PWSTR filePath; - hr = item->lpVtbl->GetDisplayName(item, SIGDN_FILESYSPATH, &filePath); + hr = dialog->lpVtbl->Show(dialog, NULL); + if(SUCCEEDED(hr)) + { + IShellItem* item; + hr = dialog->lpVtbl->GetResult(dialog, &item); + if(SUCCEEDED(hr)) + { + PWSTR filePath; + hr = item->lpVtbl->GetDisplayName(item, SIGDN_FILESYSPATH, &filePath); - if(SUCCEEDED(hr)) - { - int oc_utf8Size = WideCharToMultiByte(CP_UTF8, 0, filePath, -1, NULL, 0, NULL, NULL); - if(oc_utf8Size > 0) - { - res.ptr = oc_arena_push(arena, oc_utf8Size); - res.len = oc_utf8Size-1; - WideCharToMultiByte(CP_UTF8, 0, filePath, -1, res.ptr, oc_utf8Size, NULL, NULL); - } - CoTaskMemFree(filePath); - } - item->lpVtbl->Release(item); - } - } - } - } - CoUninitialize(); - return(res); + if(SUCCEEDED(hr)) + { + int oc_utf8Size = WideCharToMultiByte(CP_UTF8, 0, filePath, -1, NULL, 0, NULL, NULL); + if(oc_utf8Size > 0) + { + res.ptr = oc_arena_push(arena, oc_utf8Size); + res.len = oc_utf8Size - 1; + WideCharToMultiByte(CP_UTF8, 0, filePath, -1, res.ptr, oc_utf8Size, NULL, NULL); + } + CoTaskMemFree(filePath); + } + item->lpVtbl->Release(item); + } + } + } + } + CoUninitialize(); + return (res); } -#include +#include int oc_alert_popup(oc_str8 title, oc_str8 message, oc_str8_list options) { - oc_arena_scope scratch = oc_scratch_begin(); - TASKDIALOG_BUTTON* buttons = oc_arena_push_array(scratch.arena, TASKDIALOG_BUTTON, options.eltCount); + oc_arena_scope scratch = oc_scratch_begin(); + TASKDIALOG_BUTTON* buttons = oc_arena_push_array(scratch.arena, TASKDIALOG_BUTTON, options.eltCount); - int i = 0; - oc_list_for(&options.list, elt, oc_str8_elt, listElt) - { - int textWideSize = MultiByteToWideChar(CP_UTF8, 0, elt->string.ptr, elt->string.len, NULL, 0); - wchar_t* textWide = oc_arena_push_array(scratch.arena, wchar_t, textWideSize + 1); - MultiByteToWideChar(CP_UTF8, 0, elt->string.ptr, elt->string.len, textWide, textWideSize); - textWide[textWideSize] = '\0'; + int i = 0; + oc_list_for(&options.list, elt, oc_str8_elt, listElt) + { + int textWideSize = MultiByteToWideChar(CP_UTF8, 0, elt->string.ptr, elt->string.len, NULL, 0); + wchar_t* textWide = oc_arena_push_array(scratch.arena, wchar_t, textWideSize + 1); + MultiByteToWideChar(CP_UTF8, 0, elt->string.ptr, elt->string.len, textWide, textWideSize); + textWide[textWideSize] = '\0'; - buttons[i].nButtonID = i+1; - buttons[i].pszButtonText = textWide; + buttons[i].nButtonID = i + 1; + buttons[i].pszButtonText = textWide; - i++; - } + i++; + } - int titleWideSize = MultiByteToWideChar(CP_UTF8, 0, title.ptr, title.len, NULL, 0); - wchar_t* titleWide = oc_arena_push_array(scratch.arena, wchar_t, titleWideSize + 1); - MultiByteToWideChar(CP_UTF8, 0, title.ptr, title.len, titleWide, titleWideSize); - titleWide[titleWideSize] = '\0'; + int titleWideSize = MultiByteToWideChar(CP_UTF8, 0, title.ptr, title.len, NULL, 0); + wchar_t* titleWide = oc_arena_push_array(scratch.arena, wchar_t, titleWideSize + 1); + MultiByteToWideChar(CP_UTF8, 0, title.ptr, title.len, titleWide, titleWideSize); + titleWide[titleWideSize] = '\0'; - int messageWideSize = MultiByteToWideChar(CP_UTF8, 0, message.ptr, message.len, NULL, 0); - wchar_t* messageWide = oc_arena_push_array(scratch.arena, wchar_t, messageWideSize + 1); - MultiByteToWideChar(CP_UTF8, 0, message.ptr, message.len, messageWide, messageWideSize); - messageWide[messageWideSize] = '\0'; + int messageWideSize = MultiByteToWideChar(CP_UTF8, 0, message.ptr, message.len, NULL, 0); + wchar_t* messageWide = oc_arena_push_array(scratch.arena, wchar_t, messageWideSize + 1); + MultiByteToWideChar(CP_UTF8, 0, message.ptr, message.len, messageWide, messageWideSize); + messageWide[messageWideSize] = '\0'; - TASKDIALOGCONFIG config = - { - .cbSize = sizeof(TASKDIALOGCONFIG), - .hwndParent = NULL, - .hInstance = NULL, - .dwFlags = 0, - .dwCommonButtons = 0, - .pszWindowTitle = titleWide, - .hMainIcon = 0, - .pszMainIcon = TD_WARNING_ICON, - .pszMainInstruction = messageWide, - .pszContent = NULL, - .cButtons = options.eltCount, - .pButtons = buttons, - .nDefaultButton = 0, - }; + TASKDIALOGCONFIG config = { + .cbSize = sizeof(TASKDIALOGCONFIG), + .hwndParent = NULL, + .hInstance = NULL, + .dwFlags = 0, + .dwCommonButtons = 0, + .pszWindowTitle = titleWide, + .hMainIcon = 0, + .pszMainIcon = TD_WARNING_ICON, + .pszMainInstruction = messageWide, + .pszContent = NULL, + .cButtons = options.eltCount, + .pButtons = buttons, + .nDefaultButton = 0, + }; - int button = -1; - HRESULT hRes = TaskDialogIndirect(&config, &button, NULL, NULL); - if(hRes == S_OK) - { - if(button == IDCANCEL) - { - button = -1; - } - else - { - button--; - } - } + int button = -1; + HRESULT hRes = TaskDialogIndirect(&config, &button, NULL, NULL); + if(hRes == S_OK) + { + if(button == IDCANCEL) + { + button = -1; + } + else + { + button--; + } + } - oc_scratch_end(scratch); - return(button); + oc_scratch_end(scratch); + return (button); } diff --git a/src/app/win32_app.h b/src/app/win32_app.h index 45a0ca7..8f41e84 100644 --- a/src/app/win32_app.h +++ b/src/app/win32_app.h @@ -10,37 +10,37 @@ #ifndef __WIN32_APP_H_ #define __WIN32_APP_H_ -#include"app.h" +#include "app.h" #define WIN32_LEAN_AND_MEAN #define UNICODE -#include - +#include typedef struct oc_win32_window_data { - HWND hWnd; - oc_list layers; + HWND hWnd; + oc_list layers; } oc_win32_window_data; typedef struct oc_window_data oc_window_data; + typedef struct oc_layer { - oc_window_data* parent; - oc_list_elt listElt; - HWND hWnd; + oc_window_data* parent; + oc_list_elt listElt; + HWND hWnd; } oc_layer; #define OC_PLATFORM_WINDOW_DATA oc_win32_window_data win32; typedef struct oc_win32_app_data { - u32 savedConsoleCodePage; + u32 savedConsoleCodePage; - int mouseCaptureMask; - bool mouseTracked; - oc_vec2 lastMousePos; - u32 wheelScrollLines; + int mouseCaptureMask; + bool mouseTracked; + oc_vec2 lastMousePos; + u32 wheelScrollLines; } oc_win32_app_data; @@ -48,7 +48,7 @@ typedef struct oc_win32_app_data enum OC_WM_USER { - OC_WM_USER_DISPATCH_PROC = 0x0400, // WM_USER messages are defined from 0x400 to 0x7FFF + OC_WM_USER_DISPATCH_PROC = 0x0400, // WM_USER messages are defined from 0x400 to 0x7FFF }; #endif __WIN32_APP_H_ diff --git a/src/graphics/egl_surface.c b/src/graphics/egl_surface.c index 132078d..1fdaf0f 100644 --- a/src/graphics/egl_surface.c +++ b/src/graphics/egl_surface.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: egl_surface.cpp * @author: Martin Fouilleul @@ -8,176 +8,178 @@ *****************************************************************/ #define EGL_EGLEXT_PROTOTYPES -#include -#include -#include"app/app_internal.h" -#include"graphics_surface.h" -#include"gl_loader.h" +#include "app/app_internal.h" +#include "gl_loader.h" +#include "graphics_surface.h" +#include +#include #if OC_PLATFORM_MACOS - //NOTE: EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE on osx defaults to CGL backend, which doesn't handle SwapInterval correctly - #define OC_EGL_PLATFORM_ANGLE_TYPE EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE + //NOTE: EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE on osx defaults to CGL backend, which doesn't handle SwapInterval correctly + #define OC_EGL_PLATFORM_ANGLE_TYPE EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE - //NOTE: hardcode GLES versions for now - //TODO: use version hints, once we have all api versions correctly categorized by glapi.py - #define OC_GLES_VERSION_MAJOR 3 - #define OC_GLES_VERSION_MINOR 0 - #define oc_gl_load_gles oc_gl_load_gles31 + //NOTE: hardcode GLES versions for now + //TODO: use version hints, once we have all api versions correctly categorized by glapi.py + #define OC_GLES_VERSION_MAJOR 3 + #define OC_GLES_VERSION_MINOR 0 + #define oc_gl_load_gles oc_gl_load_gles31 #else - #define OC_EGL_PLATFORM_ANGLE_TYPE EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE - #define OC_GLES_VERSION_MAJOR 3 - #define OC_GLES_VERSION_MINOR 1 - #define oc_gl_load_gles oc_gl_load_gles32 + #define OC_EGL_PLATFORM_ANGLE_TYPE EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE + #define OC_GLES_VERSION_MAJOR 3 + #define OC_GLES_VERSION_MINOR 1 + #define oc_gl_load_gles oc_gl_load_gles32 #endif - typedef struct oc_egl_surface { - oc_surface_data interface; + oc_surface_data interface; - EGLDisplay eglDisplay; - EGLConfig eglConfig; - EGLContext eglContext; - EGLSurface eglSurface; + EGLDisplay eglDisplay; + EGLConfig eglConfig; + EGLContext eglContext; + EGLSurface eglSurface; - oc_gl_api api; + oc_gl_api api; } oc_egl_surface; void oc_egl_surface_destroy(oc_surface_data* interface) { - oc_egl_surface* surface = (oc_egl_surface*)interface; + oc_egl_surface* surface = (oc_egl_surface*)interface; - if(&surface->api == oc_gl_get_api()) - { - oc_gl_deselect_api(); - } - if(eglGetCurrentContext() == surface->eglContext) - { - eglMakeCurrent(surface->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - } - eglDestroyContext(surface->eglDisplay, surface->eglContext); - eglDestroySurface(surface->eglDisplay, surface->eglSurface); + if(&surface->api == oc_gl_get_api()) + { + oc_gl_deselect_api(); + } + if(eglGetCurrentContext() == surface->eglContext) + { + eglMakeCurrent(surface->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + } + eglDestroyContext(surface->eglDisplay, surface->eglContext); + eglDestroySurface(surface->eglDisplay, surface->eglSurface); - oc_surface_cleanup((oc_surface_data*)surface); - free(surface); + oc_surface_cleanup((oc_surface_data*)surface); + free(surface); } void oc_egl_surface_prepare(oc_surface_data* interface) { - oc_egl_surface* surface = (oc_egl_surface*)interface; - eglMakeCurrent(surface->eglDisplay, surface->eglSurface, surface->eglSurface, surface->eglContext); - oc_gl_select_api(&surface->api); + oc_egl_surface* surface = (oc_egl_surface*)interface; + eglMakeCurrent(surface->eglDisplay, surface->eglSurface, surface->eglSurface, surface->eglContext); + oc_gl_select_api(&surface->api); } void oc_egl_surface_present(oc_surface_data* interface) { - oc_egl_surface* surface = (oc_egl_surface*)interface; - eglSwapBuffers(surface->eglDisplay, surface->eglSurface); + oc_egl_surface* surface = (oc_egl_surface*)interface; + eglSwapBuffers(surface->eglDisplay, surface->eglSurface); } void oc_egl_surface_deselect(oc_surface_data* interface) { - oc_egl_surface* surface = (oc_egl_surface*)interface; - eglMakeCurrent(surface->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - oc_gl_deselect_api(); + oc_egl_surface* surface = (oc_egl_surface*)interface; + eglMakeCurrent(surface->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + oc_gl_deselect_api(); } void oc_egl_surface_swap_interval(oc_surface_data* interface, int swap) { - oc_egl_surface* surface = (oc_egl_surface*)interface; - eglSwapInterval(surface->eglDisplay, swap); + oc_egl_surface* surface = (oc_egl_surface*)interface; + eglSwapInterval(surface->eglDisplay, swap); } void oc_egl_surface_init(oc_egl_surface* surface) { - void* nativeLayer = surface->interface.nativeLayer((oc_surface_data*)surface); + void* nativeLayer = surface->interface.nativeLayer((oc_surface_data*)surface); - surface->interface.api = OC_GLES; + surface->interface.api = OC_GLES; - surface->interface.destroy = oc_egl_surface_destroy; - surface->interface.prepare = oc_egl_surface_prepare; - surface->interface.present = oc_egl_surface_present; - surface->interface.deselect = oc_egl_surface_deselect; - surface->interface.swapInterval = oc_egl_surface_swap_interval; + surface->interface.destroy = oc_egl_surface_destroy; + surface->interface.prepare = oc_egl_surface_prepare; + surface->interface.present = oc_egl_surface_present; + surface->interface.deselect = oc_egl_surface_deselect; + surface->interface.swapInterval = oc_egl_surface_swap_interval; - EGLAttrib displayAttribs[] = { - EGL_PLATFORM_ANGLE_TYPE_ANGLE, OC_EGL_PLATFORM_ANGLE_TYPE, - EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, - EGL_NONE}; + EGLAttrib displayAttribs[] = { + EGL_PLATFORM_ANGLE_TYPE_ANGLE, OC_EGL_PLATFORM_ANGLE_TYPE, + EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE, + EGL_NONE + }; - surface->eglDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE, (void*)EGL_DEFAULT_DISPLAY, displayAttribs); - eglInitialize(surface->eglDisplay, NULL, NULL); + surface->eglDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE, (void*)EGL_DEFAULT_DISPLAY, displayAttribs); + eglInitialize(surface->eglDisplay, NULL, NULL); - EGLint const configAttributes[] = { - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_ALPHA_SIZE, 8, - EGL_DEPTH_SIZE, 24, - EGL_STENCIL_SIZE, 8, - EGL_SAMPLE_BUFFERS, 0, - EGL_SAMPLES, EGL_DONT_CARE, - EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT, - EGL_NONE }; + EGLint const configAttributes[] = { + EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_DEPTH_SIZE, 24, + EGL_STENCIL_SIZE, 8, + EGL_SAMPLE_BUFFERS, 0, + EGL_SAMPLES, EGL_DONT_CARE, + EGL_COLOR_COMPONENT_TYPE_EXT, EGL_COLOR_COMPONENT_TYPE_FIXED_EXT, + EGL_NONE + }; - int numConfigs = 0; - eglChooseConfig(surface->eglDisplay, configAttributes, &surface->eglConfig, 1, &numConfigs); + int numConfigs = 0; + eglChooseConfig(surface->eglDisplay, configAttributes, &surface->eglConfig, 1, &numConfigs); - EGLint const surfaceAttributes[] = {EGL_NONE}; - surface->eglSurface = eglCreateWindowSurface(surface->eglDisplay, - surface->eglConfig, - nativeLayer, - surfaceAttributes); + EGLint const surfaceAttributes[] = { EGL_NONE }; + surface->eglSurface = eglCreateWindowSurface(surface->eglDisplay, + surface->eglConfig, + nativeLayer, + surfaceAttributes); - eglBindAPI(EGL_OPENGL_ES_API); - EGLint contextAttributes[] = { - EGL_CONTEXT_MAJOR_VERSION_KHR, OC_GLES_VERSION_MAJOR, - EGL_CONTEXT_MINOR_VERSION_KHR, OC_GLES_VERSION_MINOR, - EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE, - EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE, - EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE, EGL_FALSE, - EGL_NONE}; + eglBindAPI(EGL_OPENGL_ES_API); + EGLint contextAttributes[] = { + EGL_CONTEXT_MAJOR_VERSION_KHR, OC_GLES_VERSION_MAJOR, + EGL_CONTEXT_MINOR_VERSION_KHR, OC_GLES_VERSION_MINOR, + EGL_CONTEXT_BIND_GENERATES_RESOURCE_CHROMIUM, EGL_TRUE, + EGL_CONTEXT_CLIENT_ARRAYS_ENABLED_ANGLE, EGL_TRUE, + EGL_CONTEXT_OPENGL_BACKWARDS_COMPATIBLE_ANGLE, EGL_FALSE, + EGL_NONE + }; - surface->eglContext = eglCreateContext(surface->eglDisplay, surface->eglConfig, EGL_NO_CONTEXT, contextAttributes); - eglMakeCurrent(surface->eglDisplay, surface->eglSurface, surface->eglSurface, surface->eglContext); + surface->eglContext = eglCreateContext(surface->eglDisplay, surface->eglConfig, EGL_NO_CONTEXT, contextAttributes); + eglMakeCurrent(surface->eglDisplay, surface->eglSurface, surface->eglSurface, surface->eglContext); - oc_gl_load_gles(&surface->api, (oc_gl_load_proc)eglGetProcAddress); + oc_gl_load_gles(&surface->api, (oc_gl_load_proc)eglGetProcAddress); - eglSwapInterval(surface->eglDisplay, 1); + eglSwapInterval(surface->eglDisplay, 1); } oc_surface_data* oc_egl_surface_create_remote(u32 width, u32 height) { - oc_egl_surface* surface = 0; + oc_egl_surface* surface = 0; - surface = oc_malloc_type(oc_egl_surface); - if(surface) - { - memset(surface, 0, sizeof(oc_egl_surface)); + surface = oc_malloc_type(oc_egl_surface); + if(surface) + { + memset(surface, 0, sizeof(oc_egl_surface)); - oc_surface_init_remote((oc_surface_data*)surface, width, height); - oc_egl_surface_init(surface); - } + oc_surface_init_remote((oc_surface_data*)surface, width, height); + oc_egl_surface_init(surface); + } - return((oc_surface_data*)surface); + return ((oc_surface_data*)surface); } oc_surface_data* oc_egl_surface_create_for_window(oc_window window) { - oc_egl_surface* surface = 0; - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - surface = oc_malloc_type(oc_egl_surface); - if(surface) - { - memset(surface, 0, sizeof(oc_egl_surface)); + oc_egl_surface* surface = 0; + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + surface = oc_malloc_type(oc_egl_surface); + if(surface) + { + memset(surface, 0, sizeof(oc_egl_surface)); - oc_surface_init_for_window((oc_surface_data*)surface, windowData); - oc_egl_surface_init(surface); - } - } - return((oc_surface_data*)surface); + oc_surface_init_for_window((oc_surface_data*)surface, windowData); + oc_egl_surface_init(surface); + } + } + return ((oc_surface_data*)surface); } diff --git a/src/graphics/egl_surface.h b/src/graphics/egl_surface.h index 1b53f5e..82487cf 100644 --- a/src/graphics/egl_surface.h +++ b/src/graphics/egl_surface.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: egl_surface.h * @author: Martin Fouilleul @@ -9,8 +9,8 @@ #ifndef __EGL_SURFACE_H_ #define __EGL_SURFACE_H_ -#include"graphics_surface.h" -#include"app/app.h" +#include "app/app.h" +#include "graphics_surface.h" oc_surface_data* oc_egl_surface_create_for_window(oc_window window); oc_surface_data* oc_egl_surface_create_remote(u32 width, u32 height); diff --git a/src/graphics/gl_api.h b/src/graphics/gl_api.h index b09775f..0866a6e 100644 --- a/src/graphics/gl_api.h +++ b/src/graphics/gl_api.h @@ -8,563 +8,563 @@ #ifndef __GL_API_H__ #define __GL_API_H__ -#include"GL/glcorearb.h" -#include"GLES3/gl32.h" +#include "GL/glcorearb.h" +#include "GLES3/gl32.h" typedef struct oc_gl_api { - const char* name; - PFNGLGETFLOATVPROC GetFloatv; - PFNGLTEXBUFFERRANGEPROC TexBufferRange; - PFNGLISBUFFERPROC IsBuffer; - PFNGLISTEXTUREPROC IsTexture; - PFNGLDEPTHRANGEFPROC DepthRangef; - PFNGLENDCONDITIONALRENDERPROC EndConditionalRender; - PFNGLBLENDFUNCIPROC BlendFunci; - PFNGLGETPROGRAMPIPELINEIVPROC GetProgramPipelineiv; - PFNGLWAITSYNCPROC WaitSync; - PFNGLPROGRAMUNIFORMMATRIX2FVPROC ProgramUniformMatrix2fv; - PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC ProgramUniformMatrix4x3dv; - PFNGLVERTEXATTRIB1DVPROC VertexAttrib1dv; - PFNGLSAMPLERPARAMETERIPROC SamplerParameteri; - PFNGLGETVERTEXATTRIBIIVPROC GetVertexAttribIiv; - PFNGLGETSAMPLERPARAMETERFVPROC GetSamplerParameterfv; - PFNGLVERTEXATTRIB1DPROC VertexAttrib1d; - PFNGLTEXBUFFERPROC TexBuffer; - PFNGLINVALIDATEBUFFERDATAPROC InvalidateBufferData; - PFNGLPROGRAMUNIFORM2IPROC ProgramUniform2i; - PFNGLUNIFORM4DVPROC Uniform4dv; - PFNGLUSEPROGRAMPROC UseProgram; - PFNGLVERTEXATTRIBI3IVPROC VertexAttribI3iv; - PFNGLDRAWELEMENTSINDIRECTPROC DrawElementsIndirect; - PFNGLVERTEXATTRIB4UIVPROC VertexAttrib4uiv; - PFNGLGETQUERYOBJECTIVPROC GetQueryObjectiv; - PFNGLFRAMEBUFFERRENDERBUFFERPROC FramebufferRenderbuffer; - PFNGLBLENDEQUATIONIPROC BlendEquationi; - PFNGLGETACTIVESUBROUTINENAMEPROC GetActiveSubroutineName; - PFNGLVERTEXATTRIB2SPROC VertexAttrib2s; - PFNGLVERTEXATTRIBL1DPROC VertexAttribL1d; - PFNGLBINDTEXTURESPROC BindTextures; - PFNGLVERTEXATTRIB3SVPROC VertexAttrib3sv; - PFNGLGETFLOATI_VPROC GetFloati_v; - PFNGLBEGINTRANSFORMFEEDBACKPROC BeginTransformFeedback; - PFNGLCLEARSTENCILPROC ClearStencil; - PFNGLUNIFORM3IPROC Uniform3i; - PFNGLVALIDATEPROGRAMPIPELINEPROC ValidateProgramPipeline; - PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC ProgramUniformMatrix4x2fv; - PFNGLVERTEXATTRIBI4UIPROC VertexAttribI4ui; - PFNGLGETSHADERIVPROC GetShaderiv; - PFNGLREADNPIXELSPROC ReadnPixels; - PFNGLUNIFORMMATRIX4X2FVPROC UniformMatrix4x2fv; - PFNGLGETSHADERPRECISIONFORMATPROC GetShaderPrecisionFormat; - PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC ProgramUniformMatrix2x3fv; - PFNGLTEXSUBIMAGE3DPROC TexSubImage3D; - PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC GetProgramResourceLocationIndex; - PFNGLBLENDFUNCPROC BlendFunc; - PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC ProgramUniformMatrix3x4fv; - PFNGLUNIFORM3DPROC Uniform3d; - PFNGLVERTEXATTRIB1SVPROC VertexAttrib1sv; - PFNGLBINDFRAGDATALOCATIONPROC BindFragDataLocation; - PFNGLVERTEXATTRIB4BVPROC VertexAttrib4bv; - PFNGLUNIFORM4IVPROC Uniform4iv; - PFNGLPROGRAMUNIFORM2UIPROC ProgramUniform2ui; - PFNGLDRAWARRAYSPROC DrawArrays; - PFNGLPROGRAMBINARYPROC ProgramBinary; - PFNGLVERTEXATTRIB4FPROC VertexAttrib4f; - PFNGLVERTEXATTRIBP2UIVPROC VertexAttribP2uiv; - PFNGLUNIFORMMATRIX3FVPROC UniformMatrix3fv; - PFNGLUNIFORM2IPROC Uniform2i; - PFNGLGETQUERYOBJECTUIVPROC GetQueryObjectuiv; - PFNGLUNIFORMBLOCKBINDINGPROC UniformBlockBinding; - PFNGLSAMPLECOVERAGEPROC SampleCoverage; - PFNGLVERTEXATTRIB4NUSVPROC VertexAttrib4Nusv; - PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC ProgramUniformMatrix2x4dv; - PFNGLUNIFORM3UIVPROC Uniform3uiv; - PFNGLVERTEXATTRIB1SPROC VertexAttrib1s; - PFNGLGETVERTEXATTRIBPOINTERVPROC GetVertexAttribPointerv; - PFNGLBLENDBARRIERPROC BlendBarrier; - PFNGLDRAWRANGEELEMENTSPROC DrawRangeElements; - PFNGLTEXSTORAGE3DPROC TexStorage3D; - PFNGLGETINTERNALFORMATI64VPROC GetInternalformati64v; - PFNGLGETQUERYOBJECTI64VPROC GetQueryObjecti64v; - PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC CompressedTexSubImage1D; - PFNGLVERTEXATTRIB3DVPROC VertexAttrib3dv; - PFNGLVERTEXBINDINGDIVISORPROC VertexBindingDivisor; - PFNGLUSEPROGRAMSTAGESPROC UseProgramStages; - PFNGLVERTEXATTRIBBINDINGPROC VertexAttribBinding; - PFNGLDEBUGMESSAGEINSERTPROC DebugMessageInsert; - PFNGLGETTEXPARAMETERIVPROC GetTexParameteriv; - PFNGLMULTIDRAWARRAYSINDIRECTPROC MultiDrawArraysIndirect; - PFNGLGETTEXPARAMETERFVPROC GetTexParameterfv; - PFNGLGETPROGRAMPIPELINEINFOLOGPROC GetProgramPipelineInfoLog; - PFNGLENDQUERYPROC EndQuery; - PFNGLGETPROGRAMRESOURCELOCATIONPROC GetProgramResourceLocation; - PFNGLCOMPRESSEDTEXIMAGE2DPROC CompressedTexImage2D; - PFNGLVERTEXATTRIBP2UIPROC VertexAttribP2ui; - PFNGLISENABLEDIPROC IsEnabledi; - PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC GetActiveAtomicCounterBufferiv; - PFNGLISPROGRAMPROC IsProgram; - PFNGLUNIFORM1DVPROC Uniform1dv; - PFNGLTEXPARAMETERIVPROC TexParameteriv; - PFNGLUNIFORM2FVPROC Uniform2fv; - PFNGLRELEASESHADERCOMPILERPROC ReleaseShaderCompiler; - PFNGLCULLFACEPROC CullFace; - PFNGLVERTEXATTRIBI4IPROC VertexAttribI4i; - PFNGLGETPROGRAMRESOURCEINDEXPROC GetProgramResourceIndex; - PFNGLSHADERBINARYPROC ShaderBinary; - PFNGLUNIFORMMATRIX3X2DVPROC UniformMatrix3x2dv; - PFNGLINVALIDATEFRAMEBUFFERPROC InvalidateFramebuffer; - PFNGLATTACHSHADERPROC AttachShader; - PFNGLFLUSHMAPPEDBUFFERRANGEPROC FlushMappedBufferRange; - PFNGLVERTEXATTRIBP3UIVPROC VertexAttribP3uiv; - PFNGLGETACTIVEUNIFORMNAMEPROC GetActiveUniformName; - PFNGLMAPBUFFERPROC MapBuffer; - PFNGLDRAWBUFFERSPROC DrawBuffers; - PFNGLGETSYNCIVPROC GetSynciv; - PFNGLCOPYTEXSUBIMAGE2DPROC CopyTexSubImage2D; - PFNGLOBJECTLABELPROC ObjectLabel; - PFNGLBUFFERSUBDATAPROC BufferSubData; - PFNGLUNIFORM2FPROC Uniform2f; - PFNGLDEBUGMESSAGECALLBACKPROC DebugMessageCallback; - PFNGLVERTEXATTRIBL4DVPROC VertexAttribL4dv; - PFNGLISPROGRAMPIPELINEPROC IsProgramPipeline; - PFNGLRESUMETRANSFORMFEEDBACKPROC ResumeTransformFeedback; - PFNGLVERTEXATTRIBI4IVPROC VertexAttribI4iv; - PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog; - PFNGLGETINTEGERI_VPROC GetIntegeri_v; - PFNGLBINDVERTEXBUFFERPROC BindVertexBuffer; - PFNGLBLENDEQUATIONPROC BlendEquation; - PFNGLVERTEXATTRIBL2DVPROC VertexAttribL2dv; - PFNGLVERTEXATTRIBI1UIPROC VertexAttribI1ui; - PFNGLVERTEXATTRIB4NSVPROC VertexAttrib4Nsv; - PFNGLVERTEXATTRIBL4DPROC VertexAttribL4d; - PFNGLCOPYIMAGESUBDATAPROC CopyImageSubData; - PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC GetFramebufferAttachmentParameteriv; - PFNGLVERTEXATTRIBL2DPROC VertexAttribL2d; - PFNGLGETSUBROUTINEINDEXPROC GetSubroutineIndex; - PFNGLVERTEXATTRIBI3UIVPROC VertexAttribI3uiv; - PFNGLVERTEXATTRIB4IVPROC VertexAttrib4iv; - PFNGLBINDVERTEXBUFFERSPROC BindVertexBuffers; - PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC ProgramUniformMatrix2x3dv; - PFNGLPRIMITIVEBOUNDINGBOXPROC PrimitiveBoundingBox; - PFNGLSCISSORPROC Scissor; - PFNGLCLIENTWAITSYNCPROC ClientWaitSync; - PFNGLUNIFORM3UIPROC Uniform3ui; - PFNGLVERTEXATTRIBP3UIPROC VertexAttribP3ui; - PFNGLENABLEPROC Enable; - PFNGLSTENCILOPSEPARATEPROC StencilOpSeparate; - PFNGLUNIFORMMATRIX2X3DVPROC UniformMatrix2x3dv; - PFNGLPROGRAMUNIFORMMATRIX3DVPROC ProgramUniformMatrix3dv; - PFNGLTEXIMAGE2DMULTISAMPLEPROC TexImage2DMultisample; - PFNGLVERTEXATTRIB4NBVPROC VertexAttrib4Nbv; - PFNGLGETTEXIMAGEPROC GetTexImage; - PFNGLVERTEXATTRIB4SVPROC VertexAttrib4sv; - PFNGLPIXELSTOREIPROC PixelStorei; - PFNGLDEPTHMASKPROC DepthMask; - PFNGLTEXSTORAGE2DPROC TexStorage2D; - PFNGLCLEARPROC Clear; - PFNGLUNIFORMMATRIX3X4DVPROC UniformMatrix3x4dv; - PFNGLDELETETRANSFORMFEEDBACKSPROC DeleteTransformFeedbacks; - PFNGLMAPBUFFERRANGEPROC MapBufferRange; - PFNGLMEMORYBARRIERPROC MemoryBarrier; - PFNGLVIEWPORTINDEXEDFPROC ViewportIndexedf; - PFNGLVERTEXATTRIB3FVPROC VertexAttrib3fv; - PFNGLOBJECTPTRLABELPROC ObjectPtrLabel; - PFNGLTEXSTORAGE1DPROC TexStorage1D; - PFNGLCOMPRESSEDTEXIMAGE3DPROC CompressedTexImage3D; - PFNGLVERTEXATTRIB1FVPROC VertexAttrib1fv; - PFNGLVERTEXATTRIBPOINTERPROC VertexAttribPointer; - PFNGLGETQUERYINDEXEDIVPROC GetQueryIndexediv; - PFNGLCOMPILESHADERPROC CompileShader; - PFNGLPROGRAMUNIFORM1IPROC ProgramUniform1i; - PFNGLGETQUERYIVPROC GetQueryiv; - PFNGLVERTEXATTRIBI1IVPROC VertexAttribI1iv; - PFNGLCOPYTEXIMAGE2DPROC CopyTexImage2D; - PFNGLGETQUERYOBJECTUI64VPROC GetQueryObjectui64v; - PFNGLPOINTSIZEPROC PointSize; - PFNGLDISABLEIPROC Disablei; - PFNGLVERTEXATTRIBL1DVPROC VertexAttribL1dv; - PFNGLCREATESHADERPROC CreateShader; - PFNGLGETSTRINGPROC GetString; - PFNGLVIEWPORTARRAYVPROC ViewportArrayv; - PFNGLPROGRAMUNIFORM3DPROC ProgramUniform3d; - PFNGLVERTEXATTRIB4NUBVPROC VertexAttrib4Nubv; - PFNGLTEXPARAMETERIPROC TexParameteri; - PFNGLPROGRAMUNIFORM4FVPROC ProgramUniform4fv; - PFNGLGENERATEMIPMAPPROC GenerateMipmap; - PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC CompressedTexSubImage3D; - PFNGLUNIFORM3FPROC Uniform3f; - PFNGLGETUNIFORMINDICESPROC GetUniformIndices; - PFNGLVERTEXATTRIBLPOINTERPROC VertexAttribLPointer; - PFNGLVERTEXATTRIBI2UIVPROC VertexAttribI2uiv; - PFNGLQUERYCOUNTERPROC QueryCounter; - PFNGLACTIVESHADERPROGRAMPROC ActiveShaderProgram; - PFNGLUNIFORM1UIPROC Uniform1ui; - PFNGLVERTEXATTRIBI1IPROC VertexAttribI1i; - PFNGLGETTEXPARAMETERIIVPROC GetTexParameterIiv; - PFNGLGETUNIFORMFVPROC GetUniformfv; - PFNGLPROGRAMUNIFORM2UIVPROC ProgramUniform2uiv; - PFNGLGETERRORPROC GetError; - PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC GetActiveUniformBlockName; - PFNGLTEXTUREVIEWPROC TextureView; - PFNGLGETNUNIFORMIVPROC GetnUniformiv; - PFNGLPROGRAMUNIFORM4DVPROC ProgramUniform4dv; - PFNGLVIEWPORTINDEXEDFVPROC ViewportIndexedfv; - PFNGLHINTPROC Hint; - PFNGLGETSHADERSOURCEPROC GetShaderSource; - PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC ProgramUniformMatrix4x3fv; - PFNGLUNIFORM1IVPROC Uniform1iv; - PFNGLVERTEXATTRIBI4BVPROC VertexAttribI4bv; - PFNGLUNIFORMMATRIX4X2DVPROC UniformMatrix4x2dv; - PFNGLBUFFERSTORAGEPROC BufferStorage; - PFNGLISRENDERBUFFERPROC IsRenderbuffer; - PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC GetActiveSubroutineUniformName; - PFNGLLINKPROGRAMPROC LinkProgram; - PFNGLGETACTIVEUNIFORMSIVPROC GetActiveUniformsiv; - PFNGLGETDEBUGMESSAGELOGPROC GetDebugMessageLog; - PFNGLCOPYTEXSUBIMAGE3DPROC CopyTexSubImage3D; - PFNGLPOINTPARAMETERIPROC PointParameteri; - PFNGLPROGRAMUNIFORM3DVPROC ProgramUniform3dv; - PFNGLCOMPRESSEDTEXIMAGE1DPROC CompressedTexImage1D; - PFNGLUNIFORMMATRIX3X4FVPROC UniformMatrix3x4fv; - PFNGLGENSAMPLERSPROC GenSamplers; - PFNGLGETCOMPRESSEDTEXIMAGEPROC GetCompressedTexImage; - PFNGLDELETEQUERIESPROC DeleteQueries; - PFNGLGENPROGRAMPIPELINESPROC GenProgramPipelines; - PFNGLDISPATCHCOMPUTEINDIRECTPROC DispatchComputeIndirect; - PFNGLVERTEXATTRIBIPOINTERPROC VertexAttribIPointer; - PFNGLCREATEPROGRAMPROC CreateProgram; - PFNGLCLEARTEXSUBIMAGEPROC ClearTexSubImage; - PFNGLVERTEXATTRIB4DPROC VertexAttrib4d; - PFNGLFRONTFACEPROC FrontFace; - PFNGLBINDTRANSFORMFEEDBACKPROC BindTransformFeedback; - PFNGLGETPROGRAMSTAGEIVPROC GetProgramStageiv; - PFNGLSAMPLERPARAMETERIIVPROC SamplerParameterIiv; - PFNGLGETINTEGER64VPROC GetInteger64v; - PFNGLCREATESHADERPROGRAMVPROC CreateShaderProgramv; - PFNGLBINDBUFFERSRANGEPROC BindBuffersRange; - PFNGLUNIFORM3FVPROC Uniform3fv; - PFNGLPROGRAMUNIFORMMATRIX4FVPROC ProgramUniformMatrix4fv; - PFNGLBINDBUFFERSBASEPROC BindBuffersBase; - PFNGLCLEARBUFFERFIPROC ClearBufferfi; - PFNGLFRAMEBUFFERTEXTURE3DPROC FramebufferTexture3D; - PFNGLDISABLEPROC Disable; - PFNGLPROGRAMUNIFORM1IVPROC ProgramUniform1iv; - PFNGLVERTEXATTRIBI2IVPROC VertexAttribI2iv; - PFNGLDEPTHRANGEINDEXEDPROC DepthRangeIndexed; - PFNGLPATCHPARAMETERIPROC PatchParameteri; - PFNGLGETUNIFORMBLOCKINDEXPROC GetUniformBlockIndex; - PFNGLMULTIDRAWARRAYSPROC MultiDrawArrays; - PFNGLVERTEXATTRIBI4UBVPROC VertexAttribI4ubv; - PFNGLBINDBUFFERPROC BindBuffer; - PFNGLVERTEXATTRIBI3IPROC VertexAttribI3i; - PFNGLGETDOUBLEVPROC GetDoublev; - PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC DrawTransformFeedbackStream; - PFNGLVERTEXATTRIBI4UIVPROC VertexAttribI4uiv; - PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC RenderbufferStorageMultisample; - PFNGLVERTEXATTRIBL3DVPROC VertexAttribL3dv; - PFNGLSTENCILMASKSEPARATEPROC StencilMaskSeparate; - PFNGLPROGRAMUNIFORM1DPROC ProgramUniform1d; - PFNGLVIEWPORTPROC Viewport; - PFNGLVERTEXATTRIBP1UIPROC VertexAttribP1ui; - PFNGLVERTEXATTRIB4DVPROC VertexAttrib4dv; - PFNGLGENQUERIESPROC GenQueries; - PFNGLTEXPARAMETERIIVPROC TexParameterIiv; - PFNGLPROGRAMUNIFORM2DPROC ProgramUniform2d; - PFNGLPROGRAMUNIFORM1UIVPROC ProgramUniform1uiv; - PFNGLVERTEXATTRIB4NUBPROC VertexAttrib4Nub; - PFNGLISVERTEXARRAYPROC IsVertexArray; - PFNGLPROGRAMUNIFORM3FPROC ProgramUniform3f; - PFNGLPROGRAMUNIFORM3IVPROC ProgramUniform3iv; - PFNGLGETPROGRAMBINARYPROC GetProgramBinary; - PFNGLBINDRENDERBUFFERPROC BindRenderbuffer; - PFNGLBINDFRAGDATALOCATIONINDEXEDPROC BindFragDataLocationIndexed; - PFNGLGETSAMPLERPARAMETERIIVPROC GetSamplerParameterIiv; - PFNGLVERTEXATTRIBDIVISORPROC VertexAttribDivisor; - PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC ProgramUniformMatrix3x2dv; - PFNGLFRAMEBUFFERPARAMETERIPROC FramebufferParameteri; - PFNGLGENTRANSFORMFEEDBACKSPROC GenTransformFeedbacks; - PFNGLDELETESYNCPROC DeleteSync; - PFNGLPROGRAMUNIFORM1UIPROC ProgramUniform1ui; - PFNGLTEXSUBIMAGE1DPROC TexSubImage1D; - PFNGLCLEARDEPTHFPROC ClearDepthf; - PFNGLREADPIXELSPROC ReadPixels; - PFNGLVERTEXATTRIBI2IPROC VertexAttribI2i; - PFNGLFINISHPROC Finish; - PFNGLLINEWIDTHPROC LineWidth; - PFNGLDELETESHADERPROC DeleteShader; - PFNGLISSAMPLERPROC IsSampler; - PFNGLPROGRAMUNIFORMMATRIX4DVPROC ProgramUniformMatrix4dv; - PFNGLTRANSFORMFEEDBACKVARYINGSPROC TransformFeedbackVaryings; - PFNGLBEGINCONDITIONALRENDERPROC BeginConditionalRender; - PFNGLBINDSAMPLERSPROC BindSamplers; - PFNGLDELETEPROGRAMPIPELINESPROC DeleteProgramPipelines; - PFNGLCOLORMASKPROC ColorMask; - PFNGLTEXPARAMETERFVPROC TexParameterfv; - PFNGLPUSHDEBUGGROUPPROC PushDebugGroup; - PFNGLCLEARBUFFERFVPROC ClearBufferfv; - PFNGLISENABLEDPROC IsEnabled; - PFNGLVERTEXATTRIB2FPROC VertexAttrib2f; - PFNGLPROGRAMUNIFORM2FPROC ProgramUniform2f; - PFNGLGETSAMPLERPARAMETERIUIVPROC GetSamplerParameterIuiv; - PFNGLGETINTEGER64I_VPROC GetInteger64i_v; - PFNGLUNIFORM2DVPROC Uniform2dv; - PFNGLGETBUFFERSUBDATAPROC GetBufferSubData; - PFNGLMULTIDRAWELEMENTSINDIRECTPROC MultiDrawElementsIndirect; - PFNGLPROGRAMPARAMETERIPROC ProgramParameteri; - PFNGLVERTEXATTRIBP4UIPROC VertexAttribP4ui; - PFNGLSAMPLERPARAMETERFVPROC SamplerParameterfv; - PFNGLPOINTPARAMETERFPROC PointParameterf; - PFNGLUNIFORMMATRIX2X4FVPROC UniformMatrix2x4fv; - PFNGLGENBUFFERSPROC GenBuffers; - PFNGLPROGRAMUNIFORM2DVPROC ProgramUniform2dv; - PFNGLVERTEXATTRIBFORMATPROC VertexAttribFormat; - PFNGLTEXSUBIMAGE2DPROC TexSubImage2D; - PFNGLVERTEXATTRIB4UBVPROC VertexAttrib4ubv; - PFNGLGETGRAPHICSRESETSTATUSPROC GetGraphicsResetStatus; - PFNGLGETPROGRAMINTERFACEIVPROC GetProgramInterfaceiv; - PFNGLVERTEXATTRIBIFORMATPROC VertexAttribIFormat; - PFNGLGETNUNIFORMFVPROC GetnUniformfv; - PFNGLDELETEPROGRAMPROC DeleteProgram; - PFNGLCLAMPCOLORPROC ClampColor; - PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC DrawElementsInstancedBaseVertexBaseInstance; - PFNGLDRAWELEMENTSPROC DrawElements; - PFNGLDEBUGMESSAGECONTROLPROC DebugMessageControl; - PFNGLGETRENDERBUFFERPARAMETERIVPROC GetRenderbufferParameteriv; - PFNGLDETACHSHADERPROC DetachShader; - PFNGLGENFRAMEBUFFERSPROC GenFramebuffers; - PFNGLPROVOKINGVERTEXPROC ProvokingVertex; - PFNGLSAMPLEMASKIPROC SampleMaski; - PFNGLENDQUERYINDEXEDPROC EndQueryIndexed; - PFNGLPROGRAMUNIFORM1FPROC ProgramUniform1f; - PFNGLBINDFRAMEBUFFERPROC BindFramebuffer; - PFNGLBEGINQUERYINDEXEDPROC BeginQueryIndexed; - PFNGLUNIFORMSUBROUTINESUIVPROC UniformSubroutinesuiv; - PFNGLGETUNIFORMIVPROC GetUniformiv; - PFNGLFRAMEBUFFERTEXTUREPROC FramebufferTexture; - PFNGLPOINTPARAMETERFVPROC PointParameterfv; - PFNGLISTRANSFORMFEEDBACKPROC IsTransformFeedback; - PFNGLCHECKFRAMEBUFFERSTATUSPROC CheckFramebufferStatus; - PFNGLSHADERSOURCEPROC ShaderSource; - PFNGLUNIFORMMATRIX2X4DVPROC UniformMatrix2x4dv; - PFNGLBINDIMAGETEXTURESPROC BindImageTextures; - PFNGLCOPYTEXIMAGE1DPROC CopyTexImage1D; - PFNGLUNIFORMMATRIX3DVPROC UniformMatrix3dv; - PFNGLPROGRAMUNIFORM1DVPROC ProgramUniform1dv; - PFNGLBLITFRAMEBUFFERPROC BlitFramebuffer; - PFNGLPOPDEBUGGROUPPROC PopDebugGroup; - PFNGLTEXPARAMETERIUIVPROC TexParameterIuiv; - PFNGLVERTEXATTRIB2DPROC VertexAttrib2d; - PFNGLTEXIMAGE1DPROC TexImage1D; - PFNGLGETOBJECTPTRLABELPROC GetObjectPtrLabel; - PFNGLSTENCILMASKPROC StencilMask; - PFNGLBEGINQUERYPROC BeginQuery; - PFNGLUNIFORMMATRIX4FVPROC UniformMatrix4fv; - PFNGLISSYNCPROC IsSync; - PFNGLUNIFORM3DVPROC Uniform3dv; - PFNGLPROGRAMUNIFORM2FVPROC ProgramUniform2fv; - PFNGLVERTEXATTRIBI4SVPROC VertexAttribI4sv; - PFNGLSCISSORARRAYVPROC ScissorArrayv; - PFNGLVERTEXATTRIBP1UIVPROC VertexAttribP1uiv; - PFNGLUNIFORM2UIVPROC Uniform2uiv; - PFNGLDELETEBUFFERSPROC DeleteBuffers; - PFNGLPROGRAMUNIFORM3UIPROC ProgramUniform3ui; - PFNGLFRAMEBUFFERTEXTURELAYERPROC FramebufferTextureLayer; - PFNGLENDTRANSFORMFEEDBACKPROC EndTransformFeedback; - PFNGLBLENDFUNCSEPARATEIPROC BlendFuncSeparatei; - PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC DrawTransformFeedbackInstanced; - PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC DrawRangeElementsBaseVertex; - PFNGLVERTEXATTRIB1FPROC VertexAttrib1f; - PFNGLGETUNIFORMSUBROUTINEUIVPROC GetUniformSubroutineuiv; - PFNGLDISABLEVERTEXATTRIBARRAYPROC DisableVertexAttribArray; - PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC ProgramUniformMatrix3x2fv; - PFNGLVERTEXATTRIBI4USVPROC VertexAttribI4usv; - PFNGLGETOBJECTLABELPROC GetObjectLabel; - PFNGLBINDATTRIBLOCATIONPROC BindAttribLocation; - PFNGLUNIFORM1FPROC Uniform1f; - PFNGLGETUNIFORMDVPROC GetUniformdv; - PFNGLGETUNIFORMLOCATIONPROC GetUniformLocation; - PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC GetSubroutineUniformLocation; - PFNGLGETTEXPARAMETERIUIVPROC GetTexParameterIuiv; - PFNGLSAMPLERPARAMETERFPROC SamplerParameterf; - PFNGLVERTEXATTRIBL3DPROC VertexAttribL3d; - PFNGLTEXIMAGE3DMULTISAMPLEPROC TexImage3DMultisample; - PFNGLTEXIMAGE3DPROC TexImage3D; - PFNGLRENDERBUFFERSTORAGEPROC RenderbufferStorage; - PFNGLENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray; - PFNGLVERTEXATTRIBP4UIVPROC VertexAttribP4uiv; - PFNGLUNIFORM4DPROC Uniform4d; - PFNGLVERTEXATTRIB4SPROC VertexAttrib4s; - PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC DrawElementsInstancedBaseVertex; - PFNGLVERTEXATTRIB3SPROC VertexAttrib3s; - PFNGLPROGRAMUNIFORM2IVPROC ProgramUniform2iv; - PFNGLSTENCILFUNCSEPARATEPROC StencilFuncSeparate; - PFNGLDELETEFRAMEBUFFERSPROC DeleteFramebuffers; - PFNGLDEPTHRANGEPROC DepthRange; - PFNGLUNIFORMMATRIX3X2FVPROC UniformMatrix3x2fv; - PFNGLPROGRAMUNIFORMMATRIX2DVPROC ProgramUniformMatrix2dv; - PFNGLSHADERSTORAGEBLOCKBINDINGPROC ShaderStorageBlockBinding; - PFNGLCLEARDEPTHPROC ClearDepth; - PFNGLVERTEXATTRIB2DVPROC VertexAttrib2dv; - PFNGLSAMPLERPARAMETERIUIVPROC SamplerParameterIuiv; - PFNGLGETVERTEXATTRIBLDVPROC GetVertexAttribLdv; - PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC ProgramUniformMatrix3x4dv; - PFNGLDEPTHRANGEARRAYVPROC DepthRangeArrayv; - PFNGLGETACTIVEUNIFORMPROC GetActiveUniform; - PFNGLPATCHPARAMETERFVPROC PatchParameterfv; - PFNGLINVALIDATETEXIMAGEPROC InvalidateTexImage; - PFNGLVERTEXATTRIB3FPROC VertexAttrib3f; - PFNGLPROGRAMUNIFORM4IVPROC ProgramUniform4iv; - PFNGLPROGRAMUNIFORM4DPROC ProgramUniform4d; - PFNGLISFRAMEBUFFERPROC IsFramebuffer; - PFNGLPIXELSTOREFPROC PixelStoref; - PFNGLPROGRAMUNIFORM4UIVPROC ProgramUniform4uiv; - PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC ProgramUniformMatrix4x2dv; - PFNGLFENCESYNCPROC FenceSync; - PFNGLGETBUFFERPARAMETERI64VPROC GetBufferParameteri64v; - PFNGLSTENCILOPPROC StencilOp; - PFNGLCLEARBUFFERDATAPROC ClearBufferData; - PFNGLGETNUNIFORMUIVPROC GetnUniformuiv; - PFNGLGETPROGRAMRESOURCEIVPROC GetProgramResourceiv; - PFNGLGETVERTEXATTRIBDVPROC GetVertexAttribdv; - PFNGLGETTRANSFORMFEEDBACKVARYINGPROC GetTransformFeedbackVarying; - PFNGLVERTEXATTRIB2FVPROC VertexAttrib2fv; - PFNGLGETBOOLEANI_VPROC GetBooleani_v; - PFNGLCOLORMASKIPROC ColorMaski; - PFNGLINVALIDATEBUFFERSUBDATAPROC InvalidateBufferSubData; - PFNGLUNIFORMMATRIX4DVPROC UniformMatrix4dv; - PFNGLISQUERYPROC IsQuery; - PFNGLUNIFORM4UIPROC Uniform4ui; - PFNGLUNIFORM4IPROC Uniform4i; - PFNGLGETSAMPLERPARAMETERIVPROC GetSamplerParameteriv; - PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC MultiDrawElementsBaseVertex; - PFNGLVERTEXATTRIBI1UIVPROC VertexAttribI1uiv; - PFNGLGETINTEGERVPROC GetIntegerv; - PFNGLUNIFORMMATRIX2X3FVPROC UniformMatrix2x3fv; - PFNGLTEXIMAGE2DPROC TexImage2D; - PFNGLGETATTACHEDSHADERSPROC GetAttachedShaders; - PFNGLUNIFORM2DPROC Uniform2d; - PFNGLMEMORYBARRIERBYREGIONPROC MemoryBarrierByRegion; - PFNGLUNIFORMMATRIX2FVPROC UniformMatrix2fv; - PFNGLPRIMITIVERESTARTINDEXPROC PrimitiveRestartIndex; - PFNGLGETVERTEXATTRIBIVPROC GetVertexAttribiv; - PFNGLGETATTRIBLOCATIONPROC GetAttribLocation; - PFNGLTEXSTORAGE2DMULTISAMPLEPROC TexStorage2DMultisample; - PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC CompressedTexSubImage2D; - PFNGLGETVERTEXATTRIBFVPROC GetVertexAttribfv; - PFNGLGETBUFFERPARAMETERIVPROC GetBufferParameteriv; - PFNGLTEXPARAMETERFPROC TexParameterf; - PFNGLFRAMEBUFFERTEXTURE2DPROC FramebufferTexture2D; - PFNGLGETACTIVEATTRIBPROC GetActiveAttrib; - PFNGLINVALIDATETEXSUBIMAGEPROC InvalidateTexSubImage; - PFNGLDELETEVERTEXARRAYSPROC DeleteVertexArrays; - PFNGLVERTEXATTRIBI2UIPROC VertexAttribI2ui; - PFNGLPOINTPARAMETERIVPROC PointParameteriv; - PFNGLGETPOINTERVPROC GetPointerv; - PFNGLENABLEIPROC Enablei; - PFNGLBINDBUFFERRANGEPROC BindBufferRange; - PFNGLDRAWARRAYSINSTANCEDPROC DrawArraysInstanced; - PFNGLDELETETEXTURESPROC DeleteTextures; - PFNGLVERTEXATTRIB4NIVPROC VertexAttrib4Niv; - PFNGLMULTIDRAWELEMENTSPROC MultiDrawElements; - PFNGLGETPROGRAMIVPROC GetProgramiv; - PFNGLDEPTHFUNCPROC DepthFunc; - PFNGLGENTEXTURESPROC GenTextures; - PFNGLGETINTERNALFORMATIVPROC GetInternalformativ; - PFNGLPROGRAMUNIFORM3IPROC ProgramUniform3i; - PFNGLSCISSORINDEXEDPROC ScissorIndexed; - PFNGLVERTEXATTRIB2SVPROC VertexAttrib2sv; - PFNGLTEXSTORAGE3DMULTISAMPLEPROC TexStorage3DMultisample; - PFNGLUNIFORM2IVPROC Uniform2iv; - PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC DrawArraysInstancedBaseInstance; - PFNGLVERTEXATTRIBI3UIPROC VertexAttribI3ui; - PFNGLDELETESAMPLERSPROC DeleteSamplers; - PFNGLGENVERTEXARRAYSPROC GenVertexArrays; - PFNGLGETFRAMEBUFFERPARAMETERIVPROC GetFramebufferParameteriv; - PFNGLPOLYGONMODEPROC PolygonMode; - PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC ProgramUniformMatrix2x4fv; - PFNGLGETPROGRAMRESOURCENAMEPROC GetProgramResourceName; - PFNGLSAMPLERPARAMETERIVPROC SamplerParameteriv; - PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC GetActiveSubroutineUniformiv; - PFNGLGETSTRINGIPROC GetStringi; - PFNGLVERTEXATTRIBLFORMATPROC VertexAttribLFormat; - PFNGLVERTEXATTRIB3DPROC VertexAttrib3d; - PFNGLBINDVERTEXARRAYPROC BindVertexArray; - PFNGLUNMAPBUFFERPROC UnmapBuffer; - PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC DrawElementsInstancedBaseInstance; - PFNGLUNIFORM4UIVPROC Uniform4uiv; - PFNGLFRAMEBUFFERTEXTURE1DPROC FramebufferTexture1D; - PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC DrawTransformFeedbackStreamInstanced; - PFNGLSTENCILFUNCPROC StencilFunc; - PFNGLVALIDATEPROGRAMPROC ValidateProgram; - PFNGLFLUSHPROC Flush; - PFNGLPROGRAMUNIFORM3UIVPROC ProgramUniform3uiv; - PFNGLDELETERENDERBUFFERSPROC DeleteRenderbuffers; - PFNGLVERTEXATTRIB4FVPROC VertexAttrib4fv; - PFNGLUNIFORMMATRIX2DVPROC UniformMatrix2dv; - PFNGLGETFRAGDATAINDEXPROC GetFragDataIndex; - PFNGLUNIFORM3IVPROC Uniform3iv; - PFNGLMINSAMPLESHADINGPROC MinSampleShading; - PFNGLGETBOOLEANVPROC GetBooleanv; - PFNGLGETMULTISAMPLEFVPROC GetMultisamplefv; - PFNGLGETVERTEXATTRIBIUIVPROC GetVertexAttribIuiv; - PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog; - PFNGLUNIFORM4FVPROC Uniform4fv; - PFNGLDRAWBUFFERPROC DrawBuffer; - PFNGLUNIFORM1IPROC Uniform1i; - PFNGLPROGRAMUNIFORM4UIPROC ProgramUniform4ui; - PFNGLPROGRAMUNIFORMMATRIX3FVPROC ProgramUniformMatrix3fv; - PFNGLBLENDEQUATIONSEPARATEPROC BlendEquationSeparate; - PFNGLBINDPROGRAMPIPELINEPROC BindProgramPipeline; - PFNGLGETDOUBLEI_VPROC GetDoublei_v; - PFNGLBUFFERDATAPROC BufferData; - PFNGLCLEARCOLORPROC ClearColor; - PFNGLPROGRAMUNIFORM4IPROC ProgramUniform4i; - PFNGLGETTEXLEVELPARAMETERIVPROC GetTexLevelParameteriv; - PFNGLGETACTIVEUNIFORMBLOCKIVPROC GetActiveUniformBlockiv; - PFNGLPROGRAMUNIFORM1FVPROC ProgramUniform1fv; - PFNGLPAUSETRANSFORMFEEDBACKPROC PauseTransformFeedback; - PFNGLGETBUFFERPOINTERVPROC GetBufferPointerv; - PFNGLINVALIDATESUBFRAMEBUFFERPROC InvalidateSubFramebuffer; - PFNGLSCISSORINDEXEDVPROC ScissorIndexedv; - PFNGLUNIFORM2UIPROC Uniform2ui; - PFNGLBINDTEXTUREPROC BindTexture; - PFNGLDRAWELEMENTSINSTANCEDPROC DrawElementsInstanced; - PFNGLPROGRAMUNIFORM4FPROC ProgramUniform4f; - PFNGLBINDBUFFERBASEPROC BindBufferBase; - PFNGLISSHADERPROC IsShader; - PFNGLCLEARBUFFERSUBDATAPROC ClearBufferSubData; - PFNGLVERTEXATTRIB4NUIVPROC VertexAttrib4Nuiv; - PFNGLDRAWARRAYSINDIRECTPROC DrawArraysIndirect; - PFNGLVERTEXATTRIB4USVPROC VertexAttrib4usv; - PFNGLUNIFORM1DPROC Uniform1d; - PFNGLCLEARTEXIMAGEPROC ClearTexImage; - PFNGLUNIFORM1UIVPROC Uniform1uiv; - PFNGLBINDSAMPLERPROC BindSampler; - PFNGLGETTEXLEVELPARAMETERFVPROC GetTexLevelParameterfv; - PFNGLCLEARBUFFERIVPROC ClearBufferiv; - PFNGLLOGICOPPROC LogicOp; - PFNGLACTIVETEXTUREPROC ActiveTexture; - PFNGLGETFRAGDATALOCATIONPROC GetFragDataLocation; - PFNGLBLENDCOLORPROC BlendColor; - PFNGLUNIFORMMATRIX4X3FVPROC UniformMatrix4x3fv; - PFNGLPROGRAMUNIFORM3FVPROC ProgramUniform3fv; - PFNGLUNIFORM1FVPROC Uniform1fv; - PFNGLDRAWELEMENTSBASEVERTEXPROC DrawElementsBaseVertex; - PFNGLUNIFORM4FPROC Uniform4f; - PFNGLBLENDEQUATIONSEPARATEIPROC BlendEquationSeparatei; - PFNGLBLENDFUNCSEPARATEPROC BlendFuncSeparate; - PFNGLCLEARBUFFERUIVPROC ClearBufferuiv; - PFNGLCOPYTEXSUBIMAGE1DPROC CopyTexSubImage1D; - PFNGLDRAWTRANSFORMFEEDBACKPROC DrawTransformFeedback; - PFNGLREADBUFFERPROC ReadBuffer; - PFNGLCOPYBUFFERSUBDATAPROC CopyBufferSubData; - PFNGLGETUNIFORMUIVPROC GetUniformuiv; - PFNGLPOLYGONOFFSETPROC PolygonOffset; - PFNGLDISPATCHCOMPUTEPROC DispatchCompute; - PFNGLBINDIMAGETEXTUREPROC BindImageTexture; - PFNGLUNIFORMMATRIX4X3DVPROC UniformMatrix4x3dv; - PFNGLGENRENDERBUFFERSPROC GenRenderbuffers; + const char* name; + PFNGLGETFLOATVPROC GetFloatv; + PFNGLTEXBUFFERRANGEPROC TexBufferRange; + PFNGLISBUFFERPROC IsBuffer; + PFNGLISTEXTUREPROC IsTexture; + PFNGLDEPTHRANGEFPROC DepthRangef; + PFNGLENDCONDITIONALRENDERPROC EndConditionalRender; + PFNGLBLENDFUNCIPROC BlendFunci; + PFNGLGETPROGRAMPIPELINEIVPROC GetProgramPipelineiv; + PFNGLWAITSYNCPROC WaitSync; + PFNGLPROGRAMUNIFORMMATRIX2FVPROC ProgramUniformMatrix2fv; + PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC ProgramUniformMatrix4x3dv; + PFNGLVERTEXATTRIB1DVPROC VertexAttrib1dv; + PFNGLSAMPLERPARAMETERIPROC SamplerParameteri; + PFNGLGETVERTEXATTRIBIIVPROC GetVertexAttribIiv; + PFNGLGETSAMPLERPARAMETERFVPROC GetSamplerParameterfv; + PFNGLVERTEXATTRIB1DPROC VertexAttrib1d; + PFNGLTEXBUFFERPROC TexBuffer; + PFNGLINVALIDATEBUFFERDATAPROC InvalidateBufferData; + PFNGLPROGRAMUNIFORM2IPROC ProgramUniform2i; + PFNGLUNIFORM4DVPROC Uniform4dv; + PFNGLUSEPROGRAMPROC UseProgram; + PFNGLVERTEXATTRIBI3IVPROC VertexAttribI3iv; + PFNGLDRAWELEMENTSINDIRECTPROC DrawElementsIndirect; + PFNGLVERTEXATTRIB4UIVPROC VertexAttrib4uiv; + PFNGLGETQUERYOBJECTIVPROC GetQueryObjectiv; + PFNGLFRAMEBUFFERRENDERBUFFERPROC FramebufferRenderbuffer; + PFNGLBLENDEQUATIONIPROC BlendEquationi; + PFNGLGETACTIVESUBROUTINENAMEPROC GetActiveSubroutineName; + PFNGLVERTEXATTRIB2SPROC VertexAttrib2s; + PFNGLVERTEXATTRIBL1DPROC VertexAttribL1d; + PFNGLBINDTEXTURESPROC BindTextures; + PFNGLVERTEXATTRIB3SVPROC VertexAttrib3sv; + PFNGLGETFLOATI_VPROC GetFloati_v; + PFNGLBEGINTRANSFORMFEEDBACKPROC BeginTransformFeedback; + PFNGLCLEARSTENCILPROC ClearStencil; + PFNGLUNIFORM3IPROC Uniform3i; + PFNGLVALIDATEPROGRAMPIPELINEPROC ValidateProgramPipeline; + PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC ProgramUniformMatrix4x2fv; + PFNGLVERTEXATTRIBI4UIPROC VertexAttribI4ui; + PFNGLGETSHADERIVPROC GetShaderiv; + PFNGLREADNPIXELSPROC ReadnPixels; + PFNGLUNIFORMMATRIX4X2FVPROC UniformMatrix4x2fv; + PFNGLGETSHADERPRECISIONFORMATPROC GetShaderPrecisionFormat; + PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC ProgramUniformMatrix2x3fv; + PFNGLTEXSUBIMAGE3DPROC TexSubImage3D; + PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC GetProgramResourceLocationIndex; + PFNGLBLENDFUNCPROC BlendFunc; + PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC ProgramUniformMatrix3x4fv; + PFNGLUNIFORM3DPROC Uniform3d; + PFNGLVERTEXATTRIB1SVPROC VertexAttrib1sv; + PFNGLBINDFRAGDATALOCATIONPROC BindFragDataLocation; + PFNGLVERTEXATTRIB4BVPROC VertexAttrib4bv; + PFNGLUNIFORM4IVPROC Uniform4iv; + PFNGLPROGRAMUNIFORM2UIPROC ProgramUniform2ui; + PFNGLDRAWARRAYSPROC DrawArrays; + PFNGLPROGRAMBINARYPROC ProgramBinary; + PFNGLVERTEXATTRIB4FPROC VertexAttrib4f; + PFNGLVERTEXATTRIBP2UIVPROC VertexAttribP2uiv; + PFNGLUNIFORMMATRIX3FVPROC UniformMatrix3fv; + PFNGLUNIFORM2IPROC Uniform2i; + PFNGLGETQUERYOBJECTUIVPROC GetQueryObjectuiv; + PFNGLUNIFORMBLOCKBINDINGPROC UniformBlockBinding; + PFNGLSAMPLECOVERAGEPROC SampleCoverage; + PFNGLVERTEXATTRIB4NUSVPROC VertexAttrib4Nusv; + PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC ProgramUniformMatrix2x4dv; + PFNGLUNIFORM3UIVPROC Uniform3uiv; + PFNGLVERTEXATTRIB1SPROC VertexAttrib1s; + PFNGLGETVERTEXATTRIBPOINTERVPROC GetVertexAttribPointerv; + PFNGLBLENDBARRIERPROC BlendBarrier; + PFNGLDRAWRANGEELEMENTSPROC DrawRangeElements; + PFNGLTEXSTORAGE3DPROC TexStorage3D; + PFNGLGETINTERNALFORMATI64VPROC GetInternalformati64v; + PFNGLGETQUERYOBJECTI64VPROC GetQueryObjecti64v; + PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC CompressedTexSubImage1D; + PFNGLVERTEXATTRIB3DVPROC VertexAttrib3dv; + PFNGLVERTEXBINDINGDIVISORPROC VertexBindingDivisor; + PFNGLUSEPROGRAMSTAGESPROC UseProgramStages; + PFNGLVERTEXATTRIBBINDINGPROC VertexAttribBinding; + PFNGLDEBUGMESSAGEINSERTPROC DebugMessageInsert; + PFNGLGETTEXPARAMETERIVPROC GetTexParameteriv; + PFNGLMULTIDRAWARRAYSINDIRECTPROC MultiDrawArraysIndirect; + PFNGLGETTEXPARAMETERFVPROC GetTexParameterfv; + PFNGLGETPROGRAMPIPELINEINFOLOGPROC GetProgramPipelineInfoLog; + PFNGLENDQUERYPROC EndQuery; + PFNGLGETPROGRAMRESOURCELOCATIONPROC GetProgramResourceLocation; + PFNGLCOMPRESSEDTEXIMAGE2DPROC CompressedTexImage2D; + PFNGLVERTEXATTRIBP2UIPROC VertexAttribP2ui; + PFNGLISENABLEDIPROC IsEnabledi; + PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC GetActiveAtomicCounterBufferiv; + PFNGLISPROGRAMPROC IsProgram; + PFNGLUNIFORM1DVPROC Uniform1dv; + PFNGLTEXPARAMETERIVPROC TexParameteriv; + PFNGLUNIFORM2FVPROC Uniform2fv; + PFNGLRELEASESHADERCOMPILERPROC ReleaseShaderCompiler; + PFNGLCULLFACEPROC CullFace; + PFNGLVERTEXATTRIBI4IPROC VertexAttribI4i; + PFNGLGETPROGRAMRESOURCEINDEXPROC GetProgramResourceIndex; + PFNGLSHADERBINARYPROC ShaderBinary; + PFNGLUNIFORMMATRIX3X2DVPROC UniformMatrix3x2dv; + PFNGLINVALIDATEFRAMEBUFFERPROC InvalidateFramebuffer; + PFNGLATTACHSHADERPROC AttachShader; + PFNGLFLUSHMAPPEDBUFFERRANGEPROC FlushMappedBufferRange; + PFNGLVERTEXATTRIBP3UIVPROC VertexAttribP3uiv; + PFNGLGETACTIVEUNIFORMNAMEPROC GetActiveUniformName; + PFNGLMAPBUFFERPROC MapBuffer; + PFNGLDRAWBUFFERSPROC DrawBuffers; + PFNGLGETSYNCIVPROC GetSynciv; + PFNGLCOPYTEXSUBIMAGE2DPROC CopyTexSubImage2D; + PFNGLOBJECTLABELPROC ObjectLabel; + PFNGLBUFFERSUBDATAPROC BufferSubData; + PFNGLUNIFORM2FPROC Uniform2f; + PFNGLDEBUGMESSAGECALLBACKPROC DebugMessageCallback; + PFNGLVERTEXATTRIBL4DVPROC VertexAttribL4dv; + PFNGLISPROGRAMPIPELINEPROC IsProgramPipeline; + PFNGLRESUMETRANSFORMFEEDBACKPROC ResumeTransformFeedback; + PFNGLVERTEXATTRIBI4IVPROC VertexAttribI4iv; + PFNGLGETSHADERINFOLOGPROC GetShaderInfoLog; + PFNGLGETINTEGERI_VPROC GetIntegeri_v; + PFNGLBINDVERTEXBUFFERPROC BindVertexBuffer; + PFNGLBLENDEQUATIONPROC BlendEquation; + PFNGLVERTEXATTRIBL2DVPROC VertexAttribL2dv; + PFNGLVERTEXATTRIBI1UIPROC VertexAttribI1ui; + PFNGLVERTEXATTRIB4NSVPROC VertexAttrib4Nsv; + PFNGLVERTEXATTRIBL4DPROC VertexAttribL4d; + PFNGLCOPYIMAGESUBDATAPROC CopyImageSubData; + PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC GetFramebufferAttachmentParameteriv; + PFNGLVERTEXATTRIBL2DPROC VertexAttribL2d; + PFNGLGETSUBROUTINEINDEXPROC GetSubroutineIndex; + PFNGLVERTEXATTRIBI3UIVPROC VertexAttribI3uiv; + PFNGLVERTEXATTRIB4IVPROC VertexAttrib4iv; + PFNGLBINDVERTEXBUFFERSPROC BindVertexBuffers; + PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC ProgramUniformMatrix2x3dv; + PFNGLPRIMITIVEBOUNDINGBOXPROC PrimitiveBoundingBox; + PFNGLSCISSORPROC Scissor; + PFNGLCLIENTWAITSYNCPROC ClientWaitSync; + PFNGLUNIFORM3UIPROC Uniform3ui; + PFNGLVERTEXATTRIBP3UIPROC VertexAttribP3ui; + PFNGLENABLEPROC Enable; + PFNGLSTENCILOPSEPARATEPROC StencilOpSeparate; + PFNGLUNIFORMMATRIX2X3DVPROC UniformMatrix2x3dv; + PFNGLPROGRAMUNIFORMMATRIX3DVPROC ProgramUniformMatrix3dv; + PFNGLTEXIMAGE2DMULTISAMPLEPROC TexImage2DMultisample; + PFNGLVERTEXATTRIB4NBVPROC VertexAttrib4Nbv; + PFNGLGETTEXIMAGEPROC GetTexImage; + PFNGLVERTEXATTRIB4SVPROC VertexAttrib4sv; + PFNGLPIXELSTOREIPROC PixelStorei; + PFNGLDEPTHMASKPROC DepthMask; + PFNGLTEXSTORAGE2DPROC TexStorage2D; + PFNGLCLEARPROC Clear; + PFNGLUNIFORMMATRIX3X4DVPROC UniformMatrix3x4dv; + PFNGLDELETETRANSFORMFEEDBACKSPROC DeleteTransformFeedbacks; + PFNGLMAPBUFFERRANGEPROC MapBufferRange; + PFNGLMEMORYBARRIERPROC MemoryBarrier; + PFNGLVIEWPORTINDEXEDFPROC ViewportIndexedf; + PFNGLVERTEXATTRIB3FVPROC VertexAttrib3fv; + PFNGLOBJECTPTRLABELPROC ObjectPtrLabel; + PFNGLTEXSTORAGE1DPROC TexStorage1D; + PFNGLCOMPRESSEDTEXIMAGE3DPROC CompressedTexImage3D; + PFNGLVERTEXATTRIB1FVPROC VertexAttrib1fv; + PFNGLVERTEXATTRIBPOINTERPROC VertexAttribPointer; + PFNGLGETQUERYINDEXEDIVPROC GetQueryIndexediv; + PFNGLCOMPILESHADERPROC CompileShader; + PFNGLPROGRAMUNIFORM1IPROC ProgramUniform1i; + PFNGLGETQUERYIVPROC GetQueryiv; + PFNGLVERTEXATTRIBI1IVPROC VertexAttribI1iv; + PFNGLCOPYTEXIMAGE2DPROC CopyTexImage2D; + PFNGLGETQUERYOBJECTUI64VPROC GetQueryObjectui64v; + PFNGLPOINTSIZEPROC PointSize; + PFNGLDISABLEIPROC Disablei; + PFNGLVERTEXATTRIBL1DVPROC VertexAttribL1dv; + PFNGLCREATESHADERPROC CreateShader; + PFNGLGETSTRINGPROC GetString; + PFNGLVIEWPORTARRAYVPROC ViewportArrayv; + PFNGLPROGRAMUNIFORM3DPROC ProgramUniform3d; + PFNGLVERTEXATTRIB4NUBVPROC VertexAttrib4Nubv; + PFNGLTEXPARAMETERIPROC TexParameteri; + PFNGLPROGRAMUNIFORM4FVPROC ProgramUniform4fv; + PFNGLGENERATEMIPMAPPROC GenerateMipmap; + PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC CompressedTexSubImage3D; + PFNGLUNIFORM3FPROC Uniform3f; + PFNGLGETUNIFORMINDICESPROC GetUniformIndices; + PFNGLVERTEXATTRIBLPOINTERPROC VertexAttribLPointer; + PFNGLVERTEXATTRIBI2UIVPROC VertexAttribI2uiv; + PFNGLQUERYCOUNTERPROC QueryCounter; + PFNGLACTIVESHADERPROGRAMPROC ActiveShaderProgram; + PFNGLUNIFORM1UIPROC Uniform1ui; + PFNGLVERTEXATTRIBI1IPROC VertexAttribI1i; + PFNGLGETTEXPARAMETERIIVPROC GetTexParameterIiv; + PFNGLGETUNIFORMFVPROC GetUniformfv; + PFNGLPROGRAMUNIFORM2UIVPROC ProgramUniform2uiv; + PFNGLGETERRORPROC GetError; + PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC GetActiveUniformBlockName; + PFNGLTEXTUREVIEWPROC TextureView; + PFNGLGETNUNIFORMIVPROC GetnUniformiv; + PFNGLPROGRAMUNIFORM4DVPROC ProgramUniform4dv; + PFNGLVIEWPORTINDEXEDFVPROC ViewportIndexedfv; + PFNGLHINTPROC Hint; + PFNGLGETSHADERSOURCEPROC GetShaderSource; + PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC ProgramUniformMatrix4x3fv; + PFNGLUNIFORM1IVPROC Uniform1iv; + PFNGLVERTEXATTRIBI4BVPROC VertexAttribI4bv; + PFNGLUNIFORMMATRIX4X2DVPROC UniformMatrix4x2dv; + PFNGLBUFFERSTORAGEPROC BufferStorage; + PFNGLISRENDERBUFFERPROC IsRenderbuffer; + PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC GetActiveSubroutineUniformName; + PFNGLLINKPROGRAMPROC LinkProgram; + PFNGLGETACTIVEUNIFORMSIVPROC GetActiveUniformsiv; + PFNGLGETDEBUGMESSAGELOGPROC GetDebugMessageLog; + PFNGLCOPYTEXSUBIMAGE3DPROC CopyTexSubImage3D; + PFNGLPOINTPARAMETERIPROC PointParameteri; + PFNGLPROGRAMUNIFORM3DVPROC ProgramUniform3dv; + PFNGLCOMPRESSEDTEXIMAGE1DPROC CompressedTexImage1D; + PFNGLUNIFORMMATRIX3X4FVPROC UniformMatrix3x4fv; + PFNGLGENSAMPLERSPROC GenSamplers; + PFNGLGETCOMPRESSEDTEXIMAGEPROC GetCompressedTexImage; + PFNGLDELETEQUERIESPROC DeleteQueries; + PFNGLGENPROGRAMPIPELINESPROC GenProgramPipelines; + PFNGLDISPATCHCOMPUTEINDIRECTPROC DispatchComputeIndirect; + PFNGLVERTEXATTRIBIPOINTERPROC VertexAttribIPointer; + PFNGLCREATEPROGRAMPROC CreateProgram; + PFNGLCLEARTEXSUBIMAGEPROC ClearTexSubImage; + PFNGLVERTEXATTRIB4DPROC VertexAttrib4d; + PFNGLFRONTFACEPROC FrontFace; + PFNGLBINDTRANSFORMFEEDBACKPROC BindTransformFeedback; + PFNGLGETPROGRAMSTAGEIVPROC GetProgramStageiv; + PFNGLSAMPLERPARAMETERIIVPROC SamplerParameterIiv; + PFNGLGETINTEGER64VPROC GetInteger64v; + PFNGLCREATESHADERPROGRAMVPROC CreateShaderProgramv; + PFNGLBINDBUFFERSRANGEPROC BindBuffersRange; + PFNGLUNIFORM3FVPROC Uniform3fv; + PFNGLPROGRAMUNIFORMMATRIX4FVPROC ProgramUniformMatrix4fv; + PFNGLBINDBUFFERSBASEPROC BindBuffersBase; + PFNGLCLEARBUFFERFIPROC ClearBufferfi; + PFNGLFRAMEBUFFERTEXTURE3DPROC FramebufferTexture3D; + PFNGLDISABLEPROC Disable; + PFNGLPROGRAMUNIFORM1IVPROC ProgramUniform1iv; + PFNGLVERTEXATTRIBI2IVPROC VertexAttribI2iv; + PFNGLDEPTHRANGEINDEXEDPROC DepthRangeIndexed; + PFNGLPATCHPARAMETERIPROC PatchParameteri; + PFNGLGETUNIFORMBLOCKINDEXPROC GetUniformBlockIndex; + PFNGLMULTIDRAWARRAYSPROC MultiDrawArrays; + PFNGLVERTEXATTRIBI4UBVPROC VertexAttribI4ubv; + PFNGLBINDBUFFERPROC BindBuffer; + PFNGLVERTEXATTRIBI3IPROC VertexAttribI3i; + PFNGLGETDOUBLEVPROC GetDoublev; + PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC DrawTransformFeedbackStream; + PFNGLVERTEXATTRIBI4UIVPROC VertexAttribI4uiv; + PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC RenderbufferStorageMultisample; + PFNGLVERTEXATTRIBL3DVPROC VertexAttribL3dv; + PFNGLSTENCILMASKSEPARATEPROC StencilMaskSeparate; + PFNGLPROGRAMUNIFORM1DPROC ProgramUniform1d; + PFNGLVIEWPORTPROC Viewport; + PFNGLVERTEXATTRIBP1UIPROC VertexAttribP1ui; + PFNGLVERTEXATTRIB4DVPROC VertexAttrib4dv; + PFNGLGENQUERIESPROC GenQueries; + PFNGLTEXPARAMETERIIVPROC TexParameterIiv; + PFNGLPROGRAMUNIFORM2DPROC ProgramUniform2d; + PFNGLPROGRAMUNIFORM1UIVPROC ProgramUniform1uiv; + PFNGLVERTEXATTRIB4NUBPROC VertexAttrib4Nub; + PFNGLISVERTEXARRAYPROC IsVertexArray; + PFNGLPROGRAMUNIFORM3FPROC ProgramUniform3f; + PFNGLPROGRAMUNIFORM3IVPROC ProgramUniform3iv; + PFNGLGETPROGRAMBINARYPROC GetProgramBinary; + PFNGLBINDRENDERBUFFERPROC BindRenderbuffer; + PFNGLBINDFRAGDATALOCATIONINDEXEDPROC BindFragDataLocationIndexed; + PFNGLGETSAMPLERPARAMETERIIVPROC GetSamplerParameterIiv; + PFNGLVERTEXATTRIBDIVISORPROC VertexAttribDivisor; + PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC ProgramUniformMatrix3x2dv; + PFNGLFRAMEBUFFERPARAMETERIPROC FramebufferParameteri; + PFNGLGENTRANSFORMFEEDBACKSPROC GenTransformFeedbacks; + PFNGLDELETESYNCPROC DeleteSync; + PFNGLPROGRAMUNIFORM1UIPROC ProgramUniform1ui; + PFNGLTEXSUBIMAGE1DPROC TexSubImage1D; + PFNGLCLEARDEPTHFPROC ClearDepthf; + PFNGLREADPIXELSPROC ReadPixels; + PFNGLVERTEXATTRIBI2IPROC VertexAttribI2i; + PFNGLFINISHPROC Finish; + PFNGLLINEWIDTHPROC LineWidth; + PFNGLDELETESHADERPROC DeleteShader; + PFNGLISSAMPLERPROC IsSampler; + PFNGLPROGRAMUNIFORMMATRIX4DVPROC ProgramUniformMatrix4dv; + PFNGLTRANSFORMFEEDBACKVARYINGSPROC TransformFeedbackVaryings; + PFNGLBEGINCONDITIONALRENDERPROC BeginConditionalRender; + PFNGLBINDSAMPLERSPROC BindSamplers; + PFNGLDELETEPROGRAMPIPELINESPROC DeleteProgramPipelines; + PFNGLCOLORMASKPROC ColorMask; + PFNGLTEXPARAMETERFVPROC TexParameterfv; + PFNGLPUSHDEBUGGROUPPROC PushDebugGroup; + PFNGLCLEARBUFFERFVPROC ClearBufferfv; + PFNGLISENABLEDPROC IsEnabled; + PFNGLVERTEXATTRIB2FPROC VertexAttrib2f; + PFNGLPROGRAMUNIFORM2FPROC ProgramUniform2f; + PFNGLGETSAMPLERPARAMETERIUIVPROC GetSamplerParameterIuiv; + PFNGLGETINTEGER64I_VPROC GetInteger64i_v; + PFNGLUNIFORM2DVPROC Uniform2dv; + PFNGLGETBUFFERSUBDATAPROC GetBufferSubData; + PFNGLMULTIDRAWELEMENTSINDIRECTPROC MultiDrawElementsIndirect; + PFNGLPROGRAMPARAMETERIPROC ProgramParameteri; + PFNGLVERTEXATTRIBP4UIPROC VertexAttribP4ui; + PFNGLSAMPLERPARAMETERFVPROC SamplerParameterfv; + PFNGLPOINTPARAMETERFPROC PointParameterf; + PFNGLUNIFORMMATRIX2X4FVPROC UniformMatrix2x4fv; + PFNGLGENBUFFERSPROC GenBuffers; + PFNGLPROGRAMUNIFORM2DVPROC ProgramUniform2dv; + PFNGLVERTEXATTRIBFORMATPROC VertexAttribFormat; + PFNGLTEXSUBIMAGE2DPROC TexSubImage2D; + PFNGLVERTEXATTRIB4UBVPROC VertexAttrib4ubv; + PFNGLGETGRAPHICSRESETSTATUSPROC GetGraphicsResetStatus; + PFNGLGETPROGRAMINTERFACEIVPROC GetProgramInterfaceiv; + PFNGLVERTEXATTRIBIFORMATPROC VertexAttribIFormat; + PFNGLGETNUNIFORMFVPROC GetnUniformfv; + PFNGLDELETEPROGRAMPROC DeleteProgram; + PFNGLCLAMPCOLORPROC ClampColor; + PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC DrawElementsInstancedBaseVertexBaseInstance; + PFNGLDRAWELEMENTSPROC DrawElements; + PFNGLDEBUGMESSAGECONTROLPROC DebugMessageControl; + PFNGLGETRENDERBUFFERPARAMETERIVPROC GetRenderbufferParameteriv; + PFNGLDETACHSHADERPROC DetachShader; + PFNGLGENFRAMEBUFFERSPROC GenFramebuffers; + PFNGLPROVOKINGVERTEXPROC ProvokingVertex; + PFNGLSAMPLEMASKIPROC SampleMaski; + PFNGLENDQUERYINDEXEDPROC EndQueryIndexed; + PFNGLPROGRAMUNIFORM1FPROC ProgramUniform1f; + PFNGLBINDFRAMEBUFFERPROC BindFramebuffer; + PFNGLBEGINQUERYINDEXEDPROC BeginQueryIndexed; + PFNGLUNIFORMSUBROUTINESUIVPROC UniformSubroutinesuiv; + PFNGLGETUNIFORMIVPROC GetUniformiv; + PFNGLFRAMEBUFFERTEXTUREPROC FramebufferTexture; + PFNGLPOINTPARAMETERFVPROC PointParameterfv; + PFNGLISTRANSFORMFEEDBACKPROC IsTransformFeedback; + PFNGLCHECKFRAMEBUFFERSTATUSPROC CheckFramebufferStatus; + PFNGLSHADERSOURCEPROC ShaderSource; + PFNGLUNIFORMMATRIX2X4DVPROC UniformMatrix2x4dv; + PFNGLBINDIMAGETEXTURESPROC BindImageTextures; + PFNGLCOPYTEXIMAGE1DPROC CopyTexImage1D; + PFNGLUNIFORMMATRIX3DVPROC UniformMatrix3dv; + PFNGLPROGRAMUNIFORM1DVPROC ProgramUniform1dv; + PFNGLBLITFRAMEBUFFERPROC BlitFramebuffer; + PFNGLPOPDEBUGGROUPPROC PopDebugGroup; + PFNGLTEXPARAMETERIUIVPROC TexParameterIuiv; + PFNGLVERTEXATTRIB2DPROC VertexAttrib2d; + PFNGLTEXIMAGE1DPROC TexImage1D; + PFNGLGETOBJECTPTRLABELPROC GetObjectPtrLabel; + PFNGLSTENCILMASKPROC StencilMask; + PFNGLBEGINQUERYPROC BeginQuery; + PFNGLUNIFORMMATRIX4FVPROC UniformMatrix4fv; + PFNGLISSYNCPROC IsSync; + PFNGLUNIFORM3DVPROC Uniform3dv; + PFNGLPROGRAMUNIFORM2FVPROC ProgramUniform2fv; + PFNGLVERTEXATTRIBI4SVPROC VertexAttribI4sv; + PFNGLSCISSORARRAYVPROC ScissorArrayv; + PFNGLVERTEXATTRIBP1UIVPROC VertexAttribP1uiv; + PFNGLUNIFORM2UIVPROC Uniform2uiv; + PFNGLDELETEBUFFERSPROC DeleteBuffers; + PFNGLPROGRAMUNIFORM3UIPROC ProgramUniform3ui; + PFNGLFRAMEBUFFERTEXTURELAYERPROC FramebufferTextureLayer; + PFNGLENDTRANSFORMFEEDBACKPROC EndTransformFeedback; + PFNGLBLENDFUNCSEPARATEIPROC BlendFuncSeparatei; + PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC DrawTransformFeedbackInstanced; + PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC DrawRangeElementsBaseVertex; + PFNGLVERTEXATTRIB1FPROC VertexAttrib1f; + PFNGLGETUNIFORMSUBROUTINEUIVPROC GetUniformSubroutineuiv; + PFNGLDISABLEVERTEXATTRIBARRAYPROC DisableVertexAttribArray; + PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC ProgramUniformMatrix3x2fv; + PFNGLVERTEXATTRIBI4USVPROC VertexAttribI4usv; + PFNGLGETOBJECTLABELPROC GetObjectLabel; + PFNGLBINDATTRIBLOCATIONPROC BindAttribLocation; + PFNGLUNIFORM1FPROC Uniform1f; + PFNGLGETUNIFORMDVPROC GetUniformdv; + PFNGLGETUNIFORMLOCATIONPROC GetUniformLocation; + PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC GetSubroutineUniformLocation; + PFNGLGETTEXPARAMETERIUIVPROC GetTexParameterIuiv; + PFNGLSAMPLERPARAMETERFPROC SamplerParameterf; + PFNGLVERTEXATTRIBL3DPROC VertexAttribL3d; + PFNGLTEXIMAGE3DMULTISAMPLEPROC TexImage3DMultisample; + PFNGLTEXIMAGE3DPROC TexImage3D; + PFNGLRENDERBUFFERSTORAGEPROC RenderbufferStorage; + PFNGLENABLEVERTEXATTRIBARRAYPROC EnableVertexAttribArray; + PFNGLVERTEXATTRIBP4UIVPROC VertexAttribP4uiv; + PFNGLUNIFORM4DPROC Uniform4d; + PFNGLVERTEXATTRIB4SPROC VertexAttrib4s; + PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC DrawElementsInstancedBaseVertex; + PFNGLVERTEXATTRIB3SPROC VertexAttrib3s; + PFNGLPROGRAMUNIFORM2IVPROC ProgramUniform2iv; + PFNGLSTENCILFUNCSEPARATEPROC StencilFuncSeparate; + PFNGLDELETEFRAMEBUFFERSPROC DeleteFramebuffers; + PFNGLDEPTHRANGEPROC DepthRange; + PFNGLUNIFORMMATRIX3X2FVPROC UniformMatrix3x2fv; + PFNGLPROGRAMUNIFORMMATRIX2DVPROC ProgramUniformMatrix2dv; + PFNGLSHADERSTORAGEBLOCKBINDINGPROC ShaderStorageBlockBinding; + PFNGLCLEARDEPTHPROC ClearDepth; + PFNGLVERTEXATTRIB2DVPROC VertexAttrib2dv; + PFNGLSAMPLERPARAMETERIUIVPROC SamplerParameterIuiv; + PFNGLGETVERTEXATTRIBLDVPROC GetVertexAttribLdv; + PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC ProgramUniformMatrix3x4dv; + PFNGLDEPTHRANGEARRAYVPROC DepthRangeArrayv; + PFNGLGETACTIVEUNIFORMPROC GetActiveUniform; + PFNGLPATCHPARAMETERFVPROC PatchParameterfv; + PFNGLINVALIDATETEXIMAGEPROC InvalidateTexImage; + PFNGLVERTEXATTRIB3FPROC VertexAttrib3f; + PFNGLPROGRAMUNIFORM4IVPROC ProgramUniform4iv; + PFNGLPROGRAMUNIFORM4DPROC ProgramUniform4d; + PFNGLISFRAMEBUFFERPROC IsFramebuffer; + PFNGLPIXELSTOREFPROC PixelStoref; + PFNGLPROGRAMUNIFORM4UIVPROC ProgramUniform4uiv; + PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC ProgramUniformMatrix4x2dv; + PFNGLFENCESYNCPROC FenceSync; + PFNGLGETBUFFERPARAMETERI64VPROC GetBufferParameteri64v; + PFNGLSTENCILOPPROC StencilOp; + PFNGLCLEARBUFFERDATAPROC ClearBufferData; + PFNGLGETNUNIFORMUIVPROC GetnUniformuiv; + PFNGLGETPROGRAMRESOURCEIVPROC GetProgramResourceiv; + PFNGLGETVERTEXATTRIBDVPROC GetVertexAttribdv; + PFNGLGETTRANSFORMFEEDBACKVARYINGPROC GetTransformFeedbackVarying; + PFNGLVERTEXATTRIB2FVPROC VertexAttrib2fv; + PFNGLGETBOOLEANI_VPROC GetBooleani_v; + PFNGLCOLORMASKIPROC ColorMaski; + PFNGLINVALIDATEBUFFERSUBDATAPROC InvalidateBufferSubData; + PFNGLUNIFORMMATRIX4DVPROC UniformMatrix4dv; + PFNGLISQUERYPROC IsQuery; + PFNGLUNIFORM4UIPROC Uniform4ui; + PFNGLUNIFORM4IPROC Uniform4i; + PFNGLGETSAMPLERPARAMETERIVPROC GetSamplerParameteriv; + PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC MultiDrawElementsBaseVertex; + PFNGLVERTEXATTRIBI1UIVPROC VertexAttribI1uiv; + PFNGLGETINTEGERVPROC GetIntegerv; + PFNGLUNIFORMMATRIX2X3FVPROC UniformMatrix2x3fv; + PFNGLTEXIMAGE2DPROC TexImage2D; + PFNGLGETATTACHEDSHADERSPROC GetAttachedShaders; + PFNGLUNIFORM2DPROC Uniform2d; + PFNGLMEMORYBARRIERBYREGIONPROC MemoryBarrierByRegion; + PFNGLUNIFORMMATRIX2FVPROC UniformMatrix2fv; + PFNGLPRIMITIVERESTARTINDEXPROC PrimitiveRestartIndex; + PFNGLGETVERTEXATTRIBIVPROC GetVertexAttribiv; + PFNGLGETATTRIBLOCATIONPROC GetAttribLocation; + PFNGLTEXSTORAGE2DMULTISAMPLEPROC TexStorage2DMultisample; + PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC CompressedTexSubImage2D; + PFNGLGETVERTEXATTRIBFVPROC GetVertexAttribfv; + PFNGLGETBUFFERPARAMETERIVPROC GetBufferParameteriv; + PFNGLTEXPARAMETERFPROC TexParameterf; + PFNGLFRAMEBUFFERTEXTURE2DPROC FramebufferTexture2D; + PFNGLGETACTIVEATTRIBPROC GetActiveAttrib; + PFNGLINVALIDATETEXSUBIMAGEPROC InvalidateTexSubImage; + PFNGLDELETEVERTEXARRAYSPROC DeleteVertexArrays; + PFNGLVERTEXATTRIBI2UIPROC VertexAttribI2ui; + PFNGLPOINTPARAMETERIVPROC PointParameteriv; + PFNGLGETPOINTERVPROC GetPointerv; + PFNGLENABLEIPROC Enablei; + PFNGLBINDBUFFERRANGEPROC BindBufferRange; + PFNGLDRAWARRAYSINSTANCEDPROC DrawArraysInstanced; + PFNGLDELETETEXTURESPROC DeleteTextures; + PFNGLVERTEXATTRIB4NIVPROC VertexAttrib4Niv; + PFNGLMULTIDRAWELEMENTSPROC MultiDrawElements; + PFNGLGETPROGRAMIVPROC GetProgramiv; + PFNGLDEPTHFUNCPROC DepthFunc; + PFNGLGENTEXTURESPROC GenTextures; + PFNGLGETINTERNALFORMATIVPROC GetInternalformativ; + PFNGLPROGRAMUNIFORM3IPROC ProgramUniform3i; + PFNGLSCISSORINDEXEDPROC ScissorIndexed; + PFNGLVERTEXATTRIB2SVPROC VertexAttrib2sv; + PFNGLTEXSTORAGE3DMULTISAMPLEPROC TexStorage3DMultisample; + PFNGLUNIFORM2IVPROC Uniform2iv; + PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC DrawArraysInstancedBaseInstance; + PFNGLVERTEXATTRIBI3UIPROC VertexAttribI3ui; + PFNGLDELETESAMPLERSPROC DeleteSamplers; + PFNGLGENVERTEXARRAYSPROC GenVertexArrays; + PFNGLGETFRAMEBUFFERPARAMETERIVPROC GetFramebufferParameteriv; + PFNGLPOLYGONMODEPROC PolygonMode; + PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC ProgramUniformMatrix2x4fv; + PFNGLGETPROGRAMRESOURCENAMEPROC GetProgramResourceName; + PFNGLSAMPLERPARAMETERIVPROC SamplerParameteriv; + PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC GetActiveSubroutineUniformiv; + PFNGLGETSTRINGIPROC GetStringi; + PFNGLVERTEXATTRIBLFORMATPROC VertexAttribLFormat; + PFNGLVERTEXATTRIB3DPROC VertexAttrib3d; + PFNGLBINDVERTEXARRAYPROC BindVertexArray; + PFNGLUNMAPBUFFERPROC UnmapBuffer; + PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC DrawElementsInstancedBaseInstance; + PFNGLUNIFORM4UIVPROC Uniform4uiv; + PFNGLFRAMEBUFFERTEXTURE1DPROC FramebufferTexture1D; + PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC DrawTransformFeedbackStreamInstanced; + PFNGLSTENCILFUNCPROC StencilFunc; + PFNGLVALIDATEPROGRAMPROC ValidateProgram; + PFNGLFLUSHPROC Flush; + PFNGLPROGRAMUNIFORM3UIVPROC ProgramUniform3uiv; + PFNGLDELETERENDERBUFFERSPROC DeleteRenderbuffers; + PFNGLVERTEXATTRIB4FVPROC VertexAttrib4fv; + PFNGLUNIFORMMATRIX2DVPROC UniformMatrix2dv; + PFNGLGETFRAGDATAINDEXPROC GetFragDataIndex; + PFNGLUNIFORM3IVPROC Uniform3iv; + PFNGLMINSAMPLESHADINGPROC MinSampleShading; + PFNGLGETBOOLEANVPROC GetBooleanv; + PFNGLGETMULTISAMPLEFVPROC GetMultisamplefv; + PFNGLGETVERTEXATTRIBIUIVPROC GetVertexAttribIuiv; + PFNGLGETPROGRAMINFOLOGPROC GetProgramInfoLog; + PFNGLUNIFORM4FVPROC Uniform4fv; + PFNGLDRAWBUFFERPROC DrawBuffer; + PFNGLUNIFORM1IPROC Uniform1i; + PFNGLPROGRAMUNIFORM4UIPROC ProgramUniform4ui; + PFNGLPROGRAMUNIFORMMATRIX3FVPROC ProgramUniformMatrix3fv; + PFNGLBLENDEQUATIONSEPARATEPROC BlendEquationSeparate; + PFNGLBINDPROGRAMPIPELINEPROC BindProgramPipeline; + PFNGLGETDOUBLEI_VPROC GetDoublei_v; + PFNGLBUFFERDATAPROC BufferData; + PFNGLCLEARCOLORPROC ClearColor; + PFNGLPROGRAMUNIFORM4IPROC ProgramUniform4i; + PFNGLGETTEXLEVELPARAMETERIVPROC GetTexLevelParameteriv; + PFNGLGETACTIVEUNIFORMBLOCKIVPROC GetActiveUniformBlockiv; + PFNGLPROGRAMUNIFORM1FVPROC ProgramUniform1fv; + PFNGLPAUSETRANSFORMFEEDBACKPROC PauseTransformFeedback; + PFNGLGETBUFFERPOINTERVPROC GetBufferPointerv; + PFNGLINVALIDATESUBFRAMEBUFFERPROC InvalidateSubFramebuffer; + PFNGLSCISSORINDEXEDVPROC ScissorIndexedv; + PFNGLUNIFORM2UIPROC Uniform2ui; + PFNGLBINDTEXTUREPROC BindTexture; + PFNGLDRAWELEMENTSINSTANCEDPROC DrawElementsInstanced; + PFNGLPROGRAMUNIFORM4FPROC ProgramUniform4f; + PFNGLBINDBUFFERBASEPROC BindBufferBase; + PFNGLISSHADERPROC IsShader; + PFNGLCLEARBUFFERSUBDATAPROC ClearBufferSubData; + PFNGLVERTEXATTRIB4NUIVPROC VertexAttrib4Nuiv; + PFNGLDRAWARRAYSINDIRECTPROC DrawArraysIndirect; + PFNGLVERTEXATTRIB4USVPROC VertexAttrib4usv; + PFNGLUNIFORM1DPROC Uniform1d; + PFNGLCLEARTEXIMAGEPROC ClearTexImage; + PFNGLUNIFORM1UIVPROC Uniform1uiv; + PFNGLBINDSAMPLERPROC BindSampler; + PFNGLGETTEXLEVELPARAMETERFVPROC GetTexLevelParameterfv; + PFNGLCLEARBUFFERIVPROC ClearBufferiv; + PFNGLLOGICOPPROC LogicOp; + PFNGLACTIVETEXTUREPROC ActiveTexture; + PFNGLGETFRAGDATALOCATIONPROC GetFragDataLocation; + PFNGLBLENDCOLORPROC BlendColor; + PFNGLUNIFORMMATRIX4X3FVPROC UniformMatrix4x3fv; + PFNGLPROGRAMUNIFORM3FVPROC ProgramUniform3fv; + PFNGLUNIFORM1FVPROC Uniform1fv; + PFNGLDRAWELEMENTSBASEVERTEXPROC DrawElementsBaseVertex; + PFNGLUNIFORM4FPROC Uniform4f; + PFNGLBLENDEQUATIONSEPARATEIPROC BlendEquationSeparatei; + PFNGLBLENDFUNCSEPARATEPROC BlendFuncSeparate; + PFNGLCLEARBUFFERUIVPROC ClearBufferuiv; + PFNGLCOPYTEXSUBIMAGE1DPROC CopyTexSubImage1D; + PFNGLDRAWTRANSFORMFEEDBACKPROC DrawTransformFeedback; + PFNGLREADBUFFERPROC ReadBuffer; + PFNGLCOPYBUFFERSUBDATAPROC CopyBufferSubData; + PFNGLGETUNIFORMUIVPROC GetUniformuiv; + PFNGLPOLYGONOFFSETPROC PolygonOffset; + PFNGLDISPATCHCOMPUTEPROC DispatchCompute; + PFNGLBINDIMAGETEXTUREPROC BindImageTexture; + PFNGLUNIFORMMATRIX4X3DVPROC UniformMatrix4x3dv; + PFNGLGENRENDERBUFFERSPROC GenRenderbuffers; } oc_gl_api; ORCA_API oc_gl_api* oc_gl_get_api(void); diff --git a/src/graphics/gl_canvas.c b/src/graphics/gl_canvas.c index bdca5e2..831d27c 100644 --- a/src/graphics/gl_canvas.c +++ b/src/graphics/gl_canvas.c @@ -1,1827 +1,1841 @@ -/************************************************************//** +/************************************************************/ /** * * @file: gl_canvas.c * @author: Martin Fouilleul * @date: 29/01/2023 * @revision: * -*****************************************************************/ -#include"graphics_surface.h" -#include"util/macros.h" -#include"glsl_shaders.h" -#include"gl_api.h" - -typedef struct oc_gl_image -{ - oc_image_data interface; - GLuint texture; -} oc_gl_image; - -enum oc_gl_cmd_enum { - OC_GL_FILL, - OC_GL_STROKE, -}; -typedef int oc_gl_cmd; - -typedef struct oc_gl_path -{ - float uvTransform[12]; - oc_vec4 color; - oc_vec4 box; - oc_vec4 clip; - oc_gl_cmd cmd; - int textureID; - u8 pad[8]; -} oc_gl_path; - -enum oc_gl_seg_kind_enum -{ - OC_GL_LINE = 1, - OC_GL_QUADRATIC, - OC_GL_CUBIC, -}; -typedef int oc_gl_seg_kind; - -typedef struct oc_gl_path_elt -{ - oc_vec2 p[4]; - int pathIndex; - oc_gl_seg_kind kind; - -} oc_gl_path_elt; - -typedef struct oc_gl_dispatch_indirect_command -{ - u32 num_groups_x; - u32 num_groups_y; - u32 num_groups_z; - -} oc_gl_dispatch_indirect_command; -//////////////////////////////////////////////////////////// -//NOTE: these are just here for the sizes... - -#define OC_GL_LAYOUT_FIRST(name, type) \ - OC_GL_##name##_OFFSET = 0, \ - OC_GL_##name##_SIZE = OC_GL_##type##_SIZE, - -#define OC_GL_LAYOUT_NEXT(name, type, prev) \ - OC_GL_##name##_OFFSET = oc_align_up_pow2(OC_GL_##prev##_OFFSET + OC_GL_##prev##_SIZE, OC_GL_##type##_ALIGN), \ - OC_GL_##name##_SIZE = OC_GL_##type##_SIZE, - -#define OC_GL_LAYOUT_SIZE(name, last, maxAlignType) \ - OC_GL_##name##_ALIGN = oc_align_up_pow2(OC_GL_##maxAlignType##_ALIGN, OC_GL_VEC4_ALIGN), \ - OC_GL_##name##_SIZE = oc_align_up_pow2(OC_GL_##last##_OFFSET + OC_GL_##last##_SIZE, OC_GL_##name##_ALIGN), - -enum -{ - OC_GL_I32_SIZE = sizeof(i32), - OC_GL_I32_ALIGN = sizeof(i32), - OC_GL_F32_SIZE = sizeof(f32), - OC_GL_F32_ALIGN = sizeof(f32), - OC_GL_VEC2_SIZE = 2*sizeof(f32), - OC_GL_VEC2_ALIGN = 2*sizeof(f32), - OC_GL_VEC3_SIZE = 4*sizeof(f32), - OC_GL_VEC3_ALIGN = 4*sizeof(f32), - OC_GL_VEC4_SIZE = 4*sizeof(f32), - OC_GL_VEC4_ALIGN = 4*sizeof(f32), - OC_GL_MAT3_SIZE = 3*3*OC_GL_VEC3_SIZE, - OC_GL_MAT3_ALIGN = OC_GL_VEC3_ALIGN, - - OC_GL_LAYOUT_FIRST(SEGMENT_KIND, I32) - OC_GL_LAYOUT_NEXT(SEGMENT_PATH_INDEX, I32, SEGMENT_KIND) - OC_GL_LAYOUT_NEXT(SEGMENT_CONFIG, I32, SEGMENT_PATH_INDEX) - OC_GL_LAYOUT_NEXT(SEGMENT_WINDING, I32, SEGMENT_CONFIG) - OC_GL_LAYOUT_NEXT(SEGMENT_BOX, VEC4, SEGMENT_WINDING) - OC_GL_LAYOUT_NEXT(SEGMENT_IMPLICIT_MATRIX, MAT3, SEGMENT_BOX) - OC_GL_LAYOUT_NEXT(SEGMENT_HULL_VERTEX, VEC2, SEGMENT_IMPLICIT_MATRIX) - OC_GL_LAYOUT_NEXT(SEGMENT_SIGN, F32, SEGMENT_HULL_VERTEX) - OC_GL_LAYOUT_SIZE(SEGMENT, SEGMENT_SIGN, MAT3) - - OC_GL_LAYOUT_FIRST(PATH_QUEUE_AREA, VEC4) - OC_GL_LAYOUT_NEXT(PATH_QUEUE_TILE_QUEUES, I32, PATH_QUEUE_AREA) - OC_GL_LAYOUT_SIZE(PATH_QUEUE, PATH_QUEUE_TILE_QUEUES, VEC4) - - OC_GL_LAYOUT_FIRST(TILE_OP_KIND, I32) - OC_GL_LAYOUT_NEXT(TILE_OP_NEXT, I32, TILE_OP_KIND) - OC_GL_LAYOUT_NEXT(TILE_OP_INDEX, I32, TILE_OP_NEXT) - OC_GL_LAYOUT_NEXT(TILE_OP_WINDING, I32, TILE_OP_INDEX) - OC_GL_LAYOUT_SIZE(TILE_OP, TILE_OP_WINDING, I32) - - OC_GL_LAYOUT_FIRST(TILE_QUEUE_WINDING, I32) - OC_GL_LAYOUT_NEXT(TILE_QUEUE_FIRST, I32, TILE_QUEUE_WINDING) - OC_GL_LAYOUT_NEXT(TILE_QUEUE_LAST, I32, TILE_QUEUE_FIRST) - OC_GL_LAYOUT_SIZE(TILE_QUEUE, TILE_QUEUE_LAST, I32) - - OC_GL_LAYOUT_FIRST(SCREEN_TILE_COORD, VEC2) - OC_GL_LAYOUT_NEXT(SCREEN_TILE_FIRST, I32, SCREEN_TILE_COORD) - OC_GL_LAYOUT_SIZE(SCREEN_TILE, SCREEN_TILE_FIRST, VEC2) -}; - -enum { - OC_GL_INPUT_BUFFERS_COUNT = 3, - OC_GL_TILE_SIZE = 16, - OC_GL_MSAA_COUNT = 8, - OC_GL_MAX_IMAGES_PER_BATCH = 8, -}; - -typedef struct oc_gl_mapped_buffer -{ - GLuint buffer; - int size; - char* contents; -} oc_gl_mapped_buffer; - -typedef struct oc_gl_canvas_backend -{ - oc_canvas_backend interface; - oc_wgl_surface* surface; - - int msaaCount; - oc_vec2 frameSize; - - // gl stuff - GLuint vao; - - GLuint pathSetup; - GLuint segmentSetup; - GLuint backprop; - GLuint merge; - GLuint balanceWorkgroups; - GLuint raster; - GLuint blit; - - GLuint outTexture; - - int bufferIndex; - GLsync bufferSync[OC_GL_INPUT_BUFFERS_COUNT]; - oc_gl_mapped_buffer pathBuffer[OC_GL_INPUT_BUFFERS_COUNT]; - oc_gl_mapped_buffer elementBuffer[OC_GL_INPUT_BUFFERS_COUNT]; - - GLuint segmentBuffer; - GLuint segmentCountBuffer; - GLuint pathQueueBuffer; - GLuint tileQueueBuffer; - GLuint tileQueueCountBuffer; - GLuint tileOpBuffer; - GLuint tileOpCountBuffer; - GLuint screenTilesBuffer; - GLuint screenTilesCountBuffer; - GLuint rasterDispatchBuffer; - GLuint dummyVertexBuffer; - - //encoding context - int pathCount; - int eltCount; - - int pathBatchStart; - int eltBatchStart; - - oc_primitive* primitive; - oc_vec4 pathScreenExtents; - oc_vec4 pathUserExtents; - - int maxTileQueueCount; - int maxSegmentCount; - - int currentImageIndex; -} oc_gl_canvas_backend; - -static void oc_update_path_extents(oc_vec4* extents, oc_vec2 p) -{ - extents->x = oc_min(extents->x, p.x); - extents->y = oc_min(extents->y, p.y); - extents->z = oc_max(extents->z, p.x); - extents->w = oc_max(extents->w, p.y); -} - -void oc_gl_grow_input_buffer(oc_gl_mapped_buffer* buffer, int copyStart, int copySize, int newSize) -{ - oc_gl_mapped_buffer newBuffer = {0}; - newBuffer.size = newSize; - glGenBuffers(1, &newBuffer.buffer); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, newBuffer.buffer); - glBufferStorage(GL_SHADER_STORAGE_BUFFER, newBuffer.size, 0, GL_MAP_WRITE_BIT|GL_MAP_PERSISTENT_BIT); - newBuffer.contents = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, - 0, - newBuffer.size, - GL_MAP_WRITE_BIT - |GL_MAP_PERSISTENT_BIT - |GL_MAP_FLUSH_EXPLICIT_BIT); - - memcpy(newBuffer.contents + copyStart, buffer->contents + copyStart, copySize); - - glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer->buffer); - glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); - glDeleteBuffers(1, &buffer->buffer); - - *buffer = newBuffer; -} - -void oc_gl_canvas_encode_element(oc_gl_canvas_backend* backend, oc_path_elt_type kind, oc_vec2* p) -{ - int bufferIndex = backend->bufferIndex; - int bufferCap = backend->elementBuffer[bufferIndex].size / sizeof(oc_gl_path_elt); - if(backend->eltCount >= bufferCap) - { - int newBufferCap = (int)(bufferCap * 1.5); - int newBufferSize = newBufferCap * sizeof(oc_gl_path_elt); - - oc_log_info("growing element buffer to %i elements\n", newBufferCap); - - oc_gl_grow_input_buffer(&backend->elementBuffer[bufferIndex], - backend->eltBatchStart * sizeof(oc_gl_path_elt), - backend->eltCount * sizeof(oc_gl_path_elt), - newBufferSize); - } - - oc_gl_path_elt* elementData = (oc_gl_path_elt*)backend->elementBuffer[bufferIndex].contents; - oc_gl_path_elt* elt = &elementData[backend->eltCount]; - backend->eltCount++; - - elt->pathIndex = backend->pathCount - backend->pathBatchStart; - int count = 0; - switch(kind) - { - case OC_PATH_LINE: - backend->maxSegmentCount += 1; - elt->kind = OC_GL_LINE; - count = 2; - break; - - case OC_PATH_QUADRATIC: - backend->maxSegmentCount += 3; - elt->kind = OC_GL_QUADRATIC; - count = 3; - break; - - case OC_PATH_CUBIC: - backend->maxSegmentCount += 7; - elt->kind = OC_GL_CUBIC; - count = 4; - break; - - default: - break; - } - - for(int i=0; ipathUserExtents, p[i]); - - oc_vec2 screenP = oc_mat2x3_mul(backend->primitive->attributes.transform, p[i]); - elt->p[i] = (oc_vec2){screenP.x, screenP.y}; - - oc_update_path_extents(&backend->pathScreenExtents, screenP); - } -} - -void oc_gl_canvas_encode_path(oc_gl_canvas_backend* backend, oc_primitive* primitive, f32 scale) -{ - int bufferIndex = backend->bufferIndex; - int bufferCap = backend->pathBuffer[bufferIndex].size / sizeof(oc_gl_path); - if(backend->pathCount >= bufferCap) - { - int newBufferCap = (int)(bufferCap * 1.5); - int newBufferSize = newBufferCap * sizeof(oc_gl_path); - - oc_log_info("growing path buffer to %i elements\n", newBufferCap); - - oc_gl_grow_input_buffer(&backend->pathBuffer[bufferIndex], - backend->pathBatchStart * sizeof(oc_gl_path), - backend->eltCount * sizeof(oc_gl_path), - newBufferSize); - } - - oc_gl_path* pathData = (oc_gl_path*)backend->pathBuffer[backend->bufferIndex].contents; - oc_gl_path* path = &pathData[backend->pathCount]; - backend->pathCount++; - - path->cmd = (oc_gl_cmd)primitive->cmd; - - path->box = (oc_vec4){ - backend->pathScreenExtents.x, - backend->pathScreenExtents.y, - backend->pathScreenExtents.z, - backend->pathScreenExtents.w}; - - path->clip = (oc_vec4){ - primitive->attributes.clip.x, - primitive->attributes.clip.y, - primitive->attributes.clip.x + primitive->attributes.clip.w, - primitive->attributes.clip.y + primitive->attributes.clip.h}; - - path->color = (oc_vec4){ - primitive->attributes.color.r, - primitive->attributes.color.g, - primitive->attributes.color.b, - primitive->attributes.color.a}; - - oc_rect srcRegion = primitive->attributes.srcRegion; - - oc_rect destRegion = { - backend->pathUserExtents.x, - backend->pathUserExtents.y, - backend->pathUserExtents.z - backend->pathUserExtents.x, - backend->pathUserExtents.w - backend->pathUserExtents.y}; - - if(!oc_image_is_nil(primitive->attributes.image)) - { - oc_vec2 texSize = oc_image_size(primitive->attributes.image); - - oc_mat2x3 srcRegionToImage = { - 1/texSize.x, 0, srcRegion.x/texSize.x, - 0, 1/texSize.y, srcRegion.y/texSize.y}; - - oc_mat2x3 destRegionToSrcRegion = { - srcRegion.w/destRegion.w, 0, 0, - 0, srcRegion.h/destRegion.h, 0}; - - oc_mat2x3 userToDestRegion = { - 1, 0, -destRegion.x, - 0, 1, -destRegion.y}; - - oc_mat2x3 screenToUser = oc_mat2x3_inv(primitive->attributes.transform); - - oc_mat2x3 uvTransform = srcRegionToImage; - uvTransform = oc_mat2x3_mul_m(uvTransform, destRegionToSrcRegion); - uvTransform = oc_mat2x3_mul_m(uvTransform, userToDestRegion); - uvTransform = oc_mat2x3_mul_m(uvTransform, screenToUser); - - //NOTE: mat3 std430 layout is an array of oc_vec3, which are padded to _oc_vec4_ alignment - path->uvTransform[0] = uvTransform.m[0]/scale; - path->uvTransform[1] = uvTransform.m[3]/scale; - path->uvTransform[2] = 0; - path->uvTransform[3] = 0; - path->uvTransform[4] = uvTransform.m[1]/scale; - path->uvTransform[5] = uvTransform.m[4]/scale; - path->uvTransform[6] = 0; - path->uvTransform[7] = 0; - path->uvTransform[8] = uvTransform.m[2]; - path->uvTransform[9] = uvTransform.m[5]; - path->uvTransform[10] = 1; - path->uvTransform[11] = 0; - - path->textureID = backend->currentImageIndex; - } - else - { - path->textureID = -1; - } - - int firstTileX = path->box.x*scale / OC_GL_TILE_SIZE; - int firstTileY = path->box.y*scale / OC_GL_TILE_SIZE; - int lastTileX = path->box.z*scale / OC_GL_TILE_SIZE; - int lastTileY = path->box.w*scale / OC_GL_TILE_SIZE; - - int nTilesX = lastTileX - firstTileX + 1; - int nTilesY = lastTileY - firstTileY + 1; - - backend->maxTileQueueCount += (nTilesX * nTilesY); -} - -static bool oc_intersect_hull_legs(oc_vec2 p0, oc_vec2 p1, oc_vec2 p2, oc_vec2 p3, oc_vec2* intersection) -{ - /*NOTE: check intersection of lines (p0-p1) and (p2-p3) +*****************************************************************/ +#include "gl_api.h" +#include "glsl_shaders.h" +#include "graphics_surface.h" +#include "util/macros.h" + +typedef struct oc_gl_image +{ + oc_image_data interface; + GLuint texture; +} oc_gl_image; + +enum oc_gl_cmd_enum +{ + OC_GL_FILL, + OC_GL_STROKE, +}; + +typedef int oc_gl_cmd; + +typedef struct oc_gl_path +{ + float uvTransform[12]; + oc_vec4 color; + oc_vec4 box; + oc_vec4 clip; + oc_gl_cmd cmd; + int textureID; + u8 pad[8]; +} oc_gl_path; + +enum oc_gl_seg_kind_enum +{ + OC_GL_LINE = 1, + OC_GL_QUADRATIC, + OC_GL_CUBIC, +}; + +typedef int oc_gl_seg_kind; + +typedef struct oc_gl_path_elt +{ + oc_vec2 p[4]; + int pathIndex; + oc_gl_seg_kind kind; + +} oc_gl_path_elt; + +typedef struct oc_gl_dispatch_indirect_command +{ + u32 num_groups_x; + u32 num_groups_y; + u32 num_groups_z; + +} oc_gl_dispatch_indirect_command; + +//////////////////////////////////////////////////////////// +//NOTE: these are just here for the sizes... + +#define OC_GL_LAYOUT_FIRST(name, type) \ + OC_GL_##name##_OFFSET = 0, \ + OC_GL_##name##_SIZE = OC_GL_##type##_SIZE, + +#define OC_GL_LAYOUT_NEXT(name, type, prev) \ + OC_GL_##name##_OFFSET = oc_align_up_pow2(OC_GL_##prev##_OFFSET + OC_GL_##prev##_SIZE, OC_GL_##type##_ALIGN), \ + OC_GL_##name##_SIZE = OC_GL_##type##_SIZE, + +#define OC_GL_LAYOUT_SIZE(name, last, maxAlignType) \ + OC_GL_##name##_ALIGN = oc_align_up_pow2(OC_GL_##maxAlignType##_ALIGN, OC_GL_VEC4_ALIGN), \ + OC_GL_##name##_SIZE = oc_align_up_pow2(OC_GL_##last##_OFFSET + OC_GL_##last##_SIZE, OC_GL_##name##_ALIGN), + +enum +{ + OC_GL_I32_SIZE = sizeof(i32), + OC_GL_I32_ALIGN = sizeof(i32), + OC_GL_F32_SIZE = sizeof(f32), + OC_GL_F32_ALIGN = sizeof(f32), + OC_GL_VEC2_SIZE = 2 * sizeof(f32), + OC_GL_VEC2_ALIGN = 2 * sizeof(f32), + OC_GL_VEC3_SIZE = 4 * sizeof(f32), + OC_GL_VEC3_ALIGN = 4 * sizeof(f32), + OC_GL_VEC4_SIZE = 4 * sizeof(f32), + OC_GL_VEC4_ALIGN = 4 * sizeof(f32), + OC_GL_MAT3_SIZE = 3 * 3 * OC_GL_VEC3_SIZE, + OC_GL_MAT3_ALIGN = OC_GL_VEC3_ALIGN, + + OC_GL_LAYOUT_FIRST(SEGMENT_KIND, I32) + OC_GL_LAYOUT_NEXT(SEGMENT_PATH_INDEX, I32, SEGMENT_KIND) + OC_GL_LAYOUT_NEXT(SEGMENT_CONFIG, I32, SEGMENT_PATH_INDEX) + OC_GL_LAYOUT_NEXT(SEGMENT_WINDING, I32, SEGMENT_CONFIG) + OC_GL_LAYOUT_NEXT(SEGMENT_BOX, VEC4, SEGMENT_WINDING) + OC_GL_LAYOUT_NEXT(SEGMENT_IMPLICIT_MATRIX, MAT3, SEGMENT_BOX) + OC_GL_LAYOUT_NEXT(SEGMENT_HULL_VERTEX, VEC2, SEGMENT_IMPLICIT_MATRIX) + OC_GL_LAYOUT_NEXT(SEGMENT_SIGN, F32, SEGMENT_HULL_VERTEX) + OC_GL_LAYOUT_SIZE(SEGMENT, SEGMENT_SIGN, MAT3) + + OC_GL_LAYOUT_FIRST(PATH_QUEUE_AREA, VEC4) + OC_GL_LAYOUT_NEXT(PATH_QUEUE_TILE_QUEUES, I32, PATH_QUEUE_AREA) + OC_GL_LAYOUT_SIZE(PATH_QUEUE, PATH_QUEUE_TILE_QUEUES, VEC4) + + OC_GL_LAYOUT_FIRST(TILE_OP_KIND, I32) + OC_GL_LAYOUT_NEXT(TILE_OP_NEXT, I32, TILE_OP_KIND) + OC_GL_LAYOUT_NEXT(TILE_OP_INDEX, I32, TILE_OP_NEXT) + OC_GL_LAYOUT_NEXT(TILE_OP_WINDING, I32, TILE_OP_INDEX) + OC_GL_LAYOUT_SIZE(TILE_OP, TILE_OP_WINDING, I32) + + OC_GL_LAYOUT_FIRST(TILE_QUEUE_WINDING, I32) + OC_GL_LAYOUT_NEXT(TILE_QUEUE_FIRST, I32, TILE_QUEUE_WINDING) + OC_GL_LAYOUT_NEXT(TILE_QUEUE_LAST, I32, TILE_QUEUE_FIRST) + OC_GL_LAYOUT_SIZE(TILE_QUEUE, TILE_QUEUE_LAST, I32) + + OC_GL_LAYOUT_FIRST(SCREEN_TILE_COORD, VEC2) + OC_GL_LAYOUT_NEXT(SCREEN_TILE_FIRST, I32, SCREEN_TILE_COORD) + OC_GL_LAYOUT_SIZE(SCREEN_TILE, SCREEN_TILE_FIRST, VEC2) +}; + +enum +{ + OC_GL_INPUT_BUFFERS_COUNT = 3, + OC_GL_TILE_SIZE = 16, + OC_GL_MSAA_COUNT = 8, + OC_GL_MAX_IMAGES_PER_BATCH = 8, +}; + +typedef struct oc_gl_mapped_buffer +{ + GLuint buffer; + int size; + char* contents; +} oc_gl_mapped_buffer; + +typedef struct oc_gl_canvas_backend +{ + oc_canvas_backend interface; + oc_wgl_surface* surface; + + int msaaCount; + oc_vec2 frameSize; + + // gl stuff + GLuint vao; + + GLuint pathSetup; + GLuint segmentSetup; + GLuint backprop; + GLuint merge; + GLuint balanceWorkgroups; + GLuint raster; + GLuint blit; + + GLuint outTexture; + + int bufferIndex; + GLsync bufferSync[OC_GL_INPUT_BUFFERS_COUNT]; + oc_gl_mapped_buffer pathBuffer[OC_GL_INPUT_BUFFERS_COUNT]; + oc_gl_mapped_buffer elementBuffer[OC_GL_INPUT_BUFFERS_COUNT]; + + GLuint segmentBuffer; + GLuint segmentCountBuffer; + GLuint pathQueueBuffer; + GLuint tileQueueBuffer; + GLuint tileQueueCountBuffer; + GLuint tileOpBuffer; + GLuint tileOpCountBuffer; + GLuint screenTilesBuffer; + GLuint screenTilesCountBuffer; + GLuint rasterDispatchBuffer; + GLuint dummyVertexBuffer; + + //encoding context + int pathCount; + int eltCount; + + int pathBatchStart; + int eltBatchStart; + + oc_primitive* primitive; + oc_vec4 pathScreenExtents; + oc_vec4 pathUserExtents; + + int maxTileQueueCount; + int maxSegmentCount; + + int currentImageIndex; +} oc_gl_canvas_backend; + +static void oc_update_path_extents(oc_vec4* extents, oc_vec2 p) +{ + extents->x = oc_min(extents->x, p.x); + extents->y = oc_min(extents->y, p.y); + extents->z = oc_max(extents->z, p.x); + extents->w = oc_max(extents->w, p.y); +} + +void oc_gl_grow_input_buffer(oc_gl_mapped_buffer* buffer, int copyStart, int copySize, int newSize) +{ + oc_gl_mapped_buffer newBuffer = { 0 }; + newBuffer.size = newSize; + glGenBuffers(1, &newBuffer.buffer); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, newBuffer.buffer); + glBufferStorage(GL_SHADER_STORAGE_BUFFER, newBuffer.size, 0, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT); + newBuffer.contents = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, + 0, + newBuffer.size, + GL_MAP_WRITE_BIT + | GL_MAP_PERSISTENT_BIT + | GL_MAP_FLUSH_EXPLICIT_BIT); + + memcpy(newBuffer.contents + copyStart, buffer->contents + copyStart, copySize); + + glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer->buffer); + glUnmapBuffer(GL_SHADER_STORAGE_BUFFER); + glDeleteBuffers(1, &buffer->buffer); + + *buffer = newBuffer; +} + +void oc_gl_canvas_encode_element(oc_gl_canvas_backend* backend, oc_path_elt_type kind, oc_vec2* p) +{ + int bufferIndex = backend->bufferIndex; + int bufferCap = backend->elementBuffer[bufferIndex].size / sizeof(oc_gl_path_elt); + if(backend->eltCount >= bufferCap) + { + int newBufferCap = (int)(bufferCap * 1.5); + int newBufferSize = newBufferCap * sizeof(oc_gl_path_elt); + + oc_log_info("growing element buffer to %i elements\n", newBufferCap); + + oc_gl_grow_input_buffer(&backend->elementBuffer[bufferIndex], + backend->eltBatchStart * sizeof(oc_gl_path_elt), + backend->eltCount * sizeof(oc_gl_path_elt), + newBufferSize); + } + + oc_gl_path_elt* elementData = (oc_gl_path_elt*)backend->elementBuffer[bufferIndex].contents; + oc_gl_path_elt* elt = &elementData[backend->eltCount]; + backend->eltCount++; + + elt->pathIndex = backend->pathCount - backend->pathBatchStart; + int count = 0; + switch(kind) + { + case OC_PATH_LINE: + backend->maxSegmentCount += 1; + elt->kind = OC_GL_LINE; + count = 2; + break; + + case OC_PATH_QUADRATIC: + backend->maxSegmentCount += 3; + elt->kind = OC_GL_QUADRATIC; + count = 3; + break; + + case OC_PATH_CUBIC: + backend->maxSegmentCount += 7; + elt->kind = OC_GL_CUBIC; + count = 4; + break; + + default: + break; + } + + for(int i = 0; i < count; i++) + { + oc_update_path_extents(&backend->pathUserExtents, p[i]); + + oc_vec2 screenP = oc_mat2x3_mul(backend->primitive->attributes.transform, p[i]); + elt->p[i] = (oc_vec2){ screenP.x, screenP.y }; + + oc_update_path_extents(&backend->pathScreenExtents, screenP); + } +} + +void oc_gl_canvas_encode_path(oc_gl_canvas_backend* backend, oc_primitive* primitive, f32 scale) +{ + int bufferIndex = backend->bufferIndex; + int bufferCap = backend->pathBuffer[bufferIndex].size / sizeof(oc_gl_path); + if(backend->pathCount >= bufferCap) + { + int newBufferCap = (int)(bufferCap * 1.5); + int newBufferSize = newBufferCap * sizeof(oc_gl_path); + + oc_log_info("growing path buffer to %i elements\n", newBufferCap); + + oc_gl_grow_input_buffer(&backend->pathBuffer[bufferIndex], + backend->pathBatchStart * sizeof(oc_gl_path), + backend->eltCount * sizeof(oc_gl_path), + newBufferSize); + } + + oc_gl_path* pathData = (oc_gl_path*)backend->pathBuffer[backend->bufferIndex].contents; + oc_gl_path* path = &pathData[backend->pathCount]; + backend->pathCount++; + + path->cmd = (oc_gl_cmd)primitive->cmd; + + path->box = (oc_vec4){ + backend->pathScreenExtents.x, + backend->pathScreenExtents.y, + backend->pathScreenExtents.z, + backend->pathScreenExtents.w + }; + + path->clip = (oc_vec4){ + primitive->attributes.clip.x, + primitive->attributes.clip.y, + primitive->attributes.clip.x + primitive->attributes.clip.w, + primitive->attributes.clip.y + primitive->attributes.clip.h + }; + + path->color = (oc_vec4){ + primitive->attributes.color.r, + primitive->attributes.color.g, + primitive->attributes.color.b, + primitive->attributes.color.a + }; + + oc_rect srcRegion = primitive->attributes.srcRegion; + + oc_rect destRegion = { + backend->pathUserExtents.x, + backend->pathUserExtents.y, + backend->pathUserExtents.z - backend->pathUserExtents.x, + backend->pathUserExtents.w - backend->pathUserExtents.y + }; + + if(!oc_image_is_nil(primitive->attributes.image)) + { + oc_vec2 texSize = oc_image_size(primitive->attributes.image); + + oc_mat2x3 srcRegionToImage = { + 1 / texSize.x, 0, srcRegion.x / texSize.x, + 0, 1 / texSize.y, srcRegion.y / texSize.y + }; + + oc_mat2x3 destRegionToSrcRegion = { + srcRegion.w / destRegion.w, 0, 0, + 0, srcRegion.h / destRegion.h, 0 + }; + + oc_mat2x3 userToDestRegion = { + 1, 0, -destRegion.x, + 0, 1, -destRegion.y + }; + + oc_mat2x3 screenToUser = oc_mat2x3_inv(primitive->attributes.transform); + + oc_mat2x3 uvTransform = srcRegionToImage; + uvTransform = oc_mat2x3_mul_m(uvTransform, destRegionToSrcRegion); + uvTransform = oc_mat2x3_mul_m(uvTransform, userToDestRegion); + uvTransform = oc_mat2x3_mul_m(uvTransform, screenToUser); + + //NOTE: mat3 std430 layout is an array of oc_vec3, which are padded to _oc_vec4_ alignment + path->uvTransform[0] = uvTransform.m[0] / scale; + path->uvTransform[1] = uvTransform.m[3] / scale; + path->uvTransform[2] = 0; + path->uvTransform[3] = 0; + path->uvTransform[4] = uvTransform.m[1] / scale; + path->uvTransform[5] = uvTransform.m[4] / scale; + path->uvTransform[6] = 0; + path->uvTransform[7] = 0; + path->uvTransform[8] = uvTransform.m[2]; + path->uvTransform[9] = uvTransform.m[5]; + path->uvTransform[10] = 1; + path->uvTransform[11] = 0; + + path->textureID = backend->currentImageIndex; + } + else + { + path->textureID = -1; + } + + int firstTileX = path->box.x * scale / OC_GL_TILE_SIZE; + int firstTileY = path->box.y * scale / OC_GL_TILE_SIZE; + int lastTileX = path->box.z * scale / OC_GL_TILE_SIZE; + int lastTileY = path->box.w * scale / OC_GL_TILE_SIZE; + + int nTilesX = lastTileX - firstTileX + 1; + int nTilesY = lastTileY - firstTileY + 1; + + backend->maxTileQueueCount += (nTilesX * nTilesY); +} + +static bool oc_intersect_hull_legs(oc_vec2 p0, oc_vec2 p1, oc_vec2 p2, oc_vec2 p3, oc_vec2* intersection) +{ + /*NOTE: check intersection of lines (p0-p1) and (p2-p3) P = p0 + u(p1-p0) P = p2 + w(p3-p2) - */ - bool found = false; - - f32 den = (p0.x - p1.x)*(p2.y - p3.y) - (p0.y - p1.y)*(p2.x - p3.x); - if(fabs(den) > 0.0001) - { - f32 u = ((p0.x - p2.x)*(p2.y - p3.y) - (p0.y - p2.y)*(p2.x - p3.x))/den; - f32 w = ((p0.x - p2.x)*(p0.y - p1.y) - (p0.y - p2.y)*(p0.x - p1.x))/den; - - intersection->x = p0.x + u*(p1.x - p0.x); - intersection->y = p0.y + u*(p1.y - p0.y); - found = true; - } - return(found); -} - -static bool oc_offset_hull(int count, oc_vec2* p, oc_vec2* result, f32 offset) -{ - //NOTE: we should have no more than two coincident points here. This means the leg between - // those two points can't be offset, but we can set a double point at the start of first leg, - // end of first leg, or we can join the first and last leg to create a missing middle one - - oc_vec2 legs[3][2] = {0}; - bool valid[3] = {0}; - - for(int i=0; i= 1e-6) - { - n = oc_vec2_mul(offset/norm, n); - legs[i][0] = oc_vec2_add(p[i], n); - legs[i][1] = oc_vec2_add(p[i+1], n); - valid[i] = true; - } - } - - //NOTE: now we find intersections - - // first point is either the start of the first or second leg - if(valid[0]) - { - result[0] = legs[0][0]; - } - else - { - OC_ASSERT(valid[1]); - result[0] = legs[1][0]; - } - - for(int i=1; iprimitive->attributes.width; - - oc_vec2 v = {p[1].x-p[0].x, p[1].y-p[0].y}; - oc_vec2 n = {v.y, -v.x}; - f32 norm = sqrt(n.x*n.x + n.y*n.y); - oc_vec2 offset = oc_vec2_mul(0.5*width/norm, n); - - oc_vec2 left[2] = {oc_vec2_add(p[0], offset), oc_vec2_add(p[1], offset)}; - oc_vec2 right[2] = {oc_vec2_add(p[1], oc_vec2_mul(-1, offset)), oc_vec2_add(p[0], oc_vec2_mul(-1, offset))}; - oc_vec2 joint0[2] = {oc_vec2_add(p[0], oc_vec2_mul(-1, offset)), oc_vec2_add(p[0], offset)}; - oc_vec2 joint1[2] = {oc_vec2_add(p[1], offset), oc_vec2_add(p[1], oc_vec2_mul(-1, offset))}; - - oc_gl_canvas_encode_element(backend, OC_PATH_LINE, right); - - oc_gl_canvas_encode_element(backend, OC_PATH_LINE, left); - oc_gl_canvas_encode_element(backend, OC_PATH_LINE, joint0); - oc_gl_canvas_encode_element(backend, OC_PATH_LINE, joint1); -} - -enum { OC_HULL_CHECK_SAMPLE_COUNT = 5 }; - -void oc_gl_encode_stroke_quadratic(oc_gl_canvas_backend* backend, oc_vec2* p) -{ - f32 width = backend->primitive->attributes.width; - f32 tolerance = oc_min(backend->primitive->attributes.tolerance, 0.5 * width); - - //NOTE: check for degenerate line case - const f32 equalEps = 1e-3; - if(oc_vec2_close(p[0], p[1], equalEps)) - { - oc_gl_encode_stroke_line(backend, p+1); - return; - } - else if(oc_vec2_close(p[1], p[2], equalEps)) - { - oc_gl_encode_stroke_line(backend, p); - return; - } - - oc_vec2 leftHull[3]; - oc_vec2 rightHull[3]; - - if( !oc_offset_hull(3, p, leftHull, width/2) - || !oc_offset_hull(3, p, rightHull, -width/2)) - { - //TODO split and recurse - //NOTE: offsetting the hull failed, split the curve - oc_vec2 splitLeft[3]; - oc_vec2 splitRight[3]; - oc_quadratic_split(p, 0.5, splitLeft, splitRight); - oc_gl_encode_stroke_quadratic(backend, splitLeft); - oc_gl_encode_stroke_quadratic(backend, splitRight); - } - else - { - f32 checkSamples[OC_HULL_CHECK_SAMPLE_COUNT] = {1./6, 2./6, 3./6, 4./6, 5./6}; - - f32 d2LowBound = oc_square(0.5 * width - tolerance); - f32 d2HighBound = oc_square(0.5 * width + tolerance); - - f32 maxOvershoot = 0; - f32 maxOvershootParameter = 0; - - for(int i=0; i maxOvershoot) - { - maxOvershoot = overshoot; - maxOvershootParameter = t; - } - } - - if(maxOvershoot > 0) - { - oc_vec2 splitLeft[3]; - oc_vec2 splitRight[3]; - oc_quadratic_split(p, maxOvershootParameter, splitLeft, splitRight); - oc_gl_encode_stroke_quadratic(backend, splitLeft); - oc_gl_encode_stroke_quadratic(backend, splitRight); - } - else - { - oc_vec2 tmp = leftHull[0]; - leftHull[0] = leftHull[2]; - leftHull[2] = tmp; - - oc_gl_canvas_encode_element(backend, OC_PATH_QUADRATIC, rightHull); - oc_gl_canvas_encode_element(backend, OC_PATH_QUADRATIC, leftHull); - - oc_vec2 joint0[2] = {rightHull[2], leftHull[0]}; - oc_vec2 joint1[2] = {leftHull[2], rightHull[0]}; - oc_gl_canvas_encode_element(backend, OC_PATH_LINE, joint0); - oc_gl_canvas_encode_element(backend, OC_PATH_LINE, joint1); - } - } -} - -void oc_gl_encode_stroke_cubic(oc_gl_canvas_backend* backend, oc_vec2* p) -{ - f32 width = backend->primitive->attributes.width; - f32 tolerance = oc_min(backend->primitive->attributes.tolerance, 0.5 * width); - - //NOTE: check degenerate line cases - f32 equalEps = 1e-3; - - if( (oc_vec2_close(p[0], p[1], equalEps) && oc_vec2_close(p[2], p[3], equalEps)) - ||(oc_vec2_close(p[0], p[1], equalEps) && oc_vec2_close(p[1], p[2], equalEps)) - ||(oc_vec2_close(p[1], p[2], equalEps) && oc_vec2_close(p[2], p[3], equalEps))) - { - oc_vec2 line[2] = {p[0], p[3]}; - oc_gl_encode_stroke_line(backend, line); - return; - } - else if(oc_vec2_close(p[0], p[1], equalEps) && oc_vec2_close(p[1], p[3], equalEps)) - { - oc_vec2 line[2] = {p[0], oc_vec2_add(oc_vec2_mul(5./9, p[0]), oc_vec2_mul(4./9, p[2]))}; - oc_gl_encode_stroke_line(backend, line); - return; - } - else if(oc_vec2_close(p[0], p[2], equalEps) && oc_vec2_close(p[2], p[3], equalEps)) - { - oc_vec2 line[2] = {p[0], oc_vec2_add(oc_vec2_mul(5./9, p[0]), oc_vec2_mul(4./9, p[1]))}; - oc_gl_encode_stroke_line(backend, line); - return; - } - - oc_vec2 leftHull[4]; - oc_vec2 rightHull[4]; - - if( !oc_offset_hull(4, p, leftHull, width/2) - || !oc_offset_hull(4, p, rightHull, -width/2)) - { - //TODO split and recurse - //NOTE: offsetting the hull failed, split the curve - oc_vec2 splitLeft[4]; - oc_vec2 splitRight[4]; - oc_cubic_split(p, 0.5, splitLeft, splitRight); - oc_gl_encode_stroke_cubic(backend, splitLeft); - oc_gl_encode_stroke_cubic(backend, splitRight); - } - else - { - f32 checkSamples[OC_HULL_CHECK_SAMPLE_COUNT] = {1./6, 2./6, 3./6, 4./6, 5./6}; - - f32 d2LowBound = oc_square(0.5 * width - tolerance); - f32 d2HighBound = oc_square(0.5 * width + tolerance); - - f32 maxOvershoot = 0; - f32 maxOvershootParameter = 0; - - for(int i=0; i maxOvershoot) - { - maxOvershoot = overshoot; - maxOvershootParameter = t; - } - } - - if(maxOvershoot > 0) - { - oc_vec2 splitLeft[4]; - oc_vec2 splitRight[4]; - oc_cubic_split(p, maxOvershootParameter, splitLeft, splitRight); - oc_gl_encode_stroke_cubic(backend, splitLeft); - oc_gl_encode_stroke_cubic(backend, splitRight); - } - else - { - oc_vec2 tmp = leftHull[0]; - leftHull[0] = leftHull[3]; - leftHull[3] = tmp; - tmp = leftHull[1]; - leftHull[1] = leftHull[2]; - leftHull[2] = tmp; - - oc_gl_canvas_encode_element(backend, OC_PATH_CUBIC, rightHull); - oc_gl_canvas_encode_element(backend, OC_PATH_CUBIC, leftHull); - - oc_vec2 joint0[2] = {rightHull[3], leftHull[0]}; - oc_vec2 joint1[2] = {leftHull[3], rightHull[0]}; - oc_gl_canvas_encode_element(backend, OC_PATH_LINE, joint0); - oc_gl_canvas_encode_element(backend, OC_PATH_LINE, joint1); - } - } -} - -void oc_gl_encode_stroke_element(oc_gl_canvas_backend* backend, - oc_path_elt* element, - oc_vec2 currentPoint, - oc_vec2* startTangent, - oc_vec2* endTangent, - oc_vec2* endPoint) -{ - oc_vec2 controlPoints[4] = {currentPoint, element->p[0], element->p[1], element->p[2]}; - int endPointIndex = 0; - - switch(element->type) - { - case OC_PATH_LINE: - oc_gl_encode_stroke_line(backend, controlPoints); - endPointIndex = 1; - break; - - case OC_PATH_QUADRATIC: - oc_gl_encode_stroke_quadratic(backend, controlPoints); - endPointIndex = 2; - break; - - case OC_PATH_CUBIC: - oc_gl_encode_stroke_cubic(backend, controlPoints); - endPointIndex = 3; - break; - - case OC_PATH_MOVE: - OC_ASSERT(0, "should be unreachable"); - break; - } - - //NOTE: ensure tangents are properly computed even in presence of coincident points - //TODO: see if we can do this in a less hacky way - - for(int i=1; i<4; i++) - { - if( controlPoints[i].x != controlPoints[0].x - || controlPoints[i].y != controlPoints[0].y) - { - *startTangent = (oc_vec2){.x = controlPoints[i].x - controlPoints[0].x, - .y = controlPoints[i].y - controlPoints[0].y}; - break; - } - } - *endPoint = controlPoints[endPointIndex]; - - for(int i=endPointIndex-1; i>=0; i++) - { - if( controlPoints[i].x != endPoint->x - || controlPoints[i].y != endPoint->y) - { - *endTangent = (oc_vec2){.x = endPoint->x - controlPoints[i].x, - .y = endPoint->y - controlPoints[i].y}; - break; - } - } - OC_DEBUG_ASSERT(startTangent->x != 0 || startTangent->y != 0); -} - -void oc_gl_stroke_cap(oc_gl_canvas_backend* backend, - oc_vec2 p0, - oc_vec2 direction) -{ - oc_attributes* attributes = &backend->primitive->attributes; - - //NOTE(martin): compute the tangent and normal vectors (multiplied by half width) at the cap point - f32 dn = sqrt(oc_square(direction.x) + oc_square(direction.y)); - f32 alpha = 0.5 * attributes->width/dn; - - oc_vec2 n0 = {-alpha*direction.y, - alpha*direction.x}; - - oc_vec2 m0 = {alpha*direction.x, - alpha*direction.y}; - - oc_vec2 points[] = {{p0.x + n0.x, p0.y + n0.y}, - {p0.x + n0.x + m0.x, p0.y + n0.y + m0.y}, - {p0.x - n0.x + m0.x, p0.y - n0.y + m0.y}, - {p0.x - n0.x, p0.y - n0.y}, - {p0.x + n0.x, p0.y + n0.y}}; - - oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points); - oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points+1); - oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points+2); - oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points+3); -} - -void oc_gl_stroke_joint(oc_gl_canvas_backend* backend, - oc_vec2 p0, - oc_vec2 t0, - oc_vec2 t1) -{ - oc_attributes* attributes = &backend->primitive->attributes; - - //NOTE(martin): compute the normals at the joint point - f32 norm_t0 = sqrt(oc_square(t0.x) + oc_square(t0.y)); - f32 norm_t1 = sqrt(oc_square(t1.x) + oc_square(t1.y)); - - oc_vec2 n0 = {-t0.y, t0.x}; - n0.x /= norm_t0; - n0.y /= norm_t0; - - oc_vec2 n1 = {-t1.y, t1.x}; - n1.x /= norm_t1; - n1.y /= norm_t1; - - //NOTE(martin): the sign of the cross product determines if the normals are facing outwards or inwards the angle. - // we flip them to face outwards if needed - f32 crossZ = n0.x*n1.y - n0.y*n1.x; - if(crossZ > 0) - { - n0.x *= -1; - n0.y *= -1; - n1.x *= -1; - n1.y *= -1; - } - - //NOTE(martin): use the same code as hull offset to find mitter point... - /*NOTE(martin): let vector u = (n0+n1) and vector v = pIntersect - p1 + */ + bool found = false; + + f32 den = (p0.x - p1.x) * (p2.y - p3.y) - (p0.y - p1.y) * (p2.x - p3.x); + if(fabs(den) > 0.0001) + { + f32 u = ((p0.x - p2.x) * (p2.y - p3.y) - (p0.y - p2.y) * (p2.x - p3.x)) / den; + f32 w = ((p0.x - p2.x) * (p0.y - p1.y) - (p0.y - p2.y) * (p0.x - p1.x)) / den; + + intersection->x = p0.x + u * (p1.x - p0.x); + intersection->y = p0.y + u * (p1.y - p0.y); + found = true; + } + return (found); +} + +static bool oc_offset_hull(int count, oc_vec2* p, oc_vec2* result, f32 offset) +{ + //NOTE: we should have no more than two coincident points here. This means the leg between + // those two points can't be offset, but we can set a double point at the start of first leg, + // end of first leg, or we can join the first and last leg to create a missing middle one + + oc_vec2 legs[3][2] = { 0 }; + bool valid[3] = { 0 }; + + for(int i = 0; i < count - 1; i++) + { + oc_vec2 n = { p[i].y - p[i + 1].y, + p[i + 1].x - p[i].x }; + + f32 norm = sqrt(n.x * n.x + n.y * n.y); + if(norm >= 1e-6) + { + n = oc_vec2_mul(offset / norm, n); + legs[i][0] = oc_vec2_add(p[i], n); + legs[i][1] = oc_vec2_add(p[i + 1], n); + valid[i] = true; + } + } + + //NOTE: now we find intersections + + // first point is either the start of the first or second leg + if(valid[0]) + { + result[0] = legs[0][0]; + } + else + { + OC_ASSERT(valid[1]); + result[0] = legs[1][0]; + } + + for(int i = 1; i < count - 1; i++) + { + //NOTE: we're computing the control point i, at the end of leg (i-1) + + if(!valid[i - 1]) + { + OC_ASSERT(valid[i]); + result[i] = legs[i][0]; + } + else if(!valid[i]) + { + OC_ASSERT(valid[i - 1]); + result[i] = legs[i - 1][0]; + } + else + { + if(!oc_intersect_hull_legs(legs[i - 1][0], legs[i - 1][1], legs[i][0], legs[i][1], &result[i])) + { + // legs don't intersect. + return (false); + } + } + } + + if(valid[count - 2]) + { + result[count - 1] = legs[count - 2][1]; + } + else + { + OC_ASSERT(valid[count - 3]); + result[count - 1] = legs[count - 3][1]; + } + + return (true); +} + +static oc_vec2 oc_quadratic_get_point(oc_vec2 p[3], f32 t) +{ + oc_vec2 r; + + f32 oneMt = 1 - t; + f32 oneMt2 = oc_square(oneMt); + f32 t2 = oc_square(t); + + r.x = oneMt2 * p[0].x + 2 * oneMt * t * p[1].x + t2 * p[2].x; + r.y = oneMt2 * p[0].y + 2 * oneMt * t * p[1].y + t2 * p[2].y; + + return (r); +} + +static void oc_quadratic_split(oc_vec2 p[3], f32 t, oc_vec2 outLeft[3], oc_vec2 outRight[3]) +{ + //NOTE(martin): split bezier curve p at parameter t, using De Casteljau's algorithm + // the q_n are the points along the hull's segments at parameter t + // s is the split point. + + f32 oneMt = 1 - t; + + oc_vec2 q0 = { oneMt * p[0].x + t * p[1].x, + oneMt * p[0].y + t * p[1].y }; + + oc_vec2 q1 = { oneMt * p[1].x + t * p[2].x, + oneMt * p[1].y + t * p[2].y }; + + oc_vec2 s = { oneMt * q0.x + t * q1.x, + oneMt * q0.y + t * q1.y }; + + outLeft[0] = p[0]; + outLeft[1] = q0; + outLeft[2] = s; + + outRight[0] = s; + outRight[1] = q1; + outRight[2] = p[2]; +} + +static oc_vec2 oc_cubic_get_point(oc_vec2 p[4], f32 t) +{ + oc_vec2 r; + + f32 oneMt = 1 - t; + f32 oneMt2 = oc_square(oneMt); + f32 oneMt3 = oneMt2 * oneMt; + f32 t2 = oc_square(t); + f32 t3 = t2 * t; + + r.x = oneMt3 * p[0].x + 3 * oneMt2 * t * p[1].x + 3 * oneMt * t2 * p[2].x + t3 * p[3].x; + r.y = oneMt3 * p[0].y + 3 * oneMt2 * t * p[1].y + 3 * oneMt * t2 * p[2].y + t3 * p[3].y; + + return (r); +} + +static void oc_cubic_split(oc_vec2 p[4], f32 t, oc_vec2 outLeft[4], oc_vec2 outRight[4]) +{ + //NOTE(martin): split bezier curve p at parameter t, using De Casteljau's algorithm + // the q_n are the points along the hull's segments at parameter t + // the r_n are the points along the (q_n, q_n+1) segments at parameter t + // s is the split point. + + oc_vec2 q0 = { (1 - t) * p[0].x + t * p[1].x, + (1 - t) * p[0].y + t * p[1].y }; + + oc_vec2 q1 = { (1 - t) * p[1].x + t * p[2].x, + (1 - t) * p[1].y + t * p[2].y }; + + oc_vec2 q2 = { (1 - t) * p[2].x + t * p[3].x, + (1 - t) * p[2].y + t * p[3].y }; + + oc_vec2 r0 = { (1 - t) * q0.x + t * q1.x, + (1 - t) * q0.y + t * q1.y }; + + oc_vec2 r1 = { (1 - t) * q1.x + t * q2.x, + (1 - t) * q1.y + t * q2.y }; + + oc_vec2 s = { (1 - t) * r0.x + t * r1.x, + (1 - t) * r0.y + t * r1.y }; + ; + + outLeft[0] = p[0]; + outLeft[1] = q0; + outLeft[2] = r0; + outLeft[3] = s; + + outRight[0] = s; + outRight[1] = r1; + outRight[2] = q2; + outRight[3] = p[3]; +} + +void oc_gl_encode_stroke_line(oc_gl_canvas_backend* backend, oc_vec2* p) +{ + f32 width = backend->primitive->attributes.width; + + oc_vec2 v = { p[1].x - p[0].x, p[1].y - p[0].y }; + oc_vec2 n = { v.y, -v.x }; + f32 norm = sqrt(n.x * n.x + n.y * n.y); + oc_vec2 offset = oc_vec2_mul(0.5 * width / norm, n); + + oc_vec2 left[2] = { oc_vec2_add(p[0], offset), oc_vec2_add(p[1], offset) }; + oc_vec2 right[2] = { oc_vec2_add(p[1], oc_vec2_mul(-1, offset)), oc_vec2_add(p[0], oc_vec2_mul(-1, offset)) }; + oc_vec2 joint0[2] = { oc_vec2_add(p[0], oc_vec2_mul(-1, offset)), oc_vec2_add(p[0], offset) }; + oc_vec2 joint1[2] = { oc_vec2_add(p[1], offset), oc_vec2_add(p[1], oc_vec2_mul(-1, offset)) }; + + oc_gl_canvas_encode_element(backend, OC_PATH_LINE, right); + + oc_gl_canvas_encode_element(backend, OC_PATH_LINE, left); + oc_gl_canvas_encode_element(backend, OC_PATH_LINE, joint0); + oc_gl_canvas_encode_element(backend, OC_PATH_LINE, joint1); +} + +enum +{ + OC_HULL_CHECK_SAMPLE_COUNT = 5 +}; + +void oc_gl_encode_stroke_quadratic(oc_gl_canvas_backend* backend, oc_vec2* p) +{ + f32 width = backend->primitive->attributes.width; + f32 tolerance = oc_min(backend->primitive->attributes.tolerance, 0.5 * width); + + //NOTE: check for degenerate line case + const f32 equalEps = 1e-3; + if(oc_vec2_close(p[0], p[1], equalEps)) + { + oc_gl_encode_stroke_line(backend, p + 1); + return; + } + else if(oc_vec2_close(p[1], p[2], equalEps)) + { + oc_gl_encode_stroke_line(backend, p); + return; + } + + oc_vec2 leftHull[3]; + oc_vec2 rightHull[3]; + + if(!oc_offset_hull(3, p, leftHull, width / 2) + || !oc_offset_hull(3, p, rightHull, -width / 2)) + { + //TODO split and recurse + //NOTE: offsetting the hull failed, split the curve + oc_vec2 splitLeft[3]; + oc_vec2 splitRight[3]; + oc_quadratic_split(p, 0.5, splitLeft, splitRight); + oc_gl_encode_stroke_quadratic(backend, splitLeft); + oc_gl_encode_stroke_quadratic(backend, splitRight); + } + else + { + f32 checkSamples[OC_HULL_CHECK_SAMPLE_COUNT] = { 1. / 6, 2. / 6, 3. / 6, 4. / 6, 5. / 6 }; + + f32 d2LowBound = oc_square(0.5 * width - tolerance); + f32 d2HighBound = oc_square(0.5 * width + tolerance); + + f32 maxOvershoot = 0; + f32 maxOvershootParameter = 0; + + for(int i = 0; i < OC_HULL_CHECK_SAMPLE_COUNT; i++) + { + f32 t = checkSamples[i]; + + oc_vec2 c = oc_quadratic_get_point(p, t); + oc_vec2 cp = oc_quadratic_get_point(leftHull, t); + oc_vec2 cn = oc_quadratic_get_point(rightHull, t); + + f32 positiveDistSquare = oc_square(c.x - cp.x) + oc_square(c.y - cp.y); + f32 negativeDistSquare = oc_square(c.x - cn.x) + oc_square(c.y - cn.y); + + f32 positiveOvershoot = oc_max(positiveDistSquare - d2HighBound, d2LowBound - positiveDistSquare); + f32 negativeOvershoot = oc_max(negativeDistSquare - d2HighBound, d2LowBound - negativeDistSquare); + + f32 overshoot = oc_max(positiveOvershoot, negativeOvershoot); + + if(overshoot > maxOvershoot) + { + maxOvershoot = overshoot; + maxOvershootParameter = t; + } + } + + if(maxOvershoot > 0) + { + oc_vec2 splitLeft[3]; + oc_vec2 splitRight[3]; + oc_quadratic_split(p, maxOvershootParameter, splitLeft, splitRight); + oc_gl_encode_stroke_quadratic(backend, splitLeft); + oc_gl_encode_stroke_quadratic(backend, splitRight); + } + else + { + oc_vec2 tmp = leftHull[0]; + leftHull[0] = leftHull[2]; + leftHull[2] = tmp; + + oc_gl_canvas_encode_element(backend, OC_PATH_QUADRATIC, rightHull); + oc_gl_canvas_encode_element(backend, OC_PATH_QUADRATIC, leftHull); + + oc_vec2 joint0[2] = { rightHull[2], leftHull[0] }; + oc_vec2 joint1[2] = { leftHull[2], rightHull[0] }; + oc_gl_canvas_encode_element(backend, OC_PATH_LINE, joint0); + oc_gl_canvas_encode_element(backend, OC_PATH_LINE, joint1); + } + } +} + +void oc_gl_encode_stroke_cubic(oc_gl_canvas_backend* backend, oc_vec2* p) +{ + f32 width = backend->primitive->attributes.width; + f32 tolerance = oc_min(backend->primitive->attributes.tolerance, 0.5 * width); + + //NOTE: check degenerate line cases + f32 equalEps = 1e-3; + + if((oc_vec2_close(p[0], p[1], equalEps) && oc_vec2_close(p[2], p[3], equalEps)) + || (oc_vec2_close(p[0], p[1], equalEps) && oc_vec2_close(p[1], p[2], equalEps)) + || (oc_vec2_close(p[1], p[2], equalEps) && oc_vec2_close(p[2], p[3], equalEps))) + { + oc_vec2 line[2] = { p[0], p[3] }; + oc_gl_encode_stroke_line(backend, line); + return; + } + else if(oc_vec2_close(p[0], p[1], equalEps) && oc_vec2_close(p[1], p[3], equalEps)) + { + oc_vec2 line[2] = { p[0], oc_vec2_add(oc_vec2_mul(5. / 9, p[0]), oc_vec2_mul(4. / 9, p[2])) }; + oc_gl_encode_stroke_line(backend, line); + return; + } + else if(oc_vec2_close(p[0], p[2], equalEps) && oc_vec2_close(p[2], p[3], equalEps)) + { + oc_vec2 line[2] = { p[0], oc_vec2_add(oc_vec2_mul(5. / 9, p[0]), oc_vec2_mul(4. / 9, p[1])) }; + oc_gl_encode_stroke_line(backend, line); + return; + } + + oc_vec2 leftHull[4]; + oc_vec2 rightHull[4]; + + if(!oc_offset_hull(4, p, leftHull, width / 2) + || !oc_offset_hull(4, p, rightHull, -width / 2)) + { + //TODO split and recurse + //NOTE: offsetting the hull failed, split the curve + oc_vec2 splitLeft[4]; + oc_vec2 splitRight[4]; + oc_cubic_split(p, 0.5, splitLeft, splitRight); + oc_gl_encode_stroke_cubic(backend, splitLeft); + oc_gl_encode_stroke_cubic(backend, splitRight); + } + else + { + f32 checkSamples[OC_HULL_CHECK_SAMPLE_COUNT] = { 1. / 6, 2. / 6, 3. / 6, 4. / 6, 5. / 6 }; + + f32 d2LowBound = oc_square(0.5 * width - tolerance); + f32 d2HighBound = oc_square(0.5 * width + tolerance); + + f32 maxOvershoot = 0; + f32 maxOvershootParameter = 0; + + for(int i = 0; i < OC_HULL_CHECK_SAMPLE_COUNT; i++) + { + f32 t = checkSamples[i]; + + oc_vec2 c = oc_cubic_get_point(p, t); + oc_vec2 cp = oc_cubic_get_point(leftHull, t); + oc_vec2 cn = oc_cubic_get_point(rightHull, t); + + f32 positiveDistSquare = oc_square(c.x - cp.x) + oc_square(c.y - cp.y); + f32 negativeDistSquare = oc_square(c.x - cn.x) + oc_square(c.y - cn.y); + + f32 positiveOvershoot = oc_max(positiveDistSquare - d2HighBound, d2LowBound - positiveDistSquare); + f32 negativeOvershoot = oc_max(negativeDistSquare - d2HighBound, d2LowBound - negativeDistSquare); + + f32 overshoot = oc_max(positiveOvershoot, negativeOvershoot); + + if(overshoot > maxOvershoot) + { + maxOvershoot = overshoot; + maxOvershootParameter = t; + } + } + + if(maxOvershoot > 0) + { + oc_vec2 splitLeft[4]; + oc_vec2 splitRight[4]; + oc_cubic_split(p, maxOvershootParameter, splitLeft, splitRight); + oc_gl_encode_stroke_cubic(backend, splitLeft); + oc_gl_encode_stroke_cubic(backend, splitRight); + } + else + { + oc_vec2 tmp = leftHull[0]; + leftHull[0] = leftHull[3]; + leftHull[3] = tmp; + tmp = leftHull[1]; + leftHull[1] = leftHull[2]; + leftHull[2] = tmp; + + oc_gl_canvas_encode_element(backend, OC_PATH_CUBIC, rightHull); + oc_gl_canvas_encode_element(backend, OC_PATH_CUBIC, leftHull); + + oc_vec2 joint0[2] = { rightHull[3], leftHull[0] }; + oc_vec2 joint1[2] = { leftHull[3], rightHull[0] }; + oc_gl_canvas_encode_element(backend, OC_PATH_LINE, joint0); + oc_gl_canvas_encode_element(backend, OC_PATH_LINE, joint1); + } + } +} + +void oc_gl_encode_stroke_element(oc_gl_canvas_backend* backend, + oc_path_elt* element, + oc_vec2 currentPoint, + oc_vec2* startTangent, + oc_vec2* endTangent, + oc_vec2* endPoint) +{ + oc_vec2 controlPoints[4] = { currentPoint, element->p[0], element->p[1], element->p[2] }; + int endPointIndex = 0; + + switch(element->type) + { + case OC_PATH_LINE: + oc_gl_encode_stroke_line(backend, controlPoints); + endPointIndex = 1; + break; + + case OC_PATH_QUADRATIC: + oc_gl_encode_stroke_quadratic(backend, controlPoints); + endPointIndex = 2; + break; + + case OC_PATH_CUBIC: + oc_gl_encode_stroke_cubic(backend, controlPoints); + endPointIndex = 3; + break; + + case OC_PATH_MOVE: + OC_ASSERT(0, "should be unreachable"); + break; + } + + //NOTE: ensure tangents are properly computed even in presence of coincident points + //TODO: see if we can do this in a less hacky way + + for(int i = 1; i < 4; i++) + { + if(controlPoints[i].x != controlPoints[0].x + || controlPoints[i].y != controlPoints[0].y) + { + *startTangent = (oc_vec2){ .x = controlPoints[i].x - controlPoints[0].x, + .y = controlPoints[i].y - controlPoints[0].y }; + break; + } + } + *endPoint = controlPoints[endPointIndex]; + + for(int i = endPointIndex - 1; i >= 0; i++) + { + if(controlPoints[i].x != endPoint->x + || controlPoints[i].y != endPoint->y) + { + *endTangent = (oc_vec2){ .x = endPoint->x - controlPoints[i].x, + .y = endPoint->y - controlPoints[i].y }; + break; + } + } + OC_DEBUG_ASSERT(startTangent->x != 0 || startTangent->y != 0); +} + +void oc_gl_stroke_cap(oc_gl_canvas_backend* backend, + oc_vec2 p0, + oc_vec2 direction) +{ + oc_attributes* attributes = &backend->primitive->attributes; + + //NOTE(martin): compute the tangent and normal vectors (multiplied by half width) at the cap point + f32 dn = sqrt(oc_square(direction.x) + oc_square(direction.y)); + f32 alpha = 0.5 * attributes->width / dn; + + oc_vec2 n0 = { -alpha * direction.y, + alpha * direction.x }; + + oc_vec2 m0 = { alpha * direction.x, + alpha * direction.y }; + + oc_vec2 points[] = { { p0.x + n0.x, p0.y + n0.y }, + { p0.x + n0.x + m0.x, p0.y + n0.y + m0.y }, + { p0.x - n0.x + m0.x, p0.y - n0.y + m0.y }, + { p0.x - n0.x, p0.y - n0.y }, + { p0.x + n0.x, p0.y + n0.y } }; + + oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points); + oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points + 1); + oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points + 2); + oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points + 3); +} + +void oc_gl_stroke_joint(oc_gl_canvas_backend* backend, + oc_vec2 p0, + oc_vec2 t0, + oc_vec2 t1) +{ + oc_attributes* attributes = &backend->primitive->attributes; + + //NOTE(martin): compute the normals at the joint point + f32 norm_t0 = sqrt(oc_square(t0.x) + oc_square(t0.y)); + f32 norm_t1 = sqrt(oc_square(t1.x) + oc_square(t1.y)); + + oc_vec2 n0 = { -t0.y, t0.x }; + n0.x /= norm_t0; + n0.y /= norm_t0; + + oc_vec2 n1 = { -t1.y, t1.x }; + n1.x /= norm_t1; + n1.y /= norm_t1; + + //NOTE(martin): the sign of the cross product determines if the normals are facing outwards or inwards the angle. + // we flip them to face outwards if needed + f32 crossZ = n0.x * n1.y - n0.y * n1.x; + if(crossZ > 0) + { + n0.x *= -1; + n0.y *= -1; + n1.x *= -1; + n1.y *= -1; + } + + //NOTE(martin): use the same code as hull offset to find mitter point... + /*NOTE(martin): let vector u = (n0+n1) and vector v = pIntersect - p1 then v = u * (2*offset / norm(u)^2) (this can be derived from writing the pythagoras theorems in the triangles of the joint) - */ - f32 halfW = 0.5 * attributes->width; - oc_vec2 u = {n0.x + n1.x, n0.y + n1.y}; - f32 uNormSquare = u.x*u.x + u.y*u.y; - f32 alpha = attributes->width / uNormSquare; - oc_vec2 v = {u.x * alpha, u.y * alpha}; - - f32 excursionSquare = uNormSquare * oc_square(alpha - attributes->width/4); - - if( attributes->joint == OC_JOINT_MITER - && excursionSquare <= oc_square(attributes->maxJointExcursion)) - { - //NOTE(martin): add a mitter joint - oc_vec2 points[] = {p0, - {p0.x + n0.x*halfW, p0.y + n0.y*halfW}, - {p0.x + v.x, p0.y + v.y}, - {p0.x + n1.x*halfW, p0.y + n1.y*halfW}, - p0}; - - oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points); - oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points+1); - oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points+2); - oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points+3); - } - else - { - //NOTE(martin): add a bevel joint - oc_vec2 points[] = {p0, - {p0.x + n0.x*halfW, p0.y + n0.y*halfW}, - {p0.x + n1.x*halfW, p0.y + n1.y*halfW}, - p0}; - - oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points); - oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points+1); - oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points+2); - } -} - -u32 oc_gl_encode_stroke_subpath(oc_gl_canvas_backend* backend, - oc_path_elt* elements, - oc_path_descriptor* path, - u32 startIndex, - oc_vec2 startPoint) -{ - u32 eltCount = path->count; - OC_DEBUG_ASSERT(startIndex < eltCount); - - oc_vec2 currentPoint = startPoint; - oc_vec2 endPoint = {0, 0}; - oc_vec2 previousEndTangent = {0, 0}; - oc_vec2 firstTangent = {0, 0}; - oc_vec2 startTangent = {0, 0}; - oc_vec2 endTangent = {0, 0}; - - //NOTE(martin): encode first element and compute first tangent - oc_gl_encode_stroke_element(backend, elements + startIndex, currentPoint, &startTangent, &endTangent, &endPoint); - - firstTangent = startTangent; - previousEndTangent = endTangent; - currentPoint = endPoint; - - //NOTE(martin): encode subsequent elements along with their joints - - oc_attributes* attributes = &backend->primitive->attributes; - - u32 eltIndex = startIndex + 1; - for(; - eltIndexjoint != OC_JOINT_NONE) - { - oc_gl_stroke_joint(backend, currentPoint, previousEndTangent, startTangent); - } - previousEndTangent = endTangent; - currentPoint = endPoint; - } - u32 subPathEltCount = eltIndex - startIndex; - - //NOTE(martin): draw end cap / joint. We ensure there's at least two segments to draw a closing joint - if( subPathEltCount > 1 - && startPoint.x == endPoint.x - && startPoint.y == endPoint.y) - { - if(attributes->joint != OC_JOINT_NONE) - { - //NOTE(martin): add a closing joint if the path is closed - oc_gl_stroke_joint(backend, endPoint, endTangent, firstTangent); - } - } - else if(attributes->cap == OC_CAP_SQUARE) - { - //NOTE(martin): add start and end cap - oc_gl_stroke_cap(backend, startPoint, (oc_vec2){-startTangent.x, -startTangent.y}); - oc_gl_stroke_cap(backend, endPoint, endTangent); - } - return(eltIndex); -} - -void oc_gl_encode_stroke(oc_gl_canvas_backend* backend, - oc_path_elt* elements, - oc_path_descriptor* path) -{ - u32 eltCount = path->count; - OC_DEBUG_ASSERT(eltCount); - - oc_vec2 startPoint = path->startPoint; - u32 startIndex = 0; - - while(startIndex < eltCount) - { - //NOTE(martin): eliminate leading moves - while(startIndex < eltCount && elements[startIndex].type == OC_PATH_MOVE) - { - startPoint = elements[startIndex].p[0]; - startIndex++; - } - if(startIndex < eltCount) - { - startIndex = oc_gl_encode_stroke_subpath(backend, elements, path, startIndex, startPoint); - } - } -} - -void oc_gl_grow_buffer_if_needed(GLuint buffer, i32 wantedSize, const char* name) -{ - i32 oldSize = 0; - glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer); - glGetBufferParameteriv(GL_SHADER_STORAGE_BUFFER, GL_BUFFER_SIZE, &oldSize); - - if(oldSize < wantedSize) - { - oc_log_info("growing %s buffer\n", name); - - int newSize = wantedSize * 1.2; - - glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, newSize, 0, GL_DYNAMIC_COPY); - } -} - - - -void oc_gl_render_batch(oc_gl_canvas_backend* backend, - oc_wgl_surface* surface, - oc_image* images, - int tileSize, - int nTilesX, - int nTilesY, - oc_vec2 viewportSize, - f32 scale) -{ - GLuint pathBuffer = backend->pathBuffer[backend->bufferIndex].buffer; - GLuint elementBuffer = backend->elementBuffer[backend->bufferIndex].buffer; - - int pathBufferOffset = backend->pathBatchStart * sizeof(oc_gl_path); - int elementBufferOffset = backend->eltBatchStart * sizeof(oc_gl_path_elt); - int pathCount = backend->pathCount - backend->pathBatchStart; - int eltCount = backend->eltCount - backend->eltBatchStart; - - if(!pathCount || !eltCount) - { - return; - } - - //NOTE: update intermediate buffers size if needed - //TODO: compute correct sizes - - oc_gl_grow_buffer_if_needed(backend->pathQueueBuffer, pathCount * OC_GL_PATH_QUEUE_SIZE, "path queues"); - oc_gl_grow_buffer_if_needed(backend->tileQueueBuffer, backend->maxTileQueueCount * OC_GL_TILE_QUEUE_SIZE, "tile queues"); - oc_gl_grow_buffer_if_needed(backend->segmentBuffer, backend->maxSegmentCount * OC_GL_SEGMENT_SIZE, "segments"); - oc_gl_grow_buffer_if_needed(backend->screenTilesBuffer, nTilesX * nTilesY * OC_GL_SCREEN_TILE_SIZE, "screen tiles"); - oc_gl_grow_buffer_if_needed(backend->tileOpBuffer, backend->maxSegmentCount * 30 * OC_GL_TILE_OP_SIZE, "tile ops"); - - //NOTE: make the buffers visible to gl - glBindBuffer(GL_SHADER_STORAGE_BUFFER, pathBuffer); - glFlushMappedBufferRange(GL_SHADER_STORAGE_BUFFER, pathBufferOffset, pathCount*sizeof(oc_gl_path)); - - glBindBuffer(GL_SHADER_STORAGE_BUFFER, elementBuffer); - glFlushMappedBufferRange(GL_SHADER_STORAGE_BUFFER, elementBufferOffset, eltCount*sizeof(oc_gl_path_elt)); - - //NOTE: clear out texture - u8 clearColor[4] = {0}; - glClearTexImage(backend->outTexture, 0, GL_RGBA, GL_BYTE, clearColor); - - //NOTE: clear counters - int zero = 0; - glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->segmentCountBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), &zero, GL_DYNAMIC_COPY); - - glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->tileQueueCountBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), &zero, GL_DYNAMIC_COPY); - - glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->tileOpCountBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), &zero, GL_DYNAMIC_COPY); - - glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->rasterDispatchBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(oc_gl_dispatch_indirect_command), &zero, GL_DYNAMIC_COPY); - - glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->screenTilesCountBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), &zero, GL_DYNAMIC_COPY); - - glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); - - int err = glGetError(); - if(err) - { - oc_log_error("gl error %i\n", err); - } - - //NOTE: path setup pass - int maxWorkGroupCount = 0; - glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &maxWorkGroupCount); - //NOTE: glDispatchCompute errors if work group count is greater _or equal_ to GL_MAX_COMPUTE_WORK_GROUP_COUNT - // so the maximum _allowed_ group count is one less. - maxWorkGroupCount--; - - glUseProgram(backend->pathSetup); - - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, backend->tileQueueCountBuffer); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, backend->tileQueueBuffer); - - glUniform1i(0, tileSize); - glUniform1f(1, scale); - - for(int i=0; ipathBatchStart + i); - glUniform1i(3, i); - - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, pathBuffer); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->pathQueueBuffer); - - glDispatchCompute(count, 1, 1); - glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); - } - - if(!err) - { - err = glGetError(); - if(err) - { - oc_log_error("gl error %i\n", err); - } - } - - //NOTE: segment setup pass - glUseProgram(backend->segmentSetup); - - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->segmentCountBuffer); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, backend->segmentBuffer); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, backend->pathQueueBuffer); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, backend->tileQueueBuffer); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, backend->tileOpCountBuffer); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, backend->tileOpBuffer); - - glUniform1f(0, scale); - glUniform1ui(1, tileSize); - - for(int i=0; ieltBatchStart + i)); - - glDispatchCompute(count, 1, 1); - glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); - } - - if(!err) - { - err = glGetError(); - if(err) - { - oc_log_error("gl error %i\n", err); - } - } - - //NOTE: backprop pass - glUseProgram(backend->backprop); - - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->tileQueueBuffer); - - for(int i=0; ipathQueueBuffer); - - glDispatchCompute(count, 1, 1); - glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); - } - - if(!err) - { - err = glGetError(); - if(err) - { - oc_log_error("gl error %i\n", err); - } - } - - //NOTE: merge pass - glUseProgram(backend->merge); - - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, pathBuffer); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->pathQueueBuffer); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, backend->tileQueueBuffer); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, backend->tileOpCountBuffer); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, backend->tileOpBuffer); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, backend->screenTilesBuffer); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, backend->screenTilesCountBuffer); - - glUniform1i(0, tileSize); - glUniform1f(1, scale); - glUniform1i(2, pathCount); - glUniform1i(3, backend->pathBatchStart); - - glDispatchCompute(nTilesX, nTilesY, 1); - glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); - - if(!err) - { - err = glGetError(); - if(err) - { - oc_log_error("gl error %i\n", err); - } - } - - //NOTE: balance work groups - glUseProgram(backend->balanceWorkgroups); - - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, backend->screenTilesCountBuffer); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->rasterDispatchBuffer); - glUniform1ui(0, maxWorkGroupCount); - - glDispatchCompute(1, 1, 1); - glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); - - //NOTE: raster pass - glUseProgram(backend->raster); - - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, pathBuffer); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->segmentBuffer); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, backend->tileOpBuffer); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, backend->screenTilesBuffer); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, backend->screenTilesCountBuffer); - - glUniform1f(0, scale); - glUniform1i(1, backend->msaaCount); - - glBindImageTexture(0, backend->outTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8); - - for(int i=0; itexture); - } - } - } - - glUniform1i(2, backend->pathBatchStart); - glUniform1ui(3, maxWorkGroupCount); - - glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, backend->rasterDispatchBuffer); - glDispatchComputeIndirect(0); - - glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); - - if(!err) - { - err = glGetError(); - if(err) - { - oc_log_error("gl error %i\n", err); - } - } - - //NOTE: blit pass - glUseProgram(backend->blit); - glBindBuffer(GL_ARRAY_BUFFER, backend->dummyVertexBuffer); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, backend->outTexture); - glUniform1i(0, 0); - - glDrawArrays(GL_TRIANGLES, 0, 6); - - if(!err) - { - err = glGetError(); - if(err) - { - oc_log_error("gl error %i\n", err); - } - } - - backend->pathBatchStart = backend->pathCount; - backend->eltBatchStart = backend->eltCount; - - backend->maxSegmentCount = 0; - backend->maxTileQueueCount = 0; -} - -void oc_gl_canvas_resize(oc_gl_canvas_backend* backend, oc_vec2 size) -{ - int tileSize = OC_GL_TILE_SIZE; - int nTilesX = (int)(size.x + tileSize - 1)/tileSize; - int nTilesY = (int)(size.y + tileSize - 1)/tileSize; - - glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->screenTilesBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, nTilesX*nTilesY*OC_GL_SCREEN_TILE_SIZE, 0, GL_DYNAMIC_COPY); - - if(backend->outTexture) - { - //NOTE: do we need to explicitly glDeleteTextures()? - glDeleteTextures(1, &backend->outTexture); - glGenTextures(1, &backend->outTexture); - glBindTexture(GL_TEXTURE_2D, backend->outTexture); - glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, size.x, size.y); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - } - - backend->frameSize = size; -} - -void oc_gl_canvas_render(oc_canvas_backend* interface, - oc_color clearColor, - u32 primitiveCount, - oc_primitive* primitives, - u32 eltCount, - oc_path_elt* pathElements) -{ - oc_gl_canvas_backend* backend = (oc_gl_canvas_backend*)interface; - - //NOTE: roll input buffers - backend->bufferIndex = (backend->bufferIndex + 1) % OC_GL_INPUT_BUFFERS_COUNT; - if(backend->bufferSync[backend->bufferIndex] != 0) - { - glClientWaitSync(backend->bufferSync[backend->bufferIndex], GL_SYNC_FLUSH_COMMANDS_BIT, 0xffffffff); - glDeleteSync(backend->bufferSync[backend->bufferIndex]); - backend->bufferSync[backend->bufferIndex] = 0; - } - - //NOTE update screen tiles buffer size - oc_wgl_surface* surface = backend->surface; - oc_vec2 surfaceSize = surface->interface.getSize((oc_surface_data*)surface); - oc_vec2 contentsScaling = surface->interface.contentsScaling((oc_surface_data*)surface); - //TODO support scaling in both axes? - f32 scale = contentsScaling.x; - - oc_vec2 viewportSize = {surfaceSize.x * scale, surfaceSize.y * scale}; - int tileSize = OC_GL_TILE_SIZE; - int nTilesX = (int)(viewportSize.x + tileSize - 1)/tileSize; - int nTilesY = (int)(viewportSize.y + tileSize - 1)/tileSize; - - if(viewportSize.x != backend->frameSize.x || viewportSize.y != backend->frameSize.y) - { - oc_gl_canvas_resize(backend, viewportSize); - } - - glViewport(0, 0, viewportSize.x, viewportSize.y); - - //NOTE: clear screen and reset input buffer offsets - glEnable(GL_BLEND); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - - glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a); - glClear(GL_COLOR_BUFFER_BIT); - - backend->pathCount = 0; - backend->pathBatchStart = 0; - backend->eltCount = 0; - backend->eltBatchStart = 0; - backend->maxSegmentCount = 0; - backend->maxTileQueueCount = 0; - - //NOTE: encode and render batches - oc_vec2 currentPos = {0}; - oc_image images[OC_GL_MAX_IMAGES_PER_BATCH] = {0}; - int imageCount = 0; - backend->eltCount = 0; - - for(int primitiveIndex = 0; primitiveIndex < primitiveCount; primitiveIndex++) - { - oc_primitive* primitive = &primitives[primitiveIndex]; - - if(primitive->attributes.image.h != 0) - { - backend->currentImageIndex = -1; - for(int i=0; iattributes.image.h) - { - backend->currentImageIndex = i; - } - } - if(backend->currentImageIndex <= 0) - { - if(imageCountattributes.image; - backend->currentImageIndex = imageCount; - imageCount++; - } - else - { - oc_gl_render_batch(backend, - surface, - images, - tileSize, - nTilesX, - nTilesY, - viewportSize, - scale); - - images[0] = primitive->attributes.image; - backend->currentImageIndex = 0; - imageCount = 1; - } - } - } - else - { - backend->currentImageIndex = -1; - } - - if(primitive->path.count) - { - backend->primitive = primitive; - backend->pathScreenExtents = (oc_vec4){FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX}; - backend->pathUserExtents = (oc_vec4){FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX}; - - if(primitive->cmd == OC_CMD_STROKE) - { - oc_gl_encode_stroke(backend, pathElements + primitive->path.startIndex, &primitive->path); - } - else - { - int segCount = 0; - for(int eltIndex = 0; - (eltIndex < primitive->path.count) && (primitive->path.startIndex + eltIndex < eltCount); - eltIndex++) - { - oc_path_elt* elt = &pathElements[primitive->path.startIndex + eltIndex]; - - if(elt->type != OC_PATH_MOVE) - { - oc_vec2 p[4] = {currentPos, elt->p[0], elt->p[1], elt->p[2]}; - oc_gl_canvas_encode_element(backend, elt->type, p); - segCount++; - } - switch(elt->type) - { - case OC_PATH_MOVE: - currentPos = elt->p[0]; - break; - - case OC_PATH_LINE: - currentPos = elt->p[0]; - break; - - case OC_PATH_QUADRATIC: - currentPos = elt->p[1]; - break; - - case OC_PATH_CUBIC: - currentPos = elt->p[2]; - break; - } - } - } - //NOTE: push path - oc_gl_canvas_encode_path(backend, primitive, scale); - } - } - - oc_gl_render_batch(backend, - surface, - images, - tileSize, - nTilesX, - nTilesY, - viewportSize, - scale); - - //NOTE: add fence for rolling input buffers - backend->bufferSync[backend->bufferIndex] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); -} - -//-------------------------------------------------------------------- -// Image API -//-------------------------------------------------------------------- -oc_image_data* oc_gl_canvas_image_create(oc_canvas_backend* interface, oc_vec2 size) -{ - oc_gl_image* image = 0; - - image = oc_malloc_type(oc_gl_image); - if(image) - { - glGenTextures(1, &image->texture); - glBindTexture(GL_TEXTURE_2D, image->texture); - glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, size.x, size.y); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - image->interface.size = size; - } - return((oc_image_data*)image); -} - -void oc_gl_canvas_image_destroy(oc_canvas_backend* interface, oc_image_data* imageInterface) -{ - //TODO: check that this image belongs to this backend - oc_gl_image* image = (oc_gl_image*)imageInterface; - glDeleteTextures(1, &image->texture); - free(image); -} - -void oc_gl_canvas_image_upload_region(oc_canvas_backend* interface, - oc_image_data* imageInterface, - oc_rect region, - u8* pixels) -{ - //TODO: check that this image belongs to this backend - oc_gl_image* image = (oc_gl_image*)imageInterface; - glBindTexture(GL_TEXTURE_2D, image->texture); - glTexSubImage2D(GL_TEXTURE_2D, 0, region.x, region.y, region.w, region.h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); -} - -//-------------------------------------------------------------------- -// Canvas setup / destroy -//-------------------------------------------------------------------- - -void oc_gl_canvas_destroy(oc_canvas_backend* interface) -{ - oc_gl_canvas_backend* backend = (oc_gl_canvas_backend*)interface; - - //////////////////////////////////////////////////////////////////// - //TODO - //////////////////////////////////////////////////////////////////// - - free(backend); -} - -static int oc_gl_compile_shader(const char* name, GLuint shader, const char* source) -{ - int res = 0; - - const char* sources[3] = {"#version 430", glsl_common, source}; - - glShaderSource(shader, 3, sources, 0); - glCompileShader(shader); - - int status = 0; - glGetShaderiv(shader, GL_COMPILE_STATUS, &status); - if(!status) - { - char buffer[256]; - int size = 0; - glGetShaderInfoLog(shader, 256, &size, buffer); - printf("Shader compile error (%s): %.*s\n", name, size, buffer); - res = -1; - } - return(res); -} - -static int oc_gl_canvas_compile_compute_program_named(const char* name, const char* source, GLuint* outProgram) -{ - int res = 0; - *outProgram = 0; - - GLuint shader = glCreateShader(GL_COMPUTE_SHADER); - GLuint program = glCreateProgram(); - - res |= oc_gl_compile_shader(name, shader, source); - - if(!res) - { - glAttachShader(program, shader); - glLinkProgram(program); - - int status = 0; - glGetProgramiv(program, GL_LINK_STATUS, &status); - if(!status) - { - char buffer[256]; - int size = 0; - glGetProgramInfoLog(program, 256, &size, buffer); - oc_log_error("Shader link error (%s): %.*s\n", name, size, buffer); - - res = -1; - } - else - { - *outProgram = program; - } - } - return(res); -} - -int oc_gl_canvas_compile_render_program_named(const char* progName, - const char* vertexName, - const char* fragmentName, - const char* vertexSrc, - const char* fragmentSrc, - GLuint* outProgram) -{ - int res = 0; - *outProgram = 0; - - GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); - GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); - GLuint program = glCreateProgram(); - - res |= oc_gl_compile_shader(vertexName, vertexShader, vertexSrc); - res |= oc_gl_compile_shader(fragmentName, fragmentShader, fragmentSrc); - - if(!res) - { - glAttachShader(program, vertexShader); - glAttachShader(program, fragmentShader); - glLinkProgram(program); - - int status = 0; - glGetProgramiv(program, GL_LINK_STATUS, &status); - if(!status) - { - char buffer[256]; - int size = 0; - glGetProgramInfoLog(program, 256, &size, buffer); - oc_log_error("Shader link error (%s): %.*s\n", progName, size, buffer); - res = -1; - } - else - { - *outProgram = program; - } - } - return(res); -} - -#define oc_gl_canvas_compile_compute_program(src, out) \ - oc_gl_canvas_compile_compute_program_named(#src, src, out) - -#define oc_gl_canvas_compile_render_program(progName, shaderSrc, vertexSrc, out) \ - oc_gl_canvas_compile_render_program_named(progName, #shaderSrc, #vertexSrc, shaderSrc, vertexSrc, out) - -const u32 OC_GL_PATH_BUFFER_SIZE = (4<<10)*sizeof(oc_gl_path), - OC_GL_ELEMENT_BUFFER_SIZE = (4<<12)*sizeof(oc_gl_path_elt), - OC_GL_SEGMENT_BUFFER_SIZE = (4<<10)*OC_GL_SEGMENT_SIZE, - OC_GL_PATH_QUEUE_BUFFER_SIZE = (4<<10)*OC_GL_PATH_QUEUE_SIZE, - OC_GL_TILE_QUEUE_BUFFER_SIZE = (4<<10)*OC_GL_TILE_QUEUE_SIZE, - OC_GL_TILE_OP_BUFFER_SIZE = (4<<20)*OC_GL_TILE_OP_SIZE; - -oc_canvas_backend* oc_gl_canvas_backend_create(oc_wgl_surface* surface) -{ - oc_gl_canvas_backend* backend = oc_malloc_type(oc_gl_canvas_backend); - if(backend) - { - memset(backend, 0, sizeof(oc_gl_canvas_backend)); - backend->surface = surface; - - backend->msaaCount = OC_GL_MSAA_COUNT; - - //NOTE(martin): setup interface functions - backend->interface.destroy = oc_gl_canvas_destroy; - backend->interface.render = oc_gl_canvas_render; - backend->interface.imageCreate = oc_gl_canvas_image_create; - backend->interface.imageDestroy = oc_gl_canvas_image_destroy; - backend->interface.imageUploadRegion = oc_gl_canvas_image_upload_region; - - surface->interface.prepare((oc_surface_data*)surface); - - glGenVertexArrays(1, &backend->vao); - glBindVertexArray(backend->vao); - - //NOTE: create programs - int err = 0; - err |= oc_gl_canvas_compile_compute_program(glsl_path_setup, &backend->pathSetup); - err |= oc_gl_canvas_compile_compute_program(glsl_segment_setup, &backend->segmentSetup); - err |= oc_gl_canvas_compile_compute_program(glsl_backprop, &backend->backprop); - err |= oc_gl_canvas_compile_compute_program(glsl_merge, &backend->merge); - err |= oc_gl_canvas_compile_compute_program(glsl_balance_workgroups, &backend->balanceWorkgroups); - err |= oc_gl_canvas_compile_compute_program(glsl_raster, &backend->raster); - err |= oc_gl_canvas_compile_render_program("blit", glsl_blit_vertex, glsl_blit_fragment, &backend->blit); - - if(glGetError() != GL_NO_ERROR) - { - err |= -1; - } - - //NOTE: create out texture - oc_vec2 size = surface->interface.getSize((oc_surface_data*)surface); - oc_vec2 scale = surface->interface.contentsScaling((oc_surface_data*)surface); - - backend->frameSize = (oc_vec2){size.x * scale.x, size.y * scale.y}; - - glGenTextures(1, &backend->outTexture); - glBindTexture(GL_TEXTURE_2D, backend->outTexture); - glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, backend->frameSize.x, backend->frameSize.y); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - //NOTE: generate buffers - glGenBuffers(1, &backend->dummyVertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, backend->dummyVertexBuffer); - - for(int i=0; ipathBuffer[i].buffer); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->pathBuffer[i].buffer); - glBufferStorage(GL_SHADER_STORAGE_BUFFER, OC_GL_PATH_BUFFER_SIZE, 0, GL_MAP_WRITE_BIT|GL_MAP_PERSISTENT_BIT); - backend->pathBuffer[i].size = OC_GL_PATH_BUFFER_SIZE; - backend->pathBuffer[i].contents = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, - 0, - OC_GL_PATH_BUFFER_SIZE, - GL_MAP_WRITE_BIT - |GL_MAP_PERSISTENT_BIT - |GL_MAP_FLUSH_EXPLICIT_BIT); - - glGenBuffers(1, &backend->elementBuffer[i].buffer); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->elementBuffer[i].buffer); - glBufferStorage(GL_SHADER_STORAGE_BUFFER, OC_GL_ELEMENT_BUFFER_SIZE, 0, GL_MAP_WRITE_BIT|GL_MAP_PERSISTENT_BIT); - backend->elementBuffer[i].size = OC_GL_ELEMENT_BUFFER_SIZE; - backend->elementBuffer[i].contents = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, - 0, - OC_GL_ELEMENT_BUFFER_SIZE, - GL_MAP_WRITE_BIT - |GL_MAP_PERSISTENT_BIT - |GL_MAP_FLUSH_EXPLICIT_BIT); - } - - glGenBuffers(1, &backend->segmentBuffer); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->segmentBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, OC_GL_SEGMENT_BUFFER_SIZE, 0, GL_DYNAMIC_COPY); - - glGenBuffers(1, &backend->segmentCountBuffer); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->segmentCountBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), 0, GL_DYNAMIC_COPY); - - glGenBuffers(1, &backend->pathQueueBuffer); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->pathQueueBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, OC_GL_PATH_QUEUE_BUFFER_SIZE, 0, GL_DYNAMIC_COPY); - - glGenBuffers(1, &backend->tileQueueBuffer); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->tileQueueBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, OC_GL_TILE_QUEUE_BUFFER_SIZE, 0, GL_DYNAMIC_COPY); - - glGenBuffers(1, &backend->tileQueueCountBuffer); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->tileQueueCountBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), 0, GL_DYNAMIC_COPY); - - glGenBuffers(1, &backend->tileOpBuffer); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->tileOpBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, OC_GL_TILE_OP_BUFFER_SIZE, 0, GL_DYNAMIC_COPY); - - glGenBuffers(1, &backend->tileOpCountBuffer); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->tileOpCountBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), 0, GL_DYNAMIC_COPY); - - int tileSize = OC_GL_TILE_SIZE; - int nTilesX = (int)(backend->frameSize.x + tileSize - 1)/tileSize; - int nTilesY = (int)(backend->frameSize.y + tileSize - 1)/tileSize; - - glGenBuffers(1, &backend->screenTilesBuffer); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->screenTilesBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, nTilesX*nTilesY*OC_GL_SCREEN_TILE_SIZE, 0, GL_DYNAMIC_COPY); - - glGenBuffers(1, &backend->screenTilesCountBuffer); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->screenTilesCountBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), 0, GL_DYNAMIC_COPY); - - glGenBuffers(1, &backend->rasterDispatchBuffer); - glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->rasterDispatchBuffer); - glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(oc_gl_dispatch_indirect_command), 0, GL_DYNAMIC_COPY); - - if(err) - { - oc_gl_canvas_destroy((oc_canvas_backend*)backend); - backend = 0; - } - } - return((oc_canvas_backend*)backend); -} - -oc_surface_data* oc_gl_canvas_surface_create_for_window(oc_window window) -{ - oc_wgl_surface* surface = (oc_wgl_surface*)oc_wgl_surface_create_for_window(window); - - if(surface) - { - surface->interface.backend = oc_gl_canvas_backend_create(surface); - if(surface->interface.backend) - { - surface->interface.api = OC_CANVAS; - } - else - { - surface->interface.destroy((oc_surface_data*)surface); - surface = 0; - } - } - return((oc_surface_data*)surface); -} + */ + f32 halfW = 0.5 * attributes->width; + oc_vec2 u = { n0.x + n1.x, n0.y + n1.y }; + f32 uNormSquare = u.x * u.x + u.y * u.y; + f32 alpha = attributes->width / uNormSquare; + oc_vec2 v = { u.x * alpha, u.y * alpha }; + + f32 excursionSquare = uNormSquare * oc_square(alpha - attributes->width / 4); + + if(attributes->joint == OC_JOINT_MITER + && excursionSquare <= oc_square(attributes->maxJointExcursion)) + { + //NOTE(martin): add a mitter joint + oc_vec2 points[] = { p0, + { p0.x + n0.x * halfW, p0.y + n0.y * halfW }, + { p0.x + v.x, p0.y + v.y }, + { p0.x + n1.x * halfW, p0.y + n1.y * halfW }, + p0 }; + + oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points); + oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points + 1); + oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points + 2); + oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points + 3); + } + else + { + //NOTE(martin): add a bevel joint + oc_vec2 points[] = { p0, + { p0.x + n0.x * halfW, p0.y + n0.y * halfW }, + { p0.x + n1.x * halfW, p0.y + n1.y * halfW }, + p0 }; + + oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points); + oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points + 1); + oc_gl_canvas_encode_element(backend, OC_PATH_LINE, points + 2); + } +} + +u32 oc_gl_encode_stroke_subpath(oc_gl_canvas_backend* backend, + oc_path_elt* elements, + oc_path_descriptor* path, + u32 startIndex, + oc_vec2 startPoint) +{ + u32 eltCount = path->count; + OC_DEBUG_ASSERT(startIndex < eltCount); + + oc_vec2 currentPoint = startPoint; + oc_vec2 endPoint = { 0, 0 }; + oc_vec2 previousEndTangent = { 0, 0 }; + oc_vec2 firstTangent = { 0, 0 }; + oc_vec2 startTangent = { 0, 0 }; + oc_vec2 endTangent = { 0, 0 }; + + //NOTE(martin): encode first element and compute first tangent + oc_gl_encode_stroke_element(backend, elements + startIndex, currentPoint, &startTangent, &endTangent, &endPoint); + + firstTangent = startTangent; + previousEndTangent = endTangent; + currentPoint = endPoint; + + //NOTE(martin): encode subsequent elements along with their joints + + oc_attributes* attributes = &backend->primitive->attributes; + + u32 eltIndex = startIndex + 1; + for(; + eltIndex < eltCount && elements[eltIndex].type != OC_PATH_MOVE; + eltIndex++) + { + oc_gl_encode_stroke_element(backend, elements + eltIndex, currentPoint, &startTangent, &endTangent, &endPoint); + + if(attributes->joint != OC_JOINT_NONE) + { + oc_gl_stroke_joint(backend, currentPoint, previousEndTangent, startTangent); + } + previousEndTangent = endTangent; + currentPoint = endPoint; + } + u32 subPathEltCount = eltIndex - startIndex; + + //NOTE(martin): draw end cap / joint. We ensure there's at least two segments to draw a closing joint + if(subPathEltCount > 1 + && startPoint.x == endPoint.x + && startPoint.y == endPoint.y) + { + if(attributes->joint != OC_JOINT_NONE) + { + //NOTE(martin): add a closing joint if the path is closed + oc_gl_stroke_joint(backend, endPoint, endTangent, firstTangent); + } + } + else if(attributes->cap == OC_CAP_SQUARE) + { + //NOTE(martin): add start and end cap + oc_gl_stroke_cap(backend, startPoint, (oc_vec2){ -startTangent.x, -startTangent.y }); + oc_gl_stroke_cap(backend, endPoint, endTangent); + } + return (eltIndex); +} + +void oc_gl_encode_stroke(oc_gl_canvas_backend* backend, + oc_path_elt* elements, + oc_path_descriptor* path) +{ + u32 eltCount = path->count; + OC_DEBUG_ASSERT(eltCount); + + oc_vec2 startPoint = path->startPoint; + u32 startIndex = 0; + + while(startIndex < eltCount) + { + //NOTE(martin): eliminate leading moves + while(startIndex < eltCount && elements[startIndex].type == OC_PATH_MOVE) + { + startPoint = elements[startIndex].p[0]; + startIndex++; + } + if(startIndex < eltCount) + { + startIndex = oc_gl_encode_stroke_subpath(backend, elements, path, startIndex, startPoint); + } + } +} + +void oc_gl_grow_buffer_if_needed(GLuint buffer, i32 wantedSize, const char* name) +{ + i32 oldSize = 0; + glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer); + glGetBufferParameteriv(GL_SHADER_STORAGE_BUFFER, GL_BUFFER_SIZE, &oldSize); + + if(oldSize < wantedSize) + { + oc_log_info("growing %s buffer\n", name); + + int newSize = wantedSize * 1.2; + + glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, newSize, 0, GL_DYNAMIC_COPY); + } +} + +void oc_gl_render_batch(oc_gl_canvas_backend* backend, + oc_wgl_surface* surface, + oc_image* images, + int tileSize, + int nTilesX, + int nTilesY, + oc_vec2 viewportSize, + f32 scale) +{ + GLuint pathBuffer = backend->pathBuffer[backend->bufferIndex].buffer; + GLuint elementBuffer = backend->elementBuffer[backend->bufferIndex].buffer; + + int pathBufferOffset = backend->pathBatchStart * sizeof(oc_gl_path); + int elementBufferOffset = backend->eltBatchStart * sizeof(oc_gl_path_elt); + int pathCount = backend->pathCount - backend->pathBatchStart; + int eltCount = backend->eltCount - backend->eltBatchStart; + + if(!pathCount || !eltCount) + { + return; + } + + //NOTE: update intermediate buffers size if needed + //TODO: compute correct sizes + + oc_gl_grow_buffer_if_needed(backend->pathQueueBuffer, pathCount * OC_GL_PATH_QUEUE_SIZE, "path queues"); + oc_gl_grow_buffer_if_needed(backend->tileQueueBuffer, backend->maxTileQueueCount * OC_GL_TILE_QUEUE_SIZE, "tile queues"); + oc_gl_grow_buffer_if_needed(backend->segmentBuffer, backend->maxSegmentCount * OC_GL_SEGMENT_SIZE, "segments"); + oc_gl_grow_buffer_if_needed(backend->screenTilesBuffer, nTilesX * nTilesY * OC_GL_SCREEN_TILE_SIZE, "screen tiles"); + oc_gl_grow_buffer_if_needed(backend->tileOpBuffer, backend->maxSegmentCount * 30 * OC_GL_TILE_OP_SIZE, "tile ops"); + + //NOTE: make the buffers visible to gl + glBindBuffer(GL_SHADER_STORAGE_BUFFER, pathBuffer); + glFlushMappedBufferRange(GL_SHADER_STORAGE_BUFFER, pathBufferOffset, pathCount * sizeof(oc_gl_path)); + + glBindBuffer(GL_SHADER_STORAGE_BUFFER, elementBuffer); + glFlushMappedBufferRange(GL_SHADER_STORAGE_BUFFER, elementBufferOffset, eltCount * sizeof(oc_gl_path_elt)); + + //NOTE: clear out texture + u8 clearColor[4] = { 0 }; + glClearTexImage(backend->outTexture, 0, GL_RGBA, GL_BYTE, clearColor); + + //NOTE: clear counters + int zero = 0; + glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->segmentCountBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), &zero, GL_DYNAMIC_COPY); + + glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->tileQueueCountBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), &zero, GL_DYNAMIC_COPY); + + glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->tileOpCountBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), &zero, GL_DYNAMIC_COPY); + + glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->rasterDispatchBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(oc_gl_dispatch_indirect_command), &zero, GL_DYNAMIC_COPY); + + glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->screenTilesCountBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), &zero, GL_DYNAMIC_COPY); + + glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + + int err = glGetError(); + if(err) + { + oc_log_error("gl error %i\n", err); + } + + //NOTE: path setup pass + int maxWorkGroupCount = 0; + glGetIntegeri_v(GL_MAX_COMPUTE_WORK_GROUP_COUNT, 0, &maxWorkGroupCount); + //NOTE: glDispatchCompute errors if work group count is greater _or equal_ to GL_MAX_COMPUTE_WORK_GROUP_COUNT + // so the maximum _allowed_ group count is one less. + maxWorkGroupCount--; + + glUseProgram(backend->pathSetup); + + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, backend->tileQueueCountBuffer); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, backend->tileQueueBuffer); + + glUniform1i(0, tileSize); + glUniform1f(1, scale); + + for(int i = 0; i < pathCount; i += maxWorkGroupCount) + { + int count = oc_min(maxWorkGroupCount, pathCount - i); + + glUniform1i(2, backend->pathBatchStart + i); + glUniform1i(3, i); + + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, pathBuffer); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->pathQueueBuffer); + + glDispatchCompute(count, 1, 1); + glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + } + + if(!err) + { + err = glGetError(); + if(err) + { + oc_log_error("gl error %i\n", err); + } + } + + //NOTE: segment setup pass + glUseProgram(backend->segmentSetup); + + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->segmentCountBuffer); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, backend->segmentBuffer); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, backend->pathQueueBuffer); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, backend->tileQueueBuffer); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, backend->tileOpCountBuffer); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, backend->tileOpBuffer); + + glUniform1f(0, scale); + glUniform1ui(1, tileSize); + + for(int i = 0; i < eltCount; i += maxWorkGroupCount) + { + int offset = elementBufferOffset + i * sizeof(oc_gl_path_elt); + int count = oc_min(maxWorkGroupCount, eltCount - i); + + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, elementBuffer); + + glUniform1i(2, (backend->eltBatchStart + i)); + + glDispatchCompute(count, 1, 1); + glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + } + + if(!err) + { + err = glGetError(); + if(err) + { + oc_log_error("gl error %i\n", err); + } + } + + //NOTE: backprop pass + glUseProgram(backend->backprop); + + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->tileQueueBuffer); + + for(int i = 0; i < pathCount; i += maxWorkGroupCount) + { + int count = oc_min(maxWorkGroupCount, pathCount - i); + + glUniform1i(0, i); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, backend->pathQueueBuffer); + + glDispatchCompute(count, 1, 1); + glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + } + + if(!err) + { + err = glGetError(); + if(err) + { + oc_log_error("gl error %i\n", err); + } + } + + //NOTE: merge pass + glUseProgram(backend->merge); + + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, pathBuffer); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->pathQueueBuffer); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, backend->tileQueueBuffer); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, backend->tileOpCountBuffer); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, backend->tileOpBuffer); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 5, backend->screenTilesBuffer); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 6, backend->screenTilesCountBuffer); + + glUniform1i(0, tileSize); + glUniform1f(1, scale); + glUniform1i(2, pathCount); + glUniform1i(3, backend->pathBatchStart); + + glDispatchCompute(nTilesX, nTilesY, 1); + glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + + if(!err) + { + err = glGetError(); + if(err) + { + oc_log_error("gl error %i\n", err); + } + } + + //NOTE: balance work groups + glUseProgram(backend->balanceWorkgroups); + + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, backend->screenTilesCountBuffer); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->rasterDispatchBuffer); + glUniform1ui(0, maxWorkGroupCount); + + glDispatchCompute(1, 1, 1); + glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT); + + //NOTE: raster pass + glUseProgram(backend->raster); + + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, pathBuffer); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, backend->segmentBuffer); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, backend->tileOpBuffer); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 3, backend->screenTilesBuffer); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 4, backend->screenTilesCountBuffer); + + glUniform1f(0, scale); + glUniform1i(1, backend->msaaCount); + + glBindImageTexture(0, backend->outTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA8); + + for(int i = 0; i < OC_GL_MAX_IMAGES_PER_BATCH; i++) + { + if(images[i].h) + { + oc_gl_image* image = (oc_gl_image*)oc_image_data_from_handle(images[i]); + if(image) + { + glActiveTexture(GL_TEXTURE1 + i); + glBindTexture(GL_TEXTURE_2D, image->texture); + } + } + } + + glUniform1i(2, backend->pathBatchStart); + glUniform1ui(3, maxWorkGroupCount); + + glBindBuffer(GL_DISPATCH_INDIRECT_BUFFER, backend->rasterDispatchBuffer); + glDispatchComputeIndirect(0); + + glMemoryBarrier(GL_TEXTURE_FETCH_BARRIER_BIT); + + if(!err) + { + err = glGetError(); + if(err) + { + oc_log_error("gl error %i\n", err); + } + } + + //NOTE: blit pass + glUseProgram(backend->blit); + glBindBuffer(GL_ARRAY_BUFFER, backend->dummyVertexBuffer); + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, backend->outTexture); + glUniform1i(0, 0); + + glDrawArrays(GL_TRIANGLES, 0, 6); + + if(!err) + { + err = glGetError(); + if(err) + { + oc_log_error("gl error %i\n", err); + } + } + + backend->pathBatchStart = backend->pathCount; + backend->eltBatchStart = backend->eltCount; + + backend->maxSegmentCount = 0; + backend->maxTileQueueCount = 0; +} + +void oc_gl_canvas_resize(oc_gl_canvas_backend* backend, oc_vec2 size) +{ + int tileSize = OC_GL_TILE_SIZE; + int nTilesX = (int)(size.x + tileSize - 1) / tileSize; + int nTilesY = (int)(size.y + tileSize - 1) / tileSize; + + glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->screenTilesBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, nTilesX * nTilesY * OC_GL_SCREEN_TILE_SIZE, 0, GL_DYNAMIC_COPY); + + if(backend->outTexture) + { + //NOTE: do we need to explicitly glDeleteTextures()? + glDeleteTextures(1, &backend->outTexture); + glGenTextures(1, &backend->outTexture); + glBindTexture(GL_TEXTURE_2D, backend->outTexture); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, size.x, size.y); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + + backend->frameSize = size; +} + +void oc_gl_canvas_render(oc_canvas_backend* interface, + oc_color clearColor, + u32 primitiveCount, + oc_primitive* primitives, + u32 eltCount, + oc_path_elt* pathElements) +{ + oc_gl_canvas_backend* backend = (oc_gl_canvas_backend*)interface; + + //NOTE: roll input buffers + backend->bufferIndex = (backend->bufferIndex + 1) % OC_GL_INPUT_BUFFERS_COUNT; + if(backend->bufferSync[backend->bufferIndex] != 0) + { + glClientWaitSync(backend->bufferSync[backend->bufferIndex], GL_SYNC_FLUSH_COMMANDS_BIT, 0xffffffff); + glDeleteSync(backend->bufferSync[backend->bufferIndex]); + backend->bufferSync[backend->bufferIndex] = 0; + } + + //NOTE update screen tiles buffer size + oc_wgl_surface* surface = backend->surface; + oc_vec2 surfaceSize = surface->interface.getSize((oc_surface_data*)surface); + oc_vec2 contentsScaling = surface->interface.contentsScaling((oc_surface_data*)surface); + //TODO support scaling in both axes? + f32 scale = contentsScaling.x; + + oc_vec2 viewportSize = { surfaceSize.x * scale, surfaceSize.y * scale }; + int tileSize = OC_GL_TILE_SIZE; + int nTilesX = (int)(viewportSize.x + tileSize - 1) / tileSize; + int nTilesY = (int)(viewportSize.y + tileSize - 1) / tileSize; + + if(viewportSize.x != backend->frameSize.x || viewportSize.y != backend->frameSize.y) + { + oc_gl_canvas_resize(backend, viewportSize); + } + + glViewport(0, 0, viewportSize.x, viewportSize.y); + + //NOTE: clear screen and reset input buffer offsets + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + glClearColor(clearColor.r, clearColor.g, clearColor.b, clearColor.a); + glClear(GL_COLOR_BUFFER_BIT); + + backend->pathCount = 0; + backend->pathBatchStart = 0; + backend->eltCount = 0; + backend->eltBatchStart = 0; + backend->maxSegmentCount = 0; + backend->maxTileQueueCount = 0; + + //NOTE: encode and render batches + oc_vec2 currentPos = { 0 }; + oc_image images[OC_GL_MAX_IMAGES_PER_BATCH] = { 0 }; + int imageCount = 0; + backend->eltCount = 0; + + for(int primitiveIndex = 0; primitiveIndex < primitiveCount; primitiveIndex++) + { + oc_primitive* primitive = &primitives[primitiveIndex]; + + if(primitive->attributes.image.h != 0) + { + backend->currentImageIndex = -1; + for(int i = 0; i < imageCount; i++) + { + if(images[i].h == primitive->attributes.image.h) + { + backend->currentImageIndex = i; + } + } + if(backend->currentImageIndex <= 0) + { + if(imageCount < OC_GL_MAX_IMAGES_PER_BATCH) + { + images[imageCount] = primitive->attributes.image; + backend->currentImageIndex = imageCount; + imageCount++; + } + else + { + oc_gl_render_batch(backend, + surface, + images, + tileSize, + nTilesX, + nTilesY, + viewportSize, + scale); + + images[0] = primitive->attributes.image; + backend->currentImageIndex = 0; + imageCount = 1; + } + } + } + else + { + backend->currentImageIndex = -1; + } + + if(primitive->path.count) + { + backend->primitive = primitive; + backend->pathScreenExtents = (oc_vec4){ FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX }; + backend->pathUserExtents = (oc_vec4){ FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX }; + + if(primitive->cmd == OC_CMD_STROKE) + { + oc_gl_encode_stroke(backend, pathElements + primitive->path.startIndex, &primitive->path); + } + else + { + int segCount = 0; + for(int eltIndex = 0; + (eltIndex < primitive->path.count) && (primitive->path.startIndex + eltIndex < eltCount); + eltIndex++) + { + oc_path_elt* elt = &pathElements[primitive->path.startIndex + eltIndex]; + + if(elt->type != OC_PATH_MOVE) + { + oc_vec2 p[4] = { currentPos, elt->p[0], elt->p[1], elt->p[2] }; + oc_gl_canvas_encode_element(backend, elt->type, p); + segCount++; + } + switch(elt->type) + { + case OC_PATH_MOVE: + currentPos = elt->p[0]; + break; + + case OC_PATH_LINE: + currentPos = elt->p[0]; + break; + + case OC_PATH_QUADRATIC: + currentPos = elt->p[1]; + break; + + case OC_PATH_CUBIC: + currentPos = elt->p[2]; + break; + } + } + } + //NOTE: push path + oc_gl_canvas_encode_path(backend, primitive, scale); + } + } + + oc_gl_render_batch(backend, + surface, + images, + tileSize, + nTilesX, + nTilesY, + viewportSize, + scale); + + //NOTE: add fence for rolling input buffers + backend->bufferSync[backend->bufferIndex] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); +} + +//-------------------------------------------------------------------- +// Image API +//-------------------------------------------------------------------- +oc_image_data* oc_gl_canvas_image_create(oc_canvas_backend* interface, oc_vec2 size) +{ + oc_gl_image* image = 0; + + image = oc_malloc_type(oc_gl_image); + if(image) + { + glGenTextures(1, &image->texture); + glBindTexture(GL_TEXTURE_2D, image->texture); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, size.x, size.y); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + image->interface.size = size; + } + return ((oc_image_data*)image); +} + +void oc_gl_canvas_image_destroy(oc_canvas_backend* interface, oc_image_data* imageInterface) +{ + //TODO: check that this image belongs to this backend + oc_gl_image* image = (oc_gl_image*)imageInterface; + glDeleteTextures(1, &image->texture); + free(image); +} + +void oc_gl_canvas_image_upload_region(oc_canvas_backend* interface, + oc_image_data* imageInterface, + oc_rect region, + u8* pixels) +{ + //TODO: check that this image belongs to this backend + oc_gl_image* image = (oc_gl_image*)imageInterface; + glBindTexture(GL_TEXTURE_2D, image->texture); + glTexSubImage2D(GL_TEXTURE_2D, 0, region.x, region.y, region.w, region.h, GL_RGBA, GL_UNSIGNED_BYTE, pixels); +} + +//-------------------------------------------------------------------- +// Canvas setup / destroy +//-------------------------------------------------------------------- + +void oc_gl_canvas_destroy(oc_canvas_backend* interface) +{ + oc_gl_canvas_backend* backend = (oc_gl_canvas_backend*)interface; + + //////////////////////////////////////////////////////////////////// + //TODO + //////////////////////////////////////////////////////////////////// + + free(backend); +} + +static int oc_gl_compile_shader(const char* name, GLuint shader, const char* source) +{ + int res = 0; + + const char* sources[3] = { "#version 430", glsl_common, source }; + + glShaderSource(shader, 3, sources, 0); + glCompileShader(shader); + + int status = 0; + glGetShaderiv(shader, GL_COMPILE_STATUS, &status); + if(!status) + { + char buffer[256]; + int size = 0; + glGetShaderInfoLog(shader, 256, &size, buffer); + printf("Shader compile error (%s): %.*s\n", name, size, buffer); + res = -1; + } + return (res); +} + +static int oc_gl_canvas_compile_compute_program_named(const char* name, const char* source, GLuint* outProgram) +{ + int res = 0; + *outProgram = 0; + + GLuint shader = glCreateShader(GL_COMPUTE_SHADER); + GLuint program = glCreateProgram(); + + res |= oc_gl_compile_shader(name, shader, source); + + if(!res) + { + glAttachShader(program, shader); + glLinkProgram(program); + + int status = 0; + glGetProgramiv(program, GL_LINK_STATUS, &status); + if(!status) + { + char buffer[256]; + int size = 0; + glGetProgramInfoLog(program, 256, &size, buffer); + oc_log_error("Shader link error (%s): %.*s\n", name, size, buffer); + + res = -1; + } + else + { + *outProgram = program; + } + } + return (res); +} + +int oc_gl_canvas_compile_render_program_named(const char* progName, + const char* vertexName, + const char* fragmentName, + const char* vertexSrc, + const char* fragmentSrc, + GLuint* outProgram) +{ + int res = 0; + *outProgram = 0; + + GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER); + GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); + GLuint program = glCreateProgram(); + + res |= oc_gl_compile_shader(vertexName, vertexShader, vertexSrc); + res |= oc_gl_compile_shader(fragmentName, fragmentShader, fragmentSrc); + + if(!res) + { + glAttachShader(program, vertexShader); + glAttachShader(program, fragmentShader); + glLinkProgram(program); + + int status = 0; + glGetProgramiv(program, GL_LINK_STATUS, &status); + if(!status) + { + char buffer[256]; + int size = 0; + glGetProgramInfoLog(program, 256, &size, buffer); + oc_log_error("Shader link error (%s): %.*s\n", progName, size, buffer); + res = -1; + } + else + { + *outProgram = program; + } + } + return (res); +} + +#define oc_gl_canvas_compile_compute_program(src, out) \ + oc_gl_canvas_compile_compute_program_named(#src, src, out) + +#define oc_gl_canvas_compile_render_program(progName, shaderSrc, vertexSrc, out) \ + oc_gl_canvas_compile_render_program_named(progName, #shaderSrc, #vertexSrc, shaderSrc, vertexSrc, out) + +const u32 OC_GL_PATH_BUFFER_SIZE = (4 << 10) * sizeof(oc_gl_path), + OC_GL_ELEMENT_BUFFER_SIZE = (4 << 12) * sizeof(oc_gl_path_elt), + OC_GL_SEGMENT_BUFFER_SIZE = (4 << 10) * OC_GL_SEGMENT_SIZE, + OC_GL_PATH_QUEUE_BUFFER_SIZE = (4 << 10) * OC_GL_PATH_QUEUE_SIZE, + OC_GL_TILE_QUEUE_BUFFER_SIZE = (4 << 10) * OC_GL_TILE_QUEUE_SIZE, + OC_GL_TILE_OP_BUFFER_SIZE = (4 << 20) * OC_GL_TILE_OP_SIZE; + +oc_canvas_backend* oc_gl_canvas_backend_create(oc_wgl_surface* surface) +{ + oc_gl_canvas_backend* backend = oc_malloc_type(oc_gl_canvas_backend); + if(backend) + { + memset(backend, 0, sizeof(oc_gl_canvas_backend)); + backend->surface = surface; + + backend->msaaCount = OC_GL_MSAA_COUNT; + + //NOTE(martin): setup interface functions + backend->interface.destroy = oc_gl_canvas_destroy; + backend->interface.render = oc_gl_canvas_render; + backend->interface.imageCreate = oc_gl_canvas_image_create; + backend->interface.imageDestroy = oc_gl_canvas_image_destroy; + backend->interface.imageUploadRegion = oc_gl_canvas_image_upload_region; + + surface->interface.prepare((oc_surface_data*)surface); + + glGenVertexArrays(1, &backend->vao); + glBindVertexArray(backend->vao); + + //NOTE: create programs + int err = 0; + err |= oc_gl_canvas_compile_compute_program(glsl_path_setup, &backend->pathSetup); + err |= oc_gl_canvas_compile_compute_program(glsl_segment_setup, &backend->segmentSetup); + err |= oc_gl_canvas_compile_compute_program(glsl_backprop, &backend->backprop); + err |= oc_gl_canvas_compile_compute_program(glsl_merge, &backend->merge); + err |= oc_gl_canvas_compile_compute_program(glsl_balance_workgroups, &backend->balanceWorkgroups); + err |= oc_gl_canvas_compile_compute_program(glsl_raster, &backend->raster); + err |= oc_gl_canvas_compile_render_program("blit", glsl_blit_vertex, glsl_blit_fragment, &backend->blit); + + if(glGetError() != GL_NO_ERROR) + { + err |= -1; + } + + //NOTE: create out texture + oc_vec2 size = surface->interface.getSize((oc_surface_data*)surface); + oc_vec2 scale = surface->interface.contentsScaling((oc_surface_data*)surface); + + backend->frameSize = (oc_vec2){ size.x * scale.x, size.y * scale.y }; + + glGenTextures(1, &backend->outTexture); + glBindTexture(GL_TEXTURE_2D, backend->outTexture); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, backend->frameSize.x, backend->frameSize.y); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + //NOTE: generate buffers + glGenBuffers(1, &backend->dummyVertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, backend->dummyVertexBuffer); + + for(int i = 0; i < OC_GL_INPUT_BUFFERS_COUNT; i++) + { + glGenBuffers(1, &backend->pathBuffer[i].buffer); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->pathBuffer[i].buffer); + glBufferStorage(GL_SHADER_STORAGE_BUFFER, OC_GL_PATH_BUFFER_SIZE, 0, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT); + backend->pathBuffer[i].size = OC_GL_PATH_BUFFER_SIZE; + backend->pathBuffer[i].contents = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, + 0, + OC_GL_PATH_BUFFER_SIZE, + GL_MAP_WRITE_BIT + | GL_MAP_PERSISTENT_BIT + | GL_MAP_FLUSH_EXPLICIT_BIT); + + glGenBuffers(1, &backend->elementBuffer[i].buffer); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->elementBuffer[i].buffer); + glBufferStorage(GL_SHADER_STORAGE_BUFFER, OC_GL_ELEMENT_BUFFER_SIZE, 0, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT); + backend->elementBuffer[i].size = OC_GL_ELEMENT_BUFFER_SIZE; + backend->elementBuffer[i].contents = glMapBufferRange(GL_SHADER_STORAGE_BUFFER, + 0, + OC_GL_ELEMENT_BUFFER_SIZE, + GL_MAP_WRITE_BIT + | GL_MAP_PERSISTENT_BIT + | GL_MAP_FLUSH_EXPLICIT_BIT); + } + + glGenBuffers(1, &backend->segmentBuffer); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->segmentBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, OC_GL_SEGMENT_BUFFER_SIZE, 0, GL_DYNAMIC_COPY); + + glGenBuffers(1, &backend->segmentCountBuffer); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->segmentCountBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), 0, GL_DYNAMIC_COPY); + + glGenBuffers(1, &backend->pathQueueBuffer); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->pathQueueBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, OC_GL_PATH_QUEUE_BUFFER_SIZE, 0, GL_DYNAMIC_COPY); + + glGenBuffers(1, &backend->tileQueueBuffer); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->tileQueueBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, OC_GL_TILE_QUEUE_BUFFER_SIZE, 0, GL_DYNAMIC_COPY); + + glGenBuffers(1, &backend->tileQueueCountBuffer); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->tileQueueCountBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), 0, GL_DYNAMIC_COPY); + + glGenBuffers(1, &backend->tileOpBuffer); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->tileOpBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, OC_GL_TILE_OP_BUFFER_SIZE, 0, GL_DYNAMIC_COPY); + + glGenBuffers(1, &backend->tileOpCountBuffer); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->tileOpCountBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), 0, GL_DYNAMIC_COPY); + + int tileSize = OC_GL_TILE_SIZE; + int nTilesX = (int)(backend->frameSize.x + tileSize - 1) / tileSize; + int nTilesY = (int)(backend->frameSize.y + tileSize - 1) / tileSize; + + glGenBuffers(1, &backend->screenTilesBuffer); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->screenTilesBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, nTilesX * nTilesY * OC_GL_SCREEN_TILE_SIZE, 0, GL_DYNAMIC_COPY); + + glGenBuffers(1, &backend->screenTilesCountBuffer); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->screenTilesCountBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(int), 0, GL_DYNAMIC_COPY); + + glGenBuffers(1, &backend->rasterDispatchBuffer); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, backend->rasterDispatchBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(oc_gl_dispatch_indirect_command), 0, GL_DYNAMIC_COPY); + + if(err) + { + oc_gl_canvas_destroy((oc_canvas_backend*)backend); + backend = 0; + } + } + return ((oc_canvas_backend*)backend); +} + +oc_surface_data* oc_gl_canvas_surface_create_for_window(oc_window window) +{ + oc_wgl_surface* surface = (oc_wgl_surface*)oc_wgl_surface_create_for_window(window); + + if(surface) + { + surface->interface.backend = oc_gl_canvas_backend_create(surface); + if(surface->interface.backend) + { + surface->interface.api = OC_CANVAS; + } + else + { + surface->interface.destroy((oc_surface_data*)surface); + surface = 0; + } + } + return ((oc_surface_data*)surface); +} diff --git a/src/graphics/gl_loader.c b/src/graphics/gl_loader.c index 87994a0..f63ba7a 100644 --- a/src/graphics/gl_loader.c +++ b/src/graphics/gl_loader.c @@ -5,9446 +5,9998 @@ * @date: 15/082023 * *********************************************************/ -#include"gl_loader.h" -#include"platform/platform.h" +#include "gl_loader.h" +#include "platform/platform.h" oc_thread_local oc_gl_api* oc_glAPI = 0; oc_gl_api oc_glNoAPI; -void oc_glGetFloatv_noimpl(GLenum pname, GLfloat * data) +void oc_glGetFloatv_noimpl(GLenum pname, GLfloat* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetFloatv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetFloatv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glTexBufferRange_noimpl(GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexBufferRange is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexBufferRange is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLboolean oc_glIsBuffer_noimpl(GLuint buffer) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glIsBuffer is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLboolean)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glIsBuffer is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLboolean)0); } + GLboolean oc_glIsTexture_noimpl(GLuint texture) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glIsTexture is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLboolean)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glIsTexture is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLboolean)0); } + void oc_glDepthRangef_noimpl(GLfloat n, GLfloat f) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDepthRangef is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDepthRangef is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glEndConditionalRender_noimpl(void) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glEndConditionalRender is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glEndConditionalRender is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBlendFunci_noimpl(GLuint buf, GLenum src, GLenum dst) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBlendFunci is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBlendFunci is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetProgramPipelineiv_noimpl(GLuint pipeline, GLenum pname, GLint * params) + +void oc_glGetProgramPipelineiv_noimpl(GLuint pipeline, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetProgramPipelineiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetProgramPipelineiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glWaitSync_noimpl(GLsync sync, GLbitfield flags, GLuint64 timeout) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glWaitSync is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glWaitSync is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniformMatrix2fv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + +void oc_glProgramUniformMatrix2fv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniformMatrix2fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniformMatrix2fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniformMatrix4x3dv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) + +void oc_glProgramUniformMatrix4x3dv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniformMatrix4x3dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniformMatrix4x3dv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib1dv_noimpl(GLuint index, const GLdouble * v) + +void oc_glVertexAttrib1dv_noimpl(GLuint index, const GLdouble* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib1dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib1dv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glSamplerParameteri_noimpl(GLuint sampler, GLenum pname, GLint param) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glSamplerParameteri is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glSamplerParameteri is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetVertexAttribIiv_noimpl(GLuint index, GLenum pname, GLint * params) + +void oc_glGetVertexAttribIiv_noimpl(GLuint index, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetVertexAttribIiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetVertexAttribIiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetSamplerParameterfv_noimpl(GLuint sampler, GLenum pname, GLfloat * params) + +void oc_glGetSamplerParameterfv_noimpl(GLuint sampler, GLenum pname, GLfloat* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetSamplerParameterfv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetSamplerParameterfv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttrib1d_noimpl(GLuint index, GLdouble x) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib1d is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib1d is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glTexBuffer_noimpl(GLenum target, GLenum internalformat, GLuint buffer) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexBuffer is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexBuffer is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glInvalidateBufferData_noimpl(GLuint buffer) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glInvalidateBufferData is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glInvalidateBufferData is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glProgramUniform2i_noimpl(GLuint program, GLint location, GLint v0, GLint v1) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform2i is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform2i is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniform4dv_noimpl(GLint location, GLsizei count, const GLdouble * value) + +void oc_glUniform4dv_noimpl(GLint location, GLsizei count, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform4dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform4dv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glUseProgram_noimpl(GLuint program) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUseProgram is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUseProgram is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribI3iv_noimpl(GLuint index, const GLint * v) + +void oc_glVertexAttribI3iv_noimpl(GLuint index, const GLint* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI3iv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI3iv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDrawElementsIndirect_noimpl(GLenum mode, GLenum type, const void * indirect) + +void oc_glDrawElementsIndirect_noimpl(GLenum mode, GLenum type, const void* indirect) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDrawElementsIndirect is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDrawElementsIndirect is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib4uiv_noimpl(GLuint index, const GLuint * v) + +void oc_glVertexAttrib4uiv_noimpl(GLuint index, const GLuint* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib4uiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib4uiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetQueryObjectiv_noimpl(GLuint id, GLenum pname, GLint * params) + +void oc_glGetQueryObjectiv_noimpl(GLuint id, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetQueryObjectiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetQueryObjectiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glFramebufferRenderbuffer_noimpl(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glFramebufferRenderbuffer is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glFramebufferRenderbuffer is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBlendEquationi_noimpl(GLuint buf, GLenum mode) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBlendEquationi is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBlendEquationi is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetActiveSubroutineName_noimpl(GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei * length, GLchar * name) + +void oc_glGetActiveSubroutineName_noimpl(GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei* length, GLchar* name) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetActiveSubroutineName is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetActiveSubroutineName is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttrib2s_noimpl(GLuint index, GLshort x, GLshort y) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib2s is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib2s is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribL1d_noimpl(GLuint index, GLdouble x) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribL1d is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribL1d is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glBindTextures_noimpl(GLuint first, GLsizei count, const GLuint * textures) + +void oc_glBindTextures_noimpl(GLuint first, GLsizei count, const GLuint* textures) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindTextures is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindTextures is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib3sv_noimpl(GLuint index, const GLshort * v) + +void oc_glVertexAttrib3sv_noimpl(GLuint index, const GLshort* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib3sv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib3sv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetFloati_v_noimpl(GLenum target, GLuint index, GLfloat * data) + +void oc_glGetFloati_v_noimpl(GLenum target, GLuint index, GLfloat* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetFloati_v is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetFloati_v is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBeginTransformFeedback_noimpl(GLenum primitiveMode) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBeginTransformFeedback is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBeginTransformFeedback is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glClearStencil_noimpl(GLint s) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glClearStencil is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glClearStencil is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glUniform3i_noimpl(GLint location, GLint v0, GLint v1, GLint v2) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform3i is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform3i is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glValidateProgramPipeline_noimpl(GLuint pipeline) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glValidateProgramPipeline is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glValidateProgramPipeline is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniformMatrix4x2fv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + +void oc_glProgramUniformMatrix4x2fv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniformMatrix4x2fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniformMatrix4x2fv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribI4ui_noimpl(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI4ui is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI4ui is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetShaderiv_noimpl(GLuint shader, GLenum pname, GLint * params) + +void oc_glGetShaderiv_noimpl(GLuint shader, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetShaderiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetShaderiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glReadnPixels_noimpl(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void * data) + +void oc_glReadnPixels_noimpl(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glReadnPixels is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glReadnPixels is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniformMatrix4x2fv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + +void oc_glUniformMatrix4x2fv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformMatrix4x2fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformMatrix4x2fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetShaderPrecisionFormat_noimpl(GLenum shadertype, GLenum precisiontype, GLint * range, GLint * precision) + +void oc_glGetShaderPrecisionFormat_noimpl(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetShaderPrecisionFormat is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetShaderPrecisionFormat is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniformMatrix2x3fv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + +void oc_glProgramUniformMatrix2x3fv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniformMatrix2x3fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniformMatrix2x3fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glTexSubImage3D_noimpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels) + +void oc_glTexSubImage3D_noimpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* pixels) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexSubImage3D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexSubImage3D is not part of currently selected %s API\n", oc_glAPI->name); + } } -GLint oc_glGetProgramResourceLocationIndex_noimpl(GLuint program, GLenum programInterface, const GLchar * name) + +GLint oc_glGetProgramResourceLocationIndex_noimpl(GLuint program, GLenum programInterface, const GLchar* name) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetProgramResourceLocationIndex is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLint)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetProgramResourceLocationIndex is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLint)0); } + void oc_glBlendFunc_noimpl(GLenum sfactor, GLenum dfactor) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBlendFunc is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBlendFunc is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniformMatrix3x4fv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + +void oc_glProgramUniformMatrix3x4fv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniformMatrix3x4fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniformMatrix3x4fv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glUniform3d_noimpl(GLint location, GLdouble x, GLdouble y, GLdouble z) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform3d is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform3d is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib1sv_noimpl(GLuint index, const GLshort * v) + +void oc_glVertexAttrib1sv_noimpl(GLuint index, const GLshort* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib1sv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib1sv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glBindFragDataLocation_noimpl(GLuint program, GLuint color, const GLchar * name) + +void oc_glBindFragDataLocation_noimpl(GLuint program, GLuint color, const GLchar* name) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindFragDataLocation is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindFragDataLocation is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib4bv_noimpl(GLuint index, const GLbyte * v) + +void oc_glVertexAttrib4bv_noimpl(GLuint index, const GLbyte* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib4bv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib4bv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniform4iv_noimpl(GLint location, GLsizei count, const GLint * value) + +void oc_glUniform4iv_noimpl(GLint location, GLsizei count, const GLint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform4iv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform4iv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glProgramUniform2ui_noimpl(GLuint program, GLint location, GLuint v0, GLuint v1) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform2ui is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform2ui is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDrawArrays_noimpl(GLenum mode, GLint first, GLsizei count) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDrawArrays is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDrawArrays is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramBinary_noimpl(GLuint program, GLenum binaryFormat, const void * binary, GLsizei length) + +void oc_glProgramBinary_noimpl(GLuint program, GLenum binaryFormat, const void* binary, GLsizei length) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramBinary is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramBinary is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttrib4f_noimpl(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib4f is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib4f is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribP2uiv_noimpl(GLuint index, GLenum type, GLboolean normalized, const GLuint * value) + +void oc_glVertexAttribP2uiv_noimpl(GLuint index, GLenum type, GLboolean normalized, const GLuint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribP2uiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribP2uiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniformMatrix3fv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + +void oc_glUniformMatrix3fv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformMatrix3fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformMatrix3fv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glUniform2i_noimpl(GLint location, GLint v0, GLint v1) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform2i is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform2i is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetQueryObjectuiv_noimpl(GLuint id, GLenum pname, GLuint * params) + +void oc_glGetQueryObjectuiv_noimpl(GLuint id, GLenum pname, GLuint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetQueryObjectuiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetQueryObjectuiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glUniformBlockBinding_noimpl(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformBlockBinding is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformBlockBinding is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glSampleCoverage_noimpl(GLfloat value, GLboolean invert) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glSampleCoverage is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glSampleCoverage is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib4Nusv_noimpl(GLuint index, const GLushort * v) + +void oc_glVertexAttrib4Nusv_noimpl(GLuint index, const GLushort* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib4Nusv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib4Nusv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniformMatrix2x4dv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) + +void oc_glProgramUniformMatrix2x4dv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniformMatrix2x4dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniformMatrix2x4dv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniform3uiv_noimpl(GLint location, GLsizei count, const GLuint * value) + +void oc_glUniform3uiv_noimpl(GLint location, GLsizei count, const GLuint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform3uiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform3uiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttrib1s_noimpl(GLuint index, GLshort x) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib1s is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib1s is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetVertexAttribPointerv_noimpl(GLuint index, GLenum pname, void ** pointer) + +void oc_glGetVertexAttribPointerv_noimpl(GLuint index, GLenum pname, void** pointer) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetVertexAttribPointerv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetVertexAttribPointerv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBlendBarrier_noimpl(void) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBlendBarrier is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBlendBarrier is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDrawRangeElements_noimpl(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices) + +void oc_glDrawRangeElements_noimpl(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDrawRangeElements is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDrawRangeElements is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glTexStorage3D_noimpl(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexStorage3D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexStorage3D is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetInternalformati64v_noimpl(GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint64 * params) + +void oc_glGetInternalformati64v_noimpl(GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint64* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetInternalformati64v is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetInternalformati64v is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetQueryObjecti64v_noimpl(GLuint id, GLenum pname, GLint64 * params) + +void oc_glGetQueryObjecti64v_noimpl(GLuint id, GLenum pname, GLint64* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetQueryObjecti64v is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetQueryObjecti64v is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glCompressedTexSubImage1D_noimpl(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * data) + +void oc_glCompressedTexSubImage1D_noimpl(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glCompressedTexSubImage1D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glCompressedTexSubImage1D is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib3dv_noimpl(GLuint index, const GLdouble * v) + +void oc_glVertexAttrib3dv_noimpl(GLuint index, const GLdouble* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib3dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib3dv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexBindingDivisor_noimpl(GLuint bindingindex, GLuint divisor) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexBindingDivisor is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexBindingDivisor is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glUseProgramStages_noimpl(GLuint pipeline, GLbitfield stages, GLuint program) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUseProgramStages is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUseProgramStages is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribBinding_noimpl(GLuint attribindex, GLuint bindingindex) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribBinding is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribBinding is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDebugMessageInsert_noimpl(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar * buf) + +void oc_glDebugMessageInsert_noimpl(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDebugMessageInsert is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDebugMessageInsert is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetTexParameteriv_noimpl(GLenum target, GLenum pname, GLint * params) + +void oc_glGetTexParameteriv_noimpl(GLenum target, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetTexParameteriv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetTexParameteriv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glMultiDrawArraysIndirect_noimpl(GLenum mode, const void * indirect, GLsizei drawcount, GLsizei stride) + +void oc_glMultiDrawArraysIndirect_noimpl(GLenum mode, const void* indirect, GLsizei drawcount, GLsizei stride) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glMultiDrawArraysIndirect is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glMultiDrawArraysIndirect is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetTexParameterfv_noimpl(GLenum target, GLenum pname, GLfloat * params) + +void oc_glGetTexParameterfv_noimpl(GLenum target, GLenum pname, GLfloat* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetTexParameterfv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetTexParameterfv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetProgramPipelineInfoLog_noimpl(GLuint pipeline, GLsizei bufSize, GLsizei * length, GLchar * infoLog) + +void oc_glGetProgramPipelineInfoLog_noimpl(GLuint pipeline, GLsizei bufSize, GLsizei* length, GLchar* infoLog) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetProgramPipelineInfoLog is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetProgramPipelineInfoLog is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glEndQuery_noimpl(GLenum target) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glEndQuery is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glEndQuery is not part of currently selected %s API\n", oc_glAPI->name); + } } -GLint oc_glGetProgramResourceLocation_noimpl(GLuint program, GLenum programInterface, const GLchar * name) + +GLint oc_glGetProgramResourceLocation_noimpl(GLuint program, GLenum programInterface, const GLchar* name) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetProgramResourceLocation is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLint)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetProgramResourceLocation is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLint)0); } -void oc_glCompressedTexImage2D_noimpl(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * data) + +void oc_glCompressedTexImage2D_noimpl(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glCompressedTexImage2D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glCompressedTexImage2D is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribP2ui_noimpl(GLuint index, GLenum type, GLboolean normalized, GLuint value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribP2ui is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribP2ui is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLboolean oc_glIsEnabledi_noimpl(GLenum target, GLuint index) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glIsEnabledi is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLboolean)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glIsEnabledi is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLboolean)0); } -void oc_glGetActiveAtomicCounterBufferiv_noimpl(GLuint program, GLuint bufferIndex, GLenum pname, GLint * params) + +void oc_glGetActiveAtomicCounterBufferiv_noimpl(GLuint program, GLuint bufferIndex, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetActiveAtomicCounterBufferiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetActiveAtomicCounterBufferiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLboolean oc_glIsProgram_noimpl(GLuint program) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glIsProgram is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLboolean)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glIsProgram is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLboolean)0); } -void oc_glUniform1dv_noimpl(GLint location, GLsizei count, const GLdouble * value) + +void oc_glUniform1dv_noimpl(GLint location, GLsizei count, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform1dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform1dv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glTexParameteriv_noimpl(GLenum target, GLenum pname, const GLint * params) + +void oc_glTexParameteriv_noimpl(GLenum target, GLenum pname, const GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexParameteriv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexParameteriv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniform2fv_noimpl(GLint location, GLsizei count, const GLfloat * value) + +void oc_glUniform2fv_noimpl(GLint location, GLsizei count, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform2fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform2fv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glReleaseShaderCompiler_noimpl(void) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glReleaseShaderCompiler is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glReleaseShaderCompiler is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glCullFace_noimpl(GLenum mode) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glCullFace is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glCullFace is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribI4i_noimpl(GLuint index, GLint x, GLint y, GLint z, GLint w) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI4i is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI4i is not part of currently selected %s API\n", oc_glAPI->name); + } } -GLuint oc_glGetProgramResourceIndex_noimpl(GLuint program, GLenum programInterface, const GLchar * name) + +GLuint oc_glGetProgramResourceIndex_noimpl(GLuint program, GLenum programInterface, const GLchar* name) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetProgramResourceIndex is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLuint)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetProgramResourceIndex is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLuint)0); } -void oc_glShaderBinary_noimpl(GLsizei count, const GLuint * shaders, GLenum binaryFormat, const void * binary, GLsizei length) + +void oc_glShaderBinary_noimpl(GLsizei count, const GLuint* shaders, GLenum binaryFormat, const void* binary, GLsizei length) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glShaderBinary is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glShaderBinary is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniformMatrix3x2dv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) + +void oc_glUniformMatrix3x2dv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformMatrix3x2dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformMatrix3x2dv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glInvalidateFramebuffer_noimpl(GLenum target, GLsizei numAttachments, const GLenum * attachments) + +void oc_glInvalidateFramebuffer_noimpl(GLenum target, GLsizei numAttachments, const GLenum* attachments) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glInvalidateFramebuffer is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glInvalidateFramebuffer is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glAttachShader_noimpl(GLuint program, GLuint shader) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glAttachShader is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glAttachShader is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glFlushMappedBufferRange_noimpl(GLenum target, GLintptr offset, GLsizeiptr length) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glFlushMappedBufferRange is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glFlushMappedBufferRange is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribP3uiv_noimpl(GLuint index, GLenum type, GLboolean normalized, const GLuint * value) + +void oc_glVertexAttribP3uiv_noimpl(GLuint index, GLenum type, GLboolean normalized, const GLuint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribP3uiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribP3uiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetActiveUniformName_noimpl(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei * length, GLchar * uniformName) + +void oc_glGetActiveUniformName_noimpl(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformName) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetActiveUniformName is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetActiveUniformName is not part of currently selected %s API\n", oc_glAPI->name); + } } -void * oc_glMapBuffer_noimpl(GLenum target, GLenum access) + +void* oc_glMapBuffer_noimpl(GLenum target, GLenum access) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glMapBuffer is not part of currently selected %s API\n", oc_glAPI->name); - } - return((void *)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glMapBuffer is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((void*)0); } -void oc_glDrawBuffers_noimpl(GLsizei n, const GLenum * bufs) + +void oc_glDrawBuffers_noimpl(GLsizei n, const GLenum* bufs) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDrawBuffers is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDrawBuffers is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetSynciv_noimpl(GLsync sync, GLenum pname, GLsizei count, GLsizei * length, GLint * values) + +void oc_glGetSynciv_noimpl(GLsync sync, GLenum pname, GLsizei count, GLsizei* length, GLint* values) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetSynciv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetSynciv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glCopyTexSubImage2D_noimpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glCopyTexSubImage2D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glCopyTexSubImage2D is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glObjectLabel_noimpl(GLenum identifier, GLuint name, GLsizei length, const GLchar * label) + +void oc_glObjectLabel_noimpl(GLenum identifier, GLuint name, GLsizei length, const GLchar* label) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glObjectLabel is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glObjectLabel is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glBufferSubData_noimpl(GLenum target, GLintptr offset, GLsizeiptr size, const void * data) + +void oc_glBufferSubData_noimpl(GLenum target, GLintptr offset, GLsizeiptr size, const void* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBufferSubData is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBufferSubData is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glUniform2f_noimpl(GLint location, GLfloat v0, GLfloat v1) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform2f is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform2f is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDebugMessageCallback_noimpl(GLDEBUGPROC callback, const void * userParam) + +void oc_glDebugMessageCallback_noimpl(GLDEBUGPROC callback, const void* userParam) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDebugMessageCallback is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDebugMessageCallback is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribL4dv_noimpl(GLuint index, const GLdouble * v) + +void oc_glVertexAttribL4dv_noimpl(GLuint index, const GLdouble* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribL4dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribL4dv is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLboolean oc_glIsProgramPipeline_noimpl(GLuint pipeline) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glIsProgramPipeline is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLboolean)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glIsProgramPipeline is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLboolean)0); } + void oc_glResumeTransformFeedback_noimpl(void) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glResumeTransformFeedback is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glResumeTransformFeedback is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribI4iv_noimpl(GLuint index, const GLint * v) + +void oc_glVertexAttribI4iv_noimpl(GLuint index, const GLint* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI4iv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI4iv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetShaderInfoLog_noimpl(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * infoLog) + +void oc_glGetShaderInfoLog_noimpl(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetShaderInfoLog is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetShaderInfoLog is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetIntegeri_v_noimpl(GLenum target, GLuint index, GLint * data) + +void oc_glGetIntegeri_v_noimpl(GLenum target, GLuint index, GLint* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetIntegeri_v is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetIntegeri_v is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBindVertexBuffer_noimpl(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindVertexBuffer is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindVertexBuffer is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBlendEquation_noimpl(GLenum mode) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBlendEquation is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBlendEquation is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribL2dv_noimpl(GLuint index, const GLdouble * v) + +void oc_glVertexAttribL2dv_noimpl(GLuint index, const GLdouble* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribL2dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribL2dv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribI1ui_noimpl(GLuint index, GLuint x) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI1ui is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI1ui is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib4Nsv_noimpl(GLuint index, const GLshort * v) + +void oc_glVertexAttrib4Nsv_noimpl(GLuint index, const GLshort* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib4Nsv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib4Nsv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribL4d_noimpl(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribL4d is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribL4d is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glCopyImageSubData_noimpl(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glCopyImageSubData is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glCopyImageSubData is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetFramebufferAttachmentParameteriv_noimpl(GLenum target, GLenum attachment, GLenum pname, GLint * params) + +void oc_glGetFramebufferAttachmentParameteriv_noimpl(GLenum target, GLenum attachment, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetFramebufferAttachmentParameteriv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetFramebufferAttachmentParameteriv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribL2d_noimpl(GLuint index, GLdouble x, GLdouble y) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribL2d is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribL2d is not part of currently selected %s API\n", oc_glAPI->name); + } } -GLuint oc_glGetSubroutineIndex_noimpl(GLuint program, GLenum shadertype, const GLchar * name) + +GLuint oc_glGetSubroutineIndex_noimpl(GLuint program, GLenum shadertype, const GLchar* name) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetSubroutineIndex is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLuint)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetSubroutineIndex is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLuint)0); } -void oc_glVertexAttribI3uiv_noimpl(GLuint index, const GLuint * v) + +void oc_glVertexAttribI3uiv_noimpl(GLuint index, const GLuint* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI3uiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI3uiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib4iv_noimpl(GLuint index, const GLint * v) + +void oc_glVertexAttrib4iv_noimpl(GLuint index, const GLint* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib4iv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib4iv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glBindVertexBuffers_noimpl(GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizei * strides) + +void oc_glBindVertexBuffers_noimpl(GLuint first, GLsizei count, const GLuint* buffers, const GLintptr* offsets, const GLsizei* strides) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindVertexBuffers is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindVertexBuffers is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniformMatrix2x3dv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) + +void oc_glProgramUniformMatrix2x3dv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniformMatrix2x3dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniformMatrix2x3dv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glPrimitiveBoundingBox_noimpl(GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glPrimitiveBoundingBox is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glPrimitiveBoundingBox is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glScissor_noimpl(GLint x, GLint y, GLsizei width, GLsizei height) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glScissor is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glScissor is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLenum oc_glClientWaitSync_noimpl(GLsync sync, GLbitfield flags, GLuint64 timeout) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glClientWaitSync is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLenum)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glClientWaitSync is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLenum)0); } + void oc_glUniform3ui_noimpl(GLint location, GLuint v0, GLuint v1, GLuint v2) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform3ui is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform3ui is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribP3ui_noimpl(GLuint index, GLenum type, GLboolean normalized, GLuint value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribP3ui is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribP3ui is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glEnable_noimpl(GLenum cap) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glEnable is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glEnable is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glStencilOpSeparate_noimpl(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glStencilOpSeparate is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glStencilOpSeparate is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniformMatrix2x3dv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) + +void oc_glUniformMatrix2x3dv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformMatrix2x3dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformMatrix2x3dv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniformMatrix3dv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) + +void oc_glProgramUniformMatrix3dv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniformMatrix3dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniformMatrix3dv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glTexImage2DMultisample_noimpl(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexImage2DMultisample is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexImage2DMultisample is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib4Nbv_noimpl(GLuint index, const GLbyte * v) + +void oc_glVertexAttrib4Nbv_noimpl(GLuint index, const GLbyte* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib4Nbv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib4Nbv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetTexImage_noimpl(GLenum target, GLint level, GLenum format, GLenum type, void * pixels) + +void oc_glGetTexImage_noimpl(GLenum target, GLint level, GLenum format, GLenum type, void* pixels) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetTexImage is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetTexImage is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib4sv_noimpl(GLuint index, const GLshort * v) + +void oc_glVertexAttrib4sv_noimpl(GLuint index, const GLshort* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib4sv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib4sv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glPixelStorei_noimpl(GLenum pname, GLint param) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glPixelStorei is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glPixelStorei is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDepthMask_noimpl(GLboolean flag) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDepthMask is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDepthMask is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glTexStorage2D_noimpl(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexStorage2D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexStorage2D is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glClear_noimpl(GLbitfield mask) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glClear is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glClear is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniformMatrix3x4dv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) + +void oc_glUniformMatrix3x4dv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformMatrix3x4dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformMatrix3x4dv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDeleteTransformFeedbacks_noimpl(GLsizei n, const GLuint * ids) + +void oc_glDeleteTransformFeedbacks_noimpl(GLsizei n, const GLuint* ids) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDeleteTransformFeedbacks is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDeleteTransformFeedbacks is not part of currently selected %s API\n", oc_glAPI->name); + } } -void * oc_glMapBufferRange_noimpl(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) + +void* oc_glMapBufferRange_noimpl(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glMapBufferRange is not part of currently selected %s API\n", oc_glAPI->name); - } - return((void *)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glMapBufferRange is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((void*)0); } + void oc_glMemoryBarrier_noimpl(GLbitfield barriers) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glMemoryBarrier is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glMemoryBarrier is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glViewportIndexedf_noimpl(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glViewportIndexedf is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glViewportIndexedf is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib3fv_noimpl(GLuint index, const GLfloat * v) + +void oc_glVertexAttrib3fv_noimpl(GLuint index, const GLfloat* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib3fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib3fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glObjectPtrLabel_noimpl(const void * ptr, GLsizei length, const GLchar * label) + +void oc_glObjectPtrLabel_noimpl(const void* ptr, GLsizei length, const GLchar* label) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glObjectPtrLabel is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glObjectPtrLabel is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glTexStorage1D_noimpl(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexStorage1D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexStorage1D is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glCompressedTexImage3D_noimpl(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data) + +void oc_glCompressedTexImage3D_noimpl(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glCompressedTexImage3D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glCompressedTexImage3D is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib1fv_noimpl(GLuint index, const GLfloat * v) + +void oc_glVertexAttrib1fv_noimpl(GLuint index, const GLfloat* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib1fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib1fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribPointer_noimpl(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer) + +void oc_glVertexAttribPointer_noimpl(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribPointer is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribPointer is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetQueryIndexediv_noimpl(GLenum target, GLuint index, GLenum pname, GLint * params) + +void oc_glGetQueryIndexediv_noimpl(GLenum target, GLuint index, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetQueryIndexediv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetQueryIndexediv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glCompileShader_noimpl(GLuint shader) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glCompileShader is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glCompileShader is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glProgramUniform1i_noimpl(GLuint program, GLint location, GLint v0) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform1i is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform1i is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetQueryiv_noimpl(GLenum target, GLenum pname, GLint * params) + +void oc_glGetQueryiv_noimpl(GLenum target, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetQueryiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetQueryiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribI1iv_noimpl(GLuint index, const GLint * v) + +void oc_glVertexAttribI1iv_noimpl(GLuint index, const GLint* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI1iv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI1iv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glCopyTexImage2D_noimpl(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glCopyTexImage2D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glCopyTexImage2D is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetQueryObjectui64v_noimpl(GLuint id, GLenum pname, GLuint64 * params) + +void oc_glGetQueryObjectui64v_noimpl(GLuint id, GLenum pname, GLuint64* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetQueryObjectui64v is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetQueryObjectui64v is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glPointSize_noimpl(GLfloat size) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glPointSize is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glPointSize is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDisablei_noimpl(GLenum target, GLuint index) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDisablei is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDisablei is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribL1dv_noimpl(GLuint index, const GLdouble * v) + +void oc_glVertexAttribL1dv_noimpl(GLuint index, const GLdouble* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribL1dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribL1dv is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLuint oc_glCreateShader_noimpl(GLenum type) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glCreateShader is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLuint)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glCreateShader is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLuint)0); } -const GLubyte * oc_glGetString_noimpl(GLenum name) + +const GLubyte* oc_glGetString_noimpl(GLenum name) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetString is not part of currently selected %s API\n", oc_glAPI->name); - } - return((const GLubyte *)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetString is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((const GLubyte*)0); } -void oc_glViewportArrayv_noimpl(GLuint first, GLsizei count, const GLfloat * v) + +void oc_glViewportArrayv_noimpl(GLuint first, GLsizei count, const GLfloat* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glViewportArrayv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glViewportArrayv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glProgramUniform3d_noimpl(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform3d is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform3d is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib4Nubv_noimpl(GLuint index, const GLubyte * v) + +void oc_glVertexAttrib4Nubv_noimpl(GLuint index, const GLubyte* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib4Nubv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib4Nubv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glTexParameteri_noimpl(GLenum target, GLenum pname, GLint param) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexParameteri is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexParameteri is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniform4fv_noimpl(GLuint program, GLint location, GLsizei count, const GLfloat * value) + +void oc_glProgramUniform4fv_noimpl(GLuint program, GLint location, GLsizei count, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform4fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform4fv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glGenerateMipmap_noimpl(GLenum target) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGenerateMipmap is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGenerateMipmap is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glCompressedTexSubImage3D_noimpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data) + +void oc_glCompressedTexSubImage3D_noimpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glCompressedTexSubImage3D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glCompressedTexSubImage3D is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glUniform3f_noimpl(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform3f is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform3f is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetUniformIndices_noimpl(GLuint program, GLsizei uniformCount, const GLchar *const* uniformNames, GLuint * uniformIndices) + +void oc_glGetUniformIndices_noimpl(GLuint program, GLsizei uniformCount, const GLchar* const* uniformNames, GLuint* uniformIndices) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetUniformIndices is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetUniformIndices is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribLPointer_noimpl(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer) + +void oc_glVertexAttribLPointer_noimpl(GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribLPointer is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribLPointer is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribI2uiv_noimpl(GLuint index, const GLuint * v) + +void oc_glVertexAttribI2uiv_noimpl(GLuint index, const GLuint* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI2uiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI2uiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glQueryCounter_noimpl(GLuint id, GLenum target) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glQueryCounter is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glQueryCounter is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glActiveShaderProgram_noimpl(GLuint pipeline, GLuint program) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glActiveShaderProgram is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glActiveShaderProgram is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glUniform1ui_noimpl(GLint location, GLuint v0) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform1ui is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform1ui is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribI1i_noimpl(GLuint index, GLint x) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI1i is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI1i is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetTexParameterIiv_noimpl(GLenum target, GLenum pname, GLint * params) + +void oc_glGetTexParameterIiv_noimpl(GLenum target, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetTexParameterIiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetTexParameterIiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetUniformfv_noimpl(GLuint program, GLint location, GLfloat * params) + +void oc_glGetUniformfv_noimpl(GLuint program, GLint location, GLfloat* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetUniformfv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetUniformfv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniform2uiv_noimpl(GLuint program, GLint location, GLsizei count, const GLuint * value) + +void oc_glProgramUniform2uiv_noimpl(GLuint program, GLint location, GLsizei count, const GLuint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform2uiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform2uiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLenum oc_glGetError_noimpl(void) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetError is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLenum)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetError is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLenum)0); } -void oc_glGetActiveUniformBlockName_noimpl(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei * length, GLchar * uniformBlockName) + +void oc_glGetActiveUniformBlockName_noimpl(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei* length, GLchar* uniformBlockName) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetActiveUniformBlockName is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetActiveUniformBlockName is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glTextureView_noimpl(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTextureView is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTextureView is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetnUniformiv_noimpl(GLuint program, GLint location, GLsizei bufSize, GLint * params) + +void oc_glGetnUniformiv_noimpl(GLuint program, GLint location, GLsizei bufSize, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetnUniformiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetnUniformiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniform4dv_noimpl(GLuint program, GLint location, GLsizei count, const GLdouble * value) + +void oc_glProgramUniform4dv_noimpl(GLuint program, GLint location, GLsizei count, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform4dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform4dv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glViewportIndexedfv_noimpl(GLuint index, const GLfloat * v) + +void oc_glViewportIndexedfv_noimpl(GLuint index, const GLfloat* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glViewportIndexedfv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glViewportIndexedfv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glHint_noimpl(GLenum target, GLenum mode) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glHint is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glHint is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetShaderSource_noimpl(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * source) + +void oc_glGetShaderSource_noimpl(GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* source) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetShaderSource is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetShaderSource is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniformMatrix4x3fv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + +void oc_glProgramUniformMatrix4x3fv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniformMatrix4x3fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniformMatrix4x3fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniform1iv_noimpl(GLint location, GLsizei count, const GLint * value) + +void oc_glUniform1iv_noimpl(GLint location, GLsizei count, const GLint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform1iv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform1iv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribI4bv_noimpl(GLuint index, const GLbyte * v) + +void oc_glVertexAttribI4bv_noimpl(GLuint index, const GLbyte* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI4bv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI4bv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniformMatrix4x2dv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) + +void oc_glUniformMatrix4x2dv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformMatrix4x2dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformMatrix4x2dv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glBufferStorage_noimpl(GLenum target, GLsizeiptr size, const void * data, GLbitfield flags) + +void oc_glBufferStorage_noimpl(GLenum target, GLsizeiptr size, const void* data, GLbitfield flags) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBufferStorage is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBufferStorage is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLboolean oc_glIsRenderbuffer_noimpl(GLuint renderbuffer) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glIsRenderbuffer is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLboolean)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glIsRenderbuffer is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLboolean)0); } -void oc_glGetActiveSubroutineUniformName_noimpl(GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei * length, GLchar * name) + +void oc_glGetActiveSubroutineUniformName_noimpl(GLuint program, GLenum shadertype, GLuint index, GLsizei bufSize, GLsizei* length, GLchar* name) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetActiveSubroutineUniformName is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetActiveSubroutineUniformName is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glLinkProgram_noimpl(GLuint program) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glLinkProgram is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glLinkProgram is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetActiveUniformsiv_noimpl(GLuint program, GLsizei uniformCount, const GLuint * uniformIndices, GLenum pname, GLint * params) + +void oc_glGetActiveUniformsiv_noimpl(GLuint program, GLsizei uniformCount, const GLuint* uniformIndices, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetActiveUniformsiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetActiveUniformsiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -GLuint oc_glGetDebugMessageLog_noimpl(GLuint count, GLsizei bufSize, GLenum * sources, GLenum * types, GLuint * ids, GLenum * severities, GLsizei * lengths, GLchar * messageLog) + +GLuint oc_glGetDebugMessageLog_noimpl(GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetDebugMessageLog is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLuint)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetDebugMessageLog is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLuint)0); } + void oc_glCopyTexSubImage3D_noimpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glCopyTexSubImage3D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glCopyTexSubImage3D is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glPointParameteri_noimpl(GLenum pname, GLint param) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glPointParameteri is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glPointParameteri is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniform3dv_noimpl(GLuint program, GLint location, GLsizei count, const GLdouble * value) + +void oc_glProgramUniform3dv_noimpl(GLuint program, GLint location, GLsizei count, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform3dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform3dv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glCompressedTexImage1D_noimpl(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void * data) + +void oc_glCompressedTexImage1D_noimpl(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glCompressedTexImage1D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glCompressedTexImage1D is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniformMatrix3x4fv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + +void oc_glUniformMatrix3x4fv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformMatrix3x4fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformMatrix3x4fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGenSamplers_noimpl(GLsizei count, GLuint * samplers) + +void oc_glGenSamplers_noimpl(GLsizei count, GLuint* samplers) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGenSamplers is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGenSamplers is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetCompressedTexImage_noimpl(GLenum target, GLint level, void * img) + +void oc_glGetCompressedTexImage_noimpl(GLenum target, GLint level, void* img) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetCompressedTexImage is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetCompressedTexImage is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDeleteQueries_noimpl(GLsizei n, const GLuint * ids) + +void oc_glDeleteQueries_noimpl(GLsizei n, const GLuint* ids) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDeleteQueries is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDeleteQueries is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGenProgramPipelines_noimpl(GLsizei n, GLuint * pipelines) + +void oc_glGenProgramPipelines_noimpl(GLsizei n, GLuint* pipelines) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGenProgramPipelines is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGenProgramPipelines is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDispatchComputeIndirect_noimpl(GLintptr indirect) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDispatchComputeIndirect is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDispatchComputeIndirect is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribIPointer_noimpl(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer) + +void oc_glVertexAttribIPointer_noimpl(GLuint index, GLint size, GLenum type, GLsizei stride, const void* pointer) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribIPointer is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribIPointer is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLuint oc_glCreateProgram_noimpl(void) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glCreateProgram is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLuint)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glCreateProgram is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLuint)0); } -void oc_glClearTexSubImage_noimpl(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * data) + +void oc_glClearTexSubImage_noimpl(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glClearTexSubImage is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glClearTexSubImage is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttrib4d_noimpl(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib4d is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib4d is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glFrontFace_noimpl(GLenum mode) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glFrontFace is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glFrontFace is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBindTransformFeedback_noimpl(GLenum target, GLuint id) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindTransformFeedback is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindTransformFeedback is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetProgramStageiv_noimpl(GLuint program, GLenum shadertype, GLenum pname, GLint * values) + +void oc_glGetProgramStageiv_noimpl(GLuint program, GLenum shadertype, GLenum pname, GLint* values) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetProgramStageiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetProgramStageiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glSamplerParameterIiv_noimpl(GLuint sampler, GLenum pname, const GLint * param) + +void oc_glSamplerParameterIiv_noimpl(GLuint sampler, GLenum pname, const GLint* param) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glSamplerParameterIiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glSamplerParameterIiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetInteger64v_noimpl(GLenum pname, GLint64 * data) + +void oc_glGetInteger64v_noimpl(GLenum pname, GLint64* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetInteger64v is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetInteger64v is not part of currently selected %s API\n", oc_glAPI->name); + } } -GLuint oc_glCreateShaderProgramv_noimpl(GLenum type, GLsizei count, const GLchar *const* strings) + +GLuint oc_glCreateShaderProgramv_noimpl(GLenum type, GLsizei count, const GLchar* const* strings) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glCreateShaderProgramv is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLuint)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glCreateShaderProgramv is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLuint)0); } -void oc_glBindBuffersRange_noimpl(GLenum target, GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizeiptr * sizes) + +void oc_glBindBuffersRange_noimpl(GLenum target, GLuint first, GLsizei count, const GLuint* buffers, const GLintptr* offsets, const GLsizeiptr* sizes) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindBuffersRange is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindBuffersRange is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniform3fv_noimpl(GLint location, GLsizei count, const GLfloat * value) + +void oc_glUniform3fv_noimpl(GLint location, GLsizei count, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform3fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform3fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniformMatrix4fv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + +void oc_glProgramUniformMatrix4fv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniformMatrix4fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniformMatrix4fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glBindBuffersBase_noimpl(GLenum target, GLuint first, GLsizei count, const GLuint * buffers) + +void oc_glBindBuffersBase_noimpl(GLenum target, GLuint first, GLsizei count, const GLuint* buffers) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindBuffersBase is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindBuffersBase is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glClearBufferfi_noimpl(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glClearBufferfi is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glClearBufferfi is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glFramebufferTexture3D_noimpl(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glFramebufferTexture3D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glFramebufferTexture3D is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDisable_noimpl(GLenum cap) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDisable is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDisable is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniform1iv_noimpl(GLuint program, GLint location, GLsizei count, const GLint * value) + +void oc_glProgramUniform1iv_noimpl(GLuint program, GLint location, GLsizei count, const GLint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform1iv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform1iv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribI2iv_noimpl(GLuint index, const GLint * v) + +void oc_glVertexAttribI2iv_noimpl(GLuint index, const GLint* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI2iv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI2iv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDepthRangeIndexed_noimpl(GLuint index, GLdouble n, GLdouble f) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDepthRangeIndexed is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDepthRangeIndexed is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glPatchParameteri_noimpl(GLenum pname, GLint value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glPatchParameteri is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glPatchParameteri is not part of currently selected %s API\n", oc_glAPI->name); + } } -GLuint oc_glGetUniformBlockIndex_noimpl(GLuint program, const GLchar * uniformBlockName) + +GLuint oc_glGetUniformBlockIndex_noimpl(GLuint program, const GLchar* uniformBlockName) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetUniformBlockIndex is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLuint)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetUniformBlockIndex is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLuint)0); } -void oc_glMultiDrawArrays_noimpl(GLenum mode, const GLint * first, const GLsizei * count, GLsizei drawcount) + +void oc_glMultiDrawArrays_noimpl(GLenum mode, const GLint* first, const GLsizei* count, GLsizei drawcount) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glMultiDrawArrays is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glMultiDrawArrays is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribI4ubv_noimpl(GLuint index, const GLubyte * v) + +void oc_glVertexAttribI4ubv_noimpl(GLuint index, const GLubyte* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI4ubv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI4ubv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBindBuffer_noimpl(GLenum target, GLuint buffer) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindBuffer is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindBuffer is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribI3i_noimpl(GLuint index, GLint x, GLint y, GLint z) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI3i is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI3i is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetDoublev_noimpl(GLenum pname, GLdouble * data) + +void oc_glGetDoublev_noimpl(GLenum pname, GLdouble* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetDoublev is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetDoublev is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDrawTransformFeedbackStream_noimpl(GLenum mode, GLuint id, GLuint stream) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDrawTransformFeedbackStream is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDrawTransformFeedbackStream is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribI4uiv_noimpl(GLuint index, const GLuint * v) + +void oc_glVertexAttribI4uiv_noimpl(GLuint index, const GLuint* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI4uiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI4uiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glRenderbufferStorageMultisample_noimpl(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glRenderbufferStorageMultisample is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glRenderbufferStorageMultisample is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribL3dv_noimpl(GLuint index, const GLdouble * v) + +void oc_glVertexAttribL3dv_noimpl(GLuint index, const GLdouble* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribL3dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribL3dv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glStencilMaskSeparate_noimpl(GLenum face, GLuint mask) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glStencilMaskSeparate is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glStencilMaskSeparate is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glProgramUniform1d_noimpl(GLuint program, GLint location, GLdouble v0) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform1d is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform1d is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glViewport_noimpl(GLint x, GLint y, GLsizei width, GLsizei height) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glViewport is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glViewport is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribP1ui_noimpl(GLuint index, GLenum type, GLboolean normalized, GLuint value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribP1ui is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribP1ui is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib4dv_noimpl(GLuint index, const GLdouble * v) + +void oc_glVertexAttrib4dv_noimpl(GLuint index, const GLdouble* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib4dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib4dv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGenQueries_noimpl(GLsizei n, GLuint * ids) + +void oc_glGenQueries_noimpl(GLsizei n, GLuint* ids) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGenQueries is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGenQueries is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glTexParameterIiv_noimpl(GLenum target, GLenum pname, const GLint * params) + +void oc_glTexParameterIiv_noimpl(GLenum target, GLenum pname, const GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexParameterIiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexParameterIiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glProgramUniform2d_noimpl(GLuint program, GLint location, GLdouble v0, GLdouble v1) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform2d is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform2d is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniform1uiv_noimpl(GLuint program, GLint location, GLsizei count, const GLuint * value) + +void oc_glProgramUniform1uiv_noimpl(GLuint program, GLint location, GLsizei count, const GLuint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform1uiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform1uiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttrib4Nub_noimpl(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib4Nub is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib4Nub is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLboolean oc_glIsVertexArray_noimpl(GLuint array) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glIsVertexArray is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLboolean)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glIsVertexArray is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLboolean)0); } + void oc_glProgramUniform3f_noimpl(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform3f is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform3f is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniform3iv_noimpl(GLuint program, GLint location, GLsizei count, const GLint * value) + +void oc_glProgramUniform3iv_noimpl(GLuint program, GLint location, GLsizei count, const GLint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform3iv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform3iv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetProgramBinary_noimpl(GLuint program, GLsizei bufSize, GLsizei * length, GLenum * binaryFormat, void * binary) + +void oc_glGetProgramBinary_noimpl(GLuint program, GLsizei bufSize, GLsizei* length, GLenum* binaryFormat, void* binary) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetProgramBinary is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetProgramBinary is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBindRenderbuffer_noimpl(GLenum target, GLuint renderbuffer) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindRenderbuffer is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindRenderbuffer is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glBindFragDataLocationIndexed_noimpl(GLuint program, GLuint colorNumber, GLuint index, const GLchar * name) + +void oc_glBindFragDataLocationIndexed_noimpl(GLuint program, GLuint colorNumber, GLuint index, const GLchar* name) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindFragDataLocationIndexed is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindFragDataLocationIndexed is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetSamplerParameterIiv_noimpl(GLuint sampler, GLenum pname, GLint * params) + +void oc_glGetSamplerParameterIiv_noimpl(GLuint sampler, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetSamplerParameterIiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetSamplerParameterIiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribDivisor_noimpl(GLuint index, GLuint divisor) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribDivisor is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribDivisor is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniformMatrix3x2dv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) + +void oc_glProgramUniformMatrix3x2dv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniformMatrix3x2dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniformMatrix3x2dv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glFramebufferParameteri_noimpl(GLenum target, GLenum pname, GLint param) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glFramebufferParameteri is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glFramebufferParameteri is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGenTransformFeedbacks_noimpl(GLsizei n, GLuint * ids) + +void oc_glGenTransformFeedbacks_noimpl(GLsizei n, GLuint* ids) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGenTransformFeedbacks is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGenTransformFeedbacks is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDeleteSync_noimpl(GLsync sync) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDeleteSync is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDeleteSync is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glProgramUniform1ui_noimpl(GLuint program, GLint location, GLuint v0) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform1ui is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform1ui is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glTexSubImage1D_noimpl(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels) + +void oc_glTexSubImage1D_noimpl(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void* pixels) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexSubImage1D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexSubImage1D is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glClearDepthf_noimpl(GLfloat d) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glClearDepthf is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glClearDepthf is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glReadPixels_noimpl(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * pixels) + +void oc_glReadPixels_noimpl(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void* pixels) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glReadPixels is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glReadPixels is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribI2i_noimpl(GLuint index, GLint x, GLint y) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI2i is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI2i is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glFinish_noimpl(void) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glFinish is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glFinish is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glLineWidth_noimpl(GLfloat width) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glLineWidth is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glLineWidth is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDeleteShader_noimpl(GLuint shader) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDeleteShader is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDeleteShader is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLboolean oc_glIsSampler_noimpl(GLuint sampler) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glIsSampler is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLboolean)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glIsSampler is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLboolean)0); } -void oc_glProgramUniformMatrix4dv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) + +void oc_glProgramUniformMatrix4dv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniformMatrix4dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniformMatrix4dv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glTransformFeedbackVaryings_noimpl(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode) + +void oc_glTransformFeedbackVaryings_noimpl(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTransformFeedbackVaryings is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTransformFeedbackVaryings is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBeginConditionalRender_noimpl(GLuint id, GLenum mode) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBeginConditionalRender is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBeginConditionalRender is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glBindSamplers_noimpl(GLuint first, GLsizei count, const GLuint * samplers) + +void oc_glBindSamplers_noimpl(GLuint first, GLsizei count, const GLuint* samplers) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindSamplers is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindSamplers is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDeleteProgramPipelines_noimpl(GLsizei n, const GLuint * pipelines) + +void oc_glDeleteProgramPipelines_noimpl(GLsizei n, const GLuint* pipelines) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDeleteProgramPipelines is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDeleteProgramPipelines is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glColorMask_noimpl(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glColorMask is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glColorMask is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glTexParameterfv_noimpl(GLenum target, GLenum pname, const GLfloat * params) + +void oc_glTexParameterfv_noimpl(GLenum target, GLenum pname, const GLfloat* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexParameterfv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexParameterfv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glPushDebugGroup_noimpl(GLenum source, GLuint id, GLsizei length, const GLchar * message) + +void oc_glPushDebugGroup_noimpl(GLenum source, GLuint id, GLsizei length, const GLchar* message) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glPushDebugGroup is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glPushDebugGroup is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glClearBufferfv_noimpl(GLenum buffer, GLint drawbuffer, const GLfloat * value) + +void oc_glClearBufferfv_noimpl(GLenum buffer, GLint drawbuffer, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glClearBufferfv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glClearBufferfv is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLboolean oc_glIsEnabled_noimpl(GLenum cap) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glIsEnabled is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLboolean)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glIsEnabled is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLboolean)0); } + void oc_glVertexAttrib2f_noimpl(GLuint index, GLfloat x, GLfloat y) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib2f is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib2f is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glProgramUniform2f_noimpl(GLuint program, GLint location, GLfloat v0, GLfloat v1) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform2f is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform2f is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetSamplerParameterIuiv_noimpl(GLuint sampler, GLenum pname, GLuint * params) + +void oc_glGetSamplerParameterIuiv_noimpl(GLuint sampler, GLenum pname, GLuint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetSamplerParameterIuiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetSamplerParameterIuiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetInteger64i_v_noimpl(GLenum target, GLuint index, GLint64 * data) + +void oc_glGetInteger64i_v_noimpl(GLenum target, GLuint index, GLint64* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetInteger64i_v is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetInteger64i_v is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniform2dv_noimpl(GLint location, GLsizei count, const GLdouble * value) + +void oc_glUniform2dv_noimpl(GLint location, GLsizei count, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform2dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform2dv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetBufferSubData_noimpl(GLenum target, GLintptr offset, GLsizeiptr size, void * data) + +void oc_glGetBufferSubData_noimpl(GLenum target, GLintptr offset, GLsizeiptr size, void* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetBufferSubData is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetBufferSubData is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glMultiDrawElementsIndirect_noimpl(GLenum mode, GLenum type, const void * indirect, GLsizei drawcount, GLsizei stride) + +void oc_glMultiDrawElementsIndirect_noimpl(GLenum mode, GLenum type, const void* indirect, GLsizei drawcount, GLsizei stride) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glMultiDrawElementsIndirect is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glMultiDrawElementsIndirect is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glProgramParameteri_noimpl(GLuint program, GLenum pname, GLint value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramParameteri is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramParameteri is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribP4ui_noimpl(GLuint index, GLenum type, GLboolean normalized, GLuint value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribP4ui is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribP4ui is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glSamplerParameterfv_noimpl(GLuint sampler, GLenum pname, const GLfloat * param) + +void oc_glSamplerParameterfv_noimpl(GLuint sampler, GLenum pname, const GLfloat* param) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glSamplerParameterfv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glSamplerParameterfv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glPointParameterf_noimpl(GLenum pname, GLfloat param) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glPointParameterf is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glPointParameterf is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniformMatrix2x4fv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + +void oc_glUniformMatrix2x4fv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformMatrix2x4fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformMatrix2x4fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGenBuffers_noimpl(GLsizei n, GLuint * buffers) + +void oc_glGenBuffers_noimpl(GLsizei n, GLuint* buffers) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGenBuffers is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGenBuffers is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniform2dv_noimpl(GLuint program, GLint location, GLsizei count, const GLdouble * value) + +void oc_glProgramUniform2dv_noimpl(GLuint program, GLint location, GLsizei count, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform2dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform2dv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribFormat_noimpl(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribFormat is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribFormat is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glTexSubImage2D_noimpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels) + +void oc_glTexSubImage2D_noimpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexSubImage2D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexSubImage2D is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib4ubv_noimpl(GLuint index, const GLubyte * v) + +void oc_glVertexAttrib4ubv_noimpl(GLuint index, const GLubyte* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib4ubv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib4ubv is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLenum oc_glGetGraphicsResetStatus_noimpl(void) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetGraphicsResetStatus is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLenum)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetGraphicsResetStatus is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLenum)0); } -void oc_glGetProgramInterfaceiv_noimpl(GLuint program, GLenum programInterface, GLenum pname, GLint * params) + +void oc_glGetProgramInterfaceiv_noimpl(GLuint program, GLenum programInterface, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetProgramInterfaceiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetProgramInterfaceiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribIFormat_noimpl(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribIFormat is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribIFormat is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetnUniformfv_noimpl(GLuint program, GLint location, GLsizei bufSize, GLfloat * params) + +void oc_glGetnUniformfv_noimpl(GLuint program, GLint location, GLsizei bufSize, GLfloat* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetnUniformfv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetnUniformfv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDeleteProgram_noimpl(GLuint program) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDeleteProgram is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDeleteProgram is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glClampColor_noimpl(GLenum target, GLenum clamp) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glClampColor is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glClampColor is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDrawElementsInstancedBaseVertexBaseInstance_noimpl(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance) + +void oc_glDrawElementsInstancedBaseVertexBaseInstance_noimpl(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDrawElementsInstancedBaseVertexBaseInstance is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDrawElementsInstancedBaseVertexBaseInstance is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDrawElements_noimpl(GLenum mode, GLsizei count, GLenum type, const void * indices) + +void oc_glDrawElements_noimpl(GLenum mode, GLsizei count, GLenum type, const void* indices) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDrawElements is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDrawElements is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDebugMessageControl_noimpl(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled) + +void oc_glDebugMessageControl_noimpl(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDebugMessageControl is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDebugMessageControl is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetRenderbufferParameteriv_noimpl(GLenum target, GLenum pname, GLint * params) + +void oc_glGetRenderbufferParameteriv_noimpl(GLenum target, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetRenderbufferParameteriv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetRenderbufferParameteriv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDetachShader_noimpl(GLuint program, GLuint shader) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDetachShader is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDetachShader is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGenFramebuffers_noimpl(GLsizei n, GLuint * framebuffers) + +void oc_glGenFramebuffers_noimpl(GLsizei n, GLuint* framebuffers) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGenFramebuffers is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGenFramebuffers is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glProvokingVertex_noimpl(GLenum mode) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProvokingVertex is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProvokingVertex is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glSampleMaski_noimpl(GLuint maskNumber, GLbitfield mask) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glSampleMaski is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glSampleMaski is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glEndQueryIndexed_noimpl(GLenum target, GLuint index) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glEndQueryIndexed is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glEndQueryIndexed is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glProgramUniform1f_noimpl(GLuint program, GLint location, GLfloat v0) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform1f is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform1f is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBindFramebuffer_noimpl(GLenum target, GLuint framebuffer) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindFramebuffer is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindFramebuffer is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBeginQueryIndexed_noimpl(GLenum target, GLuint index, GLuint id) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBeginQueryIndexed is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBeginQueryIndexed is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniformSubroutinesuiv_noimpl(GLenum shadertype, GLsizei count, const GLuint * indices) + +void oc_glUniformSubroutinesuiv_noimpl(GLenum shadertype, GLsizei count, const GLuint* indices) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformSubroutinesuiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformSubroutinesuiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetUniformiv_noimpl(GLuint program, GLint location, GLint * params) + +void oc_glGetUniformiv_noimpl(GLuint program, GLint location, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetUniformiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetUniformiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glFramebufferTexture_noimpl(GLenum target, GLenum attachment, GLuint texture, GLint level) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glFramebufferTexture is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glFramebufferTexture is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glPointParameterfv_noimpl(GLenum pname, const GLfloat * params) + +void oc_glPointParameterfv_noimpl(GLenum pname, const GLfloat* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glPointParameterfv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glPointParameterfv is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLboolean oc_glIsTransformFeedback_noimpl(GLuint id) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glIsTransformFeedback is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLboolean)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glIsTransformFeedback is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLboolean)0); } + GLenum oc_glCheckFramebufferStatus_noimpl(GLenum target) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glCheckFramebufferStatus is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLenum)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glCheckFramebufferStatus is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLenum)0); } -void oc_glShaderSource_noimpl(GLuint shader, GLsizei count, const GLchar *const* string, const GLint * length) + +void oc_glShaderSource_noimpl(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glShaderSource is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glShaderSource is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniformMatrix2x4dv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) + +void oc_glUniformMatrix2x4dv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformMatrix2x4dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformMatrix2x4dv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glBindImageTextures_noimpl(GLuint first, GLsizei count, const GLuint * textures) + +void oc_glBindImageTextures_noimpl(GLuint first, GLsizei count, const GLuint* textures) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindImageTextures is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindImageTextures is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glCopyTexImage1D_noimpl(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glCopyTexImage1D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glCopyTexImage1D is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniformMatrix3dv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) + +void oc_glUniformMatrix3dv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformMatrix3dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformMatrix3dv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniform1dv_noimpl(GLuint program, GLint location, GLsizei count, const GLdouble * value) + +void oc_glProgramUniform1dv_noimpl(GLuint program, GLint location, GLsizei count, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform1dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform1dv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBlitFramebuffer_noimpl(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBlitFramebuffer is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBlitFramebuffer is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glPopDebugGroup_noimpl(void) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glPopDebugGroup is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glPopDebugGroup is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glTexParameterIuiv_noimpl(GLenum target, GLenum pname, const GLuint * params) + +void oc_glTexParameterIuiv_noimpl(GLenum target, GLenum pname, const GLuint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexParameterIuiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexParameterIuiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttrib2d_noimpl(GLuint index, GLdouble x, GLdouble y) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib2d is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib2d is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glTexImage1D_noimpl(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void * pixels) + +void oc_glTexImage1D_noimpl(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void* pixels) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexImage1D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexImage1D is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetObjectPtrLabel_noimpl(const void * ptr, GLsizei bufSize, GLsizei * length, GLchar * label) + +void oc_glGetObjectPtrLabel_noimpl(const void* ptr, GLsizei bufSize, GLsizei* length, GLchar* label) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetObjectPtrLabel is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetObjectPtrLabel is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glStencilMask_noimpl(GLuint mask) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glStencilMask is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glStencilMask is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBeginQuery_noimpl(GLenum target, GLuint id) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBeginQuery is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBeginQuery is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniformMatrix4fv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + +void oc_glUniformMatrix4fv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformMatrix4fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformMatrix4fv is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLboolean oc_glIsSync_noimpl(GLsync sync) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glIsSync is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLboolean)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glIsSync is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLboolean)0); } -void oc_glUniform3dv_noimpl(GLint location, GLsizei count, const GLdouble * value) + +void oc_glUniform3dv_noimpl(GLint location, GLsizei count, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform3dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform3dv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniform2fv_noimpl(GLuint program, GLint location, GLsizei count, const GLfloat * value) + +void oc_glProgramUniform2fv_noimpl(GLuint program, GLint location, GLsizei count, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform2fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform2fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribI4sv_noimpl(GLuint index, const GLshort * v) + +void oc_glVertexAttribI4sv_noimpl(GLuint index, const GLshort* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI4sv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI4sv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glScissorArrayv_noimpl(GLuint first, GLsizei count, const GLint * v) + +void oc_glScissorArrayv_noimpl(GLuint first, GLsizei count, const GLint* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glScissorArrayv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glScissorArrayv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribP1uiv_noimpl(GLuint index, GLenum type, GLboolean normalized, const GLuint * value) + +void oc_glVertexAttribP1uiv_noimpl(GLuint index, GLenum type, GLboolean normalized, const GLuint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribP1uiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribP1uiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniform2uiv_noimpl(GLint location, GLsizei count, const GLuint * value) + +void oc_glUniform2uiv_noimpl(GLint location, GLsizei count, const GLuint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform2uiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform2uiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDeleteBuffers_noimpl(GLsizei n, const GLuint * buffers) + +void oc_glDeleteBuffers_noimpl(GLsizei n, const GLuint* buffers) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDeleteBuffers is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDeleteBuffers is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glProgramUniform3ui_noimpl(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform3ui is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform3ui is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glFramebufferTextureLayer_noimpl(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glFramebufferTextureLayer is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glFramebufferTextureLayer is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glEndTransformFeedback_noimpl(void) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glEndTransformFeedback is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glEndTransformFeedback is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBlendFuncSeparatei_noimpl(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBlendFuncSeparatei is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBlendFuncSeparatei is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDrawTransformFeedbackInstanced_noimpl(GLenum mode, GLuint id, GLsizei instancecount) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDrawTransformFeedbackInstanced is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDrawTransformFeedbackInstanced is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDrawRangeElementsBaseVertex_noimpl(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices, GLint basevertex) + +void oc_glDrawRangeElementsBaseVertex_noimpl(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void* indices, GLint basevertex) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDrawRangeElementsBaseVertex is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDrawRangeElementsBaseVertex is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttrib1f_noimpl(GLuint index, GLfloat x) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib1f is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib1f is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetUniformSubroutineuiv_noimpl(GLenum shadertype, GLint location, GLuint * params) + +void oc_glGetUniformSubroutineuiv_noimpl(GLenum shadertype, GLint location, GLuint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetUniformSubroutineuiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetUniformSubroutineuiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDisableVertexAttribArray_noimpl(GLuint index) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDisableVertexAttribArray is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDisableVertexAttribArray is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniformMatrix3x2fv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + +void oc_glProgramUniformMatrix3x2fv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniformMatrix3x2fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniformMatrix3x2fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribI4usv_noimpl(GLuint index, const GLushort * v) + +void oc_glVertexAttribI4usv_noimpl(GLuint index, const GLushort* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI4usv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI4usv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetObjectLabel_noimpl(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei * length, GLchar * label) + +void oc_glGetObjectLabel_noimpl(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar* label) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetObjectLabel is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetObjectLabel is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glBindAttribLocation_noimpl(GLuint program, GLuint index, const GLchar * name) + +void oc_glBindAttribLocation_noimpl(GLuint program, GLuint index, const GLchar* name) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindAttribLocation is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindAttribLocation is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glUniform1f_noimpl(GLint location, GLfloat v0) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform1f is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform1f is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetUniformdv_noimpl(GLuint program, GLint location, GLdouble * params) + +void oc_glGetUniformdv_noimpl(GLuint program, GLint location, GLdouble* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetUniformdv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetUniformdv is not part of currently selected %s API\n", oc_glAPI->name); + } } -GLint oc_glGetUniformLocation_noimpl(GLuint program, const GLchar * name) + +GLint oc_glGetUniformLocation_noimpl(GLuint program, const GLchar* name) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetUniformLocation is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLint)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetUniformLocation is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLint)0); } -GLint oc_glGetSubroutineUniformLocation_noimpl(GLuint program, GLenum shadertype, const GLchar * name) + +GLint oc_glGetSubroutineUniformLocation_noimpl(GLuint program, GLenum shadertype, const GLchar* name) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetSubroutineUniformLocation is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLint)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetSubroutineUniformLocation is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLint)0); } -void oc_glGetTexParameterIuiv_noimpl(GLenum target, GLenum pname, GLuint * params) + +void oc_glGetTexParameterIuiv_noimpl(GLenum target, GLenum pname, GLuint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetTexParameterIuiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetTexParameterIuiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glSamplerParameterf_noimpl(GLuint sampler, GLenum pname, GLfloat param) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glSamplerParameterf is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glSamplerParameterf is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribL3d_noimpl(GLuint index, GLdouble x, GLdouble y, GLdouble z) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribL3d is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribL3d is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glTexImage3DMultisample_noimpl(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexImage3DMultisample is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexImage3DMultisample is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glTexImage3D_noimpl(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels) + +void oc_glTexImage3D_noimpl(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void* pixels) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexImage3D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexImage3D is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glRenderbufferStorage_noimpl(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glRenderbufferStorage is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glRenderbufferStorage is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glEnableVertexAttribArray_noimpl(GLuint index) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glEnableVertexAttribArray is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glEnableVertexAttribArray is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribP4uiv_noimpl(GLuint index, GLenum type, GLboolean normalized, const GLuint * value) + +void oc_glVertexAttribP4uiv_noimpl(GLuint index, GLenum type, GLboolean normalized, const GLuint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribP4uiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribP4uiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glUniform4d_noimpl(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform4d is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform4d is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttrib4s_noimpl(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib4s is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib4s is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDrawElementsInstancedBaseVertex_noimpl(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex) + +void oc_glDrawElementsInstancedBaseVertex_noimpl(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount, GLint basevertex) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDrawElementsInstancedBaseVertex is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDrawElementsInstancedBaseVertex is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttrib3s_noimpl(GLuint index, GLshort x, GLshort y, GLshort z) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib3s is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib3s is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniform2iv_noimpl(GLuint program, GLint location, GLsizei count, const GLint * value) + +void oc_glProgramUniform2iv_noimpl(GLuint program, GLint location, GLsizei count, const GLint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform2iv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform2iv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glStencilFuncSeparate_noimpl(GLenum face, GLenum func, GLint ref, GLuint mask) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glStencilFuncSeparate is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glStencilFuncSeparate is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDeleteFramebuffers_noimpl(GLsizei n, const GLuint * framebuffers) + +void oc_glDeleteFramebuffers_noimpl(GLsizei n, const GLuint* framebuffers) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDeleteFramebuffers is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDeleteFramebuffers is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDepthRange_noimpl(GLdouble n, GLdouble f) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDepthRange is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDepthRange is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniformMatrix3x2fv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + +void oc_glUniformMatrix3x2fv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformMatrix3x2fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformMatrix3x2fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniformMatrix2dv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) + +void oc_glProgramUniformMatrix2dv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniformMatrix2dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniformMatrix2dv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glShaderStorageBlockBinding_noimpl(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glShaderStorageBlockBinding is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glShaderStorageBlockBinding is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glClearDepth_noimpl(GLdouble depth) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glClearDepth is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glClearDepth is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib2dv_noimpl(GLuint index, const GLdouble * v) + +void oc_glVertexAttrib2dv_noimpl(GLuint index, const GLdouble* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib2dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib2dv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glSamplerParameterIuiv_noimpl(GLuint sampler, GLenum pname, const GLuint * param) + +void oc_glSamplerParameterIuiv_noimpl(GLuint sampler, GLenum pname, const GLuint* param) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glSamplerParameterIuiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glSamplerParameterIuiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetVertexAttribLdv_noimpl(GLuint index, GLenum pname, GLdouble * params) + +void oc_glGetVertexAttribLdv_noimpl(GLuint index, GLenum pname, GLdouble* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetVertexAttribLdv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetVertexAttribLdv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniformMatrix3x4dv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) + +void oc_glProgramUniformMatrix3x4dv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniformMatrix3x4dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniformMatrix3x4dv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDepthRangeArrayv_noimpl(GLuint first, GLsizei count, const GLdouble * v) + +void oc_glDepthRangeArrayv_noimpl(GLuint first, GLsizei count, const GLdouble* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDepthRangeArrayv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDepthRangeArrayv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetActiveUniform_noimpl(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name) + +void oc_glGetActiveUniform_noimpl(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetActiveUniform is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetActiveUniform is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glPatchParameterfv_noimpl(GLenum pname, const GLfloat * values) + +void oc_glPatchParameterfv_noimpl(GLenum pname, const GLfloat* values) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glPatchParameterfv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glPatchParameterfv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glInvalidateTexImage_noimpl(GLuint texture, GLint level) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glInvalidateTexImage is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glInvalidateTexImage is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttrib3f_noimpl(GLuint index, GLfloat x, GLfloat y, GLfloat z) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib3f is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib3f is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniform4iv_noimpl(GLuint program, GLint location, GLsizei count, const GLint * value) + +void oc_glProgramUniform4iv_noimpl(GLuint program, GLint location, GLsizei count, const GLint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform4iv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform4iv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glProgramUniform4d_noimpl(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform4d is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform4d is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLboolean oc_glIsFramebuffer_noimpl(GLuint framebuffer) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glIsFramebuffer is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLboolean)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glIsFramebuffer is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLboolean)0); } + void oc_glPixelStoref_noimpl(GLenum pname, GLfloat param) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glPixelStoref is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glPixelStoref is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniform4uiv_noimpl(GLuint program, GLint location, GLsizei count, const GLuint * value) + +void oc_glProgramUniform4uiv_noimpl(GLuint program, GLint location, GLsizei count, const GLuint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform4uiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform4uiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniformMatrix4x2dv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) + +void oc_glProgramUniformMatrix4x2dv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniformMatrix4x2dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniformMatrix4x2dv is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLsync oc_glFenceSync_noimpl(GLenum condition, GLbitfield flags) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glFenceSync is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLsync)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glFenceSync is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLsync)0); } -void oc_glGetBufferParameteri64v_noimpl(GLenum target, GLenum pname, GLint64 * params) + +void oc_glGetBufferParameteri64v_noimpl(GLenum target, GLenum pname, GLint64* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetBufferParameteri64v is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetBufferParameteri64v is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glStencilOp_noimpl(GLenum fail, GLenum zfail, GLenum zpass) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glStencilOp is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glStencilOp is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glClearBufferData_noimpl(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void * data) + +void oc_glClearBufferData_noimpl(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glClearBufferData is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glClearBufferData is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetnUniformuiv_noimpl(GLuint program, GLint location, GLsizei bufSize, GLuint * params) + +void oc_glGetnUniformuiv_noimpl(GLuint program, GLint location, GLsizei bufSize, GLuint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetnUniformuiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetnUniformuiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetProgramResourceiv_noimpl(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei count, GLsizei * length, GLint * params) + +void oc_glGetProgramResourceiv_noimpl(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum* props, GLsizei count, GLsizei* length, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetProgramResourceiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetProgramResourceiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetVertexAttribdv_noimpl(GLuint index, GLenum pname, GLdouble * params) + +void oc_glGetVertexAttribdv_noimpl(GLuint index, GLenum pname, GLdouble* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetVertexAttribdv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetVertexAttribdv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetTransformFeedbackVarying_noimpl(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name) + +void oc_glGetTransformFeedbackVarying_noimpl(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetTransformFeedbackVarying is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetTransformFeedbackVarying is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib2fv_noimpl(GLuint index, const GLfloat * v) + +void oc_glVertexAttrib2fv_noimpl(GLuint index, const GLfloat* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib2fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib2fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetBooleani_v_noimpl(GLenum target, GLuint index, GLboolean * data) + +void oc_glGetBooleani_v_noimpl(GLenum target, GLuint index, GLboolean* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetBooleani_v is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetBooleani_v is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glColorMaski_noimpl(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glColorMaski is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glColorMaski is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glInvalidateBufferSubData_noimpl(GLuint buffer, GLintptr offset, GLsizeiptr length) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glInvalidateBufferSubData is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glInvalidateBufferSubData is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniformMatrix4dv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) + +void oc_glUniformMatrix4dv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformMatrix4dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformMatrix4dv is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLboolean oc_glIsQuery_noimpl(GLuint id) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glIsQuery is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLboolean)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glIsQuery is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLboolean)0); } + void oc_glUniform4ui_noimpl(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform4ui is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform4ui is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glUniform4i_noimpl(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform4i is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform4i is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetSamplerParameteriv_noimpl(GLuint sampler, GLenum pname, GLint * params) + +void oc_glGetSamplerParameteriv_noimpl(GLuint sampler, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetSamplerParameteriv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetSamplerParameteriv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glMultiDrawElementsBaseVertex_noimpl(GLenum mode, const GLsizei * count, GLenum type, const void *const* indices, GLsizei drawcount, const GLint * basevertex) + +void oc_glMultiDrawElementsBaseVertex_noimpl(GLenum mode, const GLsizei* count, GLenum type, const void* const* indices, GLsizei drawcount, const GLint* basevertex) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glMultiDrawElementsBaseVertex is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glMultiDrawElementsBaseVertex is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttribI1uiv_noimpl(GLuint index, const GLuint * v) + +void oc_glVertexAttribI1uiv_noimpl(GLuint index, const GLuint* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI1uiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI1uiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetIntegerv_noimpl(GLenum pname, GLint * data) + +void oc_glGetIntegerv_noimpl(GLenum pname, GLint* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetIntegerv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetIntegerv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniformMatrix2x3fv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + +void oc_glUniformMatrix2x3fv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformMatrix2x3fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformMatrix2x3fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glTexImage2D_noimpl(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels) + +void oc_glTexImage2D_noimpl(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexImage2D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexImage2D is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetAttachedShaders_noimpl(GLuint program, GLsizei maxCount, GLsizei * count, GLuint * shaders) + +void oc_glGetAttachedShaders_noimpl(GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetAttachedShaders is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetAttachedShaders is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glUniform2d_noimpl(GLint location, GLdouble x, GLdouble y) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform2d is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform2d is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glMemoryBarrierByRegion_noimpl(GLbitfield barriers) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glMemoryBarrierByRegion is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glMemoryBarrierByRegion is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniformMatrix2fv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + +void oc_glUniformMatrix2fv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformMatrix2fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformMatrix2fv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glPrimitiveRestartIndex_noimpl(GLuint index) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glPrimitiveRestartIndex is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glPrimitiveRestartIndex is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetVertexAttribiv_noimpl(GLuint index, GLenum pname, GLint * params) + +void oc_glGetVertexAttribiv_noimpl(GLuint index, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetVertexAttribiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetVertexAttribiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -GLint oc_glGetAttribLocation_noimpl(GLuint program, const GLchar * name) + +GLint oc_glGetAttribLocation_noimpl(GLuint program, const GLchar* name) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetAttribLocation is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLint)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetAttribLocation is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLint)0); } + void oc_glTexStorage2DMultisample_noimpl(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexStorage2DMultisample is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexStorage2DMultisample is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glCompressedTexSubImage2D_noimpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data) + +void oc_glCompressedTexSubImage2D_noimpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glCompressedTexSubImage2D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glCompressedTexSubImage2D is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetVertexAttribfv_noimpl(GLuint index, GLenum pname, GLfloat * params) + +void oc_glGetVertexAttribfv_noimpl(GLuint index, GLenum pname, GLfloat* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetVertexAttribfv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetVertexAttribfv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetBufferParameteriv_noimpl(GLenum target, GLenum pname, GLint * params) + +void oc_glGetBufferParameteriv_noimpl(GLenum target, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetBufferParameteriv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetBufferParameteriv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glTexParameterf_noimpl(GLenum target, GLenum pname, GLfloat param) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexParameterf is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexParameterf is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glFramebufferTexture2D_noimpl(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glFramebufferTexture2D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glFramebufferTexture2D is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetActiveAttrib_noimpl(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name) + +void oc_glGetActiveAttrib_noimpl(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLint* size, GLenum* type, GLchar* name) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetActiveAttrib is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetActiveAttrib is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glInvalidateTexSubImage_noimpl(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glInvalidateTexSubImage is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glInvalidateTexSubImage is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDeleteVertexArrays_noimpl(GLsizei n, const GLuint * arrays) + +void oc_glDeleteVertexArrays_noimpl(GLsizei n, const GLuint* arrays) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDeleteVertexArrays is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDeleteVertexArrays is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribI2ui_noimpl(GLuint index, GLuint x, GLuint y) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI2ui is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI2ui is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glPointParameteriv_noimpl(GLenum pname, const GLint * params) + +void oc_glPointParameteriv_noimpl(GLenum pname, const GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glPointParameteriv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glPointParameteriv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetPointerv_noimpl(GLenum pname, void ** params) + +void oc_glGetPointerv_noimpl(GLenum pname, void** params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetPointerv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetPointerv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glEnablei_noimpl(GLenum target, GLuint index) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glEnablei is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glEnablei is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBindBufferRange_noimpl(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindBufferRange is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindBufferRange is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDrawArraysInstanced_noimpl(GLenum mode, GLint first, GLsizei count, GLsizei instancecount) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDrawArraysInstanced is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDrawArraysInstanced is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDeleteTextures_noimpl(GLsizei n, const GLuint * textures) + +void oc_glDeleteTextures_noimpl(GLsizei n, const GLuint* textures) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDeleteTextures is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDeleteTextures is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib4Niv_noimpl(GLuint index, const GLint * v) + +void oc_glVertexAttrib4Niv_noimpl(GLuint index, const GLint* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib4Niv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib4Niv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glMultiDrawElements_noimpl(GLenum mode, const GLsizei * count, GLenum type, const void *const* indices, GLsizei drawcount) + +void oc_glMultiDrawElements_noimpl(GLenum mode, const GLsizei* count, GLenum type, const void* const* indices, GLsizei drawcount) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glMultiDrawElements is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glMultiDrawElements is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetProgramiv_noimpl(GLuint program, GLenum pname, GLint * params) + +void oc_glGetProgramiv_noimpl(GLuint program, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetProgramiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetProgramiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDepthFunc_noimpl(GLenum func) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDepthFunc is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDepthFunc is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGenTextures_noimpl(GLsizei n, GLuint * textures) + +void oc_glGenTextures_noimpl(GLsizei n, GLuint* textures) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGenTextures is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGenTextures is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetInternalformativ_noimpl(GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint * params) + +void oc_glGetInternalformativ_noimpl(GLenum target, GLenum internalformat, GLenum pname, GLsizei count, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetInternalformativ is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetInternalformativ is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glProgramUniform3i_noimpl(GLuint program, GLint location, GLint v0, GLint v1, GLint v2) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform3i is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform3i is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glScissorIndexed_noimpl(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glScissorIndexed is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glScissorIndexed is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib2sv_noimpl(GLuint index, const GLshort * v) + +void oc_glVertexAttrib2sv_noimpl(GLuint index, const GLshort* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib2sv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib2sv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glTexStorage3DMultisample_noimpl(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glTexStorage3DMultisample is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glTexStorage3DMultisample is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniform2iv_noimpl(GLint location, GLsizei count, const GLint * value) + +void oc_glUniform2iv_noimpl(GLint location, GLsizei count, const GLint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform2iv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform2iv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDrawArraysInstancedBaseInstance_noimpl(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDrawArraysInstancedBaseInstance is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDrawArraysInstancedBaseInstance is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttribI3ui_noimpl(GLuint index, GLuint x, GLuint y, GLuint z) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribI3ui is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribI3ui is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDeleteSamplers_noimpl(GLsizei count, const GLuint * samplers) + +void oc_glDeleteSamplers_noimpl(GLsizei count, const GLuint* samplers) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDeleteSamplers is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDeleteSamplers is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGenVertexArrays_noimpl(GLsizei n, GLuint * arrays) + +void oc_glGenVertexArrays_noimpl(GLsizei n, GLuint* arrays) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGenVertexArrays is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGenVertexArrays is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetFramebufferParameteriv_noimpl(GLenum target, GLenum pname, GLint * params) + +void oc_glGetFramebufferParameteriv_noimpl(GLenum target, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetFramebufferParameteriv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetFramebufferParameteriv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glPolygonMode_noimpl(GLenum face, GLenum mode) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glPolygonMode is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glPolygonMode is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniformMatrix2x4fv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + +void oc_glProgramUniformMatrix2x4fv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniformMatrix2x4fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniformMatrix2x4fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetProgramResourceName_noimpl(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei * length, GLchar * name) + +void oc_glGetProgramResourceName_noimpl(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei* length, GLchar* name) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetProgramResourceName is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetProgramResourceName is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glSamplerParameteriv_noimpl(GLuint sampler, GLenum pname, const GLint * param) + +void oc_glSamplerParameteriv_noimpl(GLuint sampler, GLenum pname, const GLint* param) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glSamplerParameteriv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glSamplerParameteriv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetActiveSubroutineUniformiv_noimpl(GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint * values) + +void oc_glGetActiveSubroutineUniformiv_noimpl(GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint* values) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetActiveSubroutineUniformiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetActiveSubroutineUniformiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -const GLubyte * oc_glGetStringi_noimpl(GLenum name, GLuint index) + +const GLubyte* oc_glGetStringi_noimpl(GLenum name, GLuint index) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetStringi is not part of currently selected %s API\n", oc_glAPI->name); - } - return((const GLubyte *)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetStringi is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((const GLubyte*)0); } + void oc_glVertexAttribLFormat_noimpl(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttribLFormat is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttribLFormat is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glVertexAttrib3d_noimpl(GLuint index, GLdouble x, GLdouble y, GLdouble z) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib3d is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib3d is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBindVertexArray_noimpl(GLuint array) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindVertexArray is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindVertexArray is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLboolean oc_glUnmapBuffer_noimpl(GLenum target) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUnmapBuffer is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLboolean)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUnmapBuffer is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLboolean)0); } -void oc_glDrawElementsInstancedBaseInstance_noimpl(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLuint baseinstance) + +void oc_glDrawElementsInstancedBaseInstance_noimpl(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount, GLuint baseinstance) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDrawElementsInstancedBaseInstance is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDrawElementsInstancedBaseInstance is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniform4uiv_noimpl(GLint location, GLsizei count, const GLuint * value) + +void oc_glUniform4uiv_noimpl(GLint location, GLsizei count, const GLuint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform4uiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform4uiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glFramebufferTexture1D_noimpl(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glFramebufferTexture1D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glFramebufferTexture1D is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDrawTransformFeedbackStreamInstanced_noimpl(GLenum mode, GLuint id, GLuint stream, GLsizei instancecount) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDrawTransformFeedbackStreamInstanced is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDrawTransformFeedbackStreamInstanced is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glStencilFunc_noimpl(GLenum func, GLint ref, GLuint mask) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glStencilFunc is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glStencilFunc is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glValidateProgram_noimpl(GLuint program) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glValidateProgram is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glValidateProgram is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glFlush_noimpl(void) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glFlush is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glFlush is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniform3uiv_noimpl(GLuint program, GLint location, GLsizei count, const GLuint * value) + +void oc_glProgramUniform3uiv_noimpl(GLuint program, GLint location, GLsizei count, const GLuint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform3uiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform3uiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDeleteRenderbuffers_noimpl(GLsizei n, const GLuint * renderbuffers) + +void oc_glDeleteRenderbuffers_noimpl(GLsizei n, const GLuint* renderbuffers) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDeleteRenderbuffers is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDeleteRenderbuffers is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib4fv_noimpl(GLuint index, const GLfloat * v) + +void oc_glVertexAttrib4fv_noimpl(GLuint index, const GLfloat* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib4fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib4fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniformMatrix2dv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) + +void oc_glUniformMatrix2dv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformMatrix2dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformMatrix2dv is not part of currently selected %s API\n", oc_glAPI->name); + } } -GLint oc_glGetFragDataIndex_noimpl(GLuint program, const GLchar * name) + +GLint oc_glGetFragDataIndex_noimpl(GLuint program, const GLchar* name) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetFragDataIndex is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLint)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetFragDataIndex is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLint)0); } -void oc_glUniform3iv_noimpl(GLint location, GLsizei count, const GLint * value) + +void oc_glUniform3iv_noimpl(GLint location, GLsizei count, const GLint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform3iv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform3iv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glMinSampleShading_noimpl(GLfloat value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glMinSampleShading is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glMinSampleShading is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetBooleanv_noimpl(GLenum pname, GLboolean * data) + +void oc_glGetBooleanv_noimpl(GLenum pname, GLboolean* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetBooleanv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetBooleanv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetMultisamplefv_noimpl(GLenum pname, GLuint index, GLfloat * val) + +void oc_glGetMultisamplefv_noimpl(GLenum pname, GLuint index, GLfloat* val) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetMultisamplefv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetMultisamplefv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetVertexAttribIuiv_noimpl(GLuint index, GLenum pname, GLuint * params) + +void oc_glGetVertexAttribIuiv_noimpl(GLuint index, GLenum pname, GLuint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetVertexAttribIuiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetVertexAttribIuiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetProgramInfoLog_noimpl(GLuint program, GLsizei bufSize, GLsizei * length, GLchar * infoLog) + +void oc_glGetProgramInfoLog_noimpl(GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetProgramInfoLog is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetProgramInfoLog is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniform4fv_noimpl(GLint location, GLsizei count, const GLfloat * value) + +void oc_glUniform4fv_noimpl(GLint location, GLsizei count, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform4fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform4fv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDrawBuffer_noimpl(GLenum buf) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDrawBuffer is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDrawBuffer is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glUniform1i_noimpl(GLint location, GLint v0) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform1i is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform1i is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glProgramUniform4ui_noimpl(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform4ui is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform4ui is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniformMatrix3fv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + +void oc_glProgramUniformMatrix3fv_noimpl(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniformMatrix3fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniformMatrix3fv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBlendEquationSeparate_noimpl(GLenum modeRGB, GLenum modeAlpha) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBlendEquationSeparate is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBlendEquationSeparate is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBindProgramPipeline_noimpl(GLuint pipeline) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindProgramPipeline is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindProgramPipeline is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetDoublei_v_noimpl(GLenum target, GLuint index, GLdouble * data) + +void oc_glGetDoublei_v_noimpl(GLenum target, GLuint index, GLdouble* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetDoublei_v is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetDoublei_v is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glBufferData_noimpl(GLenum target, GLsizeiptr size, const void * data, GLenum usage) + +void oc_glBufferData_noimpl(GLenum target, GLsizeiptr size, const void* data, GLenum usage) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBufferData is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBufferData is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glClearColor_noimpl(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glClearColor is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glClearColor is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glProgramUniform4i_noimpl(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform4i is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform4i is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetTexLevelParameteriv_noimpl(GLenum target, GLint level, GLenum pname, GLint * params) + +void oc_glGetTexLevelParameteriv_noimpl(GLenum target, GLint level, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetTexLevelParameteriv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetTexLevelParameteriv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetActiveUniformBlockiv_noimpl(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint * params) + +void oc_glGetActiveUniformBlockiv_noimpl(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetActiveUniformBlockiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetActiveUniformBlockiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniform1fv_noimpl(GLuint program, GLint location, GLsizei count, const GLfloat * value) + +void oc_glProgramUniform1fv_noimpl(GLuint program, GLint location, GLsizei count, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform1fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform1fv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glPauseTransformFeedback_noimpl(void) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glPauseTransformFeedback is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glPauseTransformFeedback is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetBufferPointerv_noimpl(GLenum target, GLenum pname, void ** params) + +void oc_glGetBufferPointerv_noimpl(GLenum target, GLenum pname, void** params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetBufferPointerv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetBufferPointerv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glInvalidateSubFramebuffer_noimpl(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height) + +void oc_glInvalidateSubFramebuffer_noimpl(GLenum target, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glInvalidateSubFramebuffer is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glInvalidateSubFramebuffer is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glScissorIndexedv_noimpl(GLuint index, const GLint * v) + +void oc_glScissorIndexedv_noimpl(GLuint index, const GLint* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glScissorIndexedv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glScissorIndexedv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glUniform2ui_noimpl(GLint location, GLuint v0, GLuint v1) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform2ui is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform2ui is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBindTexture_noimpl(GLenum target, GLuint texture) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindTexture is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindTexture is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDrawElementsInstanced_noimpl(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount) + +void oc_glDrawElementsInstanced_noimpl(GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei instancecount) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDrawElementsInstanced is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDrawElementsInstanced is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glProgramUniform4f_noimpl(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform4f is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform4f is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBindBufferBase_noimpl(GLenum target, GLuint index, GLuint buffer) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindBufferBase is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindBufferBase is not part of currently selected %s API\n", oc_glAPI->name); + } } + GLboolean oc_glIsShader_noimpl(GLuint shader) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glIsShader is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLboolean)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glIsShader is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLboolean)0); } -void oc_glClearBufferSubData_noimpl(GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void * data) + +void oc_glClearBufferSubData_noimpl(GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glClearBufferSubData is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glClearBufferSubData is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib4Nuiv_noimpl(GLuint index, const GLuint * v) + +void oc_glVertexAttrib4Nuiv_noimpl(GLuint index, const GLuint* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib4Nuiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib4Nuiv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDrawArraysIndirect_noimpl(GLenum mode, const void * indirect) + +void oc_glDrawArraysIndirect_noimpl(GLenum mode, const void* indirect) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDrawArraysIndirect is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDrawArraysIndirect is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glVertexAttrib4usv_noimpl(GLuint index, const GLushort * v) + +void oc_glVertexAttrib4usv_noimpl(GLuint index, const GLushort* v) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glVertexAttrib4usv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glVertexAttrib4usv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glUniform1d_noimpl(GLint location, GLdouble x) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform1d is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform1d is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glClearTexImage_noimpl(GLuint texture, GLint level, GLenum format, GLenum type, const void * data) + +void oc_glClearTexImage_noimpl(GLuint texture, GLint level, GLenum format, GLenum type, const void* data) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glClearTexImage is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glClearTexImage is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniform1uiv_noimpl(GLint location, GLsizei count, const GLuint * value) + +void oc_glUniform1uiv_noimpl(GLint location, GLsizei count, const GLuint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform1uiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform1uiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBindSampler_noimpl(GLuint unit, GLuint sampler) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindSampler is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindSampler is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetTexLevelParameterfv_noimpl(GLenum target, GLint level, GLenum pname, GLfloat * params) + +void oc_glGetTexLevelParameterfv_noimpl(GLenum target, GLint level, GLenum pname, GLfloat* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetTexLevelParameterfv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetTexLevelParameterfv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glClearBufferiv_noimpl(GLenum buffer, GLint drawbuffer, const GLint * value) + +void oc_glClearBufferiv_noimpl(GLenum buffer, GLint drawbuffer, const GLint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glClearBufferiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glClearBufferiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glLogicOp_noimpl(GLenum opcode) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glLogicOp is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glLogicOp is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glActiveTexture_noimpl(GLenum texture) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glActiveTexture is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glActiveTexture is not part of currently selected %s API\n", oc_glAPI->name); + } } -GLint oc_glGetFragDataLocation_noimpl(GLuint program, const GLchar * name) + +GLint oc_glGetFragDataLocation_noimpl(GLuint program, const GLchar* name) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetFragDataLocation is not part of currently selected %s API\n", oc_glAPI->name); - } - return((GLint)0); + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetFragDataLocation is not part of currently selected %s API\n", oc_glAPI->name); + } + return ((GLint)0); } + void oc_glBlendColor_noimpl(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBlendColor is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBlendColor is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniformMatrix4x3fv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value) + +void oc_glUniformMatrix4x3fv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformMatrix4x3fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformMatrix4x3fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glProgramUniform3fv_noimpl(GLuint program, GLint location, GLsizei count, const GLfloat * value) + +void oc_glProgramUniform3fv_noimpl(GLuint program, GLint location, GLsizei count, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glProgramUniform3fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glProgramUniform3fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniform1fv_noimpl(GLint location, GLsizei count, const GLfloat * value) + +void oc_glUniform1fv_noimpl(GLint location, GLsizei count, const GLfloat* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform1fv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform1fv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glDrawElementsBaseVertex_noimpl(GLenum mode, GLsizei count, GLenum type, const void * indices, GLint basevertex) + +void oc_glDrawElementsBaseVertex_noimpl(GLenum mode, GLsizei count, GLenum type, const void* indices, GLint basevertex) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDrawElementsBaseVertex is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDrawElementsBaseVertex is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glUniform4f_noimpl(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniform4f is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniform4f is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBlendEquationSeparatei_noimpl(GLuint buf, GLenum modeRGB, GLenum modeAlpha) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBlendEquationSeparatei is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBlendEquationSeparatei is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBlendFuncSeparate_noimpl(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBlendFuncSeparate is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBlendFuncSeparate is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glClearBufferuiv_noimpl(GLenum buffer, GLint drawbuffer, const GLuint * value) + +void oc_glClearBufferuiv_noimpl(GLenum buffer, GLint drawbuffer, const GLuint* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glClearBufferuiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glClearBufferuiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glCopyTexSubImage1D_noimpl(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glCopyTexSubImage1D is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glCopyTexSubImage1D is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDrawTransformFeedback_noimpl(GLenum mode, GLuint id) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDrawTransformFeedback is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDrawTransformFeedback is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glReadBuffer_noimpl(GLenum src) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glReadBuffer is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glReadBuffer is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glCopyBufferSubData_noimpl(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glCopyBufferSubData is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glCopyBufferSubData is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGetUniformuiv_noimpl(GLuint program, GLint location, GLuint * params) + +void oc_glGetUniformuiv_noimpl(GLuint program, GLint location, GLuint* params) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGetUniformuiv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGetUniformuiv is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glPolygonOffset_noimpl(GLfloat factor, GLfloat units) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glPolygonOffset is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glPolygonOffset is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glDispatchCompute_noimpl(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glDispatchCompute is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glDispatchCompute is not part of currently selected %s API\n", oc_glAPI->name); + } } + void oc_glBindImageTexture_noimpl(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glBindImageTexture is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glBindImageTexture is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glUniformMatrix4x3dv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value) + +void oc_glUniformMatrix4x3dv_noimpl(GLint location, GLsizei count, GLboolean transpose, const GLdouble* value) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glUniformMatrix4x3dv is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glUniformMatrix4x3dv is not part of currently selected %s API\n", oc_glAPI->name); + } } -void oc_glGenRenderbuffers_noimpl(GLsizei n, GLuint * renderbuffers) + +void oc_glGenRenderbuffers_noimpl(GLsizei n, GLuint* renderbuffers) { - if(oc_glAPI == &oc_glNoAPI) - { - oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); - } - else - { - oc_log_error("glGenRenderbuffers is not part of currently selected %s API\n", oc_glAPI->name); - } + if(oc_glAPI == &oc_glNoAPI) + { + oc_log_error("No GL or GLES API is selected. Make sure you call oc_surface_select() before calling OpenGL API functions.\n"); + } + else + { + oc_log_error("glGenRenderbuffers is not part of currently selected %s API\n", oc_glAPI->name); + } } + oc_gl_api oc_glNoAPI = { - .GetFloatv = oc_glGetFloatv_noimpl, - .TexBufferRange = oc_glTexBufferRange_noimpl, - .IsBuffer = oc_glIsBuffer_noimpl, - .IsTexture = oc_glIsTexture_noimpl, - .DepthRangef = oc_glDepthRangef_noimpl, - .EndConditionalRender = oc_glEndConditionalRender_noimpl, - .BlendFunci = oc_glBlendFunci_noimpl, - .GetProgramPipelineiv = oc_glGetProgramPipelineiv_noimpl, - .WaitSync = oc_glWaitSync_noimpl, - .ProgramUniformMatrix2fv = oc_glProgramUniformMatrix2fv_noimpl, - .ProgramUniformMatrix4x3dv = oc_glProgramUniformMatrix4x3dv_noimpl, - .VertexAttrib1dv = oc_glVertexAttrib1dv_noimpl, - .SamplerParameteri = oc_glSamplerParameteri_noimpl, - .GetVertexAttribIiv = oc_glGetVertexAttribIiv_noimpl, - .GetSamplerParameterfv = oc_glGetSamplerParameterfv_noimpl, - .VertexAttrib1d = oc_glVertexAttrib1d_noimpl, - .TexBuffer = oc_glTexBuffer_noimpl, - .InvalidateBufferData = oc_glInvalidateBufferData_noimpl, - .ProgramUniform2i = oc_glProgramUniform2i_noimpl, - .Uniform4dv = oc_glUniform4dv_noimpl, - .UseProgram = oc_glUseProgram_noimpl, - .VertexAttribI3iv = oc_glVertexAttribI3iv_noimpl, - .DrawElementsIndirect = oc_glDrawElementsIndirect_noimpl, - .VertexAttrib4uiv = oc_glVertexAttrib4uiv_noimpl, - .GetQueryObjectiv = oc_glGetQueryObjectiv_noimpl, - .FramebufferRenderbuffer = oc_glFramebufferRenderbuffer_noimpl, - .BlendEquationi = oc_glBlendEquationi_noimpl, - .GetActiveSubroutineName = oc_glGetActiveSubroutineName_noimpl, - .VertexAttrib2s = oc_glVertexAttrib2s_noimpl, - .VertexAttribL1d = oc_glVertexAttribL1d_noimpl, - .BindTextures = oc_glBindTextures_noimpl, - .VertexAttrib3sv = oc_glVertexAttrib3sv_noimpl, - .GetFloati_v = oc_glGetFloati_v_noimpl, - .BeginTransformFeedback = oc_glBeginTransformFeedback_noimpl, - .ClearStencil = oc_glClearStencil_noimpl, - .Uniform3i = oc_glUniform3i_noimpl, - .ValidateProgramPipeline = oc_glValidateProgramPipeline_noimpl, - .ProgramUniformMatrix4x2fv = oc_glProgramUniformMatrix4x2fv_noimpl, - .VertexAttribI4ui = oc_glVertexAttribI4ui_noimpl, - .GetShaderiv = oc_glGetShaderiv_noimpl, - .ReadnPixels = oc_glReadnPixels_noimpl, - .UniformMatrix4x2fv = oc_glUniformMatrix4x2fv_noimpl, - .GetShaderPrecisionFormat = oc_glGetShaderPrecisionFormat_noimpl, - .ProgramUniformMatrix2x3fv = oc_glProgramUniformMatrix2x3fv_noimpl, - .TexSubImage3D = oc_glTexSubImage3D_noimpl, - .GetProgramResourceLocationIndex = oc_glGetProgramResourceLocationIndex_noimpl, - .BlendFunc = oc_glBlendFunc_noimpl, - .ProgramUniformMatrix3x4fv = oc_glProgramUniformMatrix3x4fv_noimpl, - .Uniform3d = oc_glUniform3d_noimpl, - .VertexAttrib1sv = oc_glVertexAttrib1sv_noimpl, - .BindFragDataLocation = oc_glBindFragDataLocation_noimpl, - .VertexAttrib4bv = oc_glVertexAttrib4bv_noimpl, - .Uniform4iv = oc_glUniform4iv_noimpl, - .ProgramUniform2ui = oc_glProgramUniform2ui_noimpl, - .DrawArrays = oc_glDrawArrays_noimpl, - .ProgramBinary = oc_glProgramBinary_noimpl, - .VertexAttrib4f = oc_glVertexAttrib4f_noimpl, - .VertexAttribP2uiv = oc_glVertexAttribP2uiv_noimpl, - .UniformMatrix3fv = oc_glUniformMatrix3fv_noimpl, - .Uniform2i = oc_glUniform2i_noimpl, - .GetQueryObjectuiv = oc_glGetQueryObjectuiv_noimpl, - .UniformBlockBinding = oc_glUniformBlockBinding_noimpl, - .SampleCoverage = oc_glSampleCoverage_noimpl, - .VertexAttrib4Nusv = oc_glVertexAttrib4Nusv_noimpl, - .ProgramUniformMatrix2x4dv = oc_glProgramUniformMatrix2x4dv_noimpl, - .Uniform3uiv = oc_glUniform3uiv_noimpl, - .VertexAttrib1s = oc_glVertexAttrib1s_noimpl, - .GetVertexAttribPointerv = oc_glGetVertexAttribPointerv_noimpl, - .BlendBarrier = oc_glBlendBarrier_noimpl, - .DrawRangeElements = oc_glDrawRangeElements_noimpl, - .TexStorage3D = oc_glTexStorage3D_noimpl, - .GetInternalformati64v = oc_glGetInternalformati64v_noimpl, - .GetQueryObjecti64v = oc_glGetQueryObjecti64v_noimpl, - .CompressedTexSubImage1D = oc_glCompressedTexSubImage1D_noimpl, - .VertexAttrib3dv = oc_glVertexAttrib3dv_noimpl, - .VertexBindingDivisor = oc_glVertexBindingDivisor_noimpl, - .UseProgramStages = oc_glUseProgramStages_noimpl, - .VertexAttribBinding = oc_glVertexAttribBinding_noimpl, - .DebugMessageInsert = oc_glDebugMessageInsert_noimpl, - .GetTexParameteriv = oc_glGetTexParameteriv_noimpl, - .MultiDrawArraysIndirect = oc_glMultiDrawArraysIndirect_noimpl, - .GetTexParameterfv = oc_glGetTexParameterfv_noimpl, - .GetProgramPipelineInfoLog = oc_glGetProgramPipelineInfoLog_noimpl, - .EndQuery = oc_glEndQuery_noimpl, - .GetProgramResourceLocation = oc_glGetProgramResourceLocation_noimpl, - .CompressedTexImage2D = oc_glCompressedTexImage2D_noimpl, - .VertexAttribP2ui = oc_glVertexAttribP2ui_noimpl, - .IsEnabledi = oc_glIsEnabledi_noimpl, - .GetActiveAtomicCounterBufferiv = oc_glGetActiveAtomicCounterBufferiv_noimpl, - .IsProgram = oc_glIsProgram_noimpl, - .Uniform1dv = oc_glUniform1dv_noimpl, - .TexParameteriv = oc_glTexParameteriv_noimpl, - .Uniform2fv = oc_glUniform2fv_noimpl, - .ReleaseShaderCompiler = oc_glReleaseShaderCompiler_noimpl, - .CullFace = oc_glCullFace_noimpl, - .VertexAttribI4i = oc_glVertexAttribI4i_noimpl, - .GetProgramResourceIndex = oc_glGetProgramResourceIndex_noimpl, - .ShaderBinary = oc_glShaderBinary_noimpl, - .UniformMatrix3x2dv = oc_glUniformMatrix3x2dv_noimpl, - .InvalidateFramebuffer = oc_glInvalidateFramebuffer_noimpl, - .AttachShader = oc_glAttachShader_noimpl, - .FlushMappedBufferRange = oc_glFlushMappedBufferRange_noimpl, - .VertexAttribP3uiv = oc_glVertexAttribP3uiv_noimpl, - .GetActiveUniformName = oc_glGetActiveUniformName_noimpl, - .MapBuffer = oc_glMapBuffer_noimpl, - .DrawBuffers = oc_glDrawBuffers_noimpl, - .GetSynciv = oc_glGetSynciv_noimpl, - .CopyTexSubImage2D = oc_glCopyTexSubImage2D_noimpl, - .ObjectLabel = oc_glObjectLabel_noimpl, - .BufferSubData = oc_glBufferSubData_noimpl, - .Uniform2f = oc_glUniform2f_noimpl, - .DebugMessageCallback = oc_glDebugMessageCallback_noimpl, - .VertexAttribL4dv = oc_glVertexAttribL4dv_noimpl, - .IsProgramPipeline = oc_glIsProgramPipeline_noimpl, - .ResumeTransformFeedback = oc_glResumeTransformFeedback_noimpl, - .VertexAttribI4iv = oc_glVertexAttribI4iv_noimpl, - .GetShaderInfoLog = oc_glGetShaderInfoLog_noimpl, - .GetIntegeri_v = oc_glGetIntegeri_v_noimpl, - .BindVertexBuffer = oc_glBindVertexBuffer_noimpl, - .BlendEquation = oc_glBlendEquation_noimpl, - .VertexAttribL2dv = oc_glVertexAttribL2dv_noimpl, - .VertexAttribI1ui = oc_glVertexAttribI1ui_noimpl, - .VertexAttrib4Nsv = oc_glVertexAttrib4Nsv_noimpl, - .VertexAttribL4d = oc_glVertexAttribL4d_noimpl, - .CopyImageSubData = oc_glCopyImageSubData_noimpl, - .GetFramebufferAttachmentParameteriv = oc_glGetFramebufferAttachmentParameteriv_noimpl, - .VertexAttribL2d = oc_glVertexAttribL2d_noimpl, - .GetSubroutineIndex = oc_glGetSubroutineIndex_noimpl, - .VertexAttribI3uiv = oc_glVertexAttribI3uiv_noimpl, - .VertexAttrib4iv = oc_glVertexAttrib4iv_noimpl, - .BindVertexBuffers = oc_glBindVertexBuffers_noimpl, - .ProgramUniformMatrix2x3dv = oc_glProgramUniformMatrix2x3dv_noimpl, - .PrimitiveBoundingBox = oc_glPrimitiveBoundingBox_noimpl, - .Scissor = oc_glScissor_noimpl, - .ClientWaitSync = oc_glClientWaitSync_noimpl, - .Uniform3ui = oc_glUniform3ui_noimpl, - .VertexAttribP3ui = oc_glVertexAttribP3ui_noimpl, - .Enable = oc_glEnable_noimpl, - .StencilOpSeparate = oc_glStencilOpSeparate_noimpl, - .UniformMatrix2x3dv = oc_glUniformMatrix2x3dv_noimpl, - .ProgramUniformMatrix3dv = oc_glProgramUniformMatrix3dv_noimpl, - .TexImage2DMultisample = oc_glTexImage2DMultisample_noimpl, - .VertexAttrib4Nbv = oc_glVertexAttrib4Nbv_noimpl, - .GetTexImage = oc_glGetTexImage_noimpl, - .VertexAttrib4sv = oc_glVertexAttrib4sv_noimpl, - .PixelStorei = oc_glPixelStorei_noimpl, - .DepthMask = oc_glDepthMask_noimpl, - .TexStorage2D = oc_glTexStorage2D_noimpl, - .Clear = oc_glClear_noimpl, - .UniformMatrix3x4dv = oc_glUniformMatrix3x4dv_noimpl, - .DeleteTransformFeedbacks = oc_glDeleteTransformFeedbacks_noimpl, - .MapBufferRange = oc_glMapBufferRange_noimpl, - .MemoryBarrier = oc_glMemoryBarrier_noimpl, - .ViewportIndexedf = oc_glViewportIndexedf_noimpl, - .VertexAttrib3fv = oc_glVertexAttrib3fv_noimpl, - .ObjectPtrLabel = oc_glObjectPtrLabel_noimpl, - .TexStorage1D = oc_glTexStorage1D_noimpl, - .CompressedTexImage3D = oc_glCompressedTexImage3D_noimpl, - .VertexAttrib1fv = oc_glVertexAttrib1fv_noimpl, - .VertexAttribPointer = oc_glVertexAttribPointer_noimpl, - .GetQueryIndexediv = oc_glGetQueryIndexediv_noimpl, - .CompileShader = oc_glCompileShader_noimpl, - .ProgramUniform1i = oc_glProgramUniform1i_noimpl, - .GetQueryiv = oc_glGetQueryiv_noimpl, - .VertexAttribI1iv = oc_glVertexAttribI1iv_noimpl, - .CopyTexImage2D = oc_glCopyTexImage2D_noimpl, - .GetQueryObjectui64v = oc_glGetQueryObjectui64v_noimpl, - .PointSize = oc_glPointSize_noimpl, - .Disablei = oc_glDisablei_noimpl, - .VertexAttribL1dv = oc_glVertexAttribL1dv_noimpl, - .CreateShader = oc_glCreateShader_noimpl, - .GetString = oc_glGetString_noimpl, - .ViewportArrayv = oc_glViewportArrayv_noimpl, - .ProgramUniform3d = oc_glProgramUniform3d_noimpl, - .VertexAttrib4Nubv = oc_glVertexAttrib4Nubv_noimpl, - .TexParameteri = oc_glTexParameteri_noimpl, - .ProgramUniform4fv = oc_glProgramUniform4fv_noimpl, - .GenerateMipmap = oc_glGenerateMipmap_noimpl, - .CompressedTexSubImage3D = oc_glCompressedTexSubImage3D_noimpl, - .Uniform3f = oc_glUniform3f_noimpl, - .GetUniformIndices = oc_glGetUniformIndices_noimpl, - .VertexAttribLPointer = oc_glVertexAttribLPointer_noimpl, - .VertexAttribI2uiv = oc_glVertexAttribI2uiv_noimpl, - .QueryCounter = oc_glQueryCounter_noimpl, - .ActiveShaderProgram = oc_glActiveShaderProgram_noimpl, - .Uniform1ui = oc_glUniform1ui_noimpl, - .VertexAttribI1i = oc_glVertexAttribI1i_noimpl, - .GetTexParameterIiv = oc_glGetTexParameterIiv_noimpl, - .GetUniformfv = oc_glGetUniformfv_noimpl, - .ProgramUniform2uiv = oc_glProgramUniform2uiv_noimpl, - .GetError = oc_glGetError_noimpl, - .GetActiveUniformBlockName = oc_glGetActiveUniformBlockName_noimpl, - .TextureView = oc_glTextureView_noimpl, - .GetnUniformiv = oc_glGetnUniformiv_noimpl, - .ProgramUniform4dv = oc_glProgramUniform4dv_noimpl, - .ViewportIndexedfv = oc_glViewportIndexedfv_noimpl, - .Hint = oc_glHint_noimpl, - .GetShaderSource = oc_glGetShaderSource_noimpl, - .ProgramUniformMatrix4x3fv = oc_glProgramUniformMatrix4x3fv_noimpl, - .Uniform1iv = oc_glUniform1iv_noimpl, - .VertexAttribI4bv = oc_glVertexAttribI4bv_noimpl, - .UniformMatrix4x2dv = oc_glUniformMatrix4x2dv_noimpl, - .BufferStorage = oc_glBufferStorage_noimpl, - .IsRenderbuffer = oc_glIsRenderbuffer_noimpl, - .GetActiveSubroutineUniformName = oc_glGetActiveSubroutineUniformName_noimpl, - .LinkProgram = oc_glLinkProgram_noimpl, - .GetActiveUniformsiv = oc_glGetActiveUniformsiv_noimpl, - .GetDebugMessageLog = oc_glGetDebugMessageLog_noimpl, - .CopyTexSubImage3D = oc_glCopyTexSubImage3D_noimpl, - .PointParameteri = oc_glPointParameteri_noimpl, - .ProgramUniform3dv = oc_glProgramUniform3dv_noimpl, - .CompressedTexImage1D = oc_glCompressedTexImage1D_noimpl, - .UniformMatrix3x4fv = oc_glUniformMatrix3x4fv_noimpl, - .GenSamplers = oc_glGenSamplers_noimpl, - .GetCompressedTexImage = oc_glGetCompressedTexImage_noimpl, - .DeleteQueries = oc_glDeleteQueries_noimpl, - .GenProgramPipelines = oc_glGenProgramPipelines_noimpl, - .DispatchComputeIndirect = oc_glDispatchComputeIndirect_noimpl, - .VertexAttribIPointer = oc_glVertexAttribIPointer_noimpl, - .CreateProgram = oc_glCreateProgram_noimpl, - .ClearTexSubImage = oc_glClearTexSubImage_noimpl, - .VertexAttrib4d = oc_glVertexAttrib4d_noimpl, - .FrontFace = oc_glFrontFace_noimpl, - .BindTransformFeedback = oc_glBindTransformFeedback_noimpl, - .GetProgramStageiv = oc_glGetProgramStageiv_noimpl, - .SamplerParameterIiv = oc_glSamplerParameterIiv_noimpl, - .GetInteger64v = oc_glGetInteger64v_noimpl, - .CreateShaderProgramv = oc_glCreateShaderProgramv_noimpl, - .BindBuffersRange = oc_glBindBuffersRange_noimpl, - .Uniform3fv = oc_glUniform3fv_noimpl, - .ProgramUniformMatrix4fv = oc_glProgramUniformMatrix4fv_noimpl, - .BindBuffersBase = oc_glBindBuffersBase_noimpl, - .ClearBufferfi = oc_glClearBufferfi_noimpl, - .FramebufferTexture3D = oc_glFramebufferTexture3D_noimpl, - .Disable = oc_glDisable_noimpl, - .ProgramUniform1iv = oc_glProgramUniform1iv_noimpl, - .VertexAttribI2iv = oc_glVertexAttribI2iv_noimpl, - .DepthRangeIndexed = oc_glDepthRangeIndexed_noimpl, - .PatchParameteri = oc_glPatchParameteri_noimpl, - .GetUniformBlockIndex = oc_glGetUniformBlockIndex_noimpl, - .MultiDrawArrays = oc_glMultiDrawArrays_noimpl, - .VertexAttribI4ubv = oc_glVertexAttribI4ubv_noimpl, - .BindBuffer = oc_glBindBuffer_noimpl, - .VertexAttribI3i = oc_glVertexAttribI3i_noimpl, - .GetDoublev = oc_glGetDoublev_noimpl, - .DrawTransformFeedbackStream = oc_glDrawTransformFeedbackStream_noimpl, - .VertexAttribI4uiv = oc_glVertexAttribI4uiv_noimpl, - .RenderbufferStorageMultisample = oc_glRenderbufferStorageMultisample_noimpl, - .VertexAttribL3dv = oc_glVertexAttribL3dv_noimpl, - .StencilMaskSeparate = oc_glStencilMaskSeparate_noimpl, - .ProgramUniform1d = oc_glProgramUniform1d_noimpl, - .Viewport = oc_glViewport_noimpl, - .VertexAttribP1ui = oc_glVertexAttribP1ui_noimpl, - .VertexAttrib4dv = oc_glVertexAttrib4dv_noimpl, - .GenQueries = oc_glGenQueries_noimpl, - .TexParameterIiv = oc_glTexParameterIiv_noimpl, - .ProgramUniform2d = oc_glProgramUniform2d_noimpl, - .ProgramUniform1uiv = oc_glProgramUniform1uiv_noimpl, - .VertexAttrib4Nub = oc_glVertexAttrib4Nub_noimpl, - .IsVertexArray = oc_glIsVertexArray_noimpl, - .ProgramUniform3f = oc_glProgramUniform3f_noimpl, - .ProgramUniform3iv = oc_glProgramUniform3iv_noimpl, - .GetProgramBinary = oc_glGetProgramBinary_noimpl, - .BindRenderbuffer = oc_glBindRenderbuffer_noimpl, - .BindFragDataLocationIndexed = oc_glBindFragDataLocationIndexed_noimpl, - .GetSamplerParameterIiv = oc_glGetSamplerParameterIiv_noimpl, - .VertexAttribDivisor = oc_glVertexAttribDivisor_noimpl, - .ProgramUniformMatrix3x2dv = oc_glProgramUniformMatrix3x2dv_noimpl, - .FramebufferParameteri = oc_glFramebufferParameteri_noimpl, - .GenTransformFeedbacks = oc_glGenTransformFeedbacks_noimpl, - .DeleteSync = oc_glDeleteSync_noimpl, - .ProgramUniform1ui = oc_glProgramUniform1ui_noimpl, - .TexSubImage1D = oc_glTexSubImage1D_noimpl, - .ClearDepthf = oc_glClearDepthf_noimpl, - .ReadPixels = oc_glReadPixels_noimpl, - .VertexAttribI2i = oc_glVertexAttribI2i_noimpl, - .Finish = oc_glFinish_noimpl, - .LineWidth = oc_glLineWidth_noimpl, - .DeleteShader = oc_glDeleteShader_noimpl, - .IsSampler = oc_glIsSampler_noimpl, - .ProgramUniformMatrix4dv = oc_glProgramUniformMatrix4dv_noimpl, - .TransformFeedbackVaryings = oc_glTransformFeedbackVaryings_noimpl, - .BeginConditionalRender = oc_glBeginConditionalRender_noimpl, - .BindSamplers = oc_glBindSamplers_noimpl, - .DeleteProgramPipelines = oc_glDeleteProgramPipelines_noimpl, - .ColorMask = oc_glColorMask_noimpl, - .TexParameterfv = oc_glTexParameterfv_noimpl, - .PushDebugGroup = oc_glPushDebugGroup_noimpl, - .ClearBufferfv = oc_glClearBufferfv_noimpl, - .IsEnabled = oc_glIsEnabled_noimpl, - .VertexAttrib2f = oc_glVertexAttrib2f_noimpl, - .ProgramUniform2f = oc_glProgramUniform2f_noimpl, - .GetSamplerParameterIuiv = oc_glGetSamplerParameterIuiv_noimpl, - .GetInteger64i_v = oc_glGetInteger64i_v_noimpl, - .Uniform2dv = oc_glUniform2dv_noimpl, - .GetBufferSubData = oc_glGetBufferSubData_noimpl, - .MultiDrawElementsIndirect = oc_glMultiDrawElementsIndirect_noimpl, - .ProgramParameteri = oc_glProgramParameteri_noimpl, - .VertexAttribP4ui = oc_glVertexAttribP4ui_noimpl, - .SamplerParameterfv = oc_glSamplerParameterfv_noimpl, - .PointParameterf = oc_glPointParameterf_noimpl, - .UniformMatrix2x4fv = oc_glUniformMatrix2x4fv_noimpl, - .GenBuffers = oc_glGenBuffers_noimpl, - .ProgramUniform2dv = oc_glProgramUniform2dv_noimpl, - .VertexAttribFormat = oc_glVertexAttribFormat_noimpl, - .TexSubImage2D = oc_glTexSubImage2D_noimpl, - .VertexAttrib4ubv = oc_glVertexAttrib4ubv_noimpl, - .GetGraphicsResetStatus = oc_glGetGraphicsResetStatus_noimpl, - .GetProgramInterfaceiv = oc_glGetProgramInterfaceiv_noimpl, - .VertexAttribIFormat = oc_glVertexAttribIFormat_noimpl, - .GetnUniformfv = oc_glGetnUniformfv_noimpl, - .DeleteProgram = oc_glDeleteProgram_noimpl, - .ClampColor = oc_glClampColor_noimpl, - .DrawElementsInstancedBaseVertexBaseInstance = oc_glDrawElementsInstancedBaseVertexBaseInstance_noimpl, - .DrawElements = oc_glDrawElements_noimpl, - .DebugMessageControl = oc_glDebugMessageControl_noimpl, - .GetRenderbufferParameteriv = oc_glGetRenderbufferParameteriv_noimpl, - .DetachShader = oc_glDetachShader_noimpl, - .GenFramebuffers = oc_glGenFramebuffers_noimpl, - .ProvokingVertex = oc_glProvokingVertex_noimpl, - .SampleMaski = oc_glSampleMaski_noimpl, - .EndQueryIndexed = oc_glEndQueryIndexed_noimpl, - .ProgramUniform1f = oc_glProgramUniform1f_noimpl, - .BindFramebuffer = oc_glBindFramebuffer_noimpl, - .BeginQueryIndexed = oc_glBeginQueryIndexed_noimpl, - .UniformSubroutinesuiv = oc_glUniformSubroutinesuiv_noimpl, - .GetUniformiv = oc_glGetUniformiv_noimpl, - .FramebufferTexture = oc_glFramebufferTexture_noimpl, - .PointParameterfv = oc_glPointParameterfv_noimpl, - .IsTransformFeedback = oc_glIsTransformFeedback_noimpl, - .CheckFramebufferStatus = oc_glCheckFramebufferStatus_noimpl, - .ShaderSource = oc_glShaderSource_noimpl, - .UniformMatrix2x4dv = oc_glUniformMatrix2x4dv_noimpl, - .BindImageTextures = oc_glBindImageTextures_noimpl, - .CopyTexImage1D = oc_glCopyTexImage1D_noimpl, - .UniformMatrix3dv = oc_glUniformMatrix3dv_noimpl, - .ProgramUniform1dv = oc_glProgramUniform1dv_noimpl, - .BlitFramebuffer = oc_glBlitFramebuffer_noimpl, - .PopDebugGroup = oc_glPopDebugGroup_noimpl, - .TexParameterIuiv = oc_glTexParameterIuiv_noimpl, - .VertexAttrib2d = oc_glVertexAttrib2d_noimpl, - .TexImage1D = oc_glTexImage1D_noimpl, - .GetObjectPtrLabel = oc_glGetObjectPtrLabel_noimpl, - .StencilMask = oc_glStencilMask_noimpl, - .BeginQuery = oc_glBeginQuery_noimpl, - .UniformMatrix4fv = oc_glUniformMatrix4fv_noimpl, - .IsSync = oc_glIsSync_noimpl, - .Uniform3dv = oc_glUniform3dv_noimpl, - .ProgramUniform2fv = oc_glProgramUniform2fv_noimpl, - .VertexAttribI4sv = oc_glVertexAttribI4sv_noimpl, - .ScissorArrayv = oc_glScissorArrayv_noimpl, - .VertexAttribP1uiv = oc_glVertexAttribP1uiv_noimpl, - .Uniform2uiv = oc_glUniform2uiv_noimpl, - .DeleteBuffers = oc_glDeleteBuffers_noimpl, - .ProgramUniform3ui = oc_glProgramUniform3ui_noimpl, - .FramebufferTextureLayer = oc_glFramebufferTextureLayer_noimpl, - .EndTransformFeedback = oc_glEndTransformFeedback_noimpl, - .BlendFuncSeparatei = oc_glBlendFuncSeparatei_noimpl, - .DrawTransformFeedbackInstanced = oc_glDrawTransformFeedbackInstanced_noimpl, - .DrawRangeElementsBaseVertex = oc_glDrawRangeElementsBaseVertex_noimpl, - .VertexAttrib1f = oc_glVertexAttrib1f_noimpl, - .GetUniformSubroutineuiv = oc_glGetUniformSubroutineuiv_noimpl, - .DisableVertexAttribArray = oc_glDisableVertexAttribArray_noimpl, - .ProgramUniformMatrix3x2fv = oc_glProgramUniformMatrix3x2fv_noimpl, - .VertexAttribI4usv = oc_glVertexAttribI4usv_noimpl, - .GetObjectLabel = oc_glGetObjectLabel_noimpl, - .BindAttribLocation = oc_glBindAttribLocation_noimpl, - .Uniform1f = oc_glUniform1f_noimpl, - .GetUniformdv = oc_glGetUniformdv_noimpl, - .GetUniformLocation = oc_glGetUniformLocation_noimpl, - .GetSubroutineUniformLocation = oc_glGetSubroutineUniformLocation_noimpl, - .GetTexParameterIuiv = oc_glGetTexParameterIuiv_noimpl, - .SamplerParameterf = oc_glSamplerParameterf_noimpl, - .VertexAttribL3d = oc_glVertexAttribL3d_noimpl, - .TexImage3DMultisample = oc_glTexImage3DMultisample_noimpl, - .TexImage3D = oc_glTexImage3D_noimpl, - .RenderbufferStorage = oc_glRenderbufferStorage_noimpl, - .EnableVertexAttribArray = oc_glEnableVertexAttribArray_noimpl, - .VertexAttribP4uiv = oc_glVertexAttribP4uiv_noimpl, - .Uniform4d = oc_glUniform4d_noimpl, - .VertexAttrib4s = oc_glVertexAttrib4s_noimpl, - .DrawElementsInstancedBaseVertex = oc_glDrawElementsInstancedBaseVertex_noimpl, - .VertexAttrib3s = oc_glVertexAttrib3s_noimpl, - .ProgramUniform2iv = oc_glProgramUniform2iv_noimpl, - .StencilFuncSeparate = oc_glStencilFuncSeparate_noimpl, - .DeleteFramebuffers = oc_glDeleteFramebuffers_noimpl, - .DepthRange = oc_glDepthRange_noimpl, - .UniformMatrix3x2fv = oc_glUniformMatrix3x2fv_noimpl, - .ProgramUniformMatrix2dv = oc_glProgramUniformMatrix2dv_noimpl, - .ShaderStorageBlockBinding = oc_glShaderStorageBlockBinding_noimpl, - .ClearDepth = oc_glClearDepth_noimpl, - .VertexAttrib2dv = oc_glVertexAttrib2dv_noimpl, - .SamplerParameterIuiv = oc_glSamplerParameterIuiv_noimpl, - .GetVertexAttribLdv = oc_glGetVertexAttribLdv_noimpl, - .ProgramUniformMatrix3x4dv = oc_glProgramUniformMatrix3x4dv_noimpl, - .DepthRangeArrayv = oc_glDepthRangeArrayv_noimpl, - .GetActiveUniform = oc_glGetActiveUniform_noimpl, - .PatchParameterfv = oc_glPatchParameterfv_noimpl, - .InvalidateTexImage = oc_glInvalidateTexImage_noimpl, - .VertexAttrib3f = oc_glVertexAttrib3f_noimpl, - .ProgramUniform4iv = oc_glProgramUniform4iv_noimpl, - .ProgramUniform4d = oc_glProgramUniform4d_noimpl, - .IsFramebuffer = oc_glIsFramebuffer_noimpl, - .PixelStoref = oc_glPixelStoref_noimpl, - .ProgramUniform4uiv = oc_glProgramUniform4uiv_noimpl, - .ProgramUniformMatrix4x2dv = oc_glProgramUniformMatrix4x2dv_noimpl, - .FenceSync = oc_glFenceSync_noimpl, - .GetBufferParameteri64v = oc_glGetBufferParameteri64v_noimpl, - .StencilOp = oc_glStencilOp_noimpl, - .ClearBufferData = oc_glClearBufferData_noimpl, - .GetnUniformuiv = oc_glGetnUniformuiv_noimpl, - .GetProgramResourceiv = oc_glGetProgramResourceiv_noimpl, - .GetVertexAttribdv = oc_glGetVertexAttribdv_noimpl, - .GetTransformFeedbackVarying = oc_glGetTransformFeedbackVarying_noimpl, - .VertexAttrib2fv = oc_glVertexAttrib2fv_noimpl, - .GetBooleani_v = oc_glGetBooleani_v_noimpl, - .ColorMaski = oc_glColorMaski_noimpl, - .InvalidateBufferSubData = oc_glInvalidateBufferSubData_noimpl, - .UniformMatrix4dv = oc_glUniformMatrix4dv_noimpl, - .IsQuery = oc_glIsQuery_noimpl, - .Uniform4ui = oc_glUniform4ui_noimpl, - .Uniform4i = oc_glUniform4i_noimpl, - .GetSamplerParameteriv = oc_glGetSamplerParameteriv_noimpl, - .MultiDrawElementsBaseVertex = oc_glMultiDrawElementsBaseVertex_noimpl, - .VertexAttribI1uiv = oc_glVertexAttribI1uiv_noimpl, - .GetIntegerv = oc_glGetIntegerv_noimpl, - .UniformMatrix2x3fv = oc_glUniformMatrix2x3fv_noimpl, - .TexImage2D = oc_glTexImage2D_noimpl, - .GetAttachedShaders = oc_glGetAttachedShaders_noimpl, - .Uniform2d = oc_glUniform2d_noimpl, - .MemoryBarrierByRegion = oc_glMemoryBarrierByRegion_noimpl, - .UniformMatrix2fv = oc_glUniformMatrix2fv_noimpl, - .PrimitiveRestartIndex = oc_glPrimitiveRestartIndex_noimpl, - .GetVertexAttribiv = oc_glGetVertexAttribiv_noimpl, - .GetAttribLocation = oc_glGetAttribLocation_noimpl, - .TexStorage2DMultisample = oc_glTexStorage2DMultisample_noimpl, - .CompressedTexSubImage2D = oc_glCompressedTexSubImage2D_noimpl, - .GetVertexAttribfv = oc_glGetVertexAttribfv_noimpl, - .GetBufferParameteriv = oc_glGetBufferParameteriv_noimpl, - .TexParameterf = oc_glTexParameterf_noimpl, - .FramebufferTexture2D = oc_glFramebufferTexture2D_noimpl, - .GetActiveAttrib = oc_glGetActiveAttrib_noimpl, - .InvalidateTexSubImage = oc_glInvalidateTexSubImage_noimpl, - .DeleteVertexArrays = oc_glDeleteVertexArrays_noimpl, - .VertexAttribI2ui = oc_glVertexAttribI2ui_noimpl, - .PointParameteriv = oc_glPointParameteriv_noimpl, - .GetPointerv = oc_glGetPointerv_noimpl, - .Enablei = oc_glEnablei_noimpl, - .BindBufferRange = oc_glBindBufferRange_noimpl, - .DrawArraysInstanced = oc_glDrawArraysInstanced_noimpl, - .DeleteTextures = oc_glDeleteTextures_noimpl, - .VertexAttrib4Niv = oc_glVertexAttrib4Niv_noimpl, - .MultiDrawElements = oc_glMultiDrawElements_noimpl, - .GetProgramiv = oc_glGetProgramiv_noimpl, - .DepthFunc = oc_glDepthFunc_noimpl, - .GenTextures = oc_glGenTextures_noimpl, - .GetInternalformativ = oc_glGetInternalformativ_noimpl, - .ProgramUniform3i = oc_glProgramUniform3i_noimpl, - .ScissorIndexed = oc_glScissorIndexed_noimpl, - .VertexAttrib2sv = oc_glVertexAttrib2sv_noimpl, - .TexStorage3DMultisample = oc_glTexStorage3DMultisample_noimpl, - .Uniform2iv = oc_glUniform2iv_noimpl, - .DrawArraysInstancedBaseInstance = oc_glDrawArraysInstancedBaseInstance_noimpl, - .VertexAttribI3ui = oc_glVertexAttribI3ui_noimpl, - .DeleteSamplers = oc_glDeleteSamplers_noimpl, - .GenVertexArrays = oc_glGenVertexArrays_noimpl, - .GetFramebufferParameteriv = oc_glGetFramebufferParameteriv_noimpl, - .PolygonMode = oc_glPolygonMode_noimpl, - .ProgramUniformMatrix2x4fv = oc_glProgramUniformMatrix2x4fv_noimpl, - .GetProgramResourceName = oc_glGetProgramResourceName_noimpl, - .SamplerParameteriv = oc_glSamplerParameteriv_noimpl, - .GetActiveSubroutineUniformiv = oc_glGetActiveSubroutineUniformiv_noimpl, - .GetStringi = oc_glGetStringi_noimpl, - .VertexAttribLFormat = oc_glVertexAttribLFormat_noimpl, - .VertexAttrib3d = oc_glVertexAttrib3d_noimpl, - .BindVertexArray = oc_glBindVertexArray_noimpl, - .UnmapBuffer = oc_glUnmapBuffer_noimpl, - .DrawElementsInstancedBaseInstance = oc_glDrawElementsInstancedBaseInstance_noimpl, - .Uniform4uiv = oc_glUniform4uiv_noimpl, - .FramebufferTexture1D = oc_glFramebufferTexture1D_noimpl, - .DrawTransformFeedbackStreamInstanced = oc_glDrawTransformFeedbackStreamInstanced_noimpl, - .StencilFunc = oc_glStencilFunc_noimpl, - .ValidateProgram = oc_glValidateProgram_noimpl, - .Flush = oc_glFlush_noimpl, - .ProgramUniform3uiv = oc_glProgramUniform3uiv_noimpl, - .DeleteRenderbuffers = oc_glDeleteRenderbuffers_noimpl, - .VertexAttrib4fv = oc_glVertexAttrib4fv_noimpl, - .UniformMatrix2dv = oc_glUniformMatrix2dv_noimpl, - .GetFragDataIndex = oc_glGetFragDataIndex_noimpl, - .Uniform3iv = oc_glUniform3iv_noimpl, - .MinSampleShading = oc_glMinSampleShading_noimpl, - .GetBooleanv = oc_glGetBooleanv_noimpl, - .GetMultisamplefv = oc_glGetMultisamplefv_noimpl, - .GetVertexAttribIuiv = oc_glGetVertexAttribIuiv_noimpl, - .GetProgramInfoLog = oc_glGetProgramInfoLog_noimpl, - .Uniform4fv = oc_glUniform4fv_noimpl, - .DrawBuffer = oc_glDrawBuffer_noimpl, - .Uniform1i = oc_glUniform1i_noimpl, - .ProgramUniform4ui = oc_glProgramUniform4ui_noimpl, - .ProgramUniformMatrix3fv = oc_glProgramUniformMatrix3fv_noimpl, - .BlendEquationSeparate = oc_glBlendEquationSeparate_noimpl, - .BindProgramPipeline = oc_glBindProgramPipeline_noimpl, - .GetDoublei_v = oc_glGetDoublei_v_noimpl, - .BufferData = oc_glBufferData_noimpl, - .ClearColor = oc_glClearColor_noimpl, - .ProgramUniform4i = oc_glProgramUniform4i_noimpl, - .GetTexLevelParameteriv = oc_glGetTexLevelParameteriv_noimpl, - .GetActiveUniformBlockiv = oc_glGetActiveUniformBlockiv_noimpl, - .ProgramUniform1fv = oc_glProgramUniform1fv_noimpl, - .PauseTransformFeedback = oc_glPauseTransformFeedback_noimpl, - .GetBufferPointerv = oc_glGetBufferPointerv_noimpl, - .InvalidateSubFramebuffer = oc_glInvalidateSubFramebuffer_noimpl, - .ScissorIndexedv = oc_glScissorIndexedv_noimpl, - .Uniform2ui = oc_glUniform2ui_noimpl, - .BindTexture = oc_glBindTexture_noimpl, - .DrawElementsInstanced = oc_glDrawElementsInstanced_noimpl, - .ProgramUniform4f = oc_glProgramUniform4f_noimpl, - .BindBufferBase = oc_glBindBufferBase_noimpl, - .IsShader = oc_glIsShader_noimpl, - .ClearBufferSubData = oc_glClearBufferSubData_noimpl, - .VertexAttrib4Nuiv = oc_glVertexAttrib4Nuiv_noimpl, - .DrawArraysIndirect = oc_glDrawArraysIndirect_noimpl, - .VertexAttrib4usv = oc_glVertexAttrib4usv_noimpl, - .Uniform1d = oc_glUniform1d_noimpl, - .ClearTexImage = oc_glClearTexImage_noimpl, - .Uniform1uiv = oc_glUniform1uiv_noimpl, - .BindSampler = oc_glBindSampler_noimpl, - .GetTexLevelParameterfv = oc_glGetTexLevelParameterfv_noimpl, - .ClearBufferiv = oc_glClearBufferiv_noimpl, - .LogicOp = oc_glLogicOp_noimpl, - .ActiveTexture = oc_glActiveTexture_noimpl, - .GetFragDataLocation = oc_glGetFragDataLocation_noimpl, - .BlendColor = oc_glBlendColor_noimpl, - .UniformMatrix4x3fv = oc_glUniformMatrix4x3fv_noimpl, - .ProgramUniform3fv = oc_glProgramUniform3fv_noimpl, - .Uniform1fv = oc_glUniform1fv_noimpl, - .DrawElementsBaseVertex = oc_glDrawElementsBaseVertex_noimpl, - .Uniform4f = oc_glUniform4f_noimpl, - .BlendEquationSeparatei = oc_glBlendEquationSeparatei_noimpl, - .BlendFuncSeparate = oc_glBlendFuncSeparate_noimpl, - .ClearBufferuiv = oc_glClearBufferuiv_noimpl, - .CopyTexSubImage1D = oc_glCopyTexSubImage1D_noimpl, - .DrawTransformFeedback = oc_glDrawTransformFeedback_noimpl, - .ReadBuffer = oc_glReadBuffer_noimpl, - .CopyBufferSubData = oc_glCopyBufferSubData_noimpl, - .GetUniformuiv = oc_glGetUniformuiv_noimpl, - .PolygonOffset = oc_glPolygonOffset_noimpl, - .DispatchCompute = oc_glDispatchCompute_noimpl, - .BindImageTexture = oc_glBindImageTexture_noimpl, - .UniformMatrix4x3dv = oc_glUniformMatrix4x3dv_noimpl, - .GenRenderbuffers = oc_glGenRenderbuffers_noimpl, + .GetFloatv = oc_glGetFloatv_noimpl, + .TexBufferRange = oc_glTexBufferRange_noimpl, + .IsBuffer = oc_glIsBuffer_noimpl, + .IsTexture = oc_glIsTexture_noimpl, + .DepthRangef = oc_glDepthRangef_noimpl, + .EndConditionalRender = oc_glEndConditionalRender_noimpl, + .BlendFunci = oc_glBlendFunci_noimpl, + .GetProgramPipelineiv = oc_glGetProgramPipelineiv_noimpl, + .WaitSync = oc_glWaitSync_noimpl, + .ProgramUniformMatrix2fv = oc_glProgramUniformMatrix2fv_noimpl, + .ProgramUniformMatrix4x3dv = oc_glProgramUniformMatrix4x3dv_noimpl, + .VertexAttrib1dv = oc_glVertexAttrib1dv_noimpl, + .SamplerParameteri = oc_glSamplerParameteri_noimpl, + .GetVertexAttribIiv = oc_glGetVertexAttribIiv_noimpl, + .GetSamplerParameterfv = oc_glGetSamplerParameterfv_noimpl, + .VertexAttrib1d = oc_glVertexAttrib1d_noimpl, + .TexBuffer = oc_glTexBuffer_noimpl, + .InvalidateBufferData = oc_glInvalidateBufferData_noimpl, + .ProgramUniform2i = oc_glProgramUniform2i_noimpl, + .Uniform4dv = oc_glUniform4dv_noimpl, + .UseProgram = oc_glUseProgram_noimpl, + .VertexAttribI3iv = oc_glVertexAttribI3iv_noimpl, + .DrawElementsIndirect = oc_glDrawElementsIndirect_noimpl, + .VertexAttrib4uiv = oc_glVertexAttrib4uiv_noimpl, + .GetQueryObjectiv = oc_glGetQueryObjectiv_noimpl, + .FramebufferRenderbuffer = oc_glFramebufferRenderbuffer_noimpl, + .BlendEquationi = oc_glBlendEquationi_noimpl, + .GetActiveSubroutineName = oc_glGetActiveSubroutineName_noimpl, + .VertexAttrib2s = oc_glVertexAttrib2s_noimpl, + .VertexAttribL1d = oc_glVertexAttribL1d_noimpl, + .BindTextures = oc_glBindTextures_noimpl, + .VertexAttrib3sv = oc_glVertexAttrib3sv_noimpl, + .GetFloati_v = oc_glGetFloati_v_noimpl, + .BeginTransformFeedback = oc_glBeginTransformFeedback_noimpl, + .ClearStencil = oc_glClearStencil_noimpl, + .Uniform3i = oc_glUniform3i_noimpl, + .ValidateProgramPipeline = oc_glValidateProgramPipeline_noimpl, + .ProgramUniformMatrix4x2fv = oc_glProgramUniformMatrix4x2fv_noimpl, + .VertexAttribI4ui = oc_glVertexAttribI4ui_noimpl, + .GetShaderiv = oc_glGetShaderiv_noimpl, + .ReadnPixels = oc_glReadnPixels_noimpl, + .UniformMatrix4x2fv = oc_glUniformMatrix4x2fv_noimpl, + .GetShaderPrecisionFormat = oc_glGetShaderPrecisionFormat_noimpl, + .ProgramUniformMatrix2x3fv = oc_glProgramUniformMatrix2x3fv_noimpl, + .TexSubImage3D = oc_glTexSubImage3D_noimpl, + .GetProgramResourceLocationIndex = oc_glGetProgramResourceLocationIndex_noimpl, + .BlendFunc = oc_glBlendFunc_noimpl, + .ProgramUniformMatrix3x4fv = oc_glProgramUniformMatrix3x4fv_noimpl, + .Uniform3d = oc_glUniform3d_noimpl, + .VertexAttrib1sv = oc_glVertexAttrib1sv_noimpl, + .BindFragDataLocation = oc_glBindFragDataLocation_noimpl, + .VertexAttrib4bv = oc_glVertexAttrib4bv_noimpl, + .Uniform4iv = oc_glUniform4iv_noimpl, + .ProgramUniform2ui = oc_glProgramUniform2ui_noimpl, + .DrawArrays = oc_glDrawArrays_noimpl, + .ProgramBinary = oc_glProgramBinary_noimpl, + .VertexAttrib4f = oc_glVertexAttrib4f_noimpl, + .VertexAttribP2uiv = oc_glVertexAttribP2uiv_noimpl, + .UniformMatrix3fv = oc_glUniformMatrix3fv_noimpl, + .Uniform2i = oc_glUniform2i_noimpl, + .GetQueryObjectuiv = oc_glGetQueryObjectuiv_noimpl, + .UniformBlockBinding = oc_glUniformBlockBinding_noimpl, + .SampleCoverage = oc_glSampleCoverage_noimpl, + .VertexAttrib4Nusv = oc_glVertexAttrib4Nusv_noimpl, + .ProgramUniformMatrix2x4dv = oc_glProgramUniformMatrix2x4dv_noimpl, + .Uniform3uiv = oc_glUniform3uiv_noimpl, + .VertexAttrib1s = oc_glVertexAttrib1s_noimpl, + .GetVertexAttribPointerv = oc_glGetVertexAttribPointerv_noimpl, + .BlendBarrier = oc_glBlendBarrier_noimpl, + .DrawRangeElements = oc_glDrawRangeElements_noimpl, + .TexStorage3D = oc_glTexStorage3D_noimpl, + .GetInternalformati64v = oc_glGetInternalformati64v_noimpl, + .GetQueryObjecti64v = oc_glGetQueryObjecti64v_noimpl, + .CompressedTexSubImage1D = oc_glCompressedTexSubImage1D_noimpl, + .VertexAttrib3dv = oc_glVertexAttrib3dv_noimpl, + .VertexBindingDivisor = oc_glVertexBindingDivisor_noimpl, + .UseProgramStages = oc_glUseProgramStages_noimpl, + .VertexAttribBinding = oc_glVertexAttribBinding_noimpl, + .DebugMessageInsert = oc_glDebugMessageInsert_noimpl, + .GetTexParameteriv = oc_glGetTexParameteriv_noimpl, + .MultiDrawArraysIndirect = oc_glMultiDrawArraysIndirect_noimpl, + .GetTexParameterfv = oc_glGetTexParameterfv_noimpl, + .GetProgramPipelineInfoLog = oc_glGetProgramPipelineInfoLog_noimpl, + .EndQuery = oc_glEndQuery_noimpl, + .GetProgramResourceLocation = oc_glGetProgramResourceLocation_noimpl, + .CompressedTexImage2D = oc_glCompressedTexImage2D_noimpl, + .VertexAttribP2ui = oc_glVertexAttribP2ui_noimpl, + .IsEnabledi = oc_glIsEnabledi_noimpl, + .GetActiveAtomicCounterBufferiv = oc_glGetActiveAtomicCounterBufferiv_noimpl, + .IsProgram = oc_glIsProgram_noimpl, + .Uniform1dv = oc_glUniform1dv_noimpl, + .TexParameteriv = oc_glTexParameteriv_noimpl, + .Uniform2fv = oc_glUniform2fv_noimpl, + .ReleaseShaderCompiler = oc_glReleaseShaderCompiler_noimpl, + .CullFace = oc_glCullFace_noimpl, + .VertexAttribI4i = oc_glVertexAttribI4i_noimpl, + .GetProgramResourceIndex = oc_glGetProgramResourceIndex_noimpl, + .ShaderBinary = oc_glShaderBinary_noimpl, + .UniformMatrix3x2dv = oc_glUniformMatrix3x2dv_noimpl, + .InvalidateFramebuffer = oc_glInvalidateFramebuffer_noimpl, + .AttachShader = oc_glAttachShader_noimpl, + .FlushMappedBufferRange = oc_glFlushMappedBufferRange_noimpl, + .VertexAttribP3uiv = oc_glVertexAttribP3uiv_noimpl, + .GetActiveUniformName = oc_glGetActiveUniformName_noimpl, + .MapBuffer = oc_glMapBuffer_noimpl, + .DrawBuffers = oc_glDrawBuffers_noimpl, + .GetSynciv = oc_glGetSynciv_noimpl, + .CopyTexSubImage2D = oc_glCopyTexSubImage2D_noimpl, + .ObjectLabel = oc_glObjectLabel_noimpl, + .BufferSubData = oc_glBufferSubData_noimpl, + .Uniform2f = oc_glUniform2f_noimpl, + .DebugMessageCallback = oc_glDebugMessageCallback_noimpl, + .VertexAttribL4dv = oc_glVertexAttribL4dv_noimpl, + .IsProgramPipeline = oc_glIsProgramPipeline_noimpl, + .ResumeTransformFeedback = oc_glResumeTransformFeedback_noimpl, + .VertexAttribI4iv = oc_glVertexAttribI4iv_noimpl, + .GetShaderInfoLog = oc_glGetShaderInfoLog_noimpl, + .GetIntegeri_v = oc_glGetIntegeri_v_noimpl, + .BindVertexBuffer = oc_glBindVertexBuffer_noimpl, + .BlendEquation = oc_glBlendEquation_noimpl, + .VertexAttribL2dv = oc_glVertexAttribL2dv_noimpl, + .VertexAttribI1ui = oc_glVertexAttribI1ui_noimpl, + .VertexAttrib4Nsv = oc_glVertexAttrib4Nsv_noimpl, + .VertexAttribL4d = oc_glVertexAttribL4d_noimpl, + .CopyImageSubData = oc_glCopyImageSubData_noimpl, + .GetFramebufferAttachmentParameteriv = oc_glGetFramebufferAttachmentParameteriv_noimpl, + .VertexAttribL2d = oc_glVertexAttribL2d_noimpl, + .GetSubroutineIndex = oc_glGetSubroutineIndex_noimpl, + .VertexAttribI3uiv = oc_glVertexAttribI3uiv_noimpl, + .VertexAttrib4iv = oc_glVertexAttrib4iv_noimpl, + .BindVertexBuffers = oc_glBindVertexBuffers_noimpl, + .ProgramUniformMatrix2x3dv = oc_glProgramUniformMatrix2x3dv_noimpl, + .PrimitiveBoundingBox = oc_glPrimitiveBoundingBox_noimpl, + .Scissor = oc_glScissor_noimpl, + .ClientWaitSync = oc_glClientWaitSync_noimpl, + .Uniform3ui = oc_glUniform3ui_noimpl, + .VertexAttribP3ui = oc_glVertexAttribP3ui_noimpl, + .Enable = oc_glEnable_noimpl, + .StencilOpSeparate = oc_glStencilOpSeparate_noimpl, + .UniformMatrix2x3dv = oc_glUniformMatrix2x3dv_noimpl, + .ProgramUniformMatrix3dv = oc_glProgramUniformMatrix3dv_noimpl, + .TexImage2DMultisample = oc_glTexImage2DMultisample_noimpl, + .VertexAttrib4Nbv = oc_glVertexAttrib4Nbv_noimpl, + .GetTexImage = oc_glGetTexImage_noimpl, + .VertexAttrib4sv = oc_glVertexAttrib4sv_noimpl, + .PixelStorei = oc_glPixelStorei_noimpl, + .DepthMask = oc_glDepthMask_noimpl, + .TexStorage2D = oc_glTexStorage2D_noimpl, + .Clear = oc_glClear_noimpl, + .UniformMatrix3x4dv = oc_glUniformMatrix3x4dv_noimpl, + .DeleteTransformFeedbacks = oc_glDeleteTransformFeedbacks_noimpl, + .MapBufferRange = oc_glMapBufferRange_noimpl, + .MemoryBarrier = oc_glMemoryBarrier_noimpl, + .ViewportIndexedf = oc_glViewportIndexedf_noimpl, + .VertexAttrib3fv = oc_glVertexAttrib3fv_noimpl, + .ObjectPtrLabel = oc_glObjectPtrLabel_noimpl, + .TexStorage1D = oc_glTexStorage1D_noimpl, + .CompressedTexImage3D = oc_glCompressedTexImage3D_noimpl, + .VertexAttrib1fv = oc_glVertexAttrib1fv_noimpl, + .VertexAttribPointer = oc_glVertexAttribPointer_noimpl, + .GetQueryIndexediv = oc_glGetQueryIndexediv_noimpl, + .CompileShader = oc_glCompileShader_noimpl, + .ProgramUniform1i = oc_glProgramUniform1i_noimpl, + .GetQueryiv = oc_glGetQueryiv_noimpl, + .VertexAttribI1iv = oc_glVertexAttribI1iv_noimpl, + .CopyTexImage2D = oc_glCopyTexImage2D_noimpl, + .GetQueryObjectui64v = oc_glGetQueryObjectui64v_noimpl, + .PointSize = oc_glPointSize_noimpl, + .Disablei = oc_glDisablei_noimpl, + .VertexAttribL1dv = oc_glVertexAttribL1dv_noimpl, + .CreateShader = oc_glCreateShader_noimpl, + .GetString = oc_glGetString_noimpl, + .ViewportArrayv = oc_glViewportArrayv_noimpl, + .ProgramUniform3d = oc_glProgramUniform3d_noimpl, + .VertexAttrib4Nubv = oc_glVertexAttrib4Nubv_noimpl, + .TexParameteri = oc_glTexParameteri_noimpl, + .ProgramUniform4fv = oc_glProgramUniform4fv_noimpl, + .GenerateMipmap = oc_glGenerateMipmap_noimpl, + .CompressedTexSubImage3D = oc_glCompressedTexSubImage3D_noimpl, + .Uniform3f = oc_glUniform3f_noimpl, + .GetUniformIndices = oc_glGetUniformIndices_noimpl, + .VertexAttribLPointer = oc_glVertexAttribLPointer_noimpl, + .VertexAttribI2uiv = oc_glVertexAttribI2uiv_noimpl, + .QueryCounter = oc_glQueryCounter_noimpl, + .ActiveShaderProgram = oc_glActiveShaderProgram_noimpl, + .Uniform1ui = oc_glUniform1ui_noimpl, + .VertexAttribI1i = oc_glVertexAttribI1i_noimpl, + .GetTexParameterIiv = oc_glGetTexParameterIiv_noimpl, + .GetUniformfv = oc_glGetUniformfv_noimpl, + .ProgramUniform2uiv = oc_glProgramUniform2uiv_noimpl, + .GetError = oc_glGetError_noimpl, + .GetActiveUniformBlockName = oc_glGetActiveUniformBlockName_noimpl, + .TextureView = oc_glTextureView_noimpl, + .GetnUniformiv = oc_glGetnUniformiv_noimpl, + .ProgramUniform4dv = oc_glProgramUniform4dv_noimpl, + .ViewportIndexedfv = oc_glViewportIndexedfv_noimpl, + .Hint = oc_glHint_noimpl, + .GetShaderSource = oc_glGetShaderSource_noimpl, + .ProgramUniformMatrix4x3fv = oc_glProgramUniformMatrix4x3fv_noimpl, + .Uniform1iv = oc_glUniform1iv_noimpl, + .VertexAttribI4bv = oc_glVertexAttribI4bv_noimpl, + .UniformMatrix4x2dv = oc_glUniformMatrix4x2dv_noimpl, + .BufferStorage = oc_glBufferStorage_noimpl, + .IsRenderbuffer = oc_glIsRenderbuffer_noimpl, + .GetActiveSubroutineUniformName = oc_glGetActiveSubroutineUniformName_noimpl, + .LinkProgram = oc_glLinkProgram_noimpl, + .GetActiveUniformsiv = oc_glGetActiveUniformsiv_noimpl, + .GetDebugMessageLog = oc_glGetDebugMessageLog_noimpl, + .CopyTexSubImage3D = oc_glCopyTexSubImage3D_noimpl, + .PointParameteri = oc_glPointParameteri_noimpl, + .ProgramUniform3dv = oc_glProgramUniform3dv_noimpl, + .CompressedTexImage1D = oc_glCompressedTexImage1D_noimpl, + .UniformMatrix3x4fv = oc_glUniformMatrix3x4fv_noimpl, + .GenSamplers = oc_glGenSamplers_noimpl, + .GetCompressedTexImage = oc_glGetCompressedTexImage_noimpl, + .DeleteQueries = oc_glDeleteQueries_noimpl, + .GenProgramPipelines = oc_glGenProgramPipelines_noimpl, + .DispatchComputeIndirect = oc_glDispatchComputeIndirect_noimpl, + .VertexAttribIPointer = oc_glVertexAttribIPointer_noimpl, + .CreateProgram = oc_glCreateProgram_noimpl, + .ClearTexSubImage = oc_glClearTexSubImage_noimpl, + .VertexAttrib4d = oc_glVertexAttrib4d_noimpl, + .FrontFace = oc_glFrontFace_noimpl, + .BindTransformFeedback = oc_glBindTransformFeedback_noimpl, + .GetProgramStageiv = oc_glGetProgramStageiv_noimpl, + .SamplerParameterIiv = oc_glSamplerParameterIiv_noimpl, + .GetInteger64v = oc_glGetInteger64v_noimpl, + .CreateShaderProgramv = oc_glCreateShaderProgramv_noimpl, + .BindBuffersRange = oc_glBindBuffersRange_noimpl, + .Uniform3fv = oc_glUniform3fv_noimpl, + .ProgramUniformMatrix4fv = oc_glProgramUniformMatrix4fv_noimpl, + .BindBuffersBase = oc_glBindBuffersBase_noimpl, + .ClearBufferfi = oc_glClearBufferfi_noimpl, + .FramebufferTexture3D = oc_glFramebufferTexture3D_noimpl, + .Disable = oc_glDisable_noimpl, + .ProgramUniform1iv = oc_glProgramUniform1iv_noimpl, + .VertexAttribI2iv = oc_glVertexAttribI2iv_noimpl, + .DepthRangeIndexed = oc_glDepthRangeIndexed_noimpl, + .PatchParameteri = oc_glPatchParameteri_noimpl, + .GetUniformBlockIndex = oc_glGetUniformBlockIndex_noimpl, + .MultiDrawArrays = oc_glMultiDrawArrays_noimpl, + .VertexAttribI4ubv = oc_glVertexAttribI4ubv_noimpl, + .BindBuffer = oc_glBindBuffer_noimpl, + .VertexAttribI3i = oc_glVertexAttribI3i_noimpl, + .GetDoublev = oc_glGetDoublev_noimpl, + .DrawTransformFeedbackStream = oc_glDrawTransformFeedbackStream_noimpl, + .VertexAttribI4uiv = oc_glVertexAttribI4uiv_noimpl, + .RenderbufferStorageMultisample = oc_glRenderbufferStorageMultisample_noimpl, + .VertexAttribL3dv = oc_glVertexAttribL3dv_noimpl, + .StencilMaskSeparate = oc_glStencilMaskSeparate_noimpl, + .ProgramUniform1d = oc_glProgramUniform1d_noimpl, + .Viewport = oc_glViewport_noimpl, + .VertexAttribP1ui = oc_glVertexAttribP1ui_noimpl, + .VertexAttrib4dv = oc_glVertexAttrib4dv_noimpl, + .GenQueries = oc_glGenQueries_noimpl, + .TexParameterIiv = oc_glTexParameterIiv_noimpl, + .ProgramUniform2d = oc_glProgramUniform2d_noimpl, + .ProgramUniform1uiv = oc_glProgramUniform1uiv_noimpl, + .VertexAttrib4Nub = oc_glVertexAttrib4Nub_noimpl, + .IsVertexArray = oc_glIsVertexArray_noimpl, + .ProgramUniform3f = oc_glProgramUniform3f_noimpl, + .ProgramUniform3iv = oc_glProgramUniform3iv_noimpl, + .GetProgramBinary = oc_glGetProgramBinary_noimpl, + .BindRenderbuffer = oc_glBindRenderbuffer_noimpl, + .BindFragDataLocationIndexed = oc_glBindFragDataLocationIndexed_noimpl, + .GetSamplerParameterIiv = oc_glGetSamplerParameterIiv_noimpl, + .VertexAttribDivisor = oc_glVertexAttribDivisor_noimpl, + .ProgramUniformMatrix3x2dv = oc_glProgramUniformMatrix3x2dv_noimpl, + .FramebufferParameteri = oc_glFramebufferParameteri_noimpl, + .GenTransformFeedbacks = oc_glGenTransformFeedbacks_noimpl, + .DeleteSync = oc_glDeleteSync_noimpl, + .ProgramUniform1ui = oc_glProgramUniform1ui_noimpl, + .TexSubImage1D = oc_glTexSubImage1D_noimpl, + .ClearDepthf = oc_glClearDepthf_noimpl, + .ReadPixels = oc_glReadPixels_noimpl, + .VertexAttribI2i = oc_glVertexAttribI2i_noimpl, + .Finish = oc_glFinish_noimpl, + .LineWidth = oc_glLineWidth_noimpl, + .DeleteShader = oc_glDeleteShader_noimpl, + .IsSampler = oc_glIsSampler_noimpl, + .ProgramUniformMatrix4dv = oc_glProgramUniformMatrix4dv_noimpl, + .TransformFeedbackVaryings = oc_glTransformFeedbackVaryings_noimpl, + .BeginConditionalRender = oc_glBeginConditionalRender_noimpl, + .BindSamplers = oc_glBindSamplers_noimpl, + .DeleteProgramPipelines = oc_glDeleteProgramPipelines_noimpl, + .ColorMask = oc_glColorMask_noimpl, + .TexParameterfv = oc_glTexParameterfv_noimpl, + .PushDebugGroup = oc_glPushDebugGroup_noimpl, + .ClearBufferfv = oc_glClearBufferfv_noimpl, + .IsEnabled = oc_glIsEnabled_noimpl, + .VertexAttrib2f = oc_glVertexAttrib2f_noimpl, + .ProgramUniform2f = oc_glProgramUniform2f_noimpl, + .GetSamplerParameterIuiv = oc_glGetSamplerParameterIuiv_noimpl, + .GetInteger64i_v = oc_glGetInteger64i_v_noimpl, + .Uniform2dv = oc_glUniform2dv_noimpl, + .GetBufferSubData = oc_glGetBufferSubData_noimpl, + .MultiDrawElementsIndirect = oc_glMultiDrawElementsIndirect_noimpl, + .ProgramParameteri = oc_glProgramParameteri_noimpl, + .VertexAttribP4ui = oc_glVertexAttribP4ui_noimpl, + .SamplerParameterfv = oc_glSamplerParameterfv_noimpl, + .PointParameterf = oc_glPointParameterf_noimpl, + .UniformMatrix2x4fv = oc_glUniformMatrix2x4fv_noimpl, + .GenBuffers = oc_glGenBuffers_noimpl, + .ProgramUniform2dv = oc_glProgramUniform2dv_noimpl, + .VertexAttribFormat = oc_glVertexAttribFormat_noimpl, + .TexSubImage2D = oc_glTexSubImage2D_noimpl, + .VertexAttrib4ubv = oc_glVertexAttrib4ubv_noimpl, + .GetGraphicsResetStatus = oc_glGetGraphicsResetStatus_noimpl, + .GetProgramInterfaceiv = oc_glGetProgramInterfaceiv_noimpl, + .VertexAttribIFormat = oc_glVertexAttribIFormat_noimpl, + .GetnUniformfv = oc_glGetnUniformfv_noimpl, + .DeleteProgram = oc_glDeleteProgram_noimpl, + .ClampColor = oc_glClampColor_noimpl, + .DrawElementsInstancedBaseVertexBaseInstance = oc_glDrawElementsInstancedBaseVertexBaseInstance_noimpl, + .DrawElements = oc_glDrawElements_noimpl, + .DebugMessageControl = oc_glDebugMessageControl_noimpl, + .GetRenderbufferParameteriv = oc_glGetRenderbufferParameteriv_noimpl, + .DetachShader = oc_glDetachShader_noimpl, + .GenFramebuffers = oc_glGenFramebuffers_noimpl, + .ProvokingVertex = oc_glProvokingVertex_noimpl, + .SampleMaski = oc_glSampleMaski_noimpl, + .EndQueryIndexed = oc_glEndQueryIndexed_noimpl, + .ProgramUniform1f = oc_glProgramUniform1f_noimpl, + .BindFramebuffer = oc_glBindFramebuffer_noimpl, + .BeginQueryIndexed = oc_glBeginQueryIndexed_noimpl, + .UniformSubroutinesuiv = oc_glUniformSubroutinesuiv_noimpl, + .GetUniformiv = oc_glGetUniformiv_noimpl, + .FramebufferTexture = oc_glFramebufferTexture_noimpl, + .PointParameterfv = oc_glPointParameterfv_noimpl, + .IsTransformFeedback = oc_glIsTransformFeedback_noimpl, + .CheckFramebufferStatus = oc_glCheckFramebufferStatus_noimpl, + .ShaderSource = oc_glShaderSource_noimpl, + .UniformMatrix2x4dv = oc_glUniformMatrix2x4dv_noimpl, + .BindImageTextures = oc_glBindImageTextures_noimpl, + .CopyTexImage1D = oc_glCopyTexImage1D_noimpl, + .UniformMatrix3dv = oc_glUniformMatrix3dv_noimpl, + .ProgramUniform1dv = oc_glProgramUniform1dv_noimpl, + .BlitFramebuffer = oc_glBlitFramebuffer_noimpl, + .PopDebugGroup = oc_glPopDebugGroup_noimpl, + .TexParameterIuiv = oc_glTexParameterIuiv_noimpl, + .VertexAttrib2d = oc_glVertexAttrib2d_noimpl, + .TexImage1D = oc_glTexImage1D_noimpl, + .GetObjectPtrLabel = oc_glGetObjectPtrLabel_noimpl, + .StencilMask = oc_glStencilMask_noimpl, + .BeginQuery = oc_glBeginQuery_noimpl, + .UniformMatrix4fv = oc_glUniformMatrix4fv_noimpl, + .IsSync = oc_glIsSync_noimpl, + .Uniform3dv = oc_glUniform3dv_noimpl, + .ProgramUniform2fv = oc_glProgramUniform2fv_noimpl, + .VertexAttribI4sv = oc_glVertexAttribI4sv_noimpl, + .ScissorArrayv = oc_glScissorArrayv_noimpl, + .VertexAttribP1uiv = oc_glVertexAttribP1uiv_noimpl, + .Uniform2uiv = oc_glUniform2uiv_noimpl, + .DeleteBuffers = oc_glDeleteBuffers_noimpl, + .ProgramUniform3ui = oc_glProgramUniform3ui_noimpl, + .FramebufferTextureLayer = oc_glFramebufferTextureLayer_noimpl, + .EndTransformFeedback = oc_glEndTransformFeedback_noimpl, + .BlendFuncSeparatei = oc_glBlendFuncSeparatei_noimpl, + .DrawTransformFeedbackInstanced = oc_glDrawTransformFeedbackInstanced_noimpl, + .DrawRangeElementsBaseVertex = oc_glDrawRangeElementsBaseVertex_noimpl, + .VertexAttrib1f = oc_glVertexAttrib1f_noimpl, + .GetUniformSubroutineuiv = oc_glGetUniformSubroutineuiv_noimpl, + .DisableVertexAttribArray = oc_glDisableVertexAttribArray_noimpl, + .ProgramUniformMatrix3x2fv = oc_glProgramUniformMatrix3x2fv_noimpl, + .VertexAttribI4usv = oc_glVertexAttribI4usv_noimpl, + .GetObjectLabel = oc_glGetObjectLabel_noimpl, + .BindAttribLocation = oc_glBindAttribLocation_noimpl, + .Uniform1f = oc_glUniform1f_noimpl, + .GetUniformdv = oc_glGetUniformdv_noimpl, + .GetUniformLocation = oc_glGetUniformLocation_noimpl, + .GetSubroutineUniformLocation = oc_glGetSubroutineUniformLocation_noimpl, + .GetTexParameterIuiv = oc_glGetTexParameterIuiv_noimpl, + .SamplerParameterf = oc_glSamplerParameterf_noimpl, + .VertexAttribL3d = oc_glVertexAttribL3d_noimpl, + .TexImage3DMultisample = oc_glTexImage3DMultisample_noimpl, + .TexImage3D = oc_glTexImage3D_noimpl, + .RenderbufferStorage = oc_glRenderbufferStorage_noimpl, + .EnableVertexAttribArray = oc_glEnableVertexAttribArray_noimpl, + .VertexAttribP4uiv = oc_glVertexAttribP4uiv_noimpl, + .Uniform4d = oc_glUniform4d_noimpl, + .VertexAttrib4s = oc_glVertexAttrib4s_noimpl, + .DrawElementsInstancedBaseVertex = oc_glDrawElementsInstancedBaseVertex_noimpl, + .VertexAttrib3s = oc_glVertexAttrib3s_noimpl, + .ProgramUniform2iv = oc_glProgramUniform2iv_noimpl, + .StencilFuncSeparate = oc_glStencilFuncSeparate_noimpl, + .DeleteFramebuffers = oc_glDeleteFramebuffers_noimpl, + .DepthRange = oc_glDepthRange_noimpl, + .UniformMatrix3x2fv = oc_glUniformMatrix3x2fv_noimpl, + .ProgramUniformMatrix2dv = oc_glProgramUniformMatrix2dv_noimpl, + .ShaderStorageBlockBinding = oc_glShaderStorageBlockBinding_noimpl, + .ClearDepth = oc_glClearDepth_noimpl, + .VertexAttrib2dv = oc_glVertexAttrib2dv_noimpl, + .SamplerParameterIuiv = oc_glSamplerParameterIuiv_noimpl, + .GetVertexAttribLdv = oc_glGetVertexAttribLdv_noimpl, + .ProgramUniformMatrix3x4dv = oc_glProgramUniformMatrix3x4dv_noimpl, + .DepthRangeArrayv = oc_glDepthRangeArrayv_noimpl, + .GetActiveUniform = oc_glGetActiveUniform_noimpl, + .PatchParameterfv = oc_glPatchParameterfv_noimpl, + .InvalidateTexImage = oc_glInvalidateTexImage_noimpl, + .VertexAttrib3f = oc_glVertexAttrib3f_noimpl, + .ProgramUniform4iv = oc_glProgramUniform4iv_noimpl, + .ProgramUniform4d = oc_glProgramUniform4d_noimpl, + .IsFramebuffer = oc_glIsFramebuffer_noimpl, + .PixelStoref = oc_glPixelStoref_noimpl, + .ProgramUniform4uiv = oc_glProgramUniform4uiv_noimpl, + .ProgramUniformMatrix4x2dv = oc_glProgramUniformMatrix4x2dv_noimpl, + .FenceSync = oc_glFenceSync_noimpl, + .GetBufferParameteri64v = oc_glGetBufferParameteri64v_noimpl, + .StencilOp = oc_glStencilOp_noimpl, + .ClearBufferData = oc_glClearBufferData_noimpl, + .GetnUniformuiv = oc_glGetnUniformuiv_noimpl, + .GetProgramResourceiv = oc_glGetProgramResourceiv_noimpl, + .GetVertexAttribdv = oc_glGetVertexAttribdv_noimpl, + .GetTransformFeedbackVarying = oc_glGetTransformFeedbackVarying_noimpl, + .VertexAttrib2fv = oc_glVertexAttrib2fv_noimpl, + .GetBooleani_v = oc_glGetBooleani_v_noimpl, + .ColorMaski = oc_glColorMaski_noimpl, + .InvalidateBufferSubData = oc_glInvalidateBufferSubData_noimpl, + .UniformMatrix4dv = oc_glUniformMatrix4dv_noimpl, + .IsQuery = oc_glIsQuery_noimpl, + .Uniform4ui = oc_glUniform4ui_noimpl, + .Uniform4i = oc_glUniform4i_noimpl, + .GetSamplerParameteriv = oc_glGetSamplerParameteriv_noimpl, + .MultiDrawElementsBaseVertex = oc_glMultiDrawElementsBaseVertex_noimpl, + .VertexAttribI1uiv = oc_glVertexAttribI1uiv_noimpl, + .GetIntegerv = oc_glGetIntegerv_noimpl, + .UniformMatrix2x3fv = oc_glUniformMatrix2x3fv_noimpl, + .TexImage2D = oc_glTexImage2D_noimpl, + .GetAttachedShaders = oc_glGetAttachedShaders_noimpl, + .Uniform2d = oc_glUniform2d_noimpl, + .MemoryBarrierByRegion = oc_glMemoryBarrierByRegion_noimpl, + .UniformMatrix2fv = oc_glUniformMatrix2fv_noimpl, + .PrimitiveRestartIndex = oc_glPrimitiveRestartIndex_noimpl, + .GetVertexAttribiv = oc_glGetVertexAttribiv_noimpl, + .GetAttribLocation = oc_glGetAttribLocation_noimpl, + .TexStorage2DMultisample = oc_glTexStorage2DMultisample_noimpl, + .CompressedTexSubImage2D = oc_glCompressedTexSubImage2D_noimpl, + .GetVertexAttribfv = oc_glGetVertexAttribfv_noimpl, + .GetBufferParameteriv = oc_glGetBufferParameteriv_noimpl, + .TexParameterf = oc_glTexParameterf_noimpl, + .FramebufferTexture2D = oc_glFramebufferTexture2D_noimpl, + .GetActiveAttrib = oc_glGetActiveAttrib_noimpl, + .InvalidateTexSubImage = oc_glInvalidateTexSubImage_noimpl, + .DeleteVertexArrays = oc_glDeleteVertexArrays_noimpl, + .VertexAttribI2ui = oc_glVertexAttribI2ui_noimpl, + .PointParameteriv = oc_glPointParameteriv_noimpl, + .GetPointerv = oc_glGetPointerv_noimpl, + .Enablei = oc_glEnablei_noimpl, + .BindBufferRange = oc_glBindBufferRange_noimpl, + .DrawArraysInstanced = oc_glDrawArraysInstanced_noimpl, + .DeleteTextures = oc_glDeleteTextures_noimpl, + .VertexAttrib4Niv = oc_glVertexAttrib4Niv_noimpl, + .MultiDrawElements = oc_glMultiDrawElements_noimpl, + .GetProgramiv = oc_glGetProgramiv_noimpl, + .DepthFunc = oc_glDepthFunc_noimpl, + .GenTextures = oc_glGenTextures_noimpl, + .GetInternalformativ = oc_glGetInternalformativ_noimpl, + .ProgramUniform3i = oc_glProgramUniform3i_noimpl, + .ScissorIndexed = oc_glScissorIndexed_noimpl, + .VertexAttrib2sv = oc_glVertexAttrib2sv_noimpl, + .TexStorage3DMultisample = oc_glTexStorage3DMultisample_noimpl, + .Uniform2iv = oc_glUniform2iv_noimpl, + .DrawArraysInstancedBaseInstance = oc_glDrawArraysInstancedBaseInstance_noimpl, + .VertexAttribI3ui = oc_glVertexAttribI3ui_noimpl, + .DeleteSamplers = oc_glDeleteSamplers_noimpl, + .GenVertexArrays = oc_glGenVertexArrays_noimpl, + .GetFramebufferParameteriv = oc_glGetFramebufferParameteriv_noimpl, + .PolygonMode = oc_glPolygonMode_noimpl, + .ProgramUniformMatrix2x4fv = oc_glProgramUniformMatrix2x4fv_noimpl, + .GetProgramResourceName = oc_glGetProgramResourceName_noimpl, + .SamplerParameteriv = oc_glSamplerParameteriv_noimpl, + .GetActiveSubroutineUniformiv = oc_glGetActiveSubroutineUniformiv_noimpl, + .GetStringi = oc_glGetStringi_noimpl, + .VertexAttribLFormat = oc_glVertexAttribLFormat_noimpl, + .VertexAttrib3d = oc_glVertexAttrib3d_noimpl, + .BindVertexArray = oc_glBindVertexArray_noimpl, + .UnmapBuffer = oc_glUnmapBuffer_noimpl, + .DrawElementsInstancedBaseInstance = oc_glDrawElementsInstancedBaseInstance_noimpl, + .Uniform4uiv = oc_glUniform4uiv_noimpl, + .FramebufferTexture1D = oc_glFramebufferTexture1D_noimpl, + .DrawTransformFeedbackStreamInstanced = oc_glDrawTransformFeedbackStreamInstanced_noimpl, + .StencilFunc = oc_glStencilFunc_noimpl, + .ValidateProgram = oc_glValidateProgram_noimpl, + .Flush = oc_glFlush_noimpl, + .ProgramUniform3uiv = oc_glProgramUniform3uiv_noimpl, + .DeleteRenderbuffers = oc_glDeleteRenderbuffers_noimpl, + .VertexAttrib4fv = oc_glVertexAttrib4fv_noimpl, + .UniformMatrix2dv = oc_glUniformMatrix2dv_noimpl, + .GetFragDataIndex = oc_glGetFragDataIndex_noimpl, + .Uniform3iv = oc_glUniform3iv_noimpl, + .MinSampleShading = oc_glMinSampleShading_noimpl, + .GetBooleanv = oc_glGetBooleanv_noimpl, + .GetMultisamplefv = oc_glGetMultisamplefv_noimpl, + .GetVertexAttribIuiv = oc_glGetVertexAttribIuiv_noimpl, + .GetProgramInfoLog = oc_glGetProgramInfoLog_noimpl, + .Uniform4fv = oc_glUniform4fv_noimpl, + .DrawBuffer = oc_glDrawBuffer_noimpl, + .Uniform1i = oc_glUniform1i_noimpl, + .ProgramUniform4ui = oc_glProgramUniform4ui_noimpl, + .ProgramUniformMatrix3fv = oc_glProgramUniformMatrix3fv_noimpl, + .BlendEquationSeparate = oc_glBlendEquationSeparate_noimpl, + .BindProgramPipeline = oc_glBindProgramPipeline_noimpl, + .GetDoublei_v = oc_glGetDoublei_v_noimpl, + .BufferData = oc_glBufferData_noimpl, + .ClearColor = oc_glClearColor_noimpl, + .ProgramUniform4i = oc_glProgramUniform4i_noimpl, + .GetTexLevelParameteriv = oc_glGetTexLevelParameteriv_noimpl, + .GetActiveUniformBlockiv = oc_glGetActiveUniformBlockiv_noimpl, + .ProgramUniform1fv = oc_glProgramUniform1fv_noimpl, + .PauseTransformFeedback = oc_glPauseTransformFeedback_noimpl, + .GetBufferPointerv = oc_glGetBufferPointerv_noimpl, + .InvalidateSubFramebuffer = oc_glInvalidateSubFramebuffer_noimpl, + .ScissorIndexedv = oc_glScissorIndexedv_noimpl, + .Uniform2ui = oc_glUniform2ui_noimpl, + .BindTexture = oc_glBindTexture_noimpl, + .DrawElementsInstanced = oc_glDrawElementsInstanced_noimpl, + .ProgramUniform4f = oc_glProgramUniform4f_noimpl, + .BindBufferBase = oc_glBindBufferBase_noimpl, + .IsShader = oc_glIsShader_noimpl, + .ClearBufferSubData = oc_glClearBufferSubData_noimpl, + .VertexAttrib4Nuiv = oc_glVertexAttrib4Nuiv_noimpl, + .DrawArraysIndirect = oc_glDrawArraysIndirect_noimpl, + .VertexAttrib4usv = oc_glVertexAttrib4usv_noimpl, + .Uniform1d = oc_glUniform1d_noimpl, + .ClearTexImage = oc_glClearTexImage_noimpl, + .Uniform1uiv = oc_glUniform1uiv_noimpl, + .BindSampler = oc_glBindSampler_noimpl, + .GetTexLevelParameterfv = oc_glGetTexLevelParameterfv_noimpl, + .ClearBufferiv = oc_glClearBufferiv_noimpl, + .LogicOp = oc_glLogicOp_noimpl, + .ActiveTexture = oc_glActiveTexture_noimpl, + .GetFragDataLocation = oc_glGetFragDataLocation_noimpl, + .BlendColor = oc_glBlendColor_noimpl, + .UniformMatrix4x3fv = oc_glUniformMatrix4x3fv_noimpl, + .ProgramUniform3fv = oc_glProgramUniform3fv_noimpl, + .Uniform1fv = oc_glUniform1fv_noimpl, + .DrawElementsBaseVertex = oc_glDrawElementsBaseVertex_noimpl, + .Uniform4f = oc_glUniform4f_noimpl, + .BlendEquationSeparatei = oc_glBlendEquationSeparatei_noimpl, + .BlendFuncSeparate = oc_glBlendFuncSeparate_noimpl, + .ClearBufferuiv = oc_glClearBufferuiv_noimpl, + .CopyTexSubImage1D = oc_glCopyTexSubImage1D_noimpl, + .DrawTransformFeedback = oc_glDrawTransformFeedback_noimpl, + .ReadBuffer = oc_glReadBuffer_noimpl, + .CopyBufferSubData = oc_glCopyBufferSubData_noimpl, + .GetUniformuiv = oc_glGetUniformuiv_noimpl, + .PolygonOffset = oc_glPolygonOffset_noimpl, + .DispatchCompute = oc_glDispatchCompute_noimpl, + .BindImageTexture = oc_glBindImageTexture_noimpl, + .UniformMatrix4x3dv = oc_glUniformMatrix4x3dv_noimpl, + .GenRenderbuffers = oc_glGenRenderbuffers_noimpl, }; void oc_gl_load_gl41(oc_gl_api* api, oc_gl_load_proc loadProc) { - api->name = "gl41"; - api->GetFloatv = loadProc("glGetFloatv"); - api->TexBufferRange = oc_glTexBufferRange_noimpl; - api->IsBuffer = loadProc("glIsBuffer"); - api->IsTexture = loadProc("glIsTexture"); - api->DepthRangef = loadProc("glDepthRangef"); - api->EndConditionalRender = loadProc("glEndConditionalRender"); - api->BlendFunci = loadProc("glBlendFunci"); - api->GetProgramPipelineiv = loadProc("glGetProgramPipelineiv"); - api->WaitSync = loadProc("glWaitSync"); - api->ProgramUniformMatrix2fv = loadProc("glProgramUniformMatrix2fv"); - api->ProgramUniformMatrix4x3dv = loadProc("glProgramUniformMatrix4x3dv"); - api->VertexAttrib1dv = loadProc("glVertexAttrib1dv"); - api->SamplerParameteri = loadProc("glSamplerParameteri"); - api->GetVertexAttribIiv = loadProc("glGetVertexAttribIiv"); - api->GetSamplerParameterfv = loadProc("glGetSamplerParameterfv"); - api->VertexAttrib1d = loadProc("glVertexAttrib1d"); - api->TexBuffer = loadProc("glTexBuffer"); - api->InvalidateBufferData = oc_glInvalidateBufferData_noimpl; - api->ProgramUniform2i = loadProc("glProgramUniform2i"); - api->Uniform4dv = loadProc("glUniform4dv"); - api->UseProgram = loadProc("glUseProgram"); - api->VertexAttribI3iv = loadProc("glVertexAttribI3iv"); - api->DrawElementsIndirect = loadProc("glDrawElementsIndirect"); - api->VertexAttrib4uiv = loadProc("glVertexAttrib4uiv"); - api->GetQueryObjectiv = loadProc("glGetQueryObjectiv"); - api->FramebufferRenderbuffer = loadProc("glFramebufferRenderbuffer"); - api->BlendEquationi = loadProc("glBlendEquationi"); - api->GetActiveSubroutineName = loadProc("glGetActiveSubroutineName"); - api->VertexAttrib2s = loadProc("glVertexAttrib2s"); - api->VertexAttribL1d = loadProc("glVertexAttribL1d"); - api->BindTextures = oc_glBindTextures_noimpl; - api->VertexAttrib3sv = loadProc("glVertexAttrib3sv"); - api->GetFloati_v = loadProc("glGetFloati_v"); - api->BeginTransformFeedback = loadProc("glBeginTransformFeedback"); - api->ClearStencil = loadProc("glClearStencil"); - api->Uniform3i = loadProc("glUniform3i"); - api->ValidateProgramPipeline = loadProc("glValidateProgramPipeline"); - api->ProgramUniformMatrix4x2fv = loadProc("glProgramUniformMatrix4x2fv"); - api->VertexAttribI4ui = loadProc("glVertexAttribI4ui"); - api->GetShaderiv = loadProc("glGetShaderiv"); - api->ReadnPixels = oc_glReadnPixels_noimpl; - api->UniformMatrix4x2fv = loadProc("glUniformMatrix4x2fv"); - api->GetShaderPrecisionFormat = loadProc("glGetShaderPrecisionFormat"); - api->ProgramUniformMatrix2x3fv = loadProc("glProgramUniformMatrix2x3fv"); - api->TexSubImage3D = loadProc("glTexSubImage3D"); - api->GetProgramResourceLocationIndex = oc_glGetProgramResourceLocationIndex_noimpl; - api->BlendFunc = loadProc("glBlendFunc"); - api->ProgramUniformMatrix3x4fv = loadProc("glProgramUniformMatrix3x4fv"); - api->Uniform3d = loadProc("glUniform3d"); - api->VertexAttrib1sv = loadProc("glVertexAttrib1sv"); - api->BindFragDataLocation = loadProc("glBindFragDataLocation"); - api->VertexAttrib4bv = loadProc("glVertexAttrib4bv"); - api->Uniform4iv = loadProc("glUniform4iv"); - api->ProgramUniform2ui = loadProc("glProgramUniform2ui"); - api->DrawArrays = loadProc("glDrawArrays"); - api->ProgramBinary = loadProc("glProgramBinary"); - api->VertexAttrib4f = loadProc("glVertexAttrib4f"); - api->VertexAttribP2uiv = loadProc("glVertexAttribP2uiv"); - api->UniformMatrix3fv = loadProc("glUniformMatrix3fv"); - api->Uniform2i = loadProc("glUniform2i"); - api->GetQueryObjectuiv = loadProc("glGetQueryObjectuiv"); - api->UniformBlockBinding = loadProc("glUniformBlockBinding"); - api->SampleCoverage = loadProc("glSampleCoverage"); - api->VertexAttrib4Nusv = loadProc("glVertexAttrib4Nusv"); - api->ProgramUniformMatrix2x4dv = loadProc("glProgramUniformMatrix2x4dv"); - api->Uniform3uiv = loadProc("glUniform3uiv"); - api->VertexAttrib1s = loadProc("glVertexAttrib1s"); - api->GetVertexAttribPointerv = loadProc("glGetVertexAttribPointerv"); - api->BlendBarrier = oc_glBlendBarrier_noimpl; - api->DrawRangeElements = loadProc("glDrawRangeElements"); - api->TexStorage3D = oc_glTexStorage3D_noimpl; - api->GetInternalformati64v = oc_glGetInternalformati64v_noimpl; - api->GetQueryObjecti64v = loadProc("glGetQueryObjecti64v"); - api->CompressedTexSubImage1D = loadProc("glCompressedTexSubImage1D"); - api->VertexAttrib3dv = loadProc("glVertexAttrib3dv"); - api->VertexBindingDivisor = oc_glVertexBindingDivisor_noimpl; - api->UseProgramStages = loadProc("glUseProgramStages"); - api->VertexAttribBinding = oc_glVertexAttribBinding_noimpl; - api->DebugMessageInsert = oc_glDebugMessageInsert_noimpl; - api->GetTexParameteriv = loadProc("glGetTexParameteriv"); - api->MultiDrawArraysIndirect = oc_glMultiDrawArraysIndirect_noimpl; - api->GetTexParameterfv = loadProc("glGetTexParameterfv"); - api->GetProgramPipelineInfoLog = loadProc("glGetProgramPipelineInfoLog"); - api->EndQuery = loadProc("glEndQuery"); - api->GetProgramResourceLocation = oc_glGetProgramResourceLocation_noimpl; - api->CompressedTexImage2D = loadProc("glCompressedTexImage2D"); - api->VertexAttribP2ui = loadProc("glVertexAttribP2ui"); - api->IsEnabledi = loadProc("glIsEnabledi"); - api->GetActiveAtomicCounterBufferiv = oc_glGetActiveAtomicCounterBufferiv_noimpl; - api->IsProgram = loadProc("glIsProgram"); - api->Uniform1dv = loadProc("glUniform1dv"); - api->TexParameteriv = loadProc("glTexParameteriv"); - api->Uniform2fv = loadProc("glUniform2fv"); - api->ReleaseShaderCompiler = loadProc("glReleaseShaderCompiler"); - api->CullFace = loadProc("glCullFace"); - api->VertexAttribI4i = loadProc("glVertexAttribI4i"); - api->GetProgramResourceIndex = oc_glGetProgramResourceIndex_noimpl; - api->ShaderBinary = loadProc("glShaderBinary"); - api->UniformMatrix3x2dv = loadProc("glUniformMatrix3x2dv"); - api->InvalidateFramebuffer = oc_glInvalidateFramebuffer_noimpl; - api->AttachShader = loadProc("glAttachShader"); - api->FlushMappedBufferRange = loadProc("glFlushMappedBufferRange"); - api->VertexAttribP3uiv = loadProc("glVertexAttribP3uiv"); - api->GetActiveUniformName = loadProc("glGetActiveUniformName"); - api->MapBuffer = loadProc("glMapBuffer"); - api->DrawBuffers = loadProc("glDrawBuffers"); - api->GetSynciv = loadProc("glGetSynciv"); - api->CopyTexSubImage2D = loadProc("glCopyTexSubImage2D"); - api->ObjectLabel = oc_glObjectLabel_noimpl; - api->BufferSubData = loadProc("glBufferSubData"); - api->Uniform2f = loadProc("glUniform2f"); - api->DebugMessageCallback = oc_glDebugMessageCallback_noimpl; - api->VertexAttribL4dv = loadProc("glVertexAttribL4dv"); - api->IsProgramPipeline = loadProc("glIsProgramPipeline"); - api->ResumeTransformFeedback = loadProc("glResumeTransformFeedback"); - api->VertexAttribI4iv = loadProc("glVertexAttribI4iv"); - api->GetShaderInfoLog = loadProc("glGetShaderInfoLog"); - api->GetIntegeri_v = loadProc("glGetIntegeri_v"); - api->BindVertexBuffer = oc_glBindVertexBuffer_noimpl; - api->BlendEquation = loadProc("glBlendEquation"); - api->VertexAttribL2dv = loadProc("glVertexAttribL2dv"); - api->VertexAttribI1ui = loadProc("glVertexAttribI1ui"); - api->VertexAttrib4Nsv = loadProc("glVertexAttrib4Nsv"); - api->VertexAttribL4d = loadProc("glVertexAttribL4d"); - api->CopyImageSubData = oc_glCopyImageSubData_noimpl; - api->GetFramebufferAttachmentParameteriv = loadProc("glGetFramebufferAttachmentParameteriv"); - api->VertexAttribL2d = loadProc("glVertexAttribL2d"); - api->GetSubroutineIndex = loadProc("glGetSubroutineIndex"); - api->VertexAttribI3uiv = loadProc("glVertexAttribI3uiv"); - api->VertexAttrib4iv = loadProc("glVertexAttrib4iv"); - api->BindVertexBuffers = oc_glBindVertexBuffers_noimpl; - api->ProgramUniformMatrix2x3dv = loadProc("glProgramUniformMatrix2x3dv"); - api->PrimitiveBoundingBox = oc_glPrimitiveBoundingBox_noimpl; - api->Scissor = loadProc("glScissor"); - api->ClientWaitSync = loadProc("glClientWaitSync"); - api->Uniform3ui = loadProc("glUniform3ui"); - api->VertexAttribP3ui = loadProc("glVertexAttribP3ui"); - api->Enable = loadProc("glEnable"); - api->StencilOpSeparate = loadProc("glStencilOpSeparate"); - api->UniformMatrix2x3dv = loadProc("glUniformMatrix2x3dv"); - api->ProgramUniformMatrix3dv = loadProc("glProgramUniformMatrix3dv"); - api->TexImage2DMultisample = loadProc("glTexImage2DMultisample"); - api->VertexAttrib4Nbv = loadProc("glVertexAttrib4Nbv"); - api->GetTexImage = loadProc("glGetTexImage"); - api->VertexAttrib4sv = loadProc("glVertexAttrib4sv"); - api->PixelStorei = loadProc("glPixelStorei"); - api->DepthMask = loadProc("glDepthMask"); - api->TexStorage2D = oc_glTexStorage2D_noimpl; - api->Clear = loadProc("glClear"); - api->UniformMatrix3x4dv = loadProc("glUniformMatrix3x4dv"); - api->DeleteTransformFeedbacks = loadProc("glDeleteTransformFeedbacks"); - api->MapBufferRange = loadProc("glMapBufferRange"); - api->MemoryBarrier = oc_glMemoryBarrier_noimpl; - api->ViewportIndexedf = loadProc("glViewportIndexedf"); - api->VertexAttrib3fv = loadProc("glVertexAttrib3fv"); - api->ObjectPtrLabel = oc_glObjectPtrLabel_noimpl; - api->TexStorage1D = oc_glTexStorage1D_noimpl; - api->CompressedTexImage3D = loadProc("glCompressedTexImage3D"); - api->VertexAttrib1fv = loadProc("glVertexAttrib1fv"); - api->VertexAttribPointer = loadProc("glVertexAttribPointer"); - api->GetQueryIndexediv = loadProc("glGetQueryIndexediv"); - api->CompileShader = loadProc("glCompileShader"); - api->ProgramUniform1i = loadProc("glProgramUniform1i"); - api->GetQueryiv = loadProc("glGetQueryiv"); - api->VertexAttribI1iv = loadProc("glVertexAttribI1iv"); - api->CopyTexImage2D = loadProc("glCopyTexImage2D"); - api->GetQueryObjectui64v = loadProc("glGetQueryObjectui64v"); - api->PointSize = loadProc("glPointSize"); - api->Disablei = loadProc("glDisablei"); - api->VertexAttribL1dv = loadProc("glVertexAttribL1dv"); - api->CreateShader = loadProc("glCreateShader"); - api->GetString = loadProc("glGetString"); - api->ViewportArrayv = loadProc("glViewportArrayv"); - api->ProgramUniform3d = loadProc("glProgramUniform3d"); - api->VertexAttrib4Nubv = loadProc("glVertexAttrib4Nubv"); - api->TexParameteri = loadProc("glTexParameteri"); - api->ProgramUniform4fv = loadProc("glProgramUniform4fv"); - api->GenerateMipmap = loadProc("glGenerateMipmap"); - api->CompressedTexSubImage3D = loadProc("glCompressedTexSubImage3D"); - api->Uniform3f = loadProc("glUniform3f"); - api->GetUniformIndices = loadProc("glGetUniformIndices"); - api->VertexAttribLPointer = loadProc("glVertexAttribLPointer"); - api->VertexAttribI2uiv = loadProc("glVertexAttribI2uiv"); - api->QueryCounter = loadProc("glQueryCounter"); - api->ActiveShaderProgram = loadProc("glActiveShaderProgram"); - api->Uniform1ui = loadProc("glUniform1ui"); - api->VertexAttribI1i = loadProc("glVertexAttribI1i"); - api->GetTexParameterIiv = loadProc("glGetTexParameterIiv"); - api->GetUniformfv = loadProc("glGetUniformfv"); - api->ProgramUniform2uiv = loadProc("glProgramUniform2uiv"); - api->GetError = loadProc("glGetError"); - api->GetActiveUniformBlockName = loadProc("glGetActiveUniformBlockName"); - api->TextureView = oc_glTextureView_noimpl; - api->GetnUniformiv = oc_glGetnUniformiv_noimpl; - api->ProgramUniform4dv = loadProc("glProgramUniform4dv"); - api->ViewportIndexedfv = loadProc("glViewportIndexedfv"); - api->Hint = loadProc("glHint"); - api->GetShaderSource = loadProc("glGetShaderSource"); - api->ProgramUniformMatrix4x3fv = loadProc("glProgramUniformMatrix4x3fv"); - api->Uniform1iv = loadProc("glUniform1iv"); - api->VertexAttribI4bv = loadProc("glVertexAttribI4bv"); - api->UniformMatrix4x2dv = loadProc("glUniformMatrix4x2dv"); - api->BufferStorage = oc_glBufferStorage_noimpl; - api->IsRenderbuffer = loadProc("glIsRenderbuffer"); - api->GetActiveSubroutineUniformName = loadProc("glGetActiveSubroutineUniformName"); - api->LinkProgram = loadProc("glLinkProgram"); - api->GetActiveUniformsiv = loadProc("glGetActiveUniformsiv"); - api->GetDebugMessageLog = oc_glGetDebugMessageLog_noimpl; - api->CopyTexSubImage3D = loadProc("glCopyTexSubImage3D"); - api->PointParameteri = loadProc("glPointParameteri"); - api->ProgramUniform3dv = loadProc("glProgramUniform3dv"); - api->CompressedTexImage1D = loadProc("glCompressedTexImage1D"); - api->UniformMatrix3x4fv = loadProc("glUniformMatrix3x4fv"); - api->GenSamplers = loadProc("glGenSamplers"); - api->GetCompressedTexImage = loadProc("glGetCompressedTexImage"); - api->DeleteQueries = loadProc("glDeleteQueries"); - api->GenProgramPipelines = loadProc("glGenProgramPipelines"); - api->DispatchComputeIndirect = oc_glDispatchComputeIndirect_noimpl; - api->VertexAttribIPointer = loadProc("glVertexAttribIPointer"); - api->CreateProgram = loadProc("glCreateProgram"); - api->ClearTexSubImage = oc_glClearTexSubImage_noimpl; - api->VertexAttrib4d = loadProc("glVertexAttrib4d"); - api->FrontFace = loadProc("glFrontFace"); - api->BindTransformFeedback = loadProc("glBindTransformFeedback"); - api->GetProgramStageiv = loadProc("glGetProgramStageiv"); - api->SamplerParameterIiv = loadProc("glSamplerParameterIiv"); - api->GetInteger64v = loadProc("glGetInteger64v"); - api->CreateShaderProgramv = loadProc("glCreateShaderProgramv"); - api->BindBuffersRange = oc_glBindBuffersRange_noimpl; - api->Uniform3fv = loadProc("glUniform3fv"); - api->ProgramUniformMatrix4fv = loadProc("glProgramUniformMatrix4fv"); - api->BindBuffersBase = oc_glBindBuffersBase_noimpl; - api->ClearBufferfi = loadProc("glClearBufferfi"); - api->FramebufferTexture3D = loadProc("glFramebufferTexture3D"); - api->Disable = loadProc("glDisable"); - api->ProgramUniform1iv = loadProc("glProgramUniform1iv"); - api->VertexAttribI2iv = loadProc("glVertexAttribI2iv"); - api->DepthRangeIndexed = loadProc("glDepthRangeIndexed"); - api->PatchParameteri = loadProc("glPatchParameteri"); - api->GetUniformBlockIndex = loadProc("glGetUniformBlockIndex"); - api->MultiDrawArrays = loadProc("glMultiDrawArrays"); - api->VertexAttribI4ubv = loadProc("glVertexAttribI4ubv"); - api->BindBuffer = loadProc("glBindBuffer"); - api->VertexAttribI3i = loadProc("glVertexAttribI3i"); - api->GetDoublev = loadProc("glGetDoublev"); - api->DrawTransformFeedbackStream = loadProc("glDrawTransformFeedbackStream"); - api->VertexAttribI4uiv = loadProc("glVertexAttribI4uiv"); - api->RenderbufferStorageMultisample = loadProc("glRenderbufferStorageMultisample"); - api->VertexAttribL3dv = loadProc("glVertexAttribL3dv"); - api->StencilMaskSeparate = loadProc("glStencilMaskSeparate"); - api->ProgramUniform1d = loadProc("glProgramUniform1d"); - api->Viewport = loadProc("glViewport"); - api->VertexAttribP1ui = loadProc("glVertexAttribP1ui"); - api->VertexAttrib4dv = loadProc("glVertexAttrib4dv"); - api->GenQueries = loadProc("glGenQueries"); - api->TexParameterIiv = loadProc("glTexParameterIiv"); - api->ProgramUniform2d = loadProc("glProgramUniform2d"); - api->ProgramUniform1uiv = loadProc("glProgramUniform1uiv"); - api->VertexAttrib4Nub = loadProc("glVertexAttrib4Nub"); - api->IsVertexArray = loadProc("glIsVertexArray"); - api->ProgramUniform3f = loadProc("glProgramUniform3f"); - api->ProgramUniform3iv = loadProc("glProgramUniform3iv"); - api->GetProgramBinary = loadProc("glGetProgramBinary"); - api->BindRenderbuffer = loadProc("glBindRenderbuffer"); - api->BindFragDataLocationIndexed = loadProc("glBindFragDataLocationIndexed"); - api->GetSamplerParameterIiv = loadProc("glGetSamplerParameterIiv"); - api->VertexAttribDivisor = loadProc("glVertexAttribDivisor"); - api->ProgramUniformMatrix3x2dv = loadProc("glProgramUniformMatrix3x2dv"); - api->FramebufferParameteri = oc_glFramebufferParameteri_noimpl; - api->GenTransformFeedbacks = loadProc("glGenTransformFeedbacks"); - api->DeleteSync = loadProc("glDeleteSync"); - api->ProgramUniform1ui = loadProc("glProgramUniform1ui"); - api->TexSubImage1D = loadProc("glTexSubImage1D"); - api->ClearDepthf = loadProc("glClearDepthf"); - api->ReadPixels = loadProc("glReadPixels"); - api->VertexAttribI2i = loadProc("glVertexAttribI2i"); - api->Finish = loadProc("glFinish"); - api->LineWidth = loadProc("glLineWidth"); - api->DeleteShader = loadProc("glDeleteShader"); - api->IsSampler = loadProc("glIsSampler"); - api->ProgramUniformMatrix4dv = loadProc("glProgramUniformMatrix4dv"); - api->TransformFeedbackVaryings = loadProc("glTransformFeedbackVaryings"); - api->BeginConditionalRender = loadProc("glBeginConditionalRender"); - api->BindSamplers = oc_glBindSamplers_noimpl; - api->DeleteProgramPipelines = loadProc("glDeleteProgramPipelines"); - api->ColorMask = loadProc("glColorMask"); - api->TexParameterfv = loadProc("glTexParameterfv"); - api->PushDebugGroup = oc_glPushDebugGroup_noimpl; - api->ClearBufferfv = loadProc("glClearBufferfv"); - api->IsEnabled = loadProc("glIsEnabled"); - api->VertexAttrib2f = loadProc("glVertexAttrib2f"); - api->ProgramUniform2f = loadProc("glProgramUniform2f"); - api->GetSamplerParameterIuiv = loadProc("glGetSamplerParameterIuiv"); - api->GetInteger64i_v = loadProc("glGetInteger64i_v"); - api->Uniform2dv = loadProc("glUniform2dv"); - api->GetBufferSubData = loadProc("glGetBufferSubData"); - api->MultiDrawElementsIndirect = oc_glMultiDrawElementsIndirect_noimpl; - api->ProgramParameteri = loadProc("glProgramParameteri"); - api->VertexAttribP4ui = loadProc("glVertexAttribP4ui"); - api->SamplerParameterfv = loadProc("glSamplerParameterfv"); - api->PointParameterf = loadProc("glPointParameterf"); - api->UniformMatrix2x4fv = loadProc("glUniformMatrix2x4fv"); - api->GenBuffers = loadProc("glGenBuffers"); - api->ProgramUniform2dv = loadProc("glProgramUniform2dv"); - api->VertexAttribFormat = oc_glVertexAttribFormat_noimpl; - api->TexSubImage2D = loadProc("glTexSubImage2D"); - api->VertexAttrib4ubv = loadProc("glVertexAttrib4ubv"); - api->GetGraphicsResetStatus = oc_glGetGraphicsResetStatus_noimpl; - api->GetProgramInterfaceiv = oc_glGetProgramInterfaceiv_noimpl; - api->VertexAttribIFormat = oc_glVertexAttribIFormat_noimpl; - api->GetnUniformfv = oc_glGetnUniformfv_noimpl; - api->DeleteProgram = loadProc("glDeleteProgram"); - api->ClampColor = loadProc("glClampColor"); - api->DrawElementsInstancedBaseVertexBaseInstance = oc_glDrawElementsInstancedBaseVertexBaseInstance_noimpl; - api->DrawElements = loadProc("glDrawElements"); - api->DebugMessageControl = oc_glDebugMessageControl_noimpl; - api->GetRenderbufferParameteriv = loadProc("glGetRenderbufferParameteriv"); - api->DetachShader = loadProc("glDetachShader"); - api->GenFramebuffers = loadProc("glGenFramebuffers"); - api->ProvokingVertex = loadProc("glProvokingVertex"); - api->SampleMaski = loadProc("glSampleMaski"); - api->EndQueryIndexed = loadProc("glEndQueryIndexed"); - api->ProgramUniform1f = loadProc("glProgramUniform1f"); - api->BindFramebuffer = loadProc("glBindFramebuffer"); - api->BeginQueryIndexed = loadProc("glBeginQueryIndexed"); - api->UniformSubroutinesuiv = loadProc("glUniformSubroutinesuiv"); - api->GetUniformiv = loadProc("glGetUniformiv"); - api->FramebufferTexture = loadProc("glFramebufferTexture"); - api->PointParameterfv = loadProc("glPointParameterfv"); - api->IsTransformFeedback = loadProc("glIsTransformFeedback"); - api->CheckFramebufferStatus = loadProc("glCheckFramebufferStatus"); - api->ShaderSource = loadProc("glShaderSource"); - api->UniformMatrix2x4dv = loadProc("glUniformMatrix2x4dv"); - api->BindImageTextures = oc_glBindImageTextures_noimpl; - api->CopyTexImage1D = loadProc("glCopyTexImage1D"); - api->UniformMatrix3dv = loadProc("glUniformMatrix3dv"); - api->ProgramUniform1dv = loadProc("glProgramUniform1dv"); - api->BlitFramebuffer = loadProc("glBlitFramebuffer"); - api->PopDebugGroup = oc_glPopDebugGroup_noimpl; - api->TexParameterIuiv = loadProc("glTexParameterIuiv"); - api->VertexAttrib2d = loadProc("glVertexAttrib2d"); - api->TexImage1D = loadProc("glTexImage1D"); - api->GetObjectPtrLabel = oc_glGetObjectPtrLabel_noimpl; - api->StencilMask = loadProc("glStencilMask"); - api->BeginQuery = loadProc("glBeginQuery"); - api->UniformMatrix4fv = loadProc("glUniformMatrix4fv"); - api->IsSync = loadProc("glIsSync"); - api->Uniform3dv = loadProc("glUniform3dv"); - api->ProgramUniform2fv = loadProc("glProgramUniform2fv"); - api->VertexAttribI4sv = loadProc("glVertexAttribI4sv"); - api->ScissorArrayv = loadProc("glScissorArrayv"); - api->VertexAttribP1uiv = loadProc("glVertexAttribP1uiv"); - api->Uniform2uiv = loadProc("glUniform2uiv"); - api->DeleteBuffers = loadProc("glDeleteBuffers"); - api->ProgramUniform3ui = loadProc("glProgramUniform3ui"); - api->FramebufferTextureLayer = loadProc("glFramebufferTextureLayer"); - api->EndTransformFeedback = loadProc("glEndTransformFeedback"); - api->BlendFuncSeparatei = loadProc("glBlendFuncSeparatei"); - api->DrawTransformFeedbackInstanced = oc_glDrawTransformFeedbackInstanced_noimpl; - api->DrawRangeElementsBaseVertex = loadProc("glDrawRangeElementsBaseVertex"); - api->VertexAttrib1f = loadProc("glVertexAttrib1f"); - api->GetUniformSubroutineuiv = loadProc("glGetUniformSubroutineuiv"); - api->DisableVertexAttribArray = loadProc("glDisableVertexAttribArray"); - api->ProgramUniformMatrix3x2fv = loadProc("glProgramUniformMatrix3x2fv"); - api->VertexAttribI4usv = loadProc("glVertexAttribI4usv"); - api->GetObjectLabel = oc_glGetObjectLabel_noimpl; - api->BindAttribLocation = loadProc("glBindAttribLocation"); - api->Uniform1f = loadProc("glUniform1f"); - api->GetUniformdv = loadProc("glGetUniformdv"); - api->GetUniformLocation = loadProc("glGetUniformLocation"); - api->GetSubroutineUniformLocation = loadProc("glGetSubroutineUniformLocation"); - api->GetTexParameterIuiv = loadProc("glGetTexParameterIuiv"); - api->SamplerParameterf = loadProc("glSamplerParameterf"); - api->VertexAttribL3d = loadProc("glVertexAttribL3d"); - api->TexImage3DMultisample = loadProc("glTexImage3DMultisample"); - api->TexImage3D = loadProc("glTexImage3D"); - api->RenderbufferStorage = loadProc("glRenderbufferStorage"); - api->EnableVertexAttribArray = loadProc("glEnableVertexAttribArray"); - api->VertexAttribP4uiv = loadProc("glVertexAttribP4uiv"); - api->Uniform4d = loadProc("glUniform4d"); - api->VertexAttrib4s = loadProc("glVertexAttrib4s"); - api->DrawElementsInstancedBaseVertex = loadProc("glDrawElementsInstancedBaseVertex"); - api->VertexAttrib3s = loadProc("glVertexAttrib3s"); - api->ProgramUniform2iv = loadProc("glProgramUniform2iv"); - api->StencilFuncSeparate = loadProc("glStencilFuncSeparate"); - api->DeleteFramebuffers = loadProc("glDeleteFramebuffers"); - api->DepthRange = loadProc("glDepthRange"); - api->UniformMatrix3x2fv = loadProc("glUniformMatrix3x2fv"); - api->ProgramUniformMatrix2dv = loadProc("glProgramUniformMatrix2dv"); - api->ShaderStorageBlockBinding = oc_glShaderStorageBlockBinding_noimpl; - api->ClearDepth = loadProc("glClearDepth"); - api->VertexAttrib2dv = loadProc("glVertexAttrib2dv"); - api->SamplerParameterIuiv = loadProc("glSamplerParameterIuiv"); - api->GetVertexAttribLdv = loadProc("glGetVertexAttribLdv"); - api->ProgramUniformMatrix3x4dv = loadProc("glProgramUniformMatrix3x4dv"); - api->DepthRangeArrayv = loadProc("glDepthRangeArrayv"); - api->GetActiveUniform = loadProc("glGetActiveUniform"); - api->PatchParameterfv = loadProc("glPatchParameterfv"); - api->InvalidateTexImage = oc_glInvalidateTexImage_noimpl; - api->VertexAttrib3f = loadProc("glVertexAttrib3f"); - api->ProgramUniform4iv = loadProc("glProgramUniform4iv"); - api->ProgramUniform4d = loadProc("glProgramUniform4d"); - api->IsFramebuffer = loadProc("glIsFramebuffer"); - api->PixelStoref = loadProc("glPixelStoref"); - api->ProgramUniform4uiv = loadProc("glProgramUniform4uiv"); - api->ProgramUniformMatrix4x2dv = loadProc("glProgramUniformMatrix4x2dv"); - api->FenceSync = loadProc("glFenceSync"); - api->GetBufferParameteri64v = loadProc("glGetBufferParameteri64v"); - api->StencilOp = loadProc("glStencilOp"); - api->ClearBufferData = oc_glClearBufferData_noimpl; - api->GetnUniformuiv = oc_glGetnUniformuiv_noimpl; - api->GetProgramResourceiv = oc_glGetProgramResourceiv_noimpl; - api->GetVertexAttribdv = loadProc("glGetVertexAttribdv"); - api->GetTransformFeedbackVarying = loadProc("glGetTransformFeedbackVarying"); - api->VertexAttrib2fv = loadProc("glVertexAttrib2fv"); - api->GetBooleani_v = loadProc("glGetBooleani_v"); - api->ColorMaski = loadProc("glColorMaski"); - api->InvalidateBufferSubData = oc_glInvalidateBufferSubData_noimpl; - api->UniformMatrix4dv = loadProc("glUniformMatrix4dv"); - api->IsQuery = loadProc("glIsQuery"); - api->Uniform4ui = loadProc("glUniform4ui"); - api->Uniform4i = loadProc("glUniform4i"); - api->GetSamplerParameteriv = loadProc("glGetSamplerParameteriv"); - api->MultiDrawElementsBaseVertex = loadProc("glMultiDrawElementsBaseVertex"); - api->VertexAttribI1uiv = loadProc("glVertexAttribI1uiv"); - api->GetIntegerv = loadProc("glGetIntegerv"); - api->UniformMatrix2x3fv = loadProc("glUniformMatrix2x3fv"); - api->TexImage2D = loadProc("glTexImage2D"); - api->GetAttachedShaders = loadProc("glGetAttachedShaders"); - api->Uniform2d = loadProc("glUniform2d"); - api->MemoryBarrierByRegion = oc_glMemoryBarrierByRegion_noimpl; - api->UniformMatrix2fv = loadProc("glUniformMatrix2fv"); - api->PrimitiveRestartIndex = loadProc("glPrimitiveRestartIndex"); - api->GetVertexAttribiv = loadProc("glGetVertexAttribiv"); - api->GetAttribLocation = loadProc("glGetAttribLocation"); - api->TexStorage2DMultisample = oc_glTexStorage2DMultisample_noimpl; - api->CompressedTexSubImage2D = loadProc("glCompressedTexSubImage2D"); - api->GetVertexAttribfv = loadProc("glGetVertexAttribfv"); - api->GetBufferParameteriv = loadProc("glGetBufferParameteriv"); - api->TexParameterf = loadProc("glTexParameterf"); - api->FramebufferTexture2D = loadProc("glFramebufferTexture2D"); - api->GetActiveAttrib = loadProc("glGetActiveAttrib"); - api->InvalidateTexSubImage = oc_glInvalidateTexSubImage_noimpl; - api->DeleteVertexArrays = loadProc("glDeleteVertexArrays"); - api->VertexAttribI2ui = loadProc("glVertexAttribI2ui"); - api->PointParameteriv = loadProc("glPointParameteriv"); - api->GetPointerv = oc_glGetPointerv_noimpl; - api->Enablei = loadProc("glEnablei"); - api->BindBufferRange = loadProc("glBindBufferRange"); - api->DrawArraysInstanced = loadProc("glDrawArraysInstanced"); - api->DeleteTextures = loadProc("glDeleteTextures"); - api->VertexAttrib4Niv = loadProc("glVertexAttrib4Niv"); - api->MultiDrawElements = loadProc("glMultiDrawElements"); - api->GetProgramiv = loadProc("glGetProgramiv"); - api->DepthFunc = loadProc("glDepthFunc"); - api->GenTextures = loadProc("glGenTextures"); - api->GetInternalformativ = oc_glGetInternalformativ_noimpl; - api->ProgramUniform3i = loadProc("glProgramUniform3i"); - api->ScissorIndexed = loadProc("glScissorIndexed"); - api->VertexAttrib2sv = loadProc("glVertexAttrib2sv"); - api->TexStorage3DMultisample = oc_glTexStorage3DMultisample_noimpl; - api->Uniform2iv = loadProc("glUniform2iv"); - api->DrawArraysInstancedBaseInstance = oc_glDrawArraysInstancedBaseInstance_noimpl; - api->VertexAttribI3ui = loadProc("glVertexAttribI3ui"); - api->DeleteSamplers = loadProc("glDeleteSamplers"); - api->GenVertexArrays = loadProc("glGenVertexArrays"); - api->GetFramebufferParameteriv = oc_glGetFramebufferParameteriv_noimpl; - api->PolygonMode = loadProc("glPolygonMode"); - api->ProgramUniformMatrix2x4fv = loadProc("glProgramUniformMatrix2x4fv"); - api->GetProgramResourceName = oc_glGetProgramResourceName_noimpl; - api->SamplerParameteriv = loadProc("glSamplerParameteriv"); - api->GetActiveSubroutineUniformiv = loadProc("glGetActiveSubroutineUniformiv"); - api->GetStringi = loadProc("glGetStringi"); - api->VertexAttribLFormat = oc_glVertexAttribLFormat_noimpl; - api->VertexAttrib3d = loadProc("glVertexAttrib3d"); - api->BindVertexArray = loadProc("glBindVertexArray"); - api->UnmapBuffer = loadProc("glUnmapBuffer"); - api->DrawElementsInstancedBaseInstance = oc_glDrawElementsInstancedBaseInstance_noimpl; - api->Uniform4uiv = loadProc("glUniform4uiv"); - api->FramebufferTexture1D = loadProc("glFramebufferTexture1D"); - api->DrawTransformFeedbackStreamInstanced = oc_glDrawTransformFeedbackStreamInstanced_noimpl; - api->StencilFunc = loadProc("glStencilFunc"); - api->ValidateProgram = loadProc("glValidateProgram"); - api->Flush = loadProc("glFlush"); - api->ProgramUniform3uiv = loadProc("glProgramUniform3uiv"); - api->DeleteRenderbuffers = loadProc("glDeleteRenderbuffers"); - api->VertexAttrib4fv = loadProc("glVertexAttrib4fv"); - api->UniformMatrix2dv = loadProc("glUniformMatrix2dv"); - api->GetFragDataIndex = loadProc("glGetFragDataIndex"); - api->Uniform3iv = loadProc("glUniform3iv"); - api->MinSampleShading = loadProc("glMinSampleShading"); - api->GetBooleanv = loadProc("glGetBooleanv"); - api->GetMultisamplefv = loadProc("glGetMultisamplefv"); - api->GetVertexAttribIuiv = loadProc("glGetVertexAttribIuiv"); - api->GetProgramInfoLog = loadProc("glGetProgramInfoLog"); - api->Uniform4fv = loadProc("glUniform4fv"); - api->DrawBuffer = loadProc("glDrawBuffer"); - api->Uniform1i = loadProc("glUniform1i"); - api->ProgramUniform4ui = loadProc("glProgramUniform4ui"); - api->ProgramUniformMatrix3fv = loadProc("glProgramUniformMatrix3fv"); - api->BlendEquationSeparate = loadProc("glBlendEquationSeparate"); - api->BindProgramPipeline = loadProc("glBindProgramPipeline"); - api->GetDoublei_v = loadProc("glGetDoublei_v"); - api->BufferData = loadProc("glBufferData"); - api->ClearColor = loadProc("glClearColor"); - api->ProgramUniform4i = loadProc("glProgramUniform4i"); - api->GetTexLevelParameteriv = loadProc("glGetTexLevelParameteriv"); - api->GetActiveUniformBlockiv = loadProc("glGetActiveUniformBlockiv"); - api->ProgramUniform1fv = loadProc("glProgramUniform1fv"); - api->PauseTransformFeedback = loadProc("glPauseTransformFeedback"); - api->GetBufferPointerv = loadProc("glGetBufferPointerv"); - api->InvalidateSubFramebuffer = oc_glInvalidateSubFramebuffer_noimpl; - api->ScissorIndexedv = loadProc("glScissorIndexedv"); - api->Uniform2ui = loadProc("glUniform2ui"); - api->BindTexture = loadProc("glBindTexture"); - api->DrawElementsInstanced = loadProc("glDrawElementsInstanced"); - api->ProgramUniform4f = loadProc("glProgramUniform4f"); - api->BindBufferBase = loadProc("glBindBufferBase"); - api->IsShader = loadProc("glIsShader"); - api->ClearBufferSubData = oc_glClearBufferSubData_noimpl; - api->VertexAttrib4Nuiv = loadProc("glVertexAttrib4Nuiv"); - api->DrawArraysIndirect = loadProc("glDrawArraysIndirect"); - api->VertexAttrib4usv = loadProc("glVertexAttrib4usv"); - api->Uniform1d = loadProc("glUniform1d"); - api->ClearTexImage = oc_glClearTexImage_noimpl; - api->Uniform1uiv = loadProc("glUniform1uiv"); - api->BindSampler = loadProc("glBindSampler"); - api->GetTexLevelParameterfv = loadProc("glGetTexLevelParameterfv"); - api->ClearBufferiv = loadProc("glClearBufferiv"); - api->LogicOp = loadProc("glLogicOp"); - api->ActiveTexture = loadProc("glActiveTexture"); - api->GetFragDataLocation = loadProc("glGetFragDataLocation"); - api->BlendColor = loadProc("glBlendColor"); - api->UniformMatrix4x3fv = loadProc("glUniformMatrix4x3fv"); - api->ProgramUniform3fv = loadProc("glProgramUniform3fv"); - api->Uniform1fv = loadProc("glUniform1fv"); - api->DrawElementsBaseVertex = loadProc("glDrawElementsBaseVertex"); - api->Uniform4f = loadProc("glUniform4f"); - api->BlendEquationSeparatei = loadProc("glBlendEquationSeparatei"); - api->BlendFuncSeparate = loadProc("glBlendFuncSeparate"); - api->ClearBufferuiv = loadProc("glClearBufferuiv"); - api->CopyTexSubImage1D = loadProc("glCopyTexSubImage1D"); - api->DrawTransformFeedback = loadProc("glDrawTransformFeedback"); - api->ReadBuffer = loadProc("glReadBuffer"); - api->CopyBufferSubData = loadProc("glCopyBufferSubData"); - api->GetUniformuiv = loadProc("glGetUniformuiv"); - api->PolygonOffset = loadProc("glPolygonOffset"); - api->DispatchCompute = oc_glDispatchCompute_noimpl; - api->BindImageTexture = oc_glBindImageTexture_noimpl; - api->UniformMatrix4x3dv = loadProc("glUniformMatrix4x3dv"); - api->GenRenderbuffers = loadProc("glGenRenderbuffers"); + api->name = "gl41"; + api->GetFloatv = loadProc("glGetFloatv"); + api->TexBufferRange = oc_glTexBufferRange_noimpl; + api->IsBuffer = loadProc("glIsBuffer"); + api->IsTexture = loadProc("glIsTexture"); + api->DepthRangef = loadProc("glDepthRangef"); + api->EndConditionalRender = loadProc("glEndConditionalRender"); + api->BlendFunci = loadProc("glBlendFunci"); + api->GetProgramPipelineiv = loadProc("glGetProgramPipelineiv"); + api->WaitSync = loadProc("glWaitSync"); + api->ProgramUniformMatrix2fv = loadProc("glProgramUniformMatrix2fv"); + api->ProgramUniformMatrix4x3dv = loadProc("glProgramUniformMatrix4x3dv"); + api->VertexAttrib1dv = loadProc("glVertexAttrib1dv"); + api->SamplerParameteri = loadProc("glSamplerParameteri"); + api->GetVertexAttribIiv = loadProc("glGetVertexAttribIiv"); + api->GetSamplerParameterfv = loadProc("glGetSamplerParameterfv"); + api->VertexAttrib1d = loadProc("glVertexAttrib1d"); + api->TexBuffer = loadProc("glTexBuffer"); + api->InvalidateBufferData = oc_glInvalidateBufferData_noimpl; + api->ProgramUniform2i = loadProc("glProgramUniform2i"); + api->Uniform4dv = loadProc("glUniform4dv"); + api->UseProgram = loadProc("glUseProgram"); + api->VertexAttribI3iv = loadProc("glVertexAttribI3iv"); + api->DrawElementsIndirect = loadProc("glDrawElementsIndirect"); + api->VertexAttrib4uiv = loadProc("glVertexAttrib4uiv"); + api->GetQueryObjectiv = loadProc("glGetQueryObjectiv"); + api->FramebufferRenderbuffer = loadProc("glFramebufferRenderbuffer"); + api->BlendEquationi = loadProc("glBlendEquationi"); + api->GetActiveSubroutineName = loadProc("glGetActiveSubroutineName"); + api->VertexAttrib2s = loadProc("glVertexAttrib2s"); + api->VertexAttribL1d = loadProc("glVertexAttribL1d"); + api->BindTextures = oc_glBindTextures_noimpl; + api->VertexAttrib3sv = loadProc("glVertexAttrib3sv"); + api->GetFloati_v = loadProc("glGetFloati_v"); + api->BeginTransformFeedback = loadProc("glBeginTransformFeedback"); + api->ClearStencil = loadProc("glClearStencil"); + api->Uniform3i = loadProc("glUniform3i"); + api->ValidateProgramPipeline = loadProc("glValidateProgramPipeline"); + api->ProgramUniformMatrix4x2fv = loadProc("glProgramUniformMatrix4x2fv"); + api->VertexAttribI4ui = loadProc("glVertexAttribI4ui"); + api->GetShaderiv = loadProc("glGetShaderiv"); + api->ReadnPixels = oc_glReadnPixels_noimpl; + api->UniformMatrix4x2fv = loadProc("glUniformMatrix4x2fv"); + api->GetShaderPrecisionFormat = loadProc("glGetShaderPrecisionFormat"); + api->ProgramUniformMatrix2x3fv = loadProc("glProgramUniformMatrix2x3fv"); + api->TexSubImage3D = loadProc("glTexSubImage3D"); + api->GetProgramResourceLocationIndex = oc_glGetProgramResourceLocationIndex_noimpl; + api->BlendFunc = loadProc("glBlendFunc"); + api->ProgramUniformMatrix3x4fv = loadProc("glProgramUniformMatrix3x4fv"); + api->Uniform3d = loadProc("glUniform3d"); + api->VertexAttrib1sv = loadProc("glVertexAttrib1sv"); + api->BindFragDataLocation = loadProc("glBindFragDataLocation"); + api->VertexAttrib4bv = loadProc("glVertexAttrib4bv"); + api->Uniform4iv = loadProc("glUniform4iv"); + api->ProgramUniform2ui = loadProc("glProgramUniform2ui"); + api->DrawArrays = loadProc("glDrawArrays"); + api->ProgramBinary = loadProc("glProgramBinary"); + api->VertexAttrib4f = loadProc("glVertexAttrib4f"); + api->VertexAttribP2uiv = loadProc("glVertexAttribP2uiv"); + api->UniformMatrix3fv = loadProc("glUniformMatrix3fv"); + api->Uniform2i = loadProc("glUniform2i"); + api->GetQueryObjectuiv = loadProc("glGetQueryObjectuiv"); + api->UniformBlockBinding = loadProc("glUniformBlockBinding"); + api->SampleCoverage = loadProc("glSampleCoverage"); + api->VertexAttrib4Nusv = loadProc("glVertexAttrib4Nusv"); + api->ProgramUniformMatrix2x4dv = loadProc("glProgramUniformMatrix2x4dv"); + api->Uniform3uiv = loadProc("glUniform3uiv"); + api->VertexAttrib1s = loadProc("glVertexAttrib1s"); + api->GetVertexAttribPointerv = loadProc("glGetVertexAttribPointerv"); + api->BlendBarrier = oc_glBlendBarrier_noimpl; + api->DrawRangeElements = loadProc("glDrawRangeElements"); + api->TexStorage3D = oc_glTexStorage3D_noimpl; + api->GetInternalformati64v = oc_glGetInternalformati64v_noimpl; + api->GetQueryObjecti64v = loadProc("glGetQueryObjecti64v"); + api->CompressedTexSubImage1D = loadProc("glCompressedTexSubImage1D"); + api->VertexAttrib3dv = loadProc("glVertexAttrib3dv"); + api->VertexBindingDivisor = oc_glVertexBindingDivisor_noimpl; + api->UseProgramStages = loadProc("glUseProgramStages"); + api->VertexAttribBinding = oc_glVertexAttribBinding_noimpl; + api->DebugMessageInsert = oc_glDebugMessageInsert_noimpl; + api->GetTexParameteriv = loadProc("glGetTexParameteriv"); + api->MultiDrawArraysIndirect = oc_glMultiDrawArraysIndirect_noimpl; + api->GetTexParameterfv = loadProc("glGetTexParameterfv"); + api->GetProgramPipelineInfoLog = loadProc("glGetProgramPipelineInfoLog"); + api->EndQuery = loadProc("glEndQuery"); + api->GetProgramResourceLocation = oc_glGetProgramResourceLocation_noimpl; + api->CompressedTexImage2D = loadProc("glCompressedTexImage2D"); + api->VertexAttribP2ui = loadProc("glVertexAttribP2ui"); + api->IsEnabledi = loadProc("glIsEnabledi"); + api->GetActiveAtomicCounterBufferiv = oc_glGetActiveAtomicCounterBufferiv_noimpl; + api->IsProgram = loadProc("glIsProgram"); + api->Uniform1dv = loadProc("glUniform1dv"); + api->TexParameteriv = loadProc("glTexParameteriv"); + api->Uniform2fv = loadProc("glUniform2fv"); + api->ReleaseShaderCompiler = loadProc("glReleaseShaderCompiler"); + api->CullFace = loadProc("glCullFace"); + api->VertexAttribI4i = loadProc("glVertexAttribI4i"); + api->GetProgramResourceIndex = oc_glGetProgramResourceIndex_noimpl; + api->ShaderBinary = loadProc("glShaderBinary"); + api->UniformMatrix3x2dv = loadProc("glUniformMatrix3x2dv"); + api->InvalidateFramebuffer = oc_glInvalidateFramebuffer_noimpl; + api->AttachShader = loadProc("glAttachShader"); + api->FlushMappedBufferRange = loadProc("glFlushMappedBufferRange"); + api->VertexAttribP3uiv = loadProc("glVertexAttribP3uiv"); + api->GetActiveUniformName = loadProc("glGetActiveUniformName"); + api->MapBuffer = loadProc("glMapBuffer"); + api->DrawBuffers = loadProc("glDrawBuffers"); + api->GetSynciv = loadProc("glGetSynciv"); + api->CopyTexSubImage2D = loadProc("glCopyTexSubImage2D"); + api->ObjectLabel = oc_glObjectLabel_noimpl; + api->BufferSubData = loadProc("glBufferSubData"); + api->Uniform2f = loadProc("glUniform2f"); + api->DebugMessageCallback = oc_glDebugMessageCallback_noimpl; + api->VertexAttribL4dv = loadProc("glVertexAttribL4dv"); + api->IsProgramPipeline = loadProc("glIsProgramPipeline"); + api->ResumeTransformFeedback = loadProc("glResumeTransformFeedback"); + api->VertexAttribI4iv = loadProc("glVertexAttribI4iv"); + api->GetShaderInfoLog = loadProc("glGetShaderInfoLog"); + api->GetIntegeri_v = loadProc("glGetIntegeri_v"); + api->BindVertexBuffer = oc_glBindVertexBuffer_noimpl; + api->BlendEquation = loadProc("glBlendEquation"); + api->VertexAttribL2dv = loadProc("glVertexAttribL2dv"); + api->VertexAttribI1ui = loadProc("glVertexAttribI1ui"); + api->VertexAttrib4Nsv = loadProc("glVertexAttrib4Nsv"); + api->VertexAttribL4d = loadProc("glVertexAttribL4d"); + api->CopyImageSubData = oc_glCopyImageSubData_noimpl; + api->GetFramebufferAttachmentParameteriv = loadProc("glGetFramebufferAttachmentParameteriv"); + api->VertexAttribL2d = loadProc("glVertexAttribL2d"); + api->GetSubroutineIndex = loadProc("glGetSubroutineIndex"); + api->VertexAttribI3uiv = loadProc("glVertexAttribI3uiv"); + api->VertexAttrib4iv = loadProc("glVertexAttrib4iv"); + api->BindVertexBuffers = oc_glBindVertexBuffers_noimpl; + api->ProgramUniformMatrix2x3dv = loadProc("glProgramUniformMatrix2x3dv"); + api->PrimitiveBoundingBox = oc_glPrimitiveBoundingBox_noimpl; + api->Scissor = loadProc("glScissor"); + api->ClientWaitSync = loadProc("glClientWaitSync"); + api->Uniform3ui = loadProc("glUniform3ui"); + api->VertexAttribP3ui = loadProc("glVertexAttribP3ui"); + api->Enable = loadProc("glEnable"); + api->StencilOpSeparate = loadProc("glStencilOpSeparate"); + api->UniformMatrix2x3dv = loadProc("glUniformMatrix2x3dv"); + api->ProgramUniformMatrix3dv = loadProc("glProgramUniformMatrix3dv"); + api->TexImage2DMultisample = loadProc("glTexImage2DMultisample"); + api->VertexAttrib4Nbv = loadProc("glVertexAttrib4Nbv"); + api->GetTexImage = loadProc("glGetTexImage"); + api->VertexAttrib4sv = loadProc("glVertexAttrib4sv"); + api->PixelStorei = loadProc("glPixelStorei"); + api->DepthMask = loadProc("glDepthMask"); + api->TexStorage2D = oc_glTexStorage2D_noimpl; + api->Clear = loadProc("glClear"); + api->UniformMatrix3x4dv = loadProc("glUniformMatrix3x4dv"); + api->DeleteTransformFeedbacks = loadProc("glDeleteTransformFeedbacks"); + api->MapBufferRange = loadProc("glMapBufferRange"); + api->MemoryBarrier = oc_glMemoryBarrier_noimpl; + api->ViewportIndexedf = loadProc("glViewportIndexedf"); + api->VertexAttrib3fv = loadProc("glVertexAttrib3fv"); + api->ObjectPtrLabel = oc_glObjectPtrLabel_noimpl; + api->TexStorage1D = oc_glTexStorage1D_noimpl; + api->CompressedTexImage3D = loadProc("glCompressedTexImage3D"); + api->VertexAttrib1fv = loadProc("glVertexAttrib1fv"); + api->VertexAttribPointer = loadProc("glVertexAttribPointer"); + api->GetQueryIndexediv = loadProc("glGetQueryIndexediv"); + api->CompileShader = loadProc("glCompileShader"); + api->ProgramUniform1i = loadProc("glProgramUniform1i"); + api->GetQueryiv = loadProc("glGetQueryiv"); + api->VertexAttribI1iv = loadProc("glVertexAttribI1iv"); + api->CopyTexImage2D = loadProc("glCopyTexImage2D"); + api->GetQueryObjectui64v = loadProc("glGetQueryObjectui64v"); + api->PointSize = loadProc("glPointSize"); + api->Disablei = loadProc("glDisablei"); + api->VertexAttribL1dv = loadProc("glVertexAttribL1dv"); + api->CreateShader = loadProc("glCreateShader"); + api->GetString = loadProc("glGetString"); + api->ViewportArrayv = loadProc("glViewportArrayv"); + api->ProgramUniform3d = loadProc("glProgramUniform3d"); + api->VertexAttrib4Nubv = loadProc("glVertexAttrib4Nubv"); + api->TexParameteri = loadProc("glTexParameteri"); + api->ProgramUniform4fv = loadProc("glProgramUniform4fv"); + api->GenerateMipmap = loadProc("glGenerateMipmap"); + api->CompressedTexSubImage3D = loadProc("glCompressedTexSubImage3D"); + api->Uniform3f = loadProc("glUniform3f"); + api->GetUniformIndices = loadProc("glGetUniformIndices"); + api->VertexAttribLPointer = loadProc("glVertexAttribLPointer"); + api->VertexAttribI2uiv = loadProc("glVertexAttribI2uiv"); + api->QueryCounter = loadProc("glQueryCounter"); + api->ActiveShaderProgram = loadProc("glActiveShaderProgram"); + api->Uniform1ui = loadProc("glUniform1ui"); + api->VertexAttribI1i = loadProc("glVertexAttribI1i"); + api->GetTexParameterIiv = loadProc("glGetTexParameterIiv"); + api->GetUniformfv = loadProc("glGetUniformfv"); + api->ProgramUniform2uiv = loadProc("glProgramUniform2uiv"); + api->GetError = loadProc("glGetError"); + api->GetActiveUniformBlockName = loadProc("glGetActiveUniformBlockName"); + api->TextureView = oc_glTextureView_noimpl; + api->GetnUniformiv = oc_glGetnUniformiv_noimpl; + api->ProgramUniform4dv = loadProc("glProgramUniform4dv"); + api->ViewportIndexedfv = loadProc("glViewportIndexedfv"); + api->Hint = loadProc("glHint"); + api->GetShaderSource = loadProc("glGetShaderSource"); + api->ProgramUniformMatrix4x3fv = loadProc("glProgramUniformMatrix4x3fv"); + api->Uniform1iv = loadProc("glUniform1iv"); + api->VertexAttribI4bv = loadProc("glVertexAttribI4bv"); + api->UniformMatrix4x2dv = loadProc("glUniformMatrix4x2dv"); + api->BufferStorage = oc_glBufferStorage_noimpl; + api->IsRenderbuffer = loadProc("glIsRenderbuffer"); + api->GetActiveSubroutineUniformName = loadProc("glGetActiveSubroutineUniformName"); + api->LinkProgram = loadProc("glLinkProgram"); + api->GetActiveUniformsiv = loadProc("glGetActiveUniformsiv"); + api->GetDebugMessageLog = oc_glGetDebugMessageLog_noimpl; + api->CopyTexSubImage3D = loadProc("glCopyTexSubImage3D"); + api->PointParameteri = loadProc("glPointParameteri"); + api->ProgramUniform3dv = loadProc("glProgramUniform3dv"); + api->CompressedTexImage1D = loadProc("glCompressedTexImage1D"); + api->UniformMatrix3x4fv = loadProc("glUniformMatrix3x4fv"); + api->GenSamplers = loadProc("glGenSamplers"); + api->GetCompressedTexImage = loadProc("glGetCompressedTexImage"); + api->DeleteQueries = loadProc("glDeleteQueries"); + api->GenProgramPipelines = loadProc("glGenProgramPipelines"); + api->DispatchComputeIndirect = oc_glDispatchComputeIndirect_noimpl; + api->VertexAttribIPointer = loadProc("glVertexAttribIPointer"); + api->CreateProgram = loadProc("glCreateProgram"); + api->ClearTexSubImage = oc_glClearTexSubImage_noimpl; + api->VertexAttrib4d = loadProc("glVertexAttrib4d"); + api->FrontFace = loadProc("glFrontFace"); + api->BindTransformFeedback = loadProc("glBindTransformFeedback"); + api->GetProgramStageiv = loadProc("glGetProgramStageiv"); + api->SamplerParameterIiv = loadProc("glSamplerParameterIiv"); + api->GetInteger64v = loadProc("glGetInteger64v"); + api->CreateShaderProgramv = loadProc("glCreateShaderProgramv"); + api->BindBuffersRange = oc_glBindBuffersRange_noimpl; + api->Uniform3fv = loadProc("glUniform3fv"); + api->ProgramUniformMatrix4fv = loadProc("glProgramUniformMatrix4fv"); + api->BindBuffersBase = oc_glBindBuffersBase_noimpl; + api->ClearBufferfi = loadProc("glClearBufferfi"); + api->FramebufferTexture3D = loadProc("glFramebufferTexture3D"); + api->Disable = loadProc("glDisable"); + api->ProgramUniform1iv = loadProc("glProgramUniform1iv"); + api->VertexAttribI2iv = loadProc("glVertexAttribI2iv"); + api->DepthRangeIndexed = loadProc("glDepthRangeIndexed"); + api->PatchParameteri = loadProc("glPatchParameteri"); + api->GetUniformBlockIndex = loadProc("glGetUniformBlockIndex"); + api->MultiDrawArrays = loadProc("glMultiDrawArrays"); + api->VertexAttribI4ubv = loadProc("glVertexAttribI4ubv"); + api->BindBuffer = loadProc("glBindBuffer"); + api->VertexAttribI3i = loadProc("glVertexAttribI3i"); + api->GetDoublev = loadProc("glGetDoublev"); + api->DrawTransformFeedbackStream = loadProc("glDrawTransformFeedbackStream"); + api->VertexAttribI4uiv = loadProc("glVertexAttribI4uiv"); + api->RenderbufferStorageMultisample = loadProc("glRenderbufferStorageMultisample"); + api->VertexAttribL3dv = loadProc("glVertexAttribL3dv"); + api->StencilMaskSeparate = loadProc("glStencilMaskSeparate"); + api->ProgramUniform1d = loadProc("glProgramUniform1d"); + api->Viewport = loadProc("glViewport"); + api->VertexAttribP1ui = loadProc("glVertexAttribP1ui"); + api->VertexAttrib4dv = loadProc("glVertexAttrib4dv"); + api->GenQueries = loadProc("glGenQueries"); + api->TexParameterIiv = loadProc("glTexParameterIiv"); + api->ProgramUniform2d = loadProc("glProgramUniform2d"); + api->ProgramUniform1uiv = loadProc("glProgramUniform1uiv"); + api->VertexAttrib4Nub = loadProc("glVertexAttrib4Nub"); + api->IsVertexArray = loadProc("glIsVertexArray"); + api->ProgramUniform3f = loadProc("glProgramUniform3f"); + api->ProgramUniform3iv = loadProc("glProgramUniform3iv"); + api->GetProgramBinary = loadProc("glGetProgramBinary"); + api->BindRenderbuffer = loadProc("glBindRenderbuffer"); + api->BindFragDataLocationIndexed = loadProc("glBindFragDataLocationIndexed"); + api->GetSamplerParameterIiv = loadProc("glGetSamplerParameterIiv"); + api->VertexAttribDivisor = loadProc("glVertexAttribDivisor"); + api->ProgramUniformMatrix3x2dv = loadProc("glProgramUniformMatrix3x2dv"); + api->FramebufferParameteri = oc_glFramebufferParameteri_noimpl; + api->GenTransformFeedbacks = loadProc("glGenTransformFeedbacks"); + api->DeleteSync = loadProc("glDeleteSync"); + api->ProgramUniform1ui = loadProc("glProgramUniform1ui"); + api->TexSubImage1D = loadProc("glTexSubImage1D"); + api->ClearDepthf = loadProc("glClearDepthf"); + api->ReadPixels = loadProc("glReadPixels"); + api->VertexAttribI2i = loadProc("glVertexAttribI2i"); + api->Finish = loadProc("glFinish"); + api->LineWidth = loadProc("glLineWidth"); + api->DeleteShader = loadProc("glDeleteShader"); + api->IsSampler = loadProc("glIsSampler"); + api->ProgramUniformMatrix4dv = loadProc("glProgramUniformMatrix4dv"); + api->TransformFeedbackVaryings = loadProc("glTransformFeedbackVaryings"); + api->BeginConditionalRender = loadProc("glBeginConditionalRender"); + api->BindSamplers = oc_glBindSamplers_noimpl; + api->DeleteProgramPipelines = loadProc("glDeleteProgramPipelines"); + api->ColorMask = loadProc("glColorMask"); + api->TexParameterfv = loadProc("glTexParameterfv"); + api->PushDebugGroup = oc_glPushDebugGroup_noimpl; + api->ClearBufferfv = loadProc("glClearBufferfv"); + api->IsEnabled = loadProc("glIsEnabled"); + api->VertexAttrib2f = loadProc("glVertexAttrib2f"); + api->ProgramUniform2f = loadProc("glProgramUniform2f"); + api->GetSamplerParameterIuiv = loadProc("glGetSamplerParameterIuiv"); + api->GetInteger64i_v = loadProc("glGetInteger64i_v"); + api->Uniform2dv = loadProc("glUniform2dv"); + api->GetBufferSubData = loadProc("glGetBufferSubData"); + api->MultiDrawElementsIndirect = oc_glMultiDrawElementsIndirect_noimpl; + api->ProgramParameteri = loadProc("glProgramParameteri"); + api->VertexAttribP4ui = loadProc("glVertexAttribP4ui"); + api->SamplerParameterfv = loadProc("glSamplerParameterfv"); + api->PointParameterf = loadProc("glPointParameterf"); + api->UniformMatrix2x4fv = loadProc("glUniformMatrix2x4fv"); + api->GenBuffers = loadProc("glGenBuffers"); + api->ProgramUniform2dv = loadProc("glProgramUniform2dv"); + api->VertexAttribFormat = oc_glVertexAttribFormat_noimpl; + api->TexSubImage2D = loadProc("glTexSubImage2D"); + api->VertexAttrib4ubv = loadProc("glVertexAttrib4ubv"); + api->GetGraphicsResetStatus = oc_glGetGraphicsResetStatus_noimpl; + api->GetProgramInterfaceiv = oc_glGetProgramInterfaceiv_noimpl; + api->VertexAttribIFormat = oc_glVertexAttribIFormat_noimpl; + api->GetnUniformfv = oc_glGetnUniformfv_noimpl; + api->DeleteProgram = loadProc("glDeleteProgram"); + api->ClampColor = loadProc("glClampColor"); + api->DrawElementsInstancedBaseVertexBaseInstance = oc_glDrawElementsInstancedBaseVertexBaseInstance_noimpl; + api->DrawElements = loadProc("glDrawElements"); + api->DebugMessageControl = oc_glDebugMessageControl_noimpl; + api->GetRenderbufferParameteriv = loadProc("glGetRenderbufferParameteriv"); + api->DetachShader = loadProc("glDetachShader"); + api->GenFramebuffers = loadProc("glGenFramebuffers"); + api->ProvokingVertex = loadProc("glProvokingVertex"); + api->SampleMaski = loadProc("glSampleMaski"); + api->EndQueryIndexed = loadProc("glEndQueryIndexed"); + api->ProgramUniform1f = loadProc("glProgramUniform1f"); + api->BindFramebuffer = loadProc("glBindFramebuffer"); + api->BeginQueryIndexed = loadProc("glBeginQueryIndexed"); + api->UniformSubroutinesuiv = loadProc("glUniformSubroutinesuiv"); + api->GetUniformiv = loadProc("glGetUniformiv"); + api->FramebufferTexture = loadProc("glFramebufferTexture"); + api->PointParameterfv = loadProc("glPointParameterfv"); + api->IsTransformFeedback = loadProc("glIsTransformFeedback"); + api->CheckFramebufferStatus = loadProc("glCheckFramebufferStatus"); + api->ShaderSource = loadProc("glShaderSource"); + api->UniformMatrix2x4dv = loadProc("glUniformMatrix2x4dv"); + api->BindImageTextures = oc_glBindImageTextures_noimpl; + api->CopyTexImage1D = loadProc("glCopyTexImage1D"); + api->UniformMatrix3dv = loadProc("glUniformMatrix3dv"); + api->ProgramUniform1dv = loadProc("glProgramUniform1dv"); + api->BlitFramebuffer = loadProc("glBlitFramebuffer"); + api->PopDebugGroup = oc_glPopDebugGroup_noimpl; + api->TexParameterIuiv = loadProc("glTexParameterIuiv"); + api->VertexAttrib2d = loadProc("glVertexAttrib2d"); + api->TexImage1D = loadProc("glTexImage1D"); + api->GetObjectPtrLabel = oc_glGetObjectPtrLabel_noimpl; + api->StencilMask = loadProc("glStencilMask"); + api->BeginQuery = loadProc("glBeginQuery"); + api->UniformMatrix4fv = loadProc("glUniformMatrix4fv"); + api->IsSync = loadProc("glIsSync"); + api->Uniform3dv = loadProc("glUniform3dv"); + api->ProgramUniform2fv = loadProc("glProgramUniform2fv"); + api->VertexAttribI4sv = loadProc("glVertexAttribI4sv"); + api->ScissorArrayv = loadProc("glScissorArrayv"); + api->VertexAttribP1uiv = loadProc("glVertexAttribP1uiv"); + api->Uniform2uiv = loadProc("glUniform2uiv"); + api->DeleteBuffers = loadProc("glDeleteBuffers"); + api->ProgramUniform3ui = loadProc("glProgramUniform3ui"); + api->FramebufferTextureLayer = loadProc("glFramebufferTextureLayer"); + api->EndTransformFeedback = loadProc("glEndTransformFeedback"); + api->BlendFuncSeparatei = loadProc("glBlendFuncSeparatei"); + api->DrawTransformFeedbackInstanced = oc_glDrawTransformFeedbackInstanced_noimpl; + api->DrawRangeElementsBaseVertex = loadProc("glDrawRangeElementsBaseVertex"); + api->VertexAttrib1f = loadProc("glVertexAttrib1f"); + api->GetUniformSubroutineuiv = loadProc("glGetUniformSubroutineuiv"); + api->DisableVertexAttribArray = loadProc("glDisableVertexAttribArray"); + api->ProgramUniformMatrix3x2fv = loadProc("glProgramUniformMatrix3x2fv"); + api->VertexAttribI4usv = loadProc("glVertexAttribI4usv"); + api->GetObjectLabel = oc_glGetObjectLabel_noimpl; + api->BindAttribLocation = loadProc("glBindAttribLocation"); + api->Uniform1f = loadProc("glUniform1f"); + api->GetUniformdv = loadProc("glGetUniformdv"); + api->GetUniformLocation = loadProc("glGetUniformLocation"); + api->GetSubroutineUniformLocation = loadProc("glGetSubroutineUniformLocation"); + api->GetTexParameterIuiv = loadProc("glGetTexParameterIuiv"); + api->SamplerParameterf = loadProc("glSamplerParameterf"); + api->VertexAttribL3d = loadProc("glVertexAttribL3d"); + api->TexImage3DMultisample = loadProc("glTexImage3DMultisample"); + api->TexImage3D = loadProc("glTexImage3D"); + api->RenderbufferStorage = loadProc("glRenderbufferStorage"); + api->EnableVertexAttribArray = loadProc("glEnableVertexAttribArray"); + api->VertexAttribP4uiv = loadProc("glVertexAttribP4uiv"); + api->Uniform4d = loadProc("glUniform4d"); + api->VertexAttrib4s = loadProc("glVertexAttrib4s"); + api->DrawElementsInstancedBaseVertex = loadProc("glDrawElementsInstancedBaseVertex"); + api->VertexAttrib3s = loadProc("glVertexAttrib3s"); + api->ProgramUniform2iv = loadProc("glProgramUniform2iv"); + api->StencilFuncSeparate = loadProc("glStencilFuncSeparate"); + api->DeleteFramebuffers = loadProc("glDeleteFramebuffers"); + api->DepthRange = loadProc("glDepthRange"); + api->UniformMatrix3x2fv = loadProc("glUniformMatrix3x2fv"); + api->ProgramUniformMatrix2dv = loadProc("glProgramUniformMatrix2dv"); + api->ShaderStorageBlockBinding = oc_glShaderStorageBlockBinding_noimpl; + api->ClearDepth = loadProc("glClearDepth"); + api->VertexAttrib2dv = loadProc("glVertexAttrib2dv"); + api->SamplerParameterIuiv = loadProc("glSamplerParameterIuiv"); + api->GetVertexAttribLdv = loadProc("glGetVertexAttribLdv"); + api->ProgramUniformMatrix3x4dv = loadProc("glProgramUniformMatrix3x4dv"); + api->DepthRangeArrayv = loadProc("glDepthRangeArrayv"); + api->GetActiveUniform = loadProc("glGetActiveUniform"); + api->PatchParameterfv = loadProc("glPatchParameterfv"); + api->InvalidateTexImage = oc_glInvalidateTexImage_noimpl; + api->VertexAttrib3f = loadProc("glVertexAttrib3f"); + api->ProgramUniform4iv = loadProc("glProgramUniform4iv"); + api->ProgramUniform4d = loadProc("glProgramUniform4d"); + api->IsFramebuffer = loadProc("glIsFramebuffer"); + api->PixelStoref = loadProc("glPixelStoref"); + api->ProgramUniform4uiv = loadProc("glProgramUniform4uiv"); + api->ProgramUniformMatrix4x2dv = loadProc("glProgramUniformMatrix4x2dv"); + api->FenceSync = loadProc("glFenceSync"); + api->GetBufferParameteri64v = loadProc("glGetBufferParameteri64v"); + api->StencilOp = loadProc("glStencilOp"); + api->ClearBufferData = oc_glClearBufferData_noimpl; + api->GetnUniformuiv = oc_glGetnUniformuiv_noimpl; + api->GetProgramResourceiv = oc_glGetProgramResourceiv_noimpl; + api->GetVertexAttribdv = loadProc("glGetVertexAttribdv"); + api->GetTransformFeedbackVarying = loadProc("glGetTransformFeedbackVarying"); + api->VertexAttrib2fv = loadProc("glVertexAttrib2fv"); + api->GetBooleani_v = loadProc("glGetBooleani_v"); + api->ColorMaski = loadProc("glColorMaski"); + api->InvalidateBufferSubData = oc_glInvalidateBufferSubData_noimpl; + api->UniformMatrix4dv = loadProc("glUniformMatrix4dv"); + api->IsQuery = loadProc("glIsQuery"); + api->Uniform4ui = loadProc("glUniform4ui"); + api->Uniform4i = loadProc("glUniform4i"); + api->GetSamplerParameteriv = loadProc("glGetSamplerParameteriv"); + api->MultiDrawElementsBaseVertex = loadProc("glMultiDrawElementsBaseVertex"); + api->VertexAttribI1uiv = loadProc("glVertexAttribI1uiv"); + api->GetIntegerv = loadProc("glGetIntegerv"); + api->UniformMatrix2x3fv = loadProc("glUniformMatrix2x3fv"); + api->TexImage2D = loadProc("glTexImage2D"); + api->GetAttachedShaders = loadProc("glGetAttachedShaders"); + api->Uniform2d = loadProc("glUniform2d"); + api->MemoryBarrierByRegion = oc_glMemoryBarrierByRegion_noimpl; + api->UniformMatrix2fv = loadProc("glUniformMatrix2fv"); + api->PrimitiveRestartIndex = loadProc("glPrimitiveRestartIndex"); + api->GetVertexAttribiv = loadProc("glGetVertexAttribiv"); + api->GetAttribLocation = loadProc("glGetAttribLocation"); + api->TexStorage2DMultisample = oc_glTexStorage2DMultisample_noimpl; + api->CompressedTexSubImage2D = loadProc("glCompressedTexSubImage2D"); + api->GetVertexAttribfv = loadProc("glGetVertexAttribfv"); + api->GetBufferParameteriv = loadProc("glGetBufferParameteriv"); + api->TexParameterf = loadProc("glTexParameterf"); + api->FramebufferTexture2D = loadProc("glFramebufferTexture2D"); + api->GetActiveAttrib = loadProc("glGetActiveAttrib"); + api->InvalidateTexSubImage = oc_glInvalidateTexSubImage_noimpl; + api->DeleteVertexArrays = loadProc("glDeleteVertexArrays"); + api->VertexAttribI2ui = loadProc("glVertexAttribI2ui"); + api->PointParameteriv = loadProc("glPointParameteriv"); + api->GetPointerv = oc_glGetPointerv_noimpl; + api->Enablei = loadProc("glEnablei"); + api->BindBufferRange = loadProc("glBindBufferRange"); + api->DrawArraysInstanced = loadProc("glDrawArraysInstanced"); + api->DeleteTextures = loadProc("glDeleteTextures"); + api->VertexAttrib4Niv = loadProc("glVertexAttrib4Niv"); + api->MultiDrawElements = loadProc("glMultiDrawElements"); + api->GetProgramiv = loadProc("glGetProgramiv"); + api->DepthFunc = loadProc("glDepthFunc"); + api->GenTextures = loadProc("glGenTextures"); + api->GetInternalformativ = oc_glGetInternalformativ_noimpl; + api->ProgramUniform3i = loadProc("glProgramUniform3i"); + api->ScissorIndexed = loadProc("glScissorIndexed"); + api->VertexAttrib2sv = loadProc("glVertexAttrib2sv"); + api->TexStorage3DMultisample = oc_glTexStorage3DMultisample_noimpl; + api->Uniform2iv = loadProc("glUniform2iv"); + api->DrawArraysInstancedBaseInstance = oc_glDrawArraysInstancedBaseInstance_noimpl; + api->VertexAttribI3ui = loadProc("glVertexAttribI3ui"); + api->DeleteSamplers = loadProc("glDeleteSamplers"); + api->GenVertexArrays = loadProc("glGenVertexArrays"); + api->GetFramebufferParameteriv = oc_glGetFramebufferParameteriv_noimpl; + api->PolygonMode = loadProc("glPolygonMode"); + api->ProgramUniformMatrix2x4fv = loadProc("glProgramUniformMatrix2x4fv"); + api->GetProgramResourceName = oc_glGetProgramResourceName_noimpl; + api->SamplerParameteriv = loadProc("glSamplerParameteriv"); + api->GetActiveSubroutineUniformiv = loadProc("glGetActiveSubroutineUniformiv"); + api->GetStringi = loadProc("glGetStringi"); + api->VertexAttribLFormat = oc_glVertexAttribLFormat_noimpl; + api->VertexAttrib3d = loadProc("glVertexAttrib3d"); + api->BindVertexArray = loadProc("glBindVertexArray"); + api->UnmapBuffer = loadProc("glUnmapBuffer"); + api->DrawElementsInstancedBaseInstance = oc_glDrawElementsInstancedBaseInstance_noimpl; + api->Uniform4uiv = loadProc("glUniform4uiv"); + api->FramebufferTexture1D = loadProc("glFramebufferTexture1D"); + api->DrawTransformFeedbackStreamInstanced = oc_glDrawTransformFeedbackStreamInstanced_noimpl; + api->StencilFunc = loadProc("glStencilFunc"); + api->ValidateProgram = loadProc("glValidateProgram"); + api->Flush = loadProc("glFlush"); + api->ProgramUniform3uiv = loadProc("glProgramUniform3uiv"); + api->DeleteRenderbuffers = loadProc("glDeleteRenderbuffers"); + api->VertexAttrib4fv = loadProc("glVertexAttrib4fv"); + api->UniformMatrix2dv = loadProc("glUniformMatrix2dv"); + api->GetFragDataIndex = loadProc("glGetFragDataIndex"); + api->Uniform3iv = loadProc("glUniform3iv"); + api->MinSampleShading = loadProc("glMinSampleShading"); + api->GetBooleanv = loadProc("glGetBooleanv"); + api->GetMultisamplefv = loadProc("glGetMultisamplefv"); + api->GetVertexAttribIuiv = loadProc("glGetVertexAttribIuiv"); + api->GetProgramInfoLog = loadProc("glGetProgramInfoLog"); + api->Uniform4fv = loadProc("glUniform4fv"); + api->DrawBuffer = loadProc("glDrawBuffer"); + api->Uniform1i = loadProc("glUniform1i"); + api->ProgramUniform4ui = loadProc("glProgramUniform4ui"); + api->ProgramUniformMatrix3fv = loadProc("glProgramUniformMatrix3fv"); + api->BlendEquationSeparate = loadProc("glBlendEquationSeparate"); + api->BindProgramPipeline = loadProc("glBindProgramPipeline"); + api->GetDoublei_v = loadProc("glGetDoublei_v"); + api->BufferData = loadProc("glBufferData"); + api->ClearColor = loadProc("glClearColor"); + api->ProgramUniform4i = loadProc("glProgramUniform4i"); + api->GetTexLevelParameteriv = loadProc("glGetTexLevelParameteriv"); + api->GetActiveUniformBlockiv = loadProc("glGetActiveUniformBlockiv"); + api->ProgramUniform1fv = loadProc("glProgramUniform1fv"); + api->PauseTransformFeedback = loadProc("glPauseTransformFeedback"); + api->GetBufferPointerv = loadProc("glGetBufferPointerv"); + api->InvalidateSubFramebuffer = oc_glInvalidateSubFramebuffer_noimpl; + api->ScissorIndexedv = loadProc("glScissorIndexedv"); + api->Uniform2ui = loadProc("glUniform2ui"); + api->BindTexture = loadProc("glBindTexture"); + api->DrawElementsInstanced = loadProc("glDrawElementsInstanced"); + api->ProgramUniform4f = loadProc("glProgramUniform4f"); + api->BindBufferBase = loadProc("glBindBufferBase"); + api->IsShader = loadProc("glIsShader"); + api->ClearBufferSubData = oc_glClearBufferSubData_noimpl; + api->VertexAttrib4Nuiv = loadProc("glVertexAttrib4Nuiv"); + api->DrawArraysIndirect = loadProc("glDrawArraysIndirect"); + api->VertexAttrib4usv = loadProc("glVertexAttrib4usv"); + api->Uniform1d = loadProc("glUniform1d"); + api->ClearTexImage = oc_glClearTexImage_noimpl; + api->Uniform1uiv = loadProc("glUniform1uiv"); + api->BindSampler = loadProc("glBindSampler"); + api->GetTexLevelParameterfv = loadProc("glGetTexLevelParameterfv"); + api->ClearBufferiv = loadProc("glClearBufferiv"); + api->LogicOp = loadProc("glLogicOp"); + api->ActiveTexture = loadProc("glActiveTexture"); + api->GetFragDataLocation = loadProc("glGetFragDataLocation"); + api->BlendColor = loadProc("glBlendColor"); + api->UniformMatrix4x3fv = loadProc("glUniformMatrix4x3fv"); + api->ProgramUniform3fv = loadProc("glProgramUniform3fv"); + api->Uniform1fv = loadProc("glUniform1fv"); + api->DrawElementsBaseVertex = loadProc("glDrawElementsBaseVertex"); + api->Uniform4f = loadProc("glUniform4f"); + api->BlendEquationSeparatei = loadProc("glBlendEquationSeparatei"); + api->BlendFuncSeparate = loadProc("glBlendFuncSeparate"); + api->ClearBufferuiv = loadProc("glClearBufferuiv"); + api->CopyTexSubImage1D = loadProc("glCopyTexSubImage1D"); + api->DrawTransformFeedback = loadProc("glDrawTransformFeedback"); + api->ReadBuffer = loadProc("glReadBuffer"); + api->CopyBufferSubData = loadProc("glCopyBufferSubData"); + api->GetUniformuiv = loadProc("glGetUniformuiv"); + api->PolygonOffset = loadProc("glPolygonOffset"); + api->DispatchCompute = oc_glDispatchCompute_noimpl; + api->BindImageTexture = oc_glBindImageTexture_noimpl; + api->UniformMatrix4x3dv = loadProc("glUniformMatrix4x3dv"); + api->GenRenderbuffers = loadProc("glGenRenderbuffers"); } void oc_gl_load_gl43(oc_gl_api* api, oc_gl_load_proc loadProc) { - api->name = "gl43"; - api->GetFloatv = loadProc("glGetFloatv"); - api->TexBufferRange = loadProc("glTexBufferRange"); - api->IsBuffer = loadProc("glIsBuffer"); - api->IsTexture = loadProc("glIsTexture"); - api->DepthRangef = loadProc("glDepthRangef"); - api->EndConditionalRender = loadProc("glEndConditionalRender"); - api->BlendFunci = loadProc("glBlendFunci"); - api->GetProgramPipelineiv = loadProc("glGetProgramPipelineiv"); - api->WaitSync = loadProc("glWaitSync"); - api->ProgramUniformMatrix2fv = loadProc("glProgramUniformMatrix2fv"); - api->ProgramUniformMatrix4x3dv = loadProc("glProgramUniformMatrix4x3dv"); - api->VertexAttrib1dv = loadProc("glVertexAttrib1dv"); - api->SamplerParameteri = loadProc("glSamplerParameteri"); - api->GetVertexAttribIiv = loadProc("glGetVertexAttribIiv"); - api->GetSamplerParameterfv = loadProc("glGetSamplerParameterfv"); - api->VertexAttrib1d = loadProc("glVertexAttrib1d"); - api->TexBuffer = loadProc("glTexBuffer"); - api->InvalidateBufferData = loadProc("glInvalidateBufferData"); - api->ProgramUniform2i = loadProc("glProgramUniform2i"); - api->Uniform4dv = loadProc("glUniform4dv"); - api->UseProgram = loadProc("glUseProgram"); - api->VertexAttribI3iv = loadProc("glVertexAttribI3iv"); - api->DrawElementsIndirect = loadProc("glDrawElementsIndirect"); - api->VertexAttrib4uiv = loadProc("glVertexAttrib4uiv"); - api->GetQueryObjectiv = loadProc("glGetQueryObjectiv"); - api->FramebufferRenderbuffer = loadProc("glFramebufferRenderbuffer"); - api->BlendEquationi = loadProc("glBlendEquationi"); - api->GetActiveSubroutineName = loadProc("glGetActiveSubroutineName"); - api->VertexAttrib2s = loadProc("glVertexAttrib2s"); - api->VertexAttribL1d = loadProc("glVertexAttribL1d"); - api->BindTextures = oc_glBindTextures_noimpl; - api->VertexAttrib3sv = loadProc("glVertexAttrib3sv"); - api->GetFloati_v = loadProc("glGetFloati_v"); - api->BeginTransformFeedback = loadProc("glBeginTransformFeedback"); - api->ClearStencil = loadProc("glClearStencil"); - api->Uniform3i = loadProc("glUniform3i"); - api->ValidateProgramPipeline = loadProc("glValidateProgramPipeline"); - api->ProgramUniformMatrix4x2fv = loadProc("glProgramUniformMatrix4x2fv"); - api->VertexAttribI4ui = loadProc("glVertexAttribI4ui"); - api->GetShaderiv = loadProc("glGetShaderiv"); - api->ReadnPixels = oc_glReadnPixels_noimpl; - api->UniformMatrix4x2fv = loadProc("glUniformMatrix4x2fv"); - api->GetShaderPrecisionFormat = loadProc("glGetShaderPrecisionFormat"); - api->ProgramUniformMatrix2x3fv = loadProc("glProgramUniformMatrix2x3fv"); - api->TexSubImage3D = loadProc("glTexSubImage3D"); - api->GetProgramResourceLocationIndex = loadProc("glGetProgramResourceLocationIndex"); - api->BlendFunc = loadProc("glBlendFunc"); - api->ProgramUniformMatrix3x4fv = loadProc("glProgramUniformMatrix3x4fv"); - api->Uniform3d = loadProc("glUniform3d"); - api->VertexAttrib1sv = loadProc("glVertexAttrib1sv"); - api->BindFragDataLocation = loadProc("glBindFragDataLocation"); - api->VertexAttrib4bv = loadProc("glVertexAttrib4bv"); - api->Uniform4iv = loadProc("glUniform4iv"); - api->ProgramUniform2ui = loadProc("glProgramUniform2ui"); - api->DrawArrays = loadProc("glDrawArrays"); - api->ProgramBinary = loadProc("glProgramBinary"); - api->VertexAttrib4f = loadProc("glVertexAttrib4f"); - api->VertexAttribP2uiv = loadProc("glVertexAttribP2uiv"); - api->UniformMatrix3fv = loadProc("glUniformMatrix3fv"); - api->Uniform2i = loadProc("glUniform2i"); - api->GetQueryObjectuiv = loadProc("glGetQueryObjectuiv"); - api->UniformBlockBinding = loadProc("glUniformBlockBinding"); - api->SampleCoverage = loadProc("glSampleCoverage"); - api->VertexAttrib4Nusv = loadProc("glVertexAttrib4Nusv"); - api->ProgramUniformMatrix2x4dv = loadProc("glProgramUniformMatrix2x4dv"); - api->Uniform3uiv = loadProc("glUniform3uiv"); - api->VertexAttrib1s = loadProc("glVertexAttrib1s"); - api->GetVertexAttribPointerv = loadProc("glGetVertexAttribPointerv"); - api->BlendBarrier = oc_glBlendBarrier_noimpl; - api->DrawRangeElements = loadProc("glDrawRangeElements"); - api->TexStorage3D = loadProc("glTexStorage3D"); - api->GetInternalformati64v = loadProc("glGetInternalformati64v"); - api->GetQueryObjecti64v = loadProc("glGetQueryObjecti64v"); - api->CompressedTexSubImage1D = loadProc("glCompressedTexSubImage1D"); - api->VertexAttrib3dv = loadProc("glVertexAttrib3dv"); - api->VertexBindingDivisor = loadProc("glVertexBindingDivisor"); - api->UseProgramStages = loadProc("glUseProgramStages"); - api->VertexAttribBinding = loadProc("glVertexAttribBinding"); - api->DebugMessageInsert = loadProc("glDebugMessageInsert"); - api->GetTexParameteriv = loadProc("glGetTexParameteriv"); - api->MultiDrawArraysIndirect = loadProc("glMultiDrawArraysIndirect"); - api->GetTexParameterfv = loadProc("glGetTexParameterfv"); - api->GetProgramPipelineInfoLog = loadProc("glGetProgramPipelineInfoLog"); - api->EndQuery = loadProc("glEndQuery"); - api->GetProgramResourceLocation = loadProc("glGetProgramResourceLocation"); - api->CompressedTexImage2D = loadProc("glCompressedTexImage2D"); - api->VertexAttribP2ui = loadProc("glVertexAttribP2ui"); - api->IsEnabledi = loadProc("glIsEnabledi"); - api->GetActiveAtomicCounterBufferiv = loadProc("glGetActiveAtomicCounterBufferiv"); - api->IsProgram = loadProc("glIsProgram"); - api->Uniform1dv = loadProc("glUniform1dv"); - api->TexParameteriv = loadProc("glTexParameteriv"); - api->Uniform2fv = loadProc("glUniform2fv"); - api->ReleaseShaderCompiler = loadProc("glReleaseShaderCompiler"); - api->CullFace = loadProc("glCullFace"); - api->VertexAttribI4i = loadProc("glVertexAttribI4i"); - api->GetProgramResourceIndex = loadProc("glGetProgramResourceIndex"); - api->ShaderBinary = loadProc("glShaderBinary"); - api->UniformMatrix3x2dv = loadProc("glUniformMatrix3x2dv"); - api->InvalidateFramebuffer = loadProc("glInvalidateFramebuffer"); - api->AttachShader = loadProc("glAttachShader"); - api->FlushMappedBufferRange = loadProc("glFlushMappedBufferRange"); - api->VertexAttribP3uiv = loadProc("glVertexAttribP3uiv"); - api->GetActiveUniformName = loadProc("glGetActiveUniformName"); - api->MapBuffer = loadProc("glMapBuffer"); - api->DrawBuffers = loadProc("glDrawBuffers"); - api->GetSynciv = loadProc("glGetSynciv"); - api->CopyTexSubImage2D = loadProc("glCopyTexSubImage2D"); - api->ObjectLabel = loadProc("glObjectLabel"); - api->BufferSubData = loadProc("glBufferSubData"); - api->Uniform2f = loadProc("glUniform2f"); - api->DebugMessageCallback = loadProc("glDebugMessageCallback"); - api->VertexAttribL4dv = loadProc("glVertexAttribL4dv"); - api->IsProgramPipeline = loadProc("glIsProgramPipeline"); - api->ResumeTransformFeedback = loadProc("glResumeTransformFeedback"); - api->VertexAttribI4iv = loadProc("glVertexAttribI4iv"); - api->GetShaderInfoLog = loadProc("glGetShaderInfoLog"); - api->GetIntegeri_v = loadProc("glGetIntegeri_v"); - api->BindVertexBuffer = loadProc("glBindVertexBuffer"); - api->BlendEquation = loadProc("glBlendEquation"); - api->VertexAttribL2dv = loadProc("glVertexAttribL2dv"); - api->VertexAttribI1ui = loadProc("glVertexAttribI1ui"); - api->VertexAttrib4Nsv = loadProc("glVertexAttrib4Nsv"); - api->VertexAttribL4d = loadProc("glVertexAttribL4d"); - api->CopyImageSubData = loadProc("glCopyImageSubData"); - api->GetFramebufferAttachmentParameteriv = loadProc("glGetFramebufferAttachmentParameteriv"); - api->VertexAttribL2d = loadProc("glVertexAttribL2d"); - api->GetSubroutineIndex = loadProc("glGetSubroutineIndex"); - api->VertexAttribI3uiv = loadProc("glVertexAttribI3uiv"); - api->VertexAttrib4iv = loadProc("glVertexAttrib4iv"); - api->BindVertexBuffers = oc_glBindVertexBuffers_noimpl; - api->ProgramUniformMatrix2x3dv = loadProc("glProgramUniformMatrix2x3dv"); - api->PrimitiveBoundingBox = oc_glPrimitiveBoundingBox_noimpl; - api->Scissor = loadProc("glScissor"); - api->ClientWaitSync = loadProc("glClientWaitSync"); - api->Uniform3ui = loadProc("glUniform3ui"); - api->VertexAttribP3ui = loadProc("glVertexAttribP3ui"); - api->Enable = loadProc("glEnable"); - api->StencilOpSeparate = loadProc("glStencilOpSeparate"); - api->UniformMatrix2x3dv = loadProc("glUniformMatrix2x3dv"); - api->ProgramUniformMatrix3dv = loadProc("glProgramUniformMatrix3dv"); - api->TexImage2DMultisample = loadProc("glTexImage2DMultisample"); - api->VertexAttrib4Nbv = loadProc("glVertexAttrib4Nbv"); - api->GetTexImage = loadProc("glGetTexImage"); - api->VertexAttrib4sv = loadProc("glVertexAttrib4sv"); - api->PixelStorei = loadProc("glPixelStorei"); - api->DepthMask = loadProc("glDepthMask"); - api->TexStorage2D = loadProc("glTexStorage2D"); - api->Clear = loadProc("glClear"); - api->UniformMatrix3x4dv = loadProc("glUniformMatrix3x4dv"); - api->DeleteTransformFeedbacks = loadProc("glDeleteTransformFeedbacks"); - api->MapBufferRange = loadProc("glMapBufferRange"); - api->MemoryBarrier = loadProc("glMemoryBarrier"); - api->ViewportIndexedf = loadProc("glViewportIndexedf"); - api->VertexAttrib3fv = loadProc("glVertexAttrib3fv"); - api->ObjectPtrLabel = loadProc("glObjectPtrLabel"); - api->TexStorage1D = loadProc("glTexStorage1D"); - api->CompressedTexImage3D = loadProc("glCompressedTexImage3D"); - api->VertexAttrib1fv = loadProc("glVertexAttrib1fv"); - api->VertexAttribPointer = loadProc("glVertexAttribPointer"); - api->GetQueryIndexediv = loadProc("glGetQueryIndexediv"); - api->CompileShader = loadProc("glCompileShader"); - api->ProgramUniform1i = loadProc("glProgramUniform1i"); - api->GetQueryiv = loadProc("glGetQueryiv"); - api->VertexAttribI1iv = loadProc("glVertexAttribI1iv"); - api->CopyTexImage2D = loadProc("glCopyTexImage2D"); - api->GetQueryObjectui64v = loadProc("glGetQueryObjectui64v"); - api->PointSize = loadProc("glPointSize"); - api->Disablei = loadProc("glDisablei"); - api->VertexAttribL1dv = loadProc("glVertexAttribL1dv"); - api->CreateShader = loadProc("glCreateShader"); - api->GetString = loadProc("glGetString"); - api->ViewportArrayv = loadProc("glViewportArrayv"); - api->ProgramUniform3d = loadProc("glProgramUniform3d"); - api->VertexAttrib4Nubv = loadProc("glVertexAttrib4Nubv"); - api->TexParameteri = loadProc("glTexParameteri"); - api->ProgramUniform4fv = loadProc("glProgramUniform4fv"); - api->GenerateMipmap = loadProc("glGenerateMipmap"); - api->CompressedTexSubImage3D = loadProc("glCompressedTexSubImage3D"); - api->Uniform3f = loadProc("glUniform3f"); - api->GetUniformIndices = loadProc("glGetUniformIndices"); - api->VertexAttribLPointer = loadProc("glVertexAttribLPointer"); - api->VertexAttribI2uiv = loadProc("glVertexAttribI2uiv"); - api->QueryCounter = loadProc("glQueryCounter"); - api->ActiveShaderProgram = loadProc("glActiveShaderProgram"); - api->Uniform1ui = loadProc("glUniform1ui"); - api->VertexAttribI1i = loadProc("glVertexAttribI1i"); - api->GetTexParameterIiv = loadProc("glGetTexParameterIiv"); - api->GetUniformfv = loadProc("glGetUniformfv"); - api->ProgramUniform2uiv = loadProc("glProgramUniform2uiv"); - api->GetError = loadProc("glGetError"); - api->GetActiveUniformBlockName = loadProc("glGetActiveUniformBlockName"); - api->TextureView = loadProc("glTextureView"); - api->GetnUniformiv = oc_glGetnUniformiv_noimpl; - api->ProgramUniform4dv = loadProc("glProgramUniform4dv"); - api->ViewportIndexedfv = loadProc("glViewportIndexedfv"); - api->Hint = loadProc("glHint"); - api->GetShaderSource = loadProc("glGetShaderSource"); - api->ProgramUniformMatrix4x3fv = loadProc("glProgramUniformMatrix4x3fv"); - api->Uniform1iv = loadProc("glUniform1iv"); - api->VertexAttribI4bv = loadProc("glVertexAttribI4bv"); - api->UniformMatrix4x2dv = loadProc("glUniformMatrix4x2dv"); - api->BufferStorage = oc_glBufferStorage_noimpl; - api->IsRenderbuffer = loadProc("glIsRenderbuffer"); - api->GetActiveSubroutineUniformName = loadProc("glGetActiveSubroutineUniformName"); - api->LinkProgram = loadProc("glLinkProgram"); - api->GetActiveUniformsiv = loadProc("glGetActiveUniformsiv"); - api->GetDebugMessageLog = loadProc("glGetDebugMessageLog"); - api->CopyTexSubImage3D = loadProc("glCopyTexSubImage3D"); - api->PointParameteri = loadProc("glPointParameteri"); - api->ProgramUniform3dv = loadProc("glProgramUniform3dv"); - api->CompressedTexImage1D = loadProc("glCompressedTexImage1D"); - api->UniformMatrix3x4fv = loadProc("glUniformMatrix3x4fv"); - api->GenSamplers = loadProc("glGenSamplers"); - api->GetCompressedTexImage = loadProc("glGetCompressedTexImage"); - api->DeleteQueries = loadProc("glDeleteQueries"); - api->GenProgramPipelines = loadProc("glGenProgramPipelines"); - api->DispatchComputeIndirect = loadProc("glDispatchComputeIndirect"); - api->VertexAttribIPointer = loadProc("glVertexAttribIPointer"); - api->CreateProgram = loadProc("glCreateProgram"); - api->ClearTexSubImage = oc_glClearTexSubImage_noimpl; - api->VertexAttrib4d = loadProc("glVertexAttrib4d"); - api->FrontFace = loadProc("glFrontFace"); - api->BindTransformFeedback = loadProc("glBindTransformFeedback"); - api->GetProgramStageiv = loadProc("glGetProgramStageiv"); - api->SamplerParameterIiv = loadProc("glSamplerParameterIiv"); - api->GetInteger64v = loadProc("glGetInteger64v"); - api->CreateShaderProgramv = loadProc("glCreateShaderProgramv"); - api->BindBuffersRange = oc_glBindBuffersRange_noimpl; - api->Uniform3fv = loadProc("glUniform3fv"); - api->ProgramUniformMatrix4fv = loadProc("glProgramUniformMatrix4fv"); - api->BindBuffersBase = oc_glBindBuffersBase_noimpl; - api->ClearBufferfi = loadProc("glClearBufferfi"); - api->FramebufferTexture3D = loadProc("glFramebufferTexture3D"); - api->Disable = loadProc("glDisable"); - api->ProgramUniform1iv = loadProc("glProgramUniform1iv"); - api->VertexAttribI2iv = loadProc("glVertexAttribI2iv"); - api->DepthRangeIndexed = loadProc("glDepthRangeIndexed"); - api->PatchParameteri = loadProc("glPatchParameteri"); - api->GetUniformBlockIndex = loadProc("glGetUniformBlockIndex"); - api->MultiDrawArrays = loadProc("glMultiDrawArrays"); - api->VertexAttribI4ubv = loadProc("glVertexAttribI4ubv"); - api->BindBuffer = loadProc("glBindBuffer"); - api->VertexAttribI3i = loadProc("glVertexAttribI3i"); - api->GetDoublev = loadProc("glGetDoublev"); - api->DrawTransformFeedbackStream = loadProc("glDrawTransformFeedbackStream"); - api->VertexAttribI4uiv = loadProc("glVertexAttribI4uiv"); - api->RenderbufferStorageMultisample = loadProc("glRenderbufferStorageMultisample"); - api->VertexAttribL3dv = loadProc("glVertexAttribL3dv"); - api->StencilMaskSeparate = loadProc("glStencilMaskSeparate"); - api->ProgramUniform1d = loadProc("glProgramUniform1d"); - api->Viewport = loadProc("glViewport"); - api->VertexAttribP1ui = loadProc("glVertexAttribP1ui"); - api->VertexAttrib4dv = loadProc("glVertexAttrib4dv"); - api->GenQueries = loadProc("glGenQueries"); - api->TexParameterIiv = loadProc("glTexParameterIiv"); - api->ProgramUniform2d = loadProc("glProgramUniform2d"); - api->ProgramUniform1uiv = loadProc("glProgramUniform1uiv"); - api->VertexAttrib4Nub = loadProc("glVertexAttrib4Nub"); - api->IsVertexArray = loadProc("glIsVertexArray"); - api->ProgramUniform3f = loadProc("glProgramUniform3f"); - api->ProgramUniform3iv = loadProc("glProgramUniform3iv"); - api->GetProgramBinary = loadProc("glGetProgramBinary"); - api->BindRenderbuffer = loadProc("glBindRenderbuffer"); - api->BindFragDataLocationIndexed = loadProc("glBindFragDataLocationIndexed"); - api->GetSamplerParameterIiv = loadProc("glGetSamplerParameterIiv"); - api->VertexAttribDivisor = loadProc("glVertexAttribDivisor"); - api->ProgramUniformMatrix3x2dv = loadProc("glProgramUniformMatrix3x2dv"); - api->FramebufferParameteri = loadProc("glFramebufferParameteri"); - api->GenTransformFeedbacks = loadProc("glGenTransformFeedbacks"); - api->DeleteSync = loadProc("glDeleteSync"); - api->ProgramUniform1ui = loadProc("glProgramUniform1ui"); - api->TexSubImage1D = loadProc("glTexSubImage1D"); - api->ClearDepthf = loadProc("glClearDepthf"); - api->ReadPixels = loadProc("glReadPixels"); - api->VertexAttribI2i = loadProc("glVertexAttribI2i"); - api->Finish = loadProc("glFinish"); - api->LineWidth = loadProc("glLineWidth"); - api->DeleteShader = loadProc("glDeleteShader"); - api->IsSampler = loadProc("glIsSampler"); - api->ProgramUniformMatrix4dv = loadProc("glProgramUniformMatrix4dv"); - api->TransformFeedbackVaryings = loadProc("glTransformFeedbackVaryings"); - api->BeginConditionalRender = loadProc("glBeginConditionalRender"); - api->BindSamplers = oc_glBindSamplers_noimpl; - api->DeleteProgramPipelines = loadProc("glDeleteProgramPipelines"); - api->ColorMask = loadProc("glColorMask"); - api->TexParameterfv = loadProc("glTexParameterfv"); - api->PushDebugGroup = loadProc("glPushDebugGroup"); - api->ClearBufferfv = loadProc("glClearBufferfv"); - api->IsEnabled = loadProc("glIsEnabled"); - api->VertexAttrib2f = loadProc("glVertexAttrib2f"); - api->ProgramUniform2f = loadProc("glProgramUniform2f"); - api->GetSamplerParameterIuiv = loadProc("glGetSamplerParameterIuiv"); - api->GetInteger64i_v = loadProc("glGetInteger64i_v"); - api->Uniform2dv = loadProc("glUniform2dv"); - api->GetBufferSubData = loadProc("glGetBufferSubData"); - api->MultiDrawElementsIndirect = loadProc("glMultiDrawElementsIndirect"); - api->ProgramParameteri = loadProc("glProgramParameteri"); - api->VertexAttribP4ui = loadProc("glVertexAttribP4ui"); - api->SamplerParameterfv = loadProc("glSamplerParameterfv"); - api->PointParameterf = loadProc("glPointParameterf"); - api->UniformMatrix2x4fv = loadProc("glUniformMatrix2x4fv"); - api->GenBuffers = loadProc("glGenBuffers"); - api->ProgramUniform2dv = loadProc("glProgramUniform2dv"); - api->VertexAttribFormat = loadProc("glVertexAttribFormat"); - api->TexSubImage2D = loadProc("glTexSubImage2D"); - api->VertexAttrib4ubv = loadProc("glVertexAttrib4ubv"); - api->GetGraphicsResetStatus = oc_glGetGraphicsResetStatus_noimpl; - api->GetProgramInterfaceiv = loadProc("glGetProgramInterfaceiv"); - api->VertexAttribIFormat = loadProc("glVertexAttribIFormat"); - api->GetnUniformfv = oc_glGetnUniformfv_noimpl; - api->DeleteProgram = loadProc("glDeleteProgram"); - api->ClampColor = loadProc("glClampColor"); - api->DrawElementsInstancedBaseVertexBaseInstance = loadProc("glDrawElementsInstancedBaseVertexBaseInstance"); - api->DrawElements = loadProc("glDrawElements"); - api->DebugMessageControl = loadProc("glDebugMessageControl"); - api->GetRenderbufferParameteriv = loadProc("glGetRenderbufferParameteriv"); - api->DetachShader = loadProc("glDetachShader"); - api->GenFramebuffers = loadProc("glGenFramebuffers"); - api->ProvokingVertex = loadProc("glProvokingVertex"); - api->SampleMaski = loadProc("glSampleMaski"); - api->EndQueryIndexed = loadProc("glEndQueryIndexed"); - api->ProgramUniform1f = loadProc("glProgramUniform1f"); - api->BindFramebuffer = loadProc("glBindFramebuffer"); - api->BeginQueryIndexed = loadProc("glBeginQueryIndexed"); - api->UniformSubroutinesuiv = loadProc("glUniformSubroutinesuiv"); - api->GetUniformiv = loadProc("glGetUniformiv"); - api->FramebufferTexture = loadProc("glFramebufferTexture"); - api->PointParameterfv = loadProc("glPointParameterfv"); - api->IsTransformFeedback = loadProc("glIsTransformFeedback"); - api->CheckFramebufferStatus = loadProc("glCheckFramebufferStatus"); - api->ShaderSource = loadProc("glShaderSource"); - api->UniformMatrix2x4dv = loadProc("glUniformMatrix2x4dv"); - api->BindImageTextures = oc_glBindImageTextures_noimpl; - api->CopyTexImage1D = loadProc("glCopyTexImage1D"); - api->UniformMatrix3dv = loadProc("glUniformMatrix3dv"); - api->ProgramUniform1dv = loadProc("glProgramUniform1dv"); - api->BlitFramebuffer = loadProc("glBlitFramebuffer"); - api->PopDebugGroup = loadProc("glPopDebugGroup"); - api->TexParameterIuiv = loadProc("glTexParameterIuiv"); - api->VertexAttrib2d = loadProc("glVertexAttrib2d"); - api->TexImage1D = loadProc("glTexImage1D"); - api->GetObjectPtrLabel = loadProc("glGetObjectPtrLabel"); - api->StencilMask = loadProc("glStencilMask"); - api->BeginQuery = loadProc("glBeginQuery"); - api->UniformMatrix4fv = loadProc("glUniformMatrix4fv"); - api->IsSync = loadProc("glIsSync"); - api->Uniform3dv = loadProc("glUniform3dv"); - api->ProgramUniform2fv = loadProc("glProgramUniform2fv"); - api->VertexAttribI4sv = loadProc("glVertexAttribI4sv"); - api->ScissorArrayv = loadProc("glScissorArrayv"); - api->VertexAttribP1uiv = loadProc("glVertexAttribP1uiv"); - api->Uniform2uiv = loadProc("glUniform2uiv"); - api->DeleteBuffers = loadProc("glDeleteBuffers"); - api->ProgramUniform3ui = loadProc("glProgramUniform3ui"); - api->FramebufferTextureLayer = loadProc("glFramebufferTextureLayer"); - api->EndTransformFeedback = loadProc("glEndTransformFeedback"); - api->BlendFuncSeparatei = loadProc("glBlendFuncSeparatei"); - api->DrawTransformFeedbackInstanced = loadProc("glDrawTransformFeedbackInstanced"); - api->DrawRangeElementsBaseVertex = loadProc("glDrawRangeElementsBaseVertex"); - api->VertexAttrib1f = loadProc("glVertexAttrib1f"); - api->GetUniformSubroutineuiv = loadProc("glGetUniformSubroutineuiv"); - api->DisableVertexAttribArray = loadProc("glDisableVertexAttribArray"); - api->ProgramUniformMatrix3x2fv = loadProc("glProgramUniformMatrix3x2fv"); - api->VertexAttribI4usv = loadProc("glVertexAttribI4usv"); - api->GetObjectLabel = loadProc("glGetObjectLabel"); - api->BindAttribLocation = loadProc("glBindAttribLocation"); - api->Uniform1f = loadProc("glUniform1f"); - api->GetUniformdv = loadProc("glGetUniformdv"); - api->GetUniformLocation = loadProc("glGetUniformLocation"); - api->GetSubroutineUniformLocation = loadProc("glGetSubroutineUniformLocation"); - api->GetTexParameterIuiv = loadProc("glGetTexParameterIuiv"); - api->SamplerParameterf = loadProc("glSamplerParameterf"); - api->VertexAttribL3d = loadProc("glVertexAttribL3d"); - api->TexImage3DMultisample = loadProc("glTexImage3DMultisample"); - api->TexImage3D = loadProc("glTexImage3D"); - api->RenderbufferStorage = loadProc("glRenderbufferStorage"); - api->EnableVertexAttribArray = loadProc("glEnableVertexAttribArray"); - api->VertexAttribP4uiv = loadProc("glVertexAttribP4uiv"); - api->Uniform4d = loadProc("glUniform4d"); - api->VertexAttrib4s = loadProc("glVertexAttrib4s"); - api->DrawElementsInstancedBaseVertex = loadProc("glDrawElementsInstancedBaseVertex"); - api->VertexAttrib3s = loadProc("glVertexAttrib3s"); - api->ProgramUniform2iv = loadProc("glProgramUniform2iv"); - api->StencilFuncSeparate = loadProc("glStencilFuncSeparate"); - api->DeleteFramebuffers = loadProc("glDeleteFramebuffers"); - api->DepthRange = loadProc("glDepthRange"); - api->UniformMatrix3x2fv = loadProc("glUniformMatrix3x2fv"); - api->ProgramUniformMatrix2dv = loadProc("glProgramUniformMatrix2dv"); - api->ShaderStorageBlockBinding = loadProc("glShaderStorageBlockBinding"); - api->ClearDepth = loadProc("glClearDepth"); - api->VertexAttrib2dv = loadProc("glVertexAttrib2dv"); - api->SamplerParameterIuiv = loadProc("glSamplerParameterIuiv"); - api->GetVertexAttribLdv = loadProc("glGetVertexAttribLdv"); - api->ProgramUniformMatrix3x4dv = loadProc("glProgramUniformMatrix3x4dv"); - api->DepthRangeArrayv = loadProc("glDepthRangeArrayv"); - api->GetActiveUniform = loadProc("glGetActiveUniform"); - api->PatchParameterfv = loadProc("glPatchParameterfv"); - api->InvalidateTexImage = loadProc("glInvalidateTexImage"); - api->VertexAttrib3f = loadProc("glVertexAttrib3f"); - api->ProgramUniform4iv = loadProc("glProgramUniform4iv"); - api->ProgramUniform4d = loadProc("glProgramUniform4d"); - api->IsFramebuffer = loadProc("glIsFramebuffer"); - api->PixelStoref = loadProc("glPixelStoref"); - api->ProgramUniform4uiv = loadProc("glProgramUniform4uiv"); - api->ProgramUniformMatrix4x2dv = loadProc("glProgramUniformMatrix4x2dv"); - api->FenceSync = loadProc("glFenceSync"); - api->GetBufferParameteri64v = loadProc("glGetBufferParameteri64v"); - api->StencilOp = loadProc("glStencilOp"); - api->ClearBufferData = loadProc("glClearBufferData"); - api->GetnUniformuiv = oc_glGetnUniformuiv_noimpl; - api->GetProgramResourceiv = loadProc("glGetProgramResourceiv"); - api->GetVertexAttribdv = loadProc("glGetVertexAttribdv"); - api->GetTransformFeedbackVarying = loadProc("glGetTransformFeedbackVarying"); - api->VertexAttrib2fv = loadProc("glVertexAttrib2fv"); - api->GetBooleani_v = loadProc("glGetBooleani_v"); - api->ColorMaski = loadProc("glColorMaski"); - api->InvalidateBufferSubData = loadProc("glInvalidateBufferSubData"); - api->UniformMatrix4dv = loadProc("glUniformMatrix4dv"); - api->IsQuery = loadProc("glIsQuery"); - api->Uniform4ui = loadProc("glUniform4ui"); - api->Uniform4i = loadProc("glUniform4i"); - api->GetSamplerParameteriv = loadProc("glGetSamplerParameteriv"); - api->MultiDrawElementsBaseVertex = loadProc("glMultiDrawElementsBaseVertex"); - api->VertexAttribI1uiv = loadProc("glVertexAttribI1uiv"); - api->GetIntegerv = loadProc("glGetIntegerv"); - api->UniformMatrix2x3fv = loadProc("glUniformMatrix2x3fv"); - api->TexImage2D = loadProc("glTexImage2D"); - api->GetAttachedShaders = loadProc("glGetAttachedShaders"); - api->Uniform2d = loadProc("glUniform2d"); - api->MemoryBarrierByRegion = oc_glMemoryBarrierByRegion_noimpl; - api->UniformMatrix2fv = loadProc("glUniformMatrix2fv"); - api->PrimitiveRestartIndex = loadProc("glPrimitiveRestartIndex"); - api->GetVertexAttribiv = loadProc("glGetVertexAttribiv"); - api->GetAttribLocation = loadProc("glGetAttribLocation"); - api->TexStorage2DMultisample = loadProc("glTexStorage2DMultisample"); - api->CompressedTexSubImage2D = loadProc("glCompressedTexSubImage2D"); - api->GetVertexAttribfv = loadProc("glGetVertexAttribfv"); - api->GetBufferParameteriv = loadProc("glGetBufferParameteriv"); - api->TexParameterf = loadProc("glTexParameterf"); - api->FramebufferTexture2D = loadProc("glFramebufferTexture2D"); - api->GetActiveAttrib = loadProc("glGetActiveAttrib"); - api->InvalidateTexSubImage = loadProc("glInvalidateTexSubImage"); - api->DeleteVertexArrays = loadProc("glDeleteVertexArrays"); - api->VertexAttribI2ui = loadProc("glVertexAttribI2ui"); - api->PointParameteriv = loadProc("glPointParameteriv"); - api->GetPointerv = loadProc("glGetPointerv"); - api->Enablei = loadProc("glEnablei"); - api->BindBufferRange = loadProc("glBindBufferRange"); - api->DrawArraysInstanced = loadProc("glDrawArraysInstanced"); - api->DeleteTextures = loadProc("glDeleteTextures"); - api->VertexAttrib4Niv = loadProc("glVertexAttrib4Niv"); - api->MultiDrawElements = loadProc("glMultiDrawElements"); - api->GetProgramiv = loadProc("glGetProgramiv"); - api->DepthFunc = loadProc("glDepthFunc"); - api->GenTextures = loadProc("glGenTextures"); - api->GetInternalformativ = loadProc("glGetInternalformativ"); - api->ProgramUniform3i = loadProc("glProgramUniform3i"); - api->ScissorIndexed = loadProc("glScissorIndexed"); - api->VertexAttrib2sv = loadProc("glVertexAttrib2sv"); - api->TexStorage3DMultisample = loadProc("glTexStorage3DMultisample"); - api->Uniform2iv = loadProc("glUniform2iv"); - api->DrawArraysInstancedBaseInstance = loadProc("glDrawArraysInstancedBaseInstance"); - api->VertexAttribI3ui = loadProc("glVertexAttribI3ui"); - api->DeleteSamplers = loadProc("glDeleteSamplers"); - api->GenVertexArrays = loadProc("glGenVertexArrays"); - api->GetFramebufferParameteriv = loadProc("glGetFramebufferParameteriv"); - api->PolygonMode = loadProc("glPolygonMode"); - api->ProgramUniformMatrix2x4fv = loadProc("glProgramUniformMatrix2x4fv"); - api->GetProgramResourceName = loadProc("glGetProgramResourceName"); - api->SamplerParameteriv = loadProc("glSamplerParameteriv"); - api->GetActiveSubroutineUniformiv = loadProc("glGetActiveSubroutineUniformiv"); - api->GetStringi = loadProc("glGetStringi"); - api->VertexAttribLFormat = loadProc("glVertexAttribLFormat"); - api->VertexAttrib3d = loadProc("glVertexAttrib3d"); - api->BindVertexArray = loadProc("glBindVertexArray"); - api->UnmapBuffer = loadProc("glUnmapBuffer"); - api->DrawElementsInstancedBaseInstance = loadProc("glDrawElementsInstancedBaseInstance"); - api->Uniform4uiv = loadProc("glUniform4uiv"); - api->FramebufferTexture1D = loadProc("glFramebufferTexture1D"); - api->DrawTransformFeedbackStreamInstanced = loadProc("glDrawTransformFeedbackStreamInstanced"); - api->StencilFunc = loadProc("glStencilFunc"); - api->ValidateProgram = loadProc("glValidateProgram"); - api->Flush = loadProc("glFlush"); - api->ProgramUniform3uiv = loadProc("glProgramUniform3uiv"); - api->DeleteRenderbuffers = loadProc("glDeleteRenderbuffers"); - api->VertexAttrib4fv = loadProc("glVertexAttrib4fv"); - api->UniformMatrix2dv = loadProc("glUniformMatrix2dv"); - api->GetFragDataIndex = loadProc("glGetFragDataIndex"); - api->Uniform3iv = loadProc("glUniform3iv"); - api->MinSampleShading = loadProc("glMinSampleShading"); - api->GetBooleanv = loadProc("glGetBooleanv"); - api->GetMultisamplefv = loadProc("glGetMultisamplefv"); - api->GetVertexAttribIuiv = loadProc("glGetVertexAttribIuiv"); - api->GetProgramInfoLog = loadProc("glGetProgramInfoLog"); - api->Uniform4fv = loadProc("glUniform4fv"); - api->DrawBuffer = loadProc("glDrawBuffer"); - api->Uniform1i = loadProc("glUniform1i"); - api->ProgramUniform4ui = loadProc("glProgramUniform4ui"); - api->ProgramUniformMatrix3fv = loadProc("glProgramUniformMatrix3fv"); - api->BlendEquationSeparate = loadProc("glBlendEquationSeparate"); - api->BindProgramPipeline = loadProc("glBindProgramPipeline"); - api->GetDoublei_v = loadProc("glGetDoublei_v"); - api->BufferData = loadProc("glBufferData"); - api->ClearColor = loadProc("glClearColor"); - api->ProgramUniform4i = loadProc("glProgramUniform4i"); - api->GetTexLevelParameteriv = loadProc("glGetTexLevelParameteriv"); - api->GetActiveUniformBlockiv = loadProc("glGetActiveUniformBlockiv"); - api->ProgramUniform1fv = loadProc("glProgramUniform1fv"); - api->PauseTransformFeedback = loadProc("glPauseTransformFeedback"); - api->GetBufferPointerv = loadProc("glGetBufferPointerv"); - api->InvalidateSubFramebuffer = loadProc("glInvalidateSubFramebuffer"); - api->ScissorIndexedv = loadProc("glScissorIndexedv"); - api->Uniform2ui = loadProc("glUniform2ui"); - api->BindTexture = loadProc("glBindTexture"); - api->DrawElementsInstanced = loadProc("glDrawElementsInstanced"); - api->ProgramUniform4f = loadProc("glProgramUniform4f"); - api->BindBufferBase = loadProc("glBindBufferBase"); - api->IsShader = loadProc("glIsShader"); - api->ClearBufferSubData = loadProc("glClearBufferSubData"); - api->VertexAttrib4Nuiv = loadProc("glVertexAttrib4Nuiv"); - api->DrawArraysIndirect = loadProc("glDrawArraysIndirect"); - api->VertexAttrib4usv = loadProc("glVertexAttrib4usv"); - api->Uniform1d = loadProc("glUniform1d"); - api->ClearTexImage = oc_glClearTexImage_noimpl; - api->Uniform1uiv = loadProc("glUniform1uiv"); - api->BindSampler = loadProc("glBindSampler"); - api->GetTexLevelParameterfv = loadProc("glGetTexLevelParameterfv"); - api->ClearBufferiv = loadProc("glClearBufferiv"); - api->LogicOp = loadProc("glLogicOp"); - api->ActiveTexture = loadProc("glActiveTexture"); - api->GetFragDataLocation = loadProc("glGetFragDataLocation"); - api->BlendColor = loadProc("glBlendColor"); - api->UniformMatrix4x3fv = loadProc("glUniformMatrix4x3fv"); - api->ProgramUniform3fv = loadProc("glProgramUniform3fv"); - api->Uniform1fv = loadProc("glUniform1fv"); - api->DrawElementsBaseVertex = loadProc("glDrawElementsBaseVertex"); - api->Uniform4f = loadProc("glUniform4f"); - api->BlendEquationSeparatei = loadProc("glBlendEquationSeparatei"); - api->BlendFuncSeparate = loadProc("glBlendFuncSeparate"); - api->ClearBufferuiv = loadProc("glClearBufferuiv"); - api->CopyTexSubImage1D = loadProc("glCopyTexSubImage1D"); - api->DrawTransformFeedback = loadProc("glDrawTransformFeedback"); - api->ReadBuffer = loadProc("glReadBuffer"); - api->CopyBufferSubData = loadProc("glCopyBufferSubData"); - api->GetUniformuiv = loadProc("glGetUniformuiv"); - api->PolygonOffset = loadProc("glPolygonOffset"); - api->DispatchCompute = loadProc("glDispatchCompute"); - api->BindImageTexture = loadProc("glBindImageTexture"); - api->UniformMatrix4x3dv = loadProc("glUniformMatrix4x3dv"); - api->GenRenderbuffers = loadProc("glGenRenderbuffers"); + api->name = "gl43"; + api->GetFloatv = loadProc("glGetFloatv"); + api->TexBufferRange = loadProc("glTexBufferRange"); + api->IsBuffer = loadProc("glIsBuffer"); + api->IsTexture = loadProc("glIsTexture"); + api->DepthRangef = loadProc("glDepthRangef"); + api->EndConditionalRender = loadProc("glEndConditionalRender"); + api->BlendFunci = loadProc("glBlendFunci"); + api->GetProgramPipelineiv = loadProc("glGetProgramPipelineiv"); + api->WaitSync = loadProc("glWaitSync"); + api->ProgramUniformMatrix2fv = loadProc("glProgramUniformMatrix2fv"); + api->ProgramUniformMatrix4x3dv = loadProc("glProgramUniformMatrix4x3dv"); + api->VertexAttrib1dv = loadProc("glVertexAttrib1dv"); + api->SamplerParameteri = loadProc("glSamplerParameteri"); + api->GetVertexAttribIiv = loadProc("glGetVertexAttribIiv"); + api->GetSamplerParameterfv = loadProc("glGetSamplerParameterfv"); + api->VertexAttrib1d = loadProc("glVertexAttrib1d"); + api->TexBuffer = loadProc("glTexBuffer"); + api->InvalidateBufferData = loadProc("glInvalidateBufferData"); + api->ProgramUniform2i = loadProc("glProgramUniform2i"); + api->Uniform4dv = loadProc("glUniform4dv"); + api->UseProgram = loadProc("glUseProgram"); + api->VertexAttribI3iv = loadProc("glVertexAttribI3iv"); + api->DrawElementsIndirect = loadProc("glDrawElementsIndirect"); + api->VertexAttrib4uiv = loadProc("glVertexAttrib4uiv"); + api->GetQueryObjectiv = loadProc("glGetQueryObjectiv"); + api->FramebufferRenderbuffer = loadProc("glFramebufferRenderbuffer"); + api->BlendEquationi = loadProc("glBlendEquationi"); + api->GetActiveSubroutineName = loadProc("glGetActiveSubroutineName"); + api->VertexAttrib2s = loadProc("glVertexAttrib2s"); + api->VertexAttribL1d = loadProc("glVertexAttribL1d"); + api->BindTextures = oc_glBindTextures_noimpl; + api->VertexAttrib3sv = loadProc("glVertexAttrib3sv"); + api->GetFloati_v = loadProc("glGetFloati_v"); + api->BeginTransformFeedback = loadProc("glBeginTransformFeedback"); + api->ClearStencil = loadProc("glClearStencil"); + api->Uniform3i = loadProc("glUniform3i"); + api->ValidateProgramPipeline = loadProc("glValidateProgramPipeline"); + api->ProgramUniformMatrix4x2fv = loadProc("glProgramUniformMatrix4x2fv"); + api->VertexAttribI4ui = loadProc("glVertexAttribI4ui"); + api->GetShaderiv = loadProc("glGetShaderiv"); + api->ReadnPixels = oc_glReadnPixels_noimpl; + api->UniformMatrix4x2fv = loadProc("glUniformMatrix4x2fv"); + api->GetShaderPrecisionFormat = loadProc("glGetShaderPrecisionFormat"); + api->ProgramUniformMatrix2x3fv = loadProc("glProgramUniformMatrix2x3fv"); + api->TexSubImage3D = loadProc("glTexSubImage3D"); + api->GetProgramResourceLocationIndex = loadProc("glGetProgramResourceLocationIndex"); + api->BlendFunc = loadProc("glBlendFunc"); + api->ProgramUniformMatrix3x4fv = loadProc("glProgramUniformMatrix3x4fv"); + api->Uniform3d = loadProc("glUniform3d"); + api->VertexAttrib1sv = loadProc("glVertexAttrib1sv"); + api->BindFragDataLocation = loadProc("glBindFragDataLocation"); + api->VertexAttrib4bv = loadProc("glVertexAttrib4bv"); + api->Uniform4iv = loadProc("glUniform4iv"); + api->ProgramUniform2ui = loadProc("glProgramUniform2ui"); + api->DrawArrays = loadProc("glDrawArrays"); + api->ProgramBinary = loadProc("glProgramBinary"); + api->VertexAttrib4f = loadProc("glVertexAttrib4f"); + api->VertexAttribP2uiv = loadProc("glVertexAttribP2uiv"); + api->UniformMatrix3fv = loadProc("glUniformMatrix3fv"); + api->Uniform2i = loadProc("glUniform2i"); + api->GetQueryObjectuiv = loadProc("glGetQueryObjectuiv"); + api->UniformBlockBinding = loadProc("glUniformBlockBinding"); + api->SampleCoverage = loadProc("glSampleCoverage"); + api->VertexAttrib4Nusv = loadProc("glVertexAttrib4Nusv"); + api->ProgramUniformMatrix2x4dv = loadProc("glProgramUniformMatrix2x4dv"); + api->Uniform3uiv = loadProc("glUniform3uiv"); + api->VertexAttrib1s = loadProc("glVertexAttrib1s"); + api->GetVertexAttribPointerv = loadProc("glGetVertexAttribPointerv"); + api->BlendBarrier = oc_glBlendBarrier_noimpl; + api->DrawRangeElements = loadProc("glDrawRangeElements"); + api->TexStorage3D = loadProc("glTexStorage3D"); + api->GetInternalformati64v = loadProc("glGetInternalformati64v"); + api->GetQueryObjecti64v = loadProc("glGetQueryObjecti64v"); + api->CompressedTexSubImage1D = loadProc("glCompressedTexSubImage1D"); + api->VertexAttrib3dv = loadProc("glVertexAttrib3dv"); + api->VertexBindingDivisor = loadProc("glVertexBindingDivisor"); + api->UseProgramStages = loadProc("glUseProgramStages"); + api->VertexAttribBinding = loadProc("glVertexAttribBinding"); + api->DebugMessageInsert = loadProc("glDebugMessageInsert"); + api->GetTexParameteriv = loadProc("glGetTexParameteriv"); + api->MultiDrawArraysIndirect = loadProc("glMultiDrawArraysIndirect"); + api->GetTexParameterfv = loadProc("glGetTexParameterfv"); + api->GetProgramPipelineInfoLog = loadProc("glGetProgramPipelineInfoLog"); + api->EndQuery = loadProc("glEndQuery"); + api->GetProgramResourceLocation = loadProc("glGetProgramResourceLocation"); + api->CompressedTexImage2D = loadProc("glCompressedTexImage2D"); + api->VertexAttribP2ui = loadProc("glVertexAttribP2ui"); + api->IsEnabledi = loadProc("glIsEnabledi"); + api->GetActiveAtomicCounterBufferiv = loadProc("glGetActiveAtomicCounterBufferiv"); + api->IsProgram = loadProc("glIsProgram"); + api->Uniform1dv = loadProc("glUniform1dv"); + api->TexParameteriv = loadProc("glTexParameteriv"); + api->Uniform2fv = loadProc("glUniform2fv"); + api->ReleaseShaderCompiler = loadProc("glReleaseShaderCompiler"); + api->CullFace = loadProc("glCullFace"); + api->VertexAttribI4i = loadProc("glVertexAttribI4i"); + api->GetProgramResourceIndex = loadProc("glGetProgramResourceIndex"); + api->ShaderBinary = loadProc("glShaderBinary"); + api->UniformMatrix3x2dv = loadProc("glUniformMatrix3x2dv"); + api->InvalidateFramebuffer = loadProc("glInvalidateFramebuffer"); + api->AttachShader = loadProc("glAttachShader"); + api->FlushMappedBufferRange = loadProc("glFlushMappedBufferRange"); + api->VertexAttribP3uiv = loadProc("glVertexAttribP3uiv"); + api->GetActiveUniformName = loadProc("glGetActiveUniformName"); + api->MapBuffer = loadProc("glMapBuffer"); + api->DrawBuffers = loadProc("glDrawBuffers"); + api->GetSynciv = loadProc("glGetSynciv"); + api->CopyTexSubImage2D = loadProc("glCopyTexSubImage2D"); + api->ObjectLabel = loadProc("glObjectLabel"); + api->BufferSubData = loadProc("glBufferSubData"); + api->Uniform2f = loadProc("glUniform2f"); + api->DebugMessageCallback = loadProc("glDebugMessageCallback"); + api->VertexAttribL4dv = loadProc("glVertexAttribL4dv"); + api->IsProgramPipeline = loadProc("glIsProgramPipeline"); + api->ResumeTransformFeedback = loadProc("glResumeTransformFeedback"); + api->VertexAttribI4iv = loadProc("glVertexAttribI4iv"); + api->GetShaderInfoLog = loadProc("glGetShaderInfoLog"); + api->GetIntegeri_v = loadProc("glGetIntegeri_v"); + api->BindVertexBuffer = loadProc("glBindVertexBuffer"); + api->BlendEquation = loadProc("glBlendEquation"); + api->VertexAttribL2dv = loadProc("glVertexAttribL2dv"); + api->VertexAttribI1ui = loadProc("glVertexAttribI1ui"); + api->VertexAttrib4Nsv = loadProc("glVertexAttrib4Nsv"); + api->VertexAttribL4d = loadProc("glVertexAttribL4d"); + api->CopyImageSubData = loadProc("glCopyImageSubData"); + api->GetFramebufferAttachmentParameteriv = loadProc("glGetFramebufferAttachmentParameteriv"); + api->VertexAttribL2d = loadProc("glVertexAttribL2d"); + api->GetSubroutineIndex = loadProc("glGetSubroutineIndex"); + api->VertexAttribI3uiv = loadProc("glVertexAttribI3uiv"); + api->VertexAttrib4iv = loadProc("glVertexAttrib4iv"); + api->BindVertexBuffers = oc_glBindVertexBuffers_noimpl; + api->ProgramUniformMatrix2x3dv = loadProc("glProgramUniformMatrix2x3dv"); + api->PrimitiveBoundingBox = oc_glPrimitiveBoundingBox_noimpl; + api->Scissor = loadProc("glScissor"); + api->ClientWaitSync = loadProc("glClientWaitSync"); + api->Uniform3ui = loadProc("glUniform3ui"); + api->VertexAttribP3ui = loadProc("glVertexAttribP3ui"); + api->Enable = loadProc("glEnable"); + api->StencilOpSeparate = loadProc("glStencilOpSeparate"); + api->UniformMatrix2x3dv = loadProc("glUniformMatrix2x3dv"); + api->ProgramUniformMatrix3dv = loadProc("glProgramUniformMatrix3dv"); + api->TexImage2DMultisample = loadProc("glTexImage2DMultisample"); + api->VertexAttrib4Nbv = loadProc("glVertexAttrib4Nbv"); + api->GetTexImage = loadProc("glGetTexImage"); + api->VertexAttrib4sv = loadProc("glVertexAttrib4sv"); + api->PixelStorei = loadProc("glPixelStorei"); + api->DepthMask = loadProc("glDepthMask"); + api->TexStorage2D = loadProc("glTexStorage2D"); + api->Clear = loadProc("glClear"); + api->UniformMatrix3x4dv = loadProc("glUniformMatrix3x4dv"); + api->DeleteTransformFeedbacks = loadProc("glDeleteTransformFeedbacks"); + api->MapBufferRange = loadProc("glMapBufferRange"); + api->MemoryBarrier = loadProc("glMemoryBarrier"); + api->ViewportIndexedf = loadProc("glViewportIndexedf"); + api->VertexAttrib3fv = loadProc("glVertexAttrib3fv"); + api->ObjectPtrLabel = loadProc("glObjectPtrLabel"); + api->TexStorage1D = loadProc("glTexStorage1D"); + api->CompressedTexImage3D = loadProc("glCompressedTexImage3D"); + api->VertexAttrib1fv = loadProc("glVertexAttrib1fv"); + api->VertexAttribPointer = loadProc("glVertexAttribPointer"); + api->GetQueryIndexediv = loadProc("glGetQueryIndexediv"); + api->CompileShader = loadProc("glCompileShader"); + api->ProgramUniform1i = loadProc("glProgramUniform1i"); + api->GetQueryiv = loadProc("glGetQueryiv"); + api->VertexAttribI1iv = loadProc("glVertexAttribI1iv"); + api->CopyTexImage2D = loadProc("glCopyTexImage2D"); + api->GetQueryObjectui64v = loadProc("glGetQueryObjectui64v"); + api->PointSize = loadProc("glPointSize"); + api->Disablei = loadProc("glDisablei"); + api->VertexAttribL1dv = loadProc("glVertexAttribL1dv"); + api->CreateShader = loadProc("glCreateShader"); + api->GetString = loadProc("glGetString"); + api->ViewportArrayv = loadProc("glViewportArrayv"); + api->ProgramUniform3d = loadProc("glProgramUniform3d"); + api->VertexAttrib4Nubv = loadProc("glVertexAttrib4Nubv"); + api->TexParameteri = loadProc("glTexParameteri"); + api->ProgramUniform4fv = loadProc("glProgramUniform4fv"); + api->GenerateMipmap = loadProc("glGenerateMipmap"); + api->CompressedTexSubImage3D = loadProc("glCompressedTexSubImage3D"); + api->Uniform3f = loadProc("glUniform3f"); + api->GetUniformIndices = loadProc("glGetUniformIndices"); + api->VertexAttribLPointer = loadProc("glVertexAttribLPointer"); + api->VertexAttribI2uiv = loadProc("glVertexAttribI2uiv"); + api->QueryCounter = loadProc("glQueryCounter"); + api->ActiveShaderProgram = loadProc("glActiveShaderProgram"); + api->Uniform1ui = loadProc("glUniform1ui"); + api->VertexAttribI1i = loadProc("glVertexAttribI1i"); + api->GetTexParameterIiv = loadProc("glGetTexParameterIiv"); + api->GetUniformfv = loadProc("glGetUniformfv"); + api->ProgramUniform2uiv = loadProc("glProgramUniform2uiv"); + api->GetError = loadProc("glGetError"); + api->GetActiveUniformBlockName = loadProc("glGetActiveUniformBlockName"); + api->TextureView = loadProc("glTextureView"); + api->GetnUniformiv = oc_glGetnUniformiv_noimpl; + api->ProgramUniform4dv = loadProc("glProgramUniform4dv"); + api->ViewportIndexedfv = loadProc("glViewportIndexedfv"); + api->Hint = loadProc("glHint"); + api->GetShaderSource = loadProc("glGetShaderSource"); + api->ProgramUniformMatrix4x3fv = loadProc("glProgramUniformMatrix4x3fv"); + api->Uniform1iv = loadProc("glUniform1iv"); + api->VertexAttribI4bv = loadProc("glVertexAttribI4bv"); + api->UniformMatrix4x2dv = loadProc("glUniformMatrix4x2dv"); + api->BufferStorage = oc_glBufferStorage_noimpl; + api->IsRenderbuffer = loadProc("glIsRenderbuffer"); + api->GetActiveSubroutineUniformName = loadProc("glGetActiveSubroutineUniformName"); + api->LinkProgram = loadProc("glLinkProgram"); + api->GetActiveUniformsiv = loadProc("glGetActiveUniformsiv"); + api->GetDebugMessageLog = loadProc("glGetDebugMessageLog"); + api->CopyTexSubImage3D = loadProc("glCopyTexSubImage3D"); + api->PointParameteri = loadProc("glPointParameteri"); + api->ProgramUniform3dv = loadProc("glProgramUniform3dv"); + api->CompressedTexImage1D = loadProc("glCompressedTexImage1D"); + api->UniformMatrix3x4fv = loadProc("glUniformMatrix3x4fv"); + api->GenSamplers = loadProc("glGenSamplers"); + api->GetCompressedTexImage = loadProc("glGetCompressedTexImage"); + api->DeleteQueries = loadProc("glDeleteQueries"); + api->GenProgramPipelines = loadProc("glGenProgramPipelines"); + api->DispatchComputeIndirect = loadProc("glDispatchComputeIndirect"); + api->VertexAttribIPointer = loadProc("glVertexAttribIPointer"); + api->CreateProgram = loadProc("glCreateProgram"); + api->ClearTexSubImage = oc_glClearTexSubImage_noimpl; + api->VertexAttrib4d = loadProc("glVertexAttrib4d"); + api->FrontFace = loadProc("glFrontFace"); + api->BindTransformFeedback = loadProc("glBindTransformFeedback"); + api->GetProgramStageiv = loadProc("glGetProgramStageiv"); + api->SamplerParameterIiv = loadProc("glSamplerParameterIiv"); + api->GetInteger64v = loadProc("glGetInteger64v"); + api->CreateShaderProgramv = loadProc("glCreateShaderProgramv"); + api->BindBuffersRange = oc_glBindBuffersRange_noimpl; + api->Uniform3fv = loadProc("glUniform3fv"); + api->ProgramUniformMatrix4fv = loadProc("glProgramUniformMatrix4fv"); + api->BindBuffersBase = oc_glBindBuffersBase_noimpl; + api->ClearBufferfi = loadProc("glClearBufferfi"); + api->FramebufferTexture3D = loadProc("glFramebufferTexture3D"); + api->Disable = loadProc("glDisable"); + api->ProgramUniform1iv = loadProc("glProgramUniform1iv"); + api->VertexAttribI2iv = loadProc("glVertexAttribI2iv"); + api->DepthRangeIndexed = loadProc("glDepthRangeIndexed"); + api->PatchParameteri = loadProc("glPatchParameteri"); + api->GetUniformBlockIndex = loadProc("glGetUniformBlockIndex"); + api->MultiDrawArrays = loadProc("glMultiDrawArrays"); + api->VertexAttribI4ubv = loadProc("glVertexAttribI4ubv"); + api->BindBuffer = loadProc("glBindBuffer"); + api->VertexAttribI3i = loadProc("glVertexAttribI3i"); + api->GetDoublev = loadProc("glGetDoublev"); + api->DrawTransformFeedbackStream = loadProc("glDrawTransformFeedbackStream"); + api->VertexAttribI4uiv = loadProc("glVertexAttribI4uiv"); + api->RenderbufferStorageMultisample = loadProc("glRenderbufferStorageMultisample"); + api->VertexAttribL3dv = loadProc("glVertexAttribL3dv"); + api->StencilMaskSeparate = loadProc("glStencilMaskSeparate"); + api->ProgramUniform1d = loadProc("glProgramUniform1d"); + api->Viewport = loadProc("glViewport"); + api->VertexAttribP1ui = loadProc("glVertexAttribP1ui"); + api->VertexAttrib4dv = loadProc("glVertexAttrib4dv"); + api->GenQueries = loadProc("glGenQueries"); + api->TexParameterIiv = loadProc("glTexParameterIiv"); + api->ProgramUniform2d = loadProc("glProgramUniform2d"); + api->ProgramUniform1uiv = loadProc("glProgramUniform1uiv"); + api->VertexAttrib4Nub = loadProc("glVertexAttrib4Nub"); + api->IsVertexArray = loadProc("glIsVertexArray"); + api->ProgramUniform3f = loadProc("glProgramUniform3f"); + api->ProgramUniform3iv = loadProc("glProgramUniform3iv"); + api->GetProgramBinary = loadProc("glGetProgramBinary"); + api->BindRenderbuffer = loadProc("glBindRenderbuffer"); + api->BindFragDataLocationIndexed = loadProc("glBindFragDataLocationIndexed"); + api->GetSamplerParameterIiv = loadProc("glGetSamplerParameterIiv"); + api->VertexAttribDivisor = loadProc("glVertexAttribDivisor"); + api->ProgramUniformMatrix3x2dv = loadProc("glProgramUniformMatrix3x2dv"); + api->FramebufferParameteri = loadProc("glFramebufferParameteri"); + api->GenTransformFeedbacks = loadProc("glGenTransformFeedbacks"); + api->DeleteSync = loadProc("glDeleteSync"); + api->ProgramUniform1ui = loadProc("glProgramUniform1ui"); + api->TexSubImage1D = loadProc("glTexSubImage1D"); + api->ClearDepthf = loadProc("glClearDepthf"); + api->ReadPixels = loadProc("glReadPixels"); + api->VertexAttribI2i = loadProc("glVertexAttribI2i"); + api->Finish = loadProc("glFinish"); + api->LineWidth = loadProc("glLineWidth"); + api->DeleteShader = loadProc("glDeleteShader"); + api->IsSampler = loadProc("glIsSampler"); + api->ProgramUniformMatrix4dv = loadProc("glProgramUniformMatrix4dv"); + api->TransformFeedbackVaryings = loadProc("glTransformFeedbackVaryings"); + api->BeginConditionalRender = loadProc("glBeginConditionalRender"); + api->BindSamplers = oc_glBindSamplers_noimpl; + api->DeleteProgramPipelines = loadProc("glDeleteProgramPipelines"); + api->ColorMask = loadProc("glColorMask"); + api->TexParameterfv = loadProc("glTexParameterfv"); + api->PushDebugGroup = loadProc("glPushDebugGroup"); + api->ClearBufferfv = loadProc("glClearBufferfv"); + api->IsEnabled = loadProc("glIsEnabled"); + api->VertexAttrib2f = loadProc("glVertexAttrib2f"); + api->ProgramUniform2f = loadProc("glProgramUniform2f"); + api->GetSamplerParameterIuiv = loadProc("glGetSamplerParameterIuiv"); + api->GetInteger64i_v = loadProc("glGetInteger64i_v"); + api->Uniform2dv = loadProc("glUniform2dv"); + api->GetBufferSubData = loadProc("glGetBufferSubData"); + api->MultiDrawElementsIndirect = loadProc("glMultiDrawElementsIndirect"); + api->ProgramParameteri = loadProc("glProgramParameteri"); + api->VertexAttribP4ui = loadProc("glVertexAttribP4ui"); + api->SamplerParameterfv = loadProc("glSamplerParameterfv"); + api->PointParameterf = loadProc("glPointParameterf"); + api->UniformMatrix2x4fv = loadProc("glUniformMatrix2x4fv"); + api->GenBuffers = loadProc("glGenBuffers"); + api->ProgramUniform2dv = loadProc("glProgramUniform2dv"); + api->VertexAttribFormat = loadProc("glVertexAttribFormat"); + api->TexSubImage2D = loadProc("glTexSubImage2D"); + api->VertexAttrib4ubv = loadProc("glVertexAttrib4ubv"); + api->GetGraphicsResetStatus = oc_glGetGraphicsResetStatus_noimpl; + api->GetProgramInterfaceiv = loadProc("glGetProgramInterfaceiv"); + api->VertexAttribIFormat = loadProc("glVertexAttribIFormat"); + api->GetnUniformfv = oc_glGetnUniformfv_noimpl; + api->DeleteProgram = loadProc("glDeleteProgram"); + api->ClampColor = loadProc("glClampColor"); + api->DrawElementsInstancedBaseVertexBaseInstance = loadProc("glDrawElementsInstancedBaseVertexBaseInstance"); + api->DrawElements = loadProc("glDrawElements"); + api->DebugMessageControl = loadProc("glDebugMessageControl"); + api->GetRenderbufferParameteriv = loadProc("glGetRenderbufferParameteriv"); + api->DetachShader = loadProc("glDetachShader"); + api->GenFramebuffers = loadProc("glGenFramebuffers"); + api->ProvokingVertex = loadProc("glProvokingVertex"); + api->SampleMaski = loadProc("glSampleMaski"); + api->EndQueryIndexed = loadProc("glEndQueryIndexed"); + api->ProgramUniform1f = loadProc("glProgramUniform1f"); + api->BindFramebuffer = loadProc("glBindFramebuffer"); + api->BeginQueryIndexed = loadProc("glBeginQueryIndexed"); + api->UniformSubroutinesuiv = loadProc("glUniformSubroutinesuiv"); + api->GetUniformiv = loadProc("glGetUniformiv"); + api->FramebufferTexture = loadProc("glFramebufferTexture"); + api->PointParameterfv = loadProc("glPointParameterfv"); + api->IsTransformFeedback = loadProc("glIsTransformFeedback"); + api->CheckFramebufferStatus = loadProc("glCheckFramebufferStatus"); + api->ShaderSource = loadProc("glShaderSource"); + api->UniformMatrix2x4dv = loadProc("glUniformMatrix2x4dv"); + api->BindImageTextures = oc_glBindImageTextures_noimpl; + api->CopyTexImage1D = loadProc("glCopyTexImage1D"); + api->UniformMatrix3dv = loadProc("glUniformMatrix3dv"); + api->ProgramUniform1dv = loadProc("glProgramUniform1dv"); + api->BlitFramebuffer = loadProc("glBlitFramebuffer"); + api->PopDebugGroup = loadProc("glPopDebugGroup"); + api->TexParameterIuiv = loadProc("glTexParameterIuiv"); + api->VertexAttrib2d = loadProc("glVertexAttrib2d"); + api->TexImage1D = loadProc("glTexImage1D"); + api->GetObjectPtrLabel = loadProc("glGetObjectPtrLabel"); + api->StencilMask = loadProc("glStencilMask"); + api->BeginQuery = loadProc("glBeginQuery"); + api->UniformMatrix4fv = loadProc("glUniformMatrix4fv"); + api->IsSync = loadProc("glIsSync"); + api->Uniform3dv = loadProc("glUniform3dv"); + api->ProgramUniform2fv = loadProc("glProgramUniform2fv"); + api->VertexAttribI4sv = loadProc("glVertexAttribI4sv"); + api->ScissorArrayv = loadProc("glScissorArrayv"); + api->VertexAttribP1uiv = loadProc("glVertexAttribP1uiv"); + api->Uniform2uiv = loadProc("glUniform2uiv"); + api->DeleteBuffers = loadProc("glDeleteBuffers"); + api->ProgramUniform3ui = loadProc("glProgramUniform3ui"); + api->FramebufferTextureLayer = loadProc("glFramebufferTextureLayer"); + api->EndTransformFeedback = loadProc("glEndTransformFeedback"); + api->BlendFuncSeparatei = loadProc("glBlendFuncSeparatei"); + api->DrawTransformFeedbackInstanced = loadProc("glDrawTransformFeedbackInstanced"); + api->DrawRangeElementsBaseVertex = loadProc("glDrawRangeElementsBaseVertex"); + api->VertexAttrib1f = loadProc("glVertexAttrib1f"); + api->GetUniformSubroutineuiv = loadProc("glGetUniformSubroutineuiv"); + api->DisableVertexAttribArray = loadProc("glDisableVertexAttribArray"); + api->ProgramUniformMatrix3x2fv = loadProc("glProgramUniformMatrix3x2fv"); + api->VertexAttribI4usv = loadProc("glVertexAttribI4usv"); + api->GetObjectLabel = loadProc("glGetObjectLabel"); + api->BindAttribLocation = loadProc("glBindAttribLocation"); + api->Uniform1f = loadProc("glUniform1f"); + api->GetUniformdv = loadProc("glGetUniformdv"); + api->GetUniformLocation = loadProc("glGetUniformLocation"); + api->GetSubroutineUniformLocation = loadProc("glGetSubroutineUniformLocation"); + api->GetTexParameterIuiv = loadProc("glGetTexParameterIuiv"); + api->SamplerParameterf = loadProc("glSamplerParameterf"); + api->VertexAttribL3d = loadProc("glVertexAttribL3d"); + api->TexImage3DMultisample = loadProc("glTexImage3DMultisample"); + api->TexImage3D = loadProc("glTexImage3D"); + api->RenderbufferStorage = loadProc("glRenderbufferStorage"); + api->EnableVertexAttribArray = loadProc("glEnableVertexAttribArray"); + api->VertexAttribP4uiv = loadProc("glVertexAttribP4uiv"); + api->Uniform4d = loadProc("glUniform4d"); + api->VertexAttrib4s = loadProc("glVertexAttrib4s"); + api->DrawElementsInstancedBaseVertex = loadProc("glDrawElementsInstancedBaseVertex"); + api->VertexAttrib3s = loadProc("glVertexAttrib3s"); + api->ProgramUniform2iv = loadProc("glProgramUniform2iv"); + api->StencilFuncSeparate = loadProc("glStencilFuncSeparate"); + api->DeleteFramebuffers = loadProc("glDeleteFramebuffers"); + api->DepthRange = loadProc("glDepthRange"); + api->UniformMatrix3x2fv = loadProc("glUniformMatrix3x2fv"); + api->ProgramUniformMatrix2dv = loadProc("glProgramUniformMatrix2dv"); + api->ShaderStorageBlockBinding = loadProc("glShaderStorageBlockBinding"); + api->ClearDepth = loadProc("glClearDepth"); + api->VertexAttrib2dv = loadProc("glVertexAttrib2dv"); + api->SamplerParameterIuiv = loadProc("glSamplerParameterIuiv"); + api->GetVertexAttribLdv = loadProc("glGetVertexAttribLdv"); + api->ProgramUniformMatrix3x4dv = loadProc("glProgramUniformMatrix3x4dv"); + api->DepthRangeArrayv = loadProc("glDepthRangeArrayv"); + api->GetActiveUniform = loadProc("glGetActiveUniform"); + api->PatchParameterfv = loadProc("glPatchParameterfv"); + api->InvalidateTexImage = loadProc("glInvalidateTexImage"); + api->VertexAttrib3f = loadProc("glVertexAttrib3f"); + api->ProgramUniform4iv = loadProc("glProgramUniform4iv"); + api->ProgramUniform4d = loadProc("glProgramUniform4d"); + api->IsFramebuffer = loadProc("glIsFramebuffer"); + api->PixelStoref = loadProc("glPixelStoref"); + api->ProgramUniform4uiv = loadProc("glProgramUniform4uiv"); + api->ProgramUniformMatrix4x2dv = loadProc("glProgramUniformMatrix4x2dv"); + api->FenceSync = loadProc("glFenceSync"); + api->GetBufferParameteri64v = loadProc("glGetBufferParameteri64v"); + api->StencilOp = loadProc("glStencilOp"); + api->ClearBufferData = loadProc("glClearBufferData"); + api->GetnUniformuiv = oc_glGetnUniformuiv_noimpl; + api->GetProgramResourceiv = loadProc("glGetProgramResourceiv"); + api->GetVertexAttribdv = loadProc("glGetVertexAttribdv"); + api->GetTransformFeedbackVarying = loadProc("glGetTransformFeedbackVarying"); + api->VertexAttrib2fv = loadProc("glVertexAttrib2fv"); + api->GetBooleani_v = loadProc("glGetBooleani_v"); + api->ColorMaski = loadProc("glColorMaski"); + api->InvalidateBufferSubData = loadProc("glInvalidateBufferSubData"); + api->UniformMatrix4dv = loadProc("glUniformMatrix4dv"); + api->IsQuery = loadProc("glIsQuery"); + api->Uniform4ui = loadProc("glUniform4ui"); + api->Uniform4i = loadProc("glUniform4i"); + api->GetSamplerParameteriv = loadProc("glGetSamplerParameteriv"); + api->MultiDrawElementsBaseVertex = loadProc("glMultiDrawElementsBaseVertex"); + api->VertexAttribI1uiv = loadProc("glVertexAttribI1uiv"); + api->GetIntegerv = loadProc("glGetIntegerv"); + api->UniformMatrix2x3fv = loadProc("glUniformMatrix2x3fv"); + api->TexImage2D = loadProc("glTexImage2D"); + api->GetAttachedShaders = loadProc("glGetAttachedShaders"); + api->Uniform2d = loadProc("glUniform2d"); + api->MemoryBarrierByRegion = oc_glMemoryBarrierByRegion_noimpl; + api->UniformMatrix2fv = loadProc("glUniformMatrix2fv"); + api->PrimitiveRestartIndex = loadProc("glPrimitiveRestartIndex"); + api->GetVertexAttribiv = loadProc("glGetVertexAttribiv"); + api->GetAttribLocation = loadProc("glGetAttribLocation"); + api->TexStorage2DMultisample = loadProc("glTexStorage2DMultisample"); + api->CompressedTexSubImage2D = loadProc("glCompressedTexSubImage2D"); + api->GetVertexAttribfv = loadProc("glGetVertexAttribfv"); + api->GetBufferParameteriv = loadProc("glGetBufferParameteriv"); + api->TexParameterf = loadProc("glTexParameterf"); + api->FramebufferTexture2D = loadProc("glFramebufferTexture2D"); + api->GetActiveAttrib = loadProc("glGetActiveAttrib"); + api->InvalidateTexSubImage = loadProc("glInvalidateTexSubImage"); + api->DeleteVertexArrays = loadProc("glDeleteVertexArrays"); + api->VertexAttribI2ui = loadProc("glVertexAttribI2ui"); + api->PointParameteriv = loadProc("glPointParameteriv"); + api->GetPointerv = loadProc("glGetPointerv"); + api->Enablei = loadProc("glEnablei"); + api->BindBufferRange = loadProc("glBindBufferRange"); + api->DrawArraysInstanced = loadProc("glDrawArraysInstanced"); + api->DeleteTextures = loadProc("glDeleteTextures"); + api->VertexAttrib4Niv = loadProc("glVertexAttrib4Niv"); + api->MultiDrawElements = loadProc("glMultiDrawElements"); + api->GetProgramiv = loadProc("glGetProgramiv"); + api->DepthFunc = loadProc("glDepthFunc"); + api->GenTextures = loadProc("glGenTextures"); + api->GetInternalformativ = loadProc("glGetInternalformativ"); + api->ProgramUniform3i = loadProc("glProgramUniform3i"); + api->ScissorIndexed = loadProc("glScissorIndexed"); + api->VertexAttrib2sv = loadProc("glVertexAttrib2sv"); + api->TexStorage3DMultisample = loadProc("glTexStorage3DMultisample"); + api->Uniform2iv = loadProc("glUniform2iv"); + api->DrawArraysInstancedBaseInstance = loadProc("glDrawArraysInstancedBaseInstance"); + api->VertexAttribI3ui = loadProc("glVertexAttribI3ui"); + api->DeleteSamplers = loadProc("glDeleteSamplers"); + api->GenVertexArrays = loadProc("glGenVertexArrays"); + api->GetFramebufferParameteriv = loadProc("glGetFramebufferParameteriv"); + api->PolygonMode = loadProc("glPolygonMode"); + api->ProgramUniformMatrix2x4fv = loadProc("glProgramUniformMatrix2x4fv"); + api->GetProgramResourceName = loadProc("glGetProgramResourceName"); + api->SamplerParameteriv = loadProc("glSamplerParameteriv"); + api->GetActiveSubroutineUniformiv = loadProc("glGetActiveSubroutineUniformiv"); + api->GetStringi = loadProc("glGetStringi"); + api->VertexAttribLFormat = loadProc("glVertexAttribLFormat"); + api->VertexAttrib3d = loadProc("glVertexAttrib3d"); + api->BindVertexArray = loadProc("glBindVertexArray"); + api->UnmapBuffer = loadProc("glUnmapBuffer"); + api->DrawElementsInstancedBaseInstance = loadProc("glDrawElementsInstancedBaseInstance"); + api->Uniform4uiv = loadProc("glUniform4uiv"); + api->FramebufferTexture1D = loadProc("glFramebufferTexture1D"); + api->DrawTransformFeedbackStreamInstanced = loadProc("glDrawTransformFeedbackStreamInstanced"); + api->StencilFunc = loadProc("glStencilFunc"); + api->ValidateProgram = loadProc("glValidateProgram"); + api->Flush = loadProc("glFlush"); + api->ProgramUniform3uiv = loadProc("glProgramUniform3uiv"); + api->DeleteRenderbuffers = loadProc("glDeleteRenderbuffers"); + api->VertexAttrib4fv = loadProc("glVertexAttrib4fv"); + api->UniformMatrix2dv = loadProc("glUniformMatrix2dv"); + api->GetFragDataIndex = loadProc("glGetFragDataIndex"); + api->Uniform3iv = loadProc("glUniform3iv"); + api->MinSampleShading = loadProc("glMinSampleShading"); + api->GetBooleanv = loadProc("glGetBooleanv"); + api->GetMultisamplefv = loadProc("glGetMultisamplefv"); + api->GetVertexAttribIuiv = loadProc("glGetVertexAttribIuiv"); + api->GetProgramInfoLog = loadProc("glGetProgramInfoLog"); + api->Uniform4fv = loadProc("glUniform4fv"); + api->DrawBuffer = loadProc("glDrawBuffer"); + api->Uniform1i = loadProc("glUniform1i"); + api->ProgramUniform4ui = loadProc("glProgramUniform4ui"); + api->ProgramUniformMatrix3fv = loadProc("glProgramUniformMatrix3fv"); + api->BlendEquationSeparate = loadProc("glBlendEquationSeparate"); + api->BindProgramPipeline = loadProc("glBindProgramPipeline"); + api->GetDoublei_v = loadProc("glGetDoublei_v"); + api->BufferData = loadProc("glBufferData"); + api->ClearColor = loadProc("glClearColor"); + api->ProgramUniform4i = loadProc("glProgramUniform4i"); + api->GetTexLevelParameteriv = loadProc("glGetTexLevelParameteriv"); + api->GetActiveUniformBlockiv = loadProc("glGetActiveUniformBlockiv"); + api->ProgramUniform1fv = loadProc("glProgramUniform1fv"); + api->PauseTransformFeedback = loadProc("glPauseTransformFeedback"); + api->GetBufferPointerv = loadProc("glGetBufferPointerv"); + api->InvalidateSubFramebuffer = loadProc("glInvalidateSubFramebuffer"); + api->ScissorIndexedv = loadProc("glScissorIndexedv"); + api->Uniform2ui = loadProc("glUniform2ui"); + api->BindTexture = loadProc("glBindTexture"); + api->DrawElementsInstanced = loadProc("glDrawElementsInstanced"); + api->ProgramUniform4f = loadProc("glProgramUniform4f"); + api->BindBufferBase = loadProc("glBindBufferBase"); + api->IsShader = loadProc("glIsShader"); + api->ClearBufferSubData = loadProc("glClearBufferSubData"); + api->VertexAttrib4Nuiv = loadProc("glVertexAttrib4Nuiv"); + api->DrawArraysIndirect = loadProc("glDrawArraysIndirect"); + api->VertexAttrib4usv = loadProc("glVertexAttrib4usv"); + api->Uniform1d = loadProc("glUniform1d"); + api->ClearTexImage = oc_glClearTexImage_noimpl; + api->Uniform1uiv = loadProc("glUniform1uiv"); + api->BindSampler = loadProc("glBindSampler"); + api->GetTexLevelParameterfv = loadProc("glGetTexLevelParameterfv"); + api->ClearBufferiv = loadProc("glClearBufferiv"); + api->LogicOp = loadProc("glLogicOp"); + api->ActiveTexture = loadProc("glActiveTexture"); + api->GetFragDataLocation = loadProc("glGetFragDataLocation"); + api->BlendColor = loadProc("glBlendColor"); + api->UniformMatrix4x3fv = loadProc("glUniformMatrix4x3fv"); + api->ProgramUniform3fv = loadProc("glProgramUniform3fv"); + api->Uniform1fv = loadProc("glUniform1fv"); + api->DrawElementsBaseVertex = loadProc("glDrawElementsBaseVertex"); + api->Uniform4f = loadProc("glUniform4f"); + api->BlendEquationSeparatei = loadProc("glBlendEquationSeparatei"); + api->BlendFuncSeparate = loadProc("glBlendFuncSeparate"); + api->ClearBufferuiv = loadProc("glClearBufferuiv"); + api->CopyTexSubImage1D = loadProc("glCopyTexSubImage1D"); + api->DrawTransformFeedback = loadProc("glDrawTransformFeedback"); + api->ReadBuffer = loadProc("glReadBuffer"); + api->CopyBufferSubData = loadProc("glCopyBufferSubData"); + api->GetUniformuiv = loadProc("glGetUniformuiv"); + api->PolygonOffset = loadProc("glPolygonOffset"); + api->DispatchCompute = loadProc("glDispatchCompute"); + api->BindImageTexture = loadProc("glBindImageTexture"); + api->UniformMatrix4x3dv = loadProc("glUniformMatrix4x3dv"); + api->GenRenderbuffers = loadProc("glGenRenderbuffers"); } void oc_gl_load_gl44(oc_gl_api* api, oc_gl_load_proc loadProc) { - api->name = "gl44"; - api->GetFloatv = loadProc("glGetFloatv"); - api->TexBufferRange = loadProc("glTexBufferRange"); - api->IsBuffer = loadProc("glIsBuffer"); - api->IsTexture = loadProc("glIsTexture"); - api->DepthRangef = loadProc("glDepthRangef"); - api->EndConditionalRender = loadProc("glEndConditionalRender"); - api->BlendFunci = loadProc("glBlendFunci"); - api->GetProgramPipelineiv = loadProc("glGetProgramPipelineiv"); - api->WaitSync = loadProc("glWaitSync"); - api->ProgramUniformMatrix2fv = loadProc("glProgramUniformMatrix2fv"); - api->ProgramUniformMatrix4x3dv = loadProc("glProgramUniformMatrix4x3dv"); - api->VertexAttrib1dv = loadProc("glVertexAttrib1dv"); - api->SamplerParameteri = loadProc("glSamplerParameteri"); - api->GetVertexAttribIiv = loadProc("glGetVertexAttribIiv"); - api->GetSamplerParameterfv = loadProc("glGetSamplerParameterfv"); - api->VertexAttrib1d = loadProc("glVertexAttrib1d"); - api->TexBuffer = loadProc("glTexBuffer"); - api->InvalidateBufferData = loadProc("glInvalidateBufferData"); - api->ProgramUniform2i = loadProc("glProgramUniform2i"); - api->Uniform4dv = loadProc("glUniform4dv"); - api->UseProgram = loadProc("glUseProgram"); - api->VertexAttribI3iv = loadProc("glVertexAttribI3iv"); - api->DrawElementsIndirect = loadProc("glDrawElementsIndirect"); - api->VertexAttrib4uiv = loadProc("glVertexAttrib4uiv"); - api->GetQueryObjectiv = loadProc("glGetQueryObjectiv"); - api->FramebufferRenderbuffer = loadProc("glFramebufferRenderbuffer"); - api->BlendEquationi = loadProc("glBlendEquationi"); - api->GetActiveSubroutineName = loadProc("glGetActiveSubroutineName"); - api->VertexAttrib2s = loadProc("glVertexAttrib2s"); - api->VertexAttribL1d = loadProc("glVertexAttribL1d"); - api->BindTextures = loadProc("glBindTextures"); - api->VertexAttrib3sv = loadProc("glVertexAttrib3sv"); - api->GetFloati_v = loadProc("glGetFloati_v"); - api->BeginTransformFeedback = loadProc("glBeginTransformFeedback"); - api->ClearStencil = loadProc("glClearStencil"); - api->Uniform3i = loadProc("glUniform3i"); - api->ValidateProgramPipeline = loadProc("glValidateProgramPipeline"); - api->ProgramUniformMatrix4x2fv = loadProc("glProgramUniformMatrix4x2fv"); - api->VertexAttribI4ui = loadProc("glVertexAttribI4ui"); - api->GetShaderiv = loadProc("glGetShaderiv"); - api->ReadnPixels = oc_glReadnPixels_noimpl; - api->UniformMatrix4x2fv = loadProc("glUniformMatrix4x2fv"); - api->GetShaderPrecisionFormat = loadProc("glGetShaderPrecisionFormat"); - api->ProgramUniformMatrix2x3fv = loadProc("glProgramUniformMatrix2x3fv"); - api->TexSubImage3D = loadProc("glTexSubImage3D"); - api->GetProgramResourceLocationIndex = loadProc("glGetProgramResourceLocationIndex"); - api->BlendFunc = loadProc("glBlendFunc"); - api->ProgramUniformMatrix3x4fv = loadProc("glProgramUniformMatrix3x4fv"); - api->Uniform3d = loadProc("glUniform3d"); - api->VertexAttrib1sv = loadProc("glVertexAttrib1sv"); - api->BindFragDataLocation = loadProc("glBindFragDataLocation"); - api->VertexAttrib4bv = loadProc("glVertexAttrib4bv"); - api->Uniform4iv = loadProc("glUniform4iv"); - api->ProgramUniform2ui = loadProc("glProgramUniform2ui"); - api->DrawArrays = loadProc("glDrawArrays"); - api->ProgramBinary = loadProc("glProgramBinary"); - api->VertexAttrib4f = loadProc("glVertexAttrib4f"); - api->VertexAttribP2uiv = loadProc("glVertexAttribP2uiv"); - api->UniformMatrix3fv = loadProc("glUniformMatrix3fv"); - api->Uniform2i = loadProc("glUniform2i"); - api->GetQueryObjectuiv = loadProc("glGetQueryObjectuiv"); - api->UniformBlockBinding = loadProc("glUniformBlockBinding"); - api->SampleCoverage = loadProc("glSampleCoverage"); - api->VertexAttrib4Nusv = loadProc("glVertexAttrib4Nusv"); - api->ProgramUniformMatrix2x4dv = loadProc("glProgramUniformMatrix2x4dv"); - api->Uniform3uiv = loadProc("glUniform3uiv"); - api->VertexAttrib1s = loadProc("glVertexAttrib1s"); - api->GetVertexAttribPointerv = loadProc("glGetVertexAttribPointerv"); - api->BlendBarrier = oc_glBlendBarrier_noimpl; - api->DrawRangeElements = loadProc("glDrawRangeElements"); - api->TexStorage3D = loadProc("glTexStorage3D"); - api->GetInternalformati64v = loadProc("glGetInternalformati64v"); - api->GetQueryObjecti64v = loadProc("glGetQueryObjecti64v"); - api->CompressedTexSubImage1D = loadProc("glCompressedTexSubImage1D"); - api->VertexAttrib3dv = loadProc("glVertexAttrib3dv"); - api->VertexBindingDivisor = loadProc("glVertexBindingDivisor"); - api->UseProgramStages = loadProc("glUseProgramStages"); - api->VertexAttribBinding = loadProc("glVertexAttribBinding"); - api->DebugMessageInsert = loadProc("glDebugMessageInsert"); - api->GetTexParameteriv = loadProc("glGetTexParameteriv"); - api->MultiDrawArraysIndirect = loadProc("glMultiDrawArraysIndirect"); - api->GetTexParameterfv = loadProc("glGetTexParameterfv"); - api->GetProgramPipelineInfoLog = loadProc("glGetProgramPipelineInfoLog"); - api->EndQuery = loadProc("glEndQuery"); - api->GetProgramResourceLocation = loadProc("glGetProgramResourceLocation"); - api->CompressedTexImage2D = loadProc("glCompressedTexImage2D"); - api->VertexAttribP2ui = loadProc("glVertexAttribP2ui"); - api->IsEnabledi = loadProc("glIsEnabledi"); - api->GetActiveAtomicCounterBufferiv = loadProc("glGetActiveAtomicCounterBufferiv"); - api->IsProgram = loadProc("glIsProgram"); - api->Uniform1dv = loadProc("glUniform1dv"); - api->TexParameteriv = loadProc("glTexParameteriv"); - api->Uniform2fv = loadProc("glUniform2fv"); - api->ReleaseShaderCompiler = loadProc("glReleaseShaderCompiler"); - api->CullFace = loadProc("glCullFace"); - api->VertexAttribI4i = loadProc("glVertexAttribI4i"); - api->GetProgramResourceIndex = loadProc("glGetProgramResourceIndex"); - api->ShaderBinary = loadProc("glShaderBinary"); - api->UniformMatrix3x2dv = loadProc("glUniformMatrix3x2dv"); - api->InvalidateFramebuffer = loadProc("glInvalidateFramebuffer"); - api->AttachShader = loadProc("glAttachShader"); - api->FlushMappedBufferRange = loadProc("glFlushMappedBufferRange"); - api->VertexAttribP3uiv = loadProc("glVertexAttribP3uiv"); - api->GetActiveUniformName = loadProc("glGetActiveUniformName"); - api->MapBuffer = loadProc("glMapBuffer"); - api->DrawBuffers = loadProc("glDrawBuffers"); - api->GetSynciv = loadProc("glGetSynciv"); - api->CopyTexSubImage2D = loadProc("glCopyTexSubImage2D"); - api->ObjectLabel = loadProc("glObjectLabel"); - api->BufferSubData = loadProc("glBufferSubData"); - api->Uniform2f = loadProc("glUniform2f"); - api->DebugMessageCallback = loadProc("glDebugMessageCallback"); - api->VertexAttribL4dv = loadProc("glVertexAttribL4dv"); - api->IsProgramPipeline = loadProc("glIsProgramPipeline"); - api->ResumeTransformFeedback = loadProc("glResumeTransformFeedback"); - api->VertexAttribI4iv = loadProc("glVertexAttribI4iv"); - api->GetShaderInfoLog = loadProc("glGetShaderInfoLog"); - api->GetIntegeri_v = loadProc("glGetIntegeri_v"); - api->BindVertexBuffer = loadProc("glBindVertexBuffer"); - api->BlendEquation = loadProc("glBlendEquation"); - api->VertexAttribL2dv = loadProc("glVertexAttribL2dv"); - api->VertexAttribI1ui = loadProc("glVertexAttribI1ui"); - api->VertexAttrib4Nsv = loadProc("glVertexAttrib4Nsv"); - api->VertexAttribL4d = loadProc("glVertexAttribL4d"); - api->CopyImageSubData = loadProc("glCopyImageSubData"); - api->GetFramebufferAttachmentParameteriv = loadProc("glGetFramebufferAttachmentParameteriv"); - api->VertexAttribL2d = loadProc("glVertexAttribL2d"); - api->GetSubroutineIndex = loadProc("glGetSubroutineIndex"); - api->VertexAttribI3uiv = loadProc("glVertexAttribI3uiv"); - api->VertexAttrib4iv = loadProc("glVertexAttrib4iv"); - api->BindVertexBuffers = loadProc("glBindVertexBuffers"); - api->ProgramUniformMatrix2x3dv = loadProc("glProgramUniformMatrix2x3dv"); - api->PrimitiveBoundingBox = oc_glPrimitiveBoundingBox_noimpl; - api->Scissor = loadProc("glScissor"); - api->ClientWaitSync = loadProc("glClientWaitSync"); - api->Uniform3ui = loadProc("glUniform3ui"); - api->VertexAttribP3ui = loadProc("glVertexAttribP3ui"); - api->Enable = loadProc("glEnable"); - api->StencilOpSeparate = loadProc("glStencilOpSeparate"); - api->UniformMatrix2x3dv = loadProc("glUniformMatrix2x3dv"); - api->ProgramUniformMatrix3dv = loadProc("glProgramUniformMatrix3dv"); - api->TexImage2DMultisample = loadProc("glTexImage2DMultisample"); - api->VertexAttrib4Nbv = loadProc("glVertexAttrib4Nbv"); - api->GetTexImage = loadProc("glGetTexImage"); - api->VertexAttrib4sv = loadProc("glVertexAttrib4sv"); - api->PixelStorei = loadProc("glPixelStorei"); - api->DepthMask = loadProc("glDepthMask"); - api->TexStorage2D = loadProc("glTexStorage2D"); - api->Clear = loadProc("glClear"); - api->UniformMatrix3x4dv = loadProc("glUniformMatrix3x4dv"); - api->DeleteTransformFeedbacks = loadProc("glDeleteTransformFeedbacks"); - api->MapBufferRange = loadProc("glMapBufferRange"); - api->MemoryBarrier = loadProc("glMemoryBarrier"); - api->ViewportIndexedf = loadProc("glViewportIndexedf"); - api->VertexAttrib3fv = loadProc("glVertexAttrib3fv"); - api->ObjectPtrLabel = loadProc("glObjectPtrLabel"); - api->TexStorage1D = loadProc("glTexStorage1D"); - api->CompressedTexImage3D = loadProc("glCompressedTexImage3D"); - api->VertexAttrib1fv = loadProc("glVertexAttrib1fv"); - api->VertexAttribPointer = loadProc("glVertexAttribPointer"); - api->GetQueryIndexediv = loadProc("glGetQueryIndexediv"); - api->CompileShader = loadProc("glCompileShader"); - api->ProgramUniform1i = loadProc("glProgramUniform1i"); - api->GetQueryiv = loadProc("glGetQueryiv"); - api->VertexAttribI1iv = loadProc("glVertexAttribI1iv"); - api->CopyTexImage2D = loadProc("glCopyTexImage2D"); - api->GetQueryObjectui64v = loadProc("glGetQueryObjectui64v"); - api->PointSize = loadProc("glPointSize"); - api->Disablei = loadProc("glDisablei"); - api->VertexAttribL1dv = loadProc("glVertexAttribL1dv"); - api->CreateShader = loadProc("glCreateShader"); - api->GetString = loadProc("glGetString"); - api->ViewportArrayv = loadProc("glViewportArrayv"); - api->ProgramUniform3d = loadProc("glProgramUniform3d"); - api->VertexAttrib4Nubv = loadProc("glVertexAttrib4Nubv"); - api->TexParameteri = loadProc("glTexParameteri"); - api->ProgramUniform4fv = loadProc("glProgramUniform4fv"); - api->GenerateMipmap = loadProc("glGenerateMipmap"); - api->CompressedTexSubImage3D = loadProc("glCompressedTexSubImage3D"); - api->Uniform3f = loadProc("glUniform3f"); - api->GetUniformIndices = loadProc("glGetUniformIndices"); - api->VertexAttribLPointer = loadProc("glVertexAttribLPointer"); - api->VertexAttribI2uiv = loadProc("glVertexAttribI2uiv"); - api->QueryCounter = loadProc("glQueryCounter"); - api->ActiveShaderProgram = loadProc("glActiveShaderProgram"); - api->Uniform1ui = loadProc("glUniform1ui"); - api->VertexAttribI1i = loadProc("glVertexAttribI1i"); - api->GetTexParameterIiv = loadProc("glGetTexParameterIiv"); - api->GetUniformfv = loadProc("glGetUniformfv"); - api->ProgramUniform2uiv = loadProc("glProgramUniform2uiv"); - api->GetError = loadProc("glGetError"); - api->GetActiveUniformBlockName = loadProc("glGetActiveUniformBlockName"); - api->TextureView = loadProc("glTextureView"); - api->GetnUniformiv = oc_glGetnUniformiv_noimpl; - api->ProgramUniform4dv = loadProc("glProgramUniform4dv"); - api->ViewportIndexedfv = loadProc("glViewportIndexedfv"); - api->Hint = loadProc("glHint"); - api->GetShaderSource = loadProc("glGetShaderSource"); - api->ProgramUniformMatrix4x3fv = loadProc("glProgramUniformMatrix4x3fv"); - api->Uniform1iv = loadProc("glUniform1iv"); - api->VertexAttribI4bv = loadProc("glVertexAttribI4bv"); - api->UniformMatrix4x2dv = loadProc("glUniformMatrix4x2dv"); - api->BufferStorage = loadProc("glBufferStorage"); - api->IsRenderbuffer = loadProc("glIsRenderbuffer"); - api->GetActiveSubroutineUniformName = loadProc("glGetActiveSubroutineUniformName"); - api->LinkProgram = loadProc("glLinkProgram"); - api->GetActiveUniformsiv = loadProc("glGetActiveUniformsiv"); - api->GetDebugMessageLog = loadProc("glGetDebugMessageLog"); - api->CopyTexSubImage3D = loadProc("glCopyTexSubImage3D"); - api->PointParameteri = loadProc("glPointParameteri"); - api->ProgramUniform3dv = loadProc("glProgramUniform3dv"); - api->CompressedTexImage1D = loadProc("glCompressedTexImage1D"); - api->UniformMatrix3x4fv = loadProc("glUniformMatrix3x4fv"); - api->GenSamplers = loadProc("glGenSamplers"); - api->GetCompressedTexImage = loadProc("glGetCompressedTexImage"); - api->DeleteQueries = loadProc("glDeleteQueries"); - api->GenProgramPipelines = loadProc("glGenProgramPipelines"); - api->DispatchComputeIndirect = loadProc("glDispatchComputeIndirect"); - api->VertexAttribIPointer = loadProc("glVertexAttribIPointer"); - api->CreateProgram = loadProc("glCreateProgram"); - api->ClearTexSubImage = loadProc("glClearTexSubImage"); - api->VertexAttrib4d = loadProc("glVertexAttrib4d"); - api->FrontFace = loadProc("glFrontFace"); - api->BindTransformFeedback = loadProc("glBindTransformFeedback"); - api->GetProgramStageiv = loadProc("glGetProgramStageiv"); - api->SamplerParameterIiv = loadProc("glSamplerParameterIiv"); - api->GetInteger64v = loadProc("glGetInteger64v"); - api->CreateShaderProgramv = loadProc("glCreateShaderProgramv"); - api->BindBuffersRange = loadProc("glBindBuffersRange"); - api->Uniform3fv = loadProc("glUniform3fv"); - api->ProgramUniformMatrix4fv = loadProc("glProgramUniformMatrix4fv"); - api->BindBuffersBase = loadProc("glBindBuffersBase"); - api->ClearBufferfi = loadProc("glClearBufferfi"); - api->FramebufferTexture3D = loadProc("glFramebufferTexture3D"); - api->Disable = loadProc("glDisable"); - api->ProgramUniform1iv = loadProc("glProgramUniform1iv"); - api->VertexAttribI2iv = loadProc("glVertexAttribI2iv"); - api->DepthRangeIndexed = loadProc("glDepthRangeIndexed"); - api->PatchParameteri = loadProc("glPatchParameteri"); - api->GetUniformBlockIndex = loadProc("glGetUniformBlockIndex"); - api->MultiDrawArrays = loadProc("glMultiDrawArrays"); - api->VertexAttribI4ubv = loadProc("glVertexAttribI4ubv"); - api->BindBuffer = loadProc("glBindBuffer"); - api->VertexAttribI3i = loadProc("glVertexAttribI3i"); - api->GetDoublev = loadProc("glGetDoublev"); - api->DrawTransformFeedbackStream = loadProc("glDrawTransformFeedbackStream"); - api->VertexAttribI4uiv = loadProc("glVertexAttribI4uiv"); - api->RenderbufferStorageMultisample = loadProc("glRenderbufferStorageMultisample"); - api->VertexAttribL3dv = loadProc("glVertexAttribL3dv"); - api->StencilMaskSeparate = loadProc("glStencilMaskSeparate"); - api->ProgramUniform1d = loadProc("glProgramUniform1d"); - api->Viewport = loadProc("glViewport"); - api->VertexAttribP1ui = loadProc("glVertexAttribP1ui"); - api->VertexAttrib4dv = loadProc("glVertexAttrib4dv"); - api->GenQueries = loadProc("glGenQueries"); - api->TexParameterIiv = loadProc("glTexParameterIiv"); - api->ProgramUniform2d = loadProc("glProgramUniform2d"); - api->ProgramUniform1uiv = loadProc("glProgramUniform1uiv"); - api->VertexAttrib4Nub = loadProc("glVertexAttrib4Nub"); - api->IsVertexArray = loadProc("glIsVertexArray"); - api->ProgramUniform3f = loadProc("glProgramUniform3f"); - api->ProgramUniform3iv = loadProc("glProgramUniform3iv"); - api->GetProgramBinary = loadProc("glGetProgramBinary"); - api->BindRenderbuffer = loadProc("glBindRenderbuffer"); - api->BindFragDataLocationIndexed = loadProc("glBindFragDataLocationIndexed"); - api->GetSamplerParameterIiv = loadProc("glGetSamplerParameterIiv"); - api->VertexAttribDivisor = loadProc("glVertexAttribDivisor"); - api->ProgramUniformMatrix3x2dv = loadProc("glProgramUniformMatrix3x2dv"); - api->FramebufferParameteri = loadProc("glFramebufferParameteri"); - api->GenTransformFeedbacks = loadProc("glGenTransformFeedbacks"); - api->DeleteSync = loadProc("glDeleteSync"); - api->ProgramUniform1ui = loadProc("glProgramUniform1ui"); - api->TexSubImage1D = loadProc("glTexSubImage1D"); - api->ClearDepthf = loadProc("glClearDepthf"); - api->ReadPixels = loadProc("glReadPixels"); - api->VertexAttribI2i = loadProc("glVertexAttribI2i"); - api->Finish = loadProc("glFinish"); - api->LineWidth = loadProc("glLineWidth"); - api->DeleteShader = loadProc("glDeleteShader"); - api->IsSampler = loadProc("glIsSampler"); - api->ProgramUniformMatrix4dv = loadProc("glProgramUniformMatrix4dv"); - api->TransformFeedbackVaryings = loadProc("glTransformFeedbackVaryings"); - api->BeginConditionalRender = loadProc("glBeginConditionalRender"); - api->BindSamplers = loadProc("glBindSamplers"); - api->DeleteProgramPipelines = loadProc("glDeleteProgramPipelines"); - api->ColorMask = loadProc("glColorMask"); - api->TexParameterfv = loadProc("glTexParameterfv"); - api->PushDebugGroup = loadProc("glPushDebugGroup"); - api->ClearBufferfv = loadProc("glClearBufferfv"); - api->IsEnabled = loadProc("glIsEnabled"); - api->VertexAttrib2f = loadProc("glVertexAttrib2f"); - api->ProgramUniform2f = loadProc("glProgramUniform2f"); - api->GetSamplerParameterIuiv = loadProc("glGetSamplerParameterIuiv"); - api->GetInteger64i_v = loadProc("glGetInteger64i_v"); - api->Uniform2dv = loadProc("glUniform2dv"); - api->GetBufferSubData = loadProc("glGetBufferSubData"); - api->MultiDrawElementsIndirect = loadProc("glMultiDrawElementsIndirect"); - api->ProgramParameteri = loadProc("glProgramParameteri"); - api->VertexAttribP4ui = loadProc("glVertexAttribP4ui"); - api->SamplerParameterfv = loadProc("glSamplerParameterfv"); - api->PointParameterf = loadProc("glPointParameterf"); - api->UniformMatrix2x4fv = loadProc("glUniformMatrix2x4fv"); - api->GenBuffers = loadProc("glGenBuffers"); - api->ProgramUniform2dv = loadProc("glProgramUniform2dv"); - api->VertexAttribFormat = loadProc("glVertexAttribFormat"); - api->TexSubImage2D = loadProc("glTexSubImage2D"); - api->VertexAttrib4ubv = loadProc("glVertexAttrib4ubv"); - api->GetGraphicsResetStatus = oc_glGetGraphicsResetStatus_noimpl; - api->GetProgramInterfaceiv = loadProc("glGetProgramInterfaceiv"); - api->VertexAttribIFormat = loadProc("glVertexAttribIFormat"); - api->GetnUniformfv = oc_glGetnUniformfv_noimpl; - api->DeleteProgram = loadProc("glDeleteProgram"); - api->ClampColor = loadProc("glClampColor"); - api->DrawElementsInstancedBaseVertexBaseInstance = loadProc("glDrawElementsInstancedBaseVertexBaseInstance"); - api->DrawElements = loadProc("glDrawElements"); - api->DebugMessageControl = loadProc("glDebugMessageControl"); - api->GetRenderbufferParameteriv = loadProc("glGetRenderbufferParameteriv"); - api->DetachShader = loadProc("glDetachShader"); - api->GenFramebuffers = loadProc("glGenFramebuffers"); - api->ProvokingVertex = loadProc("glProvokingVertex"); - api->SampleMaski = loadProc("glSampleMaski"); - api->EndQueryIndexed = loadProc("glEndQueryIndexed"); - api->ProgramUniform1f = loadProc("glProgramUniform1f"); - api->BindFramebuffer = loadProc("glBindFramebuffer"); - api->BeginQueryIndexed = loadProc("glBeginQueryIndexed"); - api->UniformSubroutinesuiv = loadProc("glUniformSubroutinesuiv"); - api->GetUniformiv = loadProc("glGetUniformiv"); - api->FramebufferTexture = loadProc("glFramebufferTexture"); - api->PointParameterfv = loadProc("glPointParameterfv"); - api->IsTransformFeedback = loadProc("glIsTransformFeedback"); - api->CheckFramebufferStatus = loadProc("glCheckFramebufferStatus"); - api->ShaderSource = loadProc("glShaderSource"); - api->UniformMatrix2x4dv = loadProc("glUniformMatrix2x4dv"); - api->BindImageTextures = loadProc("glBindImageTextures"); - api->CopyTexImage1D = loadProc("glCopyTexImage1D"); - api->UniformMatrix3dv = loadProc("glUniformMatrix3dv"); - api->ProgramUniform1dv = loadProc("glProgramUniform1dv"); - api->BlitFramebuffer = loadProc("glBlitFramebuffer"); - api->PopDebugGroup = loadProc("glPopDebugGroup"); - api->TexParameterIuiv = loadProc("glTexParameterIuiv"); - api->VertexAttrib2d = loadProc("glVertexAttrib2d"); - api->TexImage1D = loadProc("glTexImage1D"); - api->GetObjectPtrLabel = loadProc("glGetObjectPtrLabel"); - api->StencilMask = loadProc("glStencilMask"); - api->BeginQuery = loadProc("glBeginQuery"); - api->UniformMatrix4fv = loadProc("glUniformMatrix4fv"); - api->IsSync = loadProc("glIsSync"); - api->Uniform3dv = loadProc("glUniform3dv"); - api->ProgramUniform2fv = loadProc("glProgramUniform2fv"); - api->VertexAttribI4sv = loadProc("glVertexAttribI4sv"); - api->ScissorArrayv = loadProc("glScissorArrayv"); - api->VertexAttribP1uiv = loadProc("glVertexAttribP1uiv"); - api->Uniform2uiv = loadProc("glUniform2uiv"); - api->DeleteBuffers = loadProc("glDeleteBuffers"); - api->ProgramUniform3ui = loadProc("glProgramUniform3ui"); - api->FramebufferTextureLayer = loadProc("glFramebufferTextureLayer"); - api->EndTransformFeedback = loadProc("glEndTransformFeedback"); - api->BlendFuncSeparatei = loadProc("glBlendFuncSeparatei"); - api->DrawTransformFeedbackInstanced = loadProc("glDrawTransformFeedbackInstanced"); - api->DrawRangeElementsBaseVertex = loadProc("glDrawRangeElementsBaseVertex"); - api->VertexAttrib1f = loadProc("glVertexAttrib1f"); - api->GetUniformSubroutineuiv = loadProc("glGetUniformSubroutineuiv"); - api->DisableVertexAttribArray = loadProc("glDisableVertexAttribArray"); - api->ProgramUniformMatrix3x2fv = loadProc("glProgramUniformMatrix3x2fv"); - api->VertexAttribI4usv = loadProc("glVertexAttribI4usv"); - api->GetObjectLabel = loadProc("glGetObjectLabel"); - api->BindAttribLocation = loadProc("glBindAttribLocation"); - api->Uniform1f = loadProc("glUniform1f"); - api->GetUniformdv = loadProc("glGetUniformdv"); - api->GetUniformLocation = loadProc("glGetUniformLocation"); - api->GetSubroutineUniformLocation = loadProc("glGetSubroutineUniformLocation"); - api->GetTexParameterIuiv = loadProc("glGetTexParameterIuiv"); - api->SamplerParameterf = loadProc("glSamplerParameterf"); - api->VertexAttribL3d = loadProc("glVertexAttribL3d"); - api->TexImage3DMultisample = loadProc("glTexImage3DMultisample"); - api->TexImage3D = loadProc("glTexImage3D"); - api->RenderbufferStorage = loadProc("glRenderbufferStorage"); - api->EnableVertexAttribArray = loadProc("glEnableVertexAttribArray"); - api->VertexAttribP4uiv = loadProc("glVertexAttribP4uiv"); - api->Uniform4d = loadProc("glUniform4d"); - api->VertexAttrib4s = loadProc("glVertexAttrib4s"); - api->DrawElementsInstancedBaseVertex = loadProc("glDrawElementsInstancedBaseVertex"); - api->VertexAttrib3s = loadProc("glVertexAttrib3s"); - api->ProgramUniform2iv = loadProc("glProgramUniform2iv"); - api->StencilFuncSeparate = loadProc("glStencilFuncSeparate"); - api->DeleteFramebuffers = loadProc("glDeleteFramebuffers"); - api->DepthRange = loadProc("glDepthRange"); - api->UniformMatrix3x2fv = loadProc("glUniformMatrix3x2fv"); - api->ProgramUniformMatrix2dv = loadProc("glProgramUniformMatrix2dv"); - api->ShaderStorageBlockBinding = loadProc("glShaderStorageBlockBinding"); - api->ClearDepth = loadProc("glClearDepth"); - api->VertexAttrib2dv = loadProc("glVertexAttrib2dv"); - api->SamplerParameterIuiv = loadProc("glSamplerParameterIuiv"); - api->GetVertexAttribLdv = loadProc("glGetVertexAttribLdv"); - api->ProgramUniformMatrix3x4dv = loadProc("glProgramUniformMatrix3x4dv"); - api->DepthRangeArrayv = loadProc("glDepthRangeArrayv"); - api->GetActiveUniform = loadProc("glGetActiveUniform"); - api->PatchParameterfv = loadProc("glPatchParameterfv"); - api->InvalidateTexImage = loadProc("glInvalidateTexImage"); - api->VertexAttrib3f = loadProc("glVertexAttrib3f"); - api->ProgramUniform4iv = loadProc("glProgramUniform4iv"); - api->ProgramUniform4d = loadProc("glProgramUniform4d"); - api->IsFramebuffer = loadProc("glIsFramebuffer"); - api->PixelStoref = loadProc("glPixelStoref"); - api->ProgramUniform4uiv = loadProc("glProgramUniform4uiv"); - api->ProgramUniformMatrix4x2dv = loadProc("glProgramUniformMatrix4x2dv"); - api->FenceSync = loadProc("glFenceSync"); - api->GetBufferParameteri64v = loadProc("glGetBufferParameteri64v"); - api->StencilOp = loadProc("glStencilOp"); - api->ClearBufferData = loadProc("glClearBufferData"); - api->GetnUniformuiv = oc_glGetnUniformuiv_noimpl; - api->GetProgramResourceiv = loadProc("glGetProgramResourceiv"); - api->GetVertexAttribdv = loadProc("glGetVertexAttribdv"); - api->GetTransformFeedbackVarying = loadProc("glGetTransformFeedbackVarying"); - api->VertexAttrib2fv = loadProc("glVertexAttrib2fv"); - api->GetBooleani_v = loadProc("glGetBooleani_v"); - api->ColorMaski = loadProc("glColorMaski"); - api->InvalidateBufferSubData = loadProc("glInvalidateBufferSubData"); - api->UniformMatrix4dv = loadProc("glUniformMatrix4dv"); - api->IsQuery = loadProc("glIsQuery"); - api->Uniform4ui = loadProc("glUniform4ui"); - api->Uniform4i = loadProc("glUniform4i"); - api->GetSamplerParameteriv = loadProc("glGetSamplerParameteriv"); - api->MultiDrawElementsBaseVertex = loadProc("glMultiDrawElementsBaseVertex"); - api->VertexAttribI1uiv = loadProc("glVertexAttribI1uiv"); - api->GetIntegerv = loadProc("glGetIntegerv"); - api->UniformMatrix2x3fv = loadProc("glUniformMatrix2x3fv"); - api->TexImage2D = loadProc("glTexImage2D"); - api->GetAttachedShaders = loadProc("glGetAttachedShaders"); - api->Uniform2d = loadProc("glUniform2d"); - api->MemoryBarrierByRegion = oc_glMemoryBarrierByRegion_noimpl; - api->UniformMatrix2fv = loadProc("glUniformMatrix2fv"); - api->PrimitiveRestartIndex = loadProc("glPrimitiveRestartIndex"); - api->GetVertexAttribiv = loadProc("glGetVertexAttribiv"); - api->GetAttribLocation = loadProc("glGetAttribLocation"); - api->TexStorage2DMultisample = loadProc("glTexStorage2DMultisample"); - api->CompressedTexSubImage2D = loadProc("glCompressedTexSubImage2D"); - api->GetVertexAttribfv = loadProc("glGetVertexAttribfv"); - api->GetBufferParameteriv = loadProc("glGetBufferParameteriv"); - api->TexParameterf = loadProc("glTexParameterf"); - api->FramebufferTexture2D = loadProc("glFramebufferTexture2D"); - api->GetActiveAttrib = loadProc("glGetActiveAttrib"); - api->InvalidateTexSubImage = loadProc("glInvalidateTexSubImage"); - api->DeleteVertexArrays = loadProc("glDeleteVertexArrays"); - api->VertexAttribI2ui = loadProc("glVertexAttribI2ui"); - api->PointParameteriv = loadProc("glPointParameteriv"); - api->GetPointerv = loadProc("glGetPointerv"); - api->Enablei = loadProc("glEnablei"); - api->BindBufferRange = loadProc("glBindBufferRange"); - api->DrawArraysInstanced = loadProc("glDrawArraysInstanced"); - api->DeleteTextures = loadProc("glDeleteTextures"); - api->VertexAttrib4Niv = loadProc("glVertexAttrib4Niv"); - api->MultiDrawElements = loadProc("glMultiDrawElements"); - api->GetProgramiv = loadProc("glGetProgramiv"); - api->DepthFunc = loadProc("glDepthFunc"); - api->GenTextures = loadProc("glGenTextures"); - api->GetInternalformativ = loadProc("glGetInternalformativ"); - api->ProgramUniform3i = loadProc("glProgramUniform3i"); - api->ScissorIndexed = loadProc("glScissorIndexed"); - api->VertexAttrib2sv = loadProc("glVertexAttrib2sv"); - api->TexStorage3DMultisample = loadProc("glTexStorage3DMultisample"); - api->Uniform2iv = loadProc("glUniform2iv"); - api->DrawArraysInstancedBaseInstance = loadProc("glDrawArraysInstancedBaseInstance"); - api->VertexAttribI3ui = loadProc("glVertexAttribI3ui"); - api->DeleteSamplers = loadProc("glDeleteSamplers"); - api->GenVertexArrays = loadProc("glGenVertexArrays"); - api->GetFramebufferParameteriv = loadProc("glGetFramebufferParameteriv"); - api->PolygonMode = loadProc("glPolygonMode"); - api->ProgramUniformMatrix2x4fv = loadProc("glProgramUniformMatrix2x4fv"); - api->GetProgramResourceName = loadProc("glGetProgramResourceName"); - api->SamplerParameteriv = loadProc("glSamplerParameteriv"); - api->GetActiveSubroutineUniformiv = loadProc("glGetActiveSubroutineUniformiv"); - api->GetStringi = loadProc("glGetStringi"); - api->VertexAttribLFormat = loadProc("glVertexAttribLFormat"); - api->VertexAttrib3d = loadProc("glVertexAttrib3d"); - api->BindVertexArray = loadProc("glBindVertexArray"); - api->UnmapBuffer = loadProc("glUnmapBuffer"); - api->DrawElementsInstancedBaseInstance = loadProc("glDrawElementsInstancedBaseInstance"); - api->Uniform4uiv = loadProc("glUniform4uiv"); - api->FramebufferTexture1D = loadProc("glFramebufferTexture1D"); - api->DrawTransformFeedbackStreamInstanced = loadProc("glDrawTransformFeedbackStreamInstanced"); - api->StencilFunc = loadProc("glStencilFunc"); - api->ValidateProgram = loadProc("glValidateProgram"); - api->Flush = loadProc("glFlush"); - api->ProgramUniform3uiv = loadProc("glProgramUniform3uiv"); - api->DeleteRenderbuffers = loadProc("glDeleteRenderbuffers"); - api->VertexAttrib4fv = loadProc("glVertexAttrib4fv"); - api->UniformMatrix2dv = loadProc("glUniformMatrix2dv"); - api->GetFragDataIndex = loadProc("glGetFragDataIndex"); - api->Uniform3iv = loadProc("glUniform3iv"); - api->MinSampleShading = loadProc("glMinSampleShading"); - api->GetBooleanv = loadProc("glGetBooleanv"); - api->GetMultisamplefv = loadProc("glGetMultisamplefv"); - api->GetVertexAttribIuiv = loadProc("glGetVertexAttribIuiv"); - api->GetProgramInfoLog = loadProc("glGetProgramInfoLog"); - api->Uniform4fv = loadProc("glUniform4fv"); - api->DrawBuffer = loadProc("glDrawBuffer"); - api->Uniform1i = loadProc("glUniform1i"); - api->ProgramUniform4ui = loadProc("glProgramUniform4ui"); - api->ProgramUniformMatrix3fv = loadProc("glProgramUniformMatrix3fv"); - api->BlendEquationSeparate = loadProc("glBlendEquationSeparate"); - api->BindProgramPipeline = loadProc("glBindProgramPipeline"); - api->GetDoublei_v = loadProc("glGetDoublei_v"); - api->BufferData = loadProc("glBufferData"); - api->ClearColor = loadProc("glClearColor"); - api->ProgramUniform4i = loadProc("glProgramUniform4i"); - api->GetTexLevelParameteriv = loadProc("glGetTexLevelParameteriv"); - api->GetActiveUniformBlockiv = loadProc("glGetActiveUniformBlockiv"); - api->ProgramUniform1fv = loadProc("glProgramUniform1fv"); - api->PauseTransformFeedback = loadProc("glPauseTransformFeedback"); - api->GetBufferPointerv = loadProc("glGetBufferPointerv"); - api->InvalidateSubFramebuffer = loadProc("glInvalidateSubFramebuffer"); - api->ScissorIndexedv = loadProc("glScissorIndexedv"); - api->Uniform2ui = loadProc("glUniform2ui"); - api->BindTexture = loadProc("glBindTexture"); - api->DrawElementsInstanced = loadProc("glDrawElementsInstanced"); - api->ProgramUniform4f = loadProc("glProgramUniform4f"); - api->BindBufferBase = loadProc("glBindBufferBase"); - api->IsShader = loadProc("glIsShader"); - api->ClearBufferSubData = loadProc("glClearBufferSubData"); - api->VertexAttrib4Nuiv = loadProc("glVertexAttrib4Nuiv"); - api->DrawArraysIndirect = loadProc("glDrawArraysIndirect"); - api->VertexAttrib4usv = loadProc("glVertexAttrib4usv"); - api->Uniform1d = loadProc("glUniform1d"); - api->ClearTexImage = loadProc("glClearTexImage"); - api->Uniform1uiv = loadProc("glUniform1uiv"); - api->BindSampler = loadProc("glBindSampler"); - api->GetTexLevelParameterfv = loadProc("glGetTexLevelParameterfv"); - api->ClearBufferiv = loadProc("glClearBufferiv"); - api->LogicOp = loadProc("glLogicOp"); - api->ActiveTexture = loadProc("glActiveTexture"); - api->GetFragDataLocation = loadProc("glGetFragDataLocation"); - api->BlendColor = loadProc("glBlendColor"); - api->UniformMatrix4x3fv = loadProc("glUniformMatrix4x3fv"); - api->ProgramUniform3fv = loadProc("glProgramUniform3fv"); - api->Uniform1fv = loadProc("glUniform1fv"); - api->DrawElementsBaseVertex = loadProc("glDrawElementsBaseVertex"); - api->Uniform4f = loadProc("glUniform4f"); - api->BlendEquationSeparatei = loadProc("glBlendEquationSeparatei"); - api->BlendFuncSeparate = loadProc("glBlendFuncSeparate"); - api->ClearBufferuiv = loadProc("glClearBufferuiv"); - api->CopyTexSubImage1D = loadProc("glCopyTexSubImage1D"); - api->DrawTransformFeedback = loadProc("glDrawTransformFeedback"); - api->ReadBuffer = loadProc("glReadBuffer"); - api->CopyBufferSubData = loadProc("glCopyBufferSubData"); - api->GetUniformuiv = loadProc("glGetUniformuiv"); - api->PolygonOffset = loadProc("glPolygonOffset"); - api->DispatchCompute = loadProc("glDispatchCompute"); - api->BindImageTexture = loadProc("glBindImageTexture"); - api->UniformMatrix4x3dv = loadProc("glUniformMatrix4x3dv"); - api->GenRenderbuffers = loadProc("glGenRenderbuffers"); + api->name = "gl44"; + api->GetFloatv = loadProc("glGetFloatv"); + api->TexBufferRange = loadProc("glTexBufferRange"); + api->IsBuffer = loadProc("glIsBuffer"); + api->IsTexture = loadProc("glIsTexture"); + api->DepthRangef = loadProc("glDepthRangef"); + api->EndConditionalRender = loadProc("glEndConditionalRender"); + api->BlendFunci = loadProc("glBlendFunci"); + api->GetProgramPipelineiv = loadProc("glGetProgramPipelineiv"); + api->WaitSync = loadProc("glWaitSync"); + api->ProgramUniformMatrix2fv = loadProc("glProgramUniformMatrix2fv"); + api->ProgramUniformMatrix4x3dv = loadProc("glProgramUniformMatrix4x3dv"); + api->VertexAttrib1dv = loadProc("glVertexAttrib1dv"); + api->SamplerParameteri = loadProc("glSamplerParameteri"); + api->GetVertexAttribIiv = loadProc("glGetVertexAttribIiv"); + api->GetSamplerParameterfv = loadProc("glGetSamplerParameterfv"); + api->VertexAttrib1d = loadProc("glVertexAttrib1d"); + api->TexBuffer = loadProc("glTexBuffer"); + api->InvalidateBufferData = loadProc("glInvalidateBufferData"); + api->ProgramUniform2i = loadProc("glProgramUniform2i"); + api->Uniform4dv = loadProc("glUniform4dv"); + api->UseProgram = loadProc("glUseProgram"); + api->VertexAttribI3iv = loadProc("glVertexAttribI3iv"); + api->DrawElementsIndirect = loadProc("glDrawElementsIndirect"); + api->VertexAttrib4uiv = loadProc("glVertexAttrib4uiv"); + api->GetQueryObjectiv = loadProc("glGetQueryObjectiv"); + api->FramebufferRenderbuffer = loadProc("glFramebufferRenderbuffer"); + api->BlendEquationi = loadProc("glBlendEquationi"); + api->GetActiveSubroutineName = loadProc("glGetActiveSubroutineName"); + api->VertexAttrib2s = loadProc("glVertexAttrib2s"); + api->VertexAttribL1d = loadProc("glVertexAttribL1d"); + api->BindTextures = loadProc("glBindTextures"); + api->VertexAttrib3sv = loadProc("glVertexAttrib3sv"); + api->GetFloati_v = loadProc("glGetFloati_v"); + api->BeginTransformFeedback = loadProc("glBeginTransformFeedback"); + api->ClearStencil = loadProc("glClearStencil"); + api->Uniform3i = loadProc("glUniform3i"); + api->ValidateProgramPipeline = loadProc("glValidateProgramPipeline"); + api->ProgramUniformMatrix4x2fv = loadProc("glProgramUniformMatrix4x2fv"); + api->VertexAttribI4ui = loadProc("glVertexAttribI4ui"); + api->GetShaderiv = loadProc("glGetShaderiv"); + api->ReadnPixels = oc_glReadnPixels_noimpl; + api->UniformMatrix4x2fv = loadProc("glUniformMatrix4x2fv"); + api->GetShaderPrecisionFormat = loadProc("glGetShaderPrecisionFormat"); + api->ProgramUniformMatrix2x3fv = loadProc("glProgramUniformMatrix2x3fv"); + api->TexSubImage3D = loadProc("glTexSubImage3D"); + api->GetProgramResourceLocationIndex = loadProc("glGetProgramResourceLocationIndex"); + api->BlendFunc = loadProc("glBlendFunc"); + api->ProgramUniformMatrix3x4fv = loadProc("glProgramUniformMatrix3x4fv"); + api->Uniform3d = loadProc("glUniform3d"); + api->VertexAttrib1sv = loadProc("glVertexAttrib1sv"); + api->BindFragDataLocation = loadProc("glBindFragDataLocation"); + api->VertexAttrib4bv = loadProc("glVertexAttrib4bv"); + api->Uniform4iv = loadProc("glUniform4iv"); + api->ProgramUniform2ui = loadProc("glProgramUniform2ui"); + api->DrawArrays = loadProc("glDrawArrays"); + api->ProgramBinary = loadProc("glProgramBinary"); + api->VertexAttrib4f = loadProc("glVertexAttrib4f"); + api->VertexAttribP2uiv = loadProc("glVertexAttribP2uiv"); + api->UniformMatrix3fv = loadProc("glUniformMatrix3fv"); + api->Uniform2i = loadProc("glUniform2i"); + api->GetQueryObjectuiv = loadProc("glGetQueryObjectuiv"); + api->UniformBlockBinding = loadProc("glUniformBlockBinding"); + api->SampleCoverage = loadProc("glSampleCoverage"); + api->VertexAttrib4Nusv = loadProc("glVertexAttrib4Nusv"); + api->ProgramUniformMatrix2x4dv = loadProc("glProgramUniformMatrix2x4dv"); + api->Uniform3uiv = loadProc("glUniform3uiv"); + api->VertexAttrib1s = loadProc("glVertexAttrib1s"); + api->GetVertexAttribPointerv = loadProc("glGetVertexAttribPointerv"); + api->BlendBarrier = oc_glBlendBarrier_noimpl; + api->DrawRangeElements = loadProc("glDrawRangeElements"); + api->TexStorage3D = loadProc("glTexStorage3D"); + api->GetInternalformati64v = loadProc("glGetInternalformati64v"); + api->GetQueryObjecti64v = loadProc("glGetQueryObjecti64v"); + api->CompressedTexSubImage1D = loadProc("glCompressedTexSubImage1D"); + api->VertexAttrib3dv = loadProc("glVertexAttrib3dv"); + api->VertexBindingDivisor = loadProc("glVertexBindingDivisor"); + api->UseProgramStages = loadProc("glUseProgramStages"); + api->VertexAttribBinding = loadProc("glVertexAttribBinding"); + api->DebugMessageInsert = loadProc("glDebugMessageInsert"); + api->GetTexParameteriv = loadProc("glGetTexParameteriv"); + api->MultiDrawArraysIndirect = loadProc("glMultiDrawArraysIndirect"); + api->GetTexParameterfv = loadProc("glGetTexParameterfv"); + api->GetProgramPipelineInfoLog = loadProc("glGetProgramPipelineInfoLog"); + api->EndQuery = loadProc("glEndQuery"); + api->GetProgramResourceLocation = loadProc("glGetProgramResourceLocation"); + api->CompressedTexImage2D = loadProc("glCompressedTexImage2D"); + api->VertexAttribP2ui = loadProc("glVertexAttribP2ui"); + api->IsEnabledi = loadProc("glIsEnabledi"); + api->GetActiveAtomicCounterBufferiv = loadProc("glGetActiveAtomicCounterBufferiv"); + api->IsProgram = loadProc("glIsProgram"); + api->Uniform1dv = loadProc("glUniform1dv"); + api->TexParameteriv = loadProc("glTexParameteriv"); + api->Uniform2fv = loadProc("glUniform2fv"); + api->ReleaseShaderCompiler = loadProc("glReleaseShaderCompiler"); + api->CullFace = loadProc("glCullFace"); + api->VertexAttribI4i = loadProc("glVertexAttribI4i"); + api->GetProgramResourceIndex = loadProc("glGetProgramResourceIndex"); + api->ShaderBinary = loadProc("glShaderBinary"); + api->UniformMatrix3x2dv = loadProc("glUniformMatrix3x2dv"); + api->InvalidateFramebuffer = loadProc("glInvalidateFramebuffer"); + api->AttachShader = loadProc("glAttachShader"); + api->FlushMappedBufferRange = loadProc("glFlushMappedBufferRange"); + api->VertexAttribP3uiv = loadProc("glVertexAttribP3uiv"); + api->GetActiveUniformName = loadProc("glGetActiveUniformName"); + api->MapBuffer = loadProc("glMapBuffer"); + api->DrawBuffers = loadProc("glDrawBuffers"); + api->GetSynciv = loadProc("glGetSynciv"); + api->CopyTexSubImage2D = loadProc("glCopyTexSubImage2D"); + api->ObjectLabel = loadProc("glObjectLabel"); + api->BufferSubData = loadProc("glBufferSubData"); + api->Uniform2f = loadProc("glUniform2f"); + api->DebugMessageCallback = loadProc("glDebugMessageCallback"); + api->VertexAttribL4dv = loadProc("glVertexAttribL4dv"); + api->IsProgramPipeline = loadProc("glIsProgramPipeline"); + api->ResumeTransformFeedback = loadProc("glResumeTransformFeedback"); + api->VertexAttribI4iv = loadProc("glVertexAttribI4iv"); + api->GetShaderInfoLog = loadProc("glGetShaderInfoLog"); + api->GetIntegeri_v = loadProc("glGetIntegeri_v"); + api->BindVertexBuffer = loadProc("glBindVertexBuffer"); + api->BlendEquation = loadProc("glBlendEquation"); + api->VertexAttribL2dv = loadProc("glVertexAttribL2dv"); + api->VertexAttribI1ui = loadProc("glVertexAttribI1ui"); + api->VertexAttrib4Nsv = loadProc("glVertexAttrib4Nsv"); + api->VertexAttribL4d = loadProc("glVertexAttribL4d"); + api->CopyImageSubData = loadProc("glCopyImageSubData"); + api->GetFramebufferAttachmentParameteriv = loadProc("glGetFramebufferAttachmentParameteriv"); + api->VertexAttribL2d = loadProc("glVertexAttribL2d"); + api->GetSubroutineIndex = loadProc("glGetSubroutineIndex"); + api->VertexAttribI3uiv = loadProc("glVertexAttribI3uiv"); + api->VertexAttrib4iv = loadProc("glVertexAttrib4iv"); + api->BindVertexBuffers = loadProc("glBindVertexBuffers"); + api->ProgramUniformMatrix2x3dv = loadProc("glProgramUniformMatrix2x3dv"); + api->PrimitiveBoundingBox = oc_glPrimitiveBoundingBox_noimpl; + api->Scissor = loadProc("glScissor"); + api->ClientWaitSync = loadProc("glClientWaitSync"); + api->Uniform3ui = loadProc("glUniform3ui"); + api->VertexAttribP3ui = loadProc("glVertexAttribP3ui"); + api->Enable = loadProc("glEnable"); + api->StencilOpSeparate = loadProc("glStencilOpSeparate"); + api->UniformMatrix2x3dv = loadProc("glUniformMatrix2x3dv"); + api->ProgramUniformMatrix3dv = loadProc("glProgramUniformMatrix3dv"); + api->TexImage2DMultisample = loadProc("glTexImage2DMultisample"); + api->VertexAttrib4Nbv = loadProc("glVertexAttrib4Nbv"); + api->GetTexImage = loadProc("glGetTexImage"); + api->VertexAttrib4sv = loadProc("glVertexAttrib4sv"); + api->PixelStorei = loadProc("glPixelStorei"); + api->DepthMask = loadProc("glDepthMask"); + api->TexStorage2D = loadProc("glTexStorage2D"); + api->Clear = loadProc("glClear"); + api->UniformMatrix3x4dv = loadProc("glUniformMatrix3x4dv"); + api->DeleteTransformFeedbacks = loadProc("glDeleteTransformFeedbacks"); + api->MapBufferRange = loadProc("glMapBufferRange"); + api->MemoryBarrier = loadProc("glMemoryBarrier"); + api->ViewportIndexedf = loadProc("glViewportIndexedf"); + api->VertexAttrib3fv = loadProc("glVertexAttrib3fv"); + api->ObjectPtrLabel = loadProc("glObjectPtrLabel"); + api->TexStorage1D = loadProc("glTexStorage1D"); + api->CompressedTexImage3D = loadProc("glCompressedTexImage3D"); + api->VertexAttrib1fv = loadProc("glVertexAttrib1fv"); + api->VertexAttribPointer = loadProc("glVertexAttribPointer"); + api->GetQueryIndexediv = loadProc("glGetQueryIndexediv"); + api->CompileShader = loadProc("glCompileShader"); + api->ProgramUniform1i = loadProc("glProgramUniform1i"); + api->GetQueryiv = loadProc("glGetQueryiv"); + api->VertexAttribI1iv = loadProc("glVertexAttribI1iv"); + api->CopyTexImage2D = loadProc("glCopyTexImage2D"); + api->GetQueryObjectui64v = loadProc("glGetQueryObjectui64v"); + api->PointSize = loadProc("glPointSize"); + api->Disablei = loadProc("glDisablei"); + api->VertexAttribL1dv = loadProc("glVertexAttribL1dv"); + api->CreateShader = loadProc("glCreateShader"); + api->GetString = loadProc("glGetString"); + api->ViewportArrayv = loadProc("glViewportArrayv"); + api->ProgramUniform3d = loadProc("glProgramUniform3d"); + api->VertexAttrib4Nubv = loadProc("glVertexAttrib4Nubv"); + api->TexParameteri = loadProc("glTexParameteri"); + api->ProgramUniform4fv = loadProc("glProgramUniform4fv"); + api->GenerateMipmap = loadProc("glGenerateMipmap"); + api->CompressedTexSubImage3D = loadProc("glCompressedTexSubImage3D"); + api->Uniform3f = loadProc("glUniform3f"); + api->GetUniformIndices = loadProc("glGetUniformIndices"); + api->VertexAttribLPointer = loadProc("glVertexAttribLPointer"); + api->VertexAttribI2uiv = loadProc("glVertexAttribI2uiv"); + api->QueryCounter = loadProc("glQueryCounter"); + api->ActiveShaderProgram = loadProc("glActiveShaderProgram"); + api->Uniform1ui = loadProc("glUniform1ui"); + api->VertexAttribI1i = loadProc("glVertexAttribI1i"); + api->GetTexParameterIiv = loadProc("glGetTexParameterIiv"); + api->GetUniformfv = loadProc("glGetUniformfv"); + api->ProgramUniform2uiv = loadProc("glProgramUniform2uiv"); + api->GetError = loadProc("glGetError"); + api->GetActiveUniformBlockName = loadProc("glGetActiveUniformBlockName"); + api->TextureView = loadProc("glTextureView"); + api->GetnUniformiv = oc_glGetnUniformiv_noimpl; + api->ProgramUniform4dv = loadProc("glProgramUniform4dv"); + api->ViewportIndexedfv = loadProc("glViewportIndexedfv"); + api->Hint = loadProc("glHint"); + api->GetShaderSource = loadProc("glGetShaderSource"); + api->ProgramUniformMatrix4x3fv = loadProc("glProgramUniformMatrix4x3fv"); + api->Uniform1iv = loadProc("glUniform1iv"); + api->VertexAttribI4bv = loadProc("glVertexAttribI4bv"); + api->UniformMatrix4x2dv = loadProc("glUniformMatrix4x2dv"); + api->BufferStorage = loadProc("glBufferStorage"); + api->IsRenderbuffer = loadProc("glIsRenderbuffer"); + api->GetActiveSubroutineUniformName = loadProc("glGetActiveSubroutineUniformName"); + api->LinkProgram = loadProc("glLinkProgram"); + api->GetActiveUniformsiv = loadProc("glGetActiveUniformsiv"); + api->GetDebugMessageLog = loadProc("glGetDebugMessageLog"); + api->CopyTexSubImage3D = loadProc("glCopyTexSubImage3D"); + api->PointParameteri = loadProc("glPointParameteri"); + api->ProgramUniform3dv = loadProc("glProgramUniform3dv"); + api->CompressedTexImage1D = loadProc("glCompressedTexImage1D"); + api->UniformMatrix3x4fv = loadProc("glUniformMatrix3x4fv"); + api->GenSamplers = loadProc("glGenSamplers"); + api->GetCompressedTexImage = loadProc("glGetCompressedTexImage"); + api->DeleteQueries = loadProc("glDeleteQueries"); + api->GenProgramPipelines = loadProc("glGenProgramPipelines"); + api->DispatchComputeIndirect = loadProc("glDispatchComputeIndirect"); + api->VertexAttribIPointer = loadProc("glVertexAttribIPointer"); + api->CreateProgram = loadProc("glCreateProgram"); + api->ClearTexSubImage = loadProc("glClearTexSubImage"); + api->VertexAttrib4d = loadProc("glVertexAttrib4d"); + api->FrontFace = loadProc("glFrontFace"); + api->BindTransformFeedback = loadProc("glBindTransformFeedback"); + api->GetProgramStageiv = loadProc("glGetProgramStageiv"); + api->SamplerParameterIiv = loadProc("glSamplerParameterIiv"); + api->GetInteger64v = loadProc("glGetInteger64v"); + api->CreateShaderProgramv = loadProc("glCreateShaderProgramv"); + api->BindBuffersRange = loadProc("glBindBuffersRange"); + api->Uniform3fv = loadProc("glUniform3fv"); + api->ProgramUniformMatrix4fv = loadProc("glProgramUniformMatrix4fv"); + api->BindBuffersBase = loadProc("glBindBuffersBase"); + api->ClearBufferfi = loadProc("glClearBufferfi"); + api->FramebufferTexture3D = loadProc("glFramebufferTexture3D"); + api->Disable = loadProc("glDisable"); + api->ProgramUniform1iv = loadProc("glProgramUniform1iv"); + api->VertexAttribI2iv = loadProc("glVertexAttribI2iv"); + api->DepthRangeIndexed = loadProc("glDepthRangeIndexed"); + api->PatchParameteri = loadProc("glPatchParameteri"); + api->GetUniformBlockIndex = loadProc("glGetUniformBlockIndex"); + api->MultiDrawArrays = loadProc("glMultiDrawArrays"); + api->VertexAttribI4ubv = loadProc("glVertexAttribI4ubv"); + api->BindBuffer = loadProc("glBindBuffer"); + api->VertexAttribI3i = loadProc("glVertexAttribI3i"); + api->GetDoublev = loadProc("glGetDoublev"); + api->DrawTransformFeedbackStream = loadProc("glDrawTransformFeedbackStream"); + api->VertexAttribI4uiv = loadProc("glVertexAttribI4uiv"); + api->RenderbufferStorageMultisample = loadProc("glRenderbufferStorageMultisample"); + api->VertexAttribL3dv = loadProc("glVertexAttribL3dv"); + api->StencilMaskSeparate = loadProc("glStencilMaskSeparate"); + api->ProgramUniform1d = loadProc("glProgramUniform1d"); + api->Viewport = loadProc("glViewport"); + api->VertexAttribP1ui = loadProc("glVertexAttribP1ui"); + api->VertexAttrib4dv = loadProc("glVertexAttrib4dv"); + api->GenQueries = loadProc("glGenQueries"); + api->TexParameterIiv = loadProc("glTexParameterIiv"); + api->ProgramUniform2d = loadProc("glProgramUniform2d"); + api->ProgramUniform1uiv = loadProc("glProgramUniform1uiv"); + api->VertexAttrib4Nub = loadProc("glVertexAttrib4Nub"); + api->IsVertexArray = loadProc("glIsVertexArray"); + api->ProgramUniform3f = loadProc("glProgramUniform3f"); + api->ProgramUniform3iv = loadProc("glProgramUniform3iv"); + api->GetProgramBinary = loadProc("glGetProgramBinary"); + api->BindRenderbuffer = loadProc("glBindRenderbuffer"); + api->BindFragDataLocationIndexed = loadProc("glBindFragDataLocationIndexed"); + api->GetSamplerParameterIiv = loadProc("glGetSamplerParameterIiv"); + api->VertexAttribDivisor = loadProc("glVertexAttribDivisor"); + api->ProgramUniformMatrix3x2dv = loadProc("glProgramUniformMatrix3x2dv"); + api->FramebufferParameteri = loadProc("glFramebufferParameteri"); + api->GenTransformFeedbacks = loadProc("glGenTransformFeedbacks"); + api->DeleteSync = loadProc("glDeleteSync"); + api->ProgramUniform1ui = loadProc("glProgramUniform1ui"); + api->TexSubImage1D = loadProc("glTexSubImage1D"); + api->ClearDepthf = loadProc("glClearDepthf"); + api->ReadPixels = loadProc("glReadPixels"); + api->VertexAttribI2i = loadProc("glVertexAttribI2i"); + api->Finish = loadProc("glFinish"); + api->LineWidth = loadProc("glLineWidth"); + api->DeleteShader = loadProc("glDeleteShader"); + api->IsSampler = loadProc("glIsSampler"); + api->ProgramUniformMatrix4dv = loadProc("glProgramUniformMatrix4dv"); + api->TransformFeedbackVaryings = loadProc("glTransformFeedbackVaryings"); + api->BeginConditionalRender = loadProc("glBeginConditionalRender"); + api->BindSamplers = loadProc("glBindSamplers"); + api->DeleteProgramPipelines = loadProc("glDeleteProgramPipelines"); + api->ColorMask = loadProc("glColorMask"); + api->TexParameterfv = loadProc("glTexParameterfv"); + api->PushDebugGroup = loadProc("glPushDebugGroup"); + api->ClearBufferfv = loadProc("glClearBufferfv"); + api->IsEnabled = loadProc("glIsEnabled"); + api->VertexAttrib2f = loadProc("glVertexAttrib2f"); + api->ProgramUniform2f = loadProc("glProgramUniform2f"); + api->GetSamplerParameterIuiv = loadProc("glGetSamplerParameterIuiv"); + api->GetInteger64i_v = loadProc("glGetInteger64i_v"); + api->Uniform2dv = loadProc("glUniform2dv"); + api->GetBufferSubData = loadProc("glGetBufferSubData"); + api->MultiDrawElementsIndirect = loadProc("glMultiDrawElementsIndirect"); + api->ProgramParameteri = loadProc("glProgramParameteri"); + api->VertexAttribP4ui = loadProc("glVertexAttribP4ui"); + api->SamplerParameterfv = loadProc("glSamplerParameterfv"); + api->PointParameterf = loadProc("glPointParameterf"); + api->UniformMatrix2x4fv = loadProc("glUniformMatrix2x4fv"); + api->GenBuffers = loadProc("glGenBuffers"); + api->ProgramUniform2dv = loadProc("glProgramUniform2dv"); + api->VertexAttribFormat = loadProc("glVertexAttribFormat"); + api->TexSubImage2D = loadProc("glTexSubImage2D"); + api->VertexAttrib4ubv = loadProc("glVertexAttrib4ubv"); + api->GetGraphicsResetStatus = oc_glGetGraphicsResetStatus_noimpl; + api->GetProgramInterfaceiv = loadProc("glGetProgramInterfaceiv"); + api->VertexAttribIFormat = loadProc("glVertexAttribIFormat"); + api->GetnUniformfv = oc_glGetnUniformfv_noimpl; + api->DeleteProgram = loadProc("glDeleteProgram"); + api->ClampColor = loadProc("glClampColor"); + api->DrawElementsInstancedBaseVertexBaseInstance = loadProc("glDrawElementsInstancedBaseVertexBaseInstance"); + api->DrawElements = loadProc("glDrawElements"); + api->DebugMessageControl = loadProc("glDebugMessageControl"); + api->GetRenderbufferParameteriv = loadProc("glGetRenderbufferParameteriv"); + api->DetachShader = loadProc("glDetachShader"); + api->GenFramebuffers = loadProc("glGenFramebuffers"); + api->ProvokingVertex = loadProc("glProvokingVertex"); + api->SampleMaski = loadProc("glSampleMaski"); + api->EndQueryIndexed = loadProc("glEndQueryIndexed"); + api->ProgramUniform1f = loadProc("glProgramUniform1f"); + api->BindFramebuffer = loadProc("glBindFramebuffer"); + api->BeginQueryIndexed = loadProc("glBeginQueryIndexed"); + api->UniformSubroutinesuiv = loadProc("glUniformSubroutinesuiv"); + api->GetUniformiv = loadProc("glGetUniformiv"); + api->FramebufferTexture = loadProc("glFramebufferTexture"); + api->PointParameterfv = loadProc("glPointParameterfv"); + api->IsTransformFeedback = loadProc("glIsTransformFeedback"); + api->CheckFramebufferStatus = loadProc("glCheckFramebufferStatus"); + api->ShaderSource = loadProc("glShaderSource"); + api->UniformMatrix2x4dv = loadProc("glUniformMatrix2x4dv"); + api->BindImageTextures = loadProc("glBindImageTextures"); + api->CopyTexImage1D = loadProc("glCopyTexImage1D"); + api->UniformMatrix3dv = loadProc("glUniformMatrix3dv"); + api->ProgramUniform1dv = loadProc("glProgramUniform1dv"); + api->BlitFramebuffer = loadProc("glBlitFramebuffer"); + api->PopDebugGroup = loadProc("glPopDebugGroup"); + api->TexParameterIuiv = loadProc("glTexParameterIuiv"); + api->VertexAttrib2d = loadProc("glVertexAttrib2d"); + api->TexImage1D = loadProc("glTexImage1D"); + api->GetObjectPtrLabel = loadProc("glGetObjectPtrLabel"); + api->StencilMask = loadProc("glStencilMask"); + api->BeginQuery = loadProc("glBeginQuery"); + api->UniformMatrix4fv = loadProc("glUniformMatrix4fv"); + api->IsSync = loadProc("glIsSync"); + api->Uniform3dv = loadProc("glUniform3dv"); + api->ProgramUniform2fv = loadProc("glProgramUniform2fv"); + api->VertexAttribI4sv = loadProc("glVertexAttribI4sv"); + api->ScissorArrayv = loadProc("glScissorArrayv"); + api->VertexAttribP1uiv = loadProc("glVertexAttribP1uiv"); + api->Uniform2uiv = loadProc("glUniform2uiv"); + api->DeleteBuffers = loadProc("glDeleteBuffers"); + api->ProgramUniform3ui = loadProc("glProgramUniform3ui"); + api->FramebufferTextureLayer = loadProc("glFramebufferTextureLayer"); + api->EndTransformFeedback = loadProc("glEndTransformFeedback"); + api->BlendFuncSeparatei = loadProc("glBlendFuncSeparatei"); + api->DrawTransformFeedbackInstanced = loadProc("glDrawTransformFeedbackInstanced"); + api->DrawRangeElementsBaseVertex = loadProc("glDrawRangeElementsBaseVertex"); + api->VertexAttrib1f = loadProc("glVertexAttrib1f"); + api->GetUniformSubroutineuiv = loadProc("glGetUniformSubroutineuiv"); + api->DisableVertexAttribArray = loadProc("glDisableVertexAttribArray"); + api->ProgramUniformMatrix3x2fv = loadProc("glProgramUniformMatrix3x2fv"); + api->VertexAttribI4usv = loadProc("glVertexAttribI4usv"); + api->GetObjectLabel = loadProc("glGetObjectLabel"); + api->BindAttribLocation = loadProc("glBindAttribLocation"); + api->Uniform1f = loadProc("glUniform1f"); + api->GetUniformdv = loadProc("glGetUniformdv"); + api->GetUniformLocation = loadProc("glGetUniformLocation"); + api->GetSubroutineUniformLocation = loadProc("glGetSubroutineUniformLocation"); + api->GetTexParameterIuiv = loadProc("glGetTexParameterIuiv"); + api->SamplerParameterf = loadProc("glSamplerParameterf"); + api->VertexAttribL3d = loadProc("glVertexAttribL3d"); + api->TexImage3DMultisample = loadProc("glTexImage3DMultisample"); + api->TexImage3D = loadProc("glTexImage3D"); + api->RenderbufferStorage = loadProc("glRenderbufferStorage"); + api->EnableVertexAttribArray = loadProc("glEnableVertexAttribArray"); + api->VertexAttribP4uiv = loadProc("glVertexAttribP4uiv"); + api->Uniform4d = loadProc("glUniform4d"); + api->VertexAttrib4s = loadProc("glVertexAttrib4s"); + api->DrawElementsInstancedBaseVertex = loadProc("glDrawElementsInstancedBaseVertex"); + api->VertexAttrib3s = loadProc("glVertexAttrib3s"); + api->ProgramUniform2iv = loadProc("glProgramUniform2iv"); + api->StencilFuncSeparate = loadProc("glStencilFuncSeparate"); + api->DeleteFramebuffers = loadProc("glDeleteFramebuffers"); + api->DepthRange = loadProc("glDepthRange"); + api->UniformMatrix3x2fv = loadProc("glUniformMatrix3x2fv"); + api->ProgramUniformMatrix2dv = loadProc("glProgramUniformMatrix2dv"); + api->ShaderStorageBlockBinding = loadProc("glShaderStorageBlockBinding"); + api->ClearDepth = loadProc("glClearDepth"); + api->VertexAttrib2dv = loadProc("glVertexAttrib2dv"); + api->SamplerParameterIuiv = loadProc("glSamplerParameterIuiv"); + api->GetVertexAttribLdv = loadProc("glGetVertexAttribLdv"); + api->ProgramUniformMatrix3x4dv = loadProc("glProgramUniformMatrix3x4dv"); + api->DepthRangeArrayv = loadProc("glDepthRangeArrayv"); + api->GetActiveUniform = loadProc("glGetActiveUniform"); + api->PatchParameterfv = loadProc("glPatchParameterfv"); + api->InvalidateTexImage = loadProc("glInvalidateTexImage"); + api->VertexAttrib3f = loadProc("glVertexAttrib3f"); + api->ProgramUniform4iv = loadProc("glProgramUniform4iv"); + api->ProgramUniform4d = loadProc("glProgramUniform4d"); + api->IsFramebuffer = loadProc("glIsFramebuffer"); + api->PixelStoref = loadProc("glPixelStoref"); + api->ProgramUniform4uiv = loadProc("glProgramUniform4uiv"); + api->ProgramUniformMatrix4x2dv = loadProc("glProgramUniformMatrix4x2dv"); + api->FenceSync = loadProc("glFenceSync"); + api->GetBufferParameteri64v = loadProc("glGetBufferParameteri64v"); + api->StencilOp = loadProc("glStencilOp"); + api->ClearBufferData = loadProc("glClearBufferData"); + api->GetnUniformuiv = oc_glGetnUniformuiv_noimpl; + api->GetProgramResourceiv = loadProc("glGetProgramResourceiv"); + api->GetVertexAttribdv = loadProc("glGetVertexAttribdv"); + api->GetTransformFeedbackVarying = loadProc("glGetTransformFeedbackVarying"); + api->VertexAttrib2fv = loadProc("glVertexAttrib2fv"); + api->GetBooleani_v = loadProc("glGetBooleani_v"); + api->ColorMaski = loadProc("glColorMaski"); + api->InvalidateBufferSubData = loadProc("glInvalidateBufferSubData"); + api->UniformMatrix4dv = loadProc("glUniformMatrix4dv"); + api->IsQuery = loadProc("glIsQuery"); + api->Uniform4ui = loadProc("glUniform4ui"); + api->Uniform4i = loadProc("glUniform4i"); + api->GetSamplerParameteriv = loadProc("glGetSamplerParameteriv"); + api->MultiDrawElementsBaseVertex = loadProc("glMultiDrawElementsBaseVertex"); + api->VertexAttribI1uiv = loadProc("glVertexAttribI1uiv"); + api->GetIntegerv = loadProc("glGetIntegerv"); + api->UniformMatrix2x3fv = loadProc("glUniformMatrix2x3fv"); + api->TexImage2D = loadProc("glTexImage2D"); + api->GetAttachedShaders = loadProc("glGetAttachedShaders"); + api->Uniform2d = loadProc("glUniform2d"); + api->MemoryBarrierByRegion = oc_glMemoryBarrierByRegion_noimpl; + api->UniformMatrix2fv = loadProc("glUniformMatrix2fv"); + api->PrimitiveRestartIndex = loadProc("glPrimitiveRestartIndex"); + api->GetVertexAttribiv = loadProc("glGetVertexAttribiv"); + api->GetAttribLocation = loadProc("glGetAttribLocation"); + api->TexStorage2DMultisample = loadProc("glTexStorage2DMultisample"); + api->CompressedTexSubImage2D = loadProc("glCompressedTexSubImage2D"); + api->GetVertexAttribfv = loadProc("glGetVertexAttribfv"); + api->GetBufferParameteriv = loadProc("glGetBufferParameteriv"); + api->TexParameterf = loadProc("glTexParameterf"); + api->FramebufferTexture2D = loadProc("glFramebufferTexture2D"); + api->GetActiveAttrib = loadProc("glGetActiveAttrib"); + api->InvalidateTexSubImage = loadProc("glInvalidateTexSubImage"); + api->DeleteVertexArrays = loadProc("glDeleteVertexArrays"); + api->VertexAttribI2ui = loadProc("glVertexAttribI2ui"); + api->PointParameteriv = loadProc("glPointParameteriv"); + api->GetPointerv = loadProc("glGetPointerv"); + api->Enablei = loadProc("glEnablei"); + api->BindBufferRange = loadProc("glBindBufferRange"); + api->DrawArraysInstanced = loadProc("glDrawArraysInstanced"); + api->DeleteTextures = loadProc("glDeleteTextures"); + api->VertexAttrib4Niv = loadProc("glVertexAttrib4Niv"); + api->MultiDrawElements = loadProc("glMultiDrawElements"); + api->GetProgramiv = loadProc("glGetProgramiv"); + api->DepthFunc = loadProc("glDepthFunc"); + api->GenTextures = loadProc("glGenTextures"); + api->GetInternalformativ = loadProc("glGetInternalformativ"); + api->ProgramUniform3i = loadProc("glProgramUniform3i"); + api->ScissorIndexed = loadProc("glScissorIndexed"); + api->VertexAttrib2sv = loadProc("glVertexAttrib2sv"); + api->TexStorage3DMultisample = loadProc("glTexStorage3DMultisample"); + api->Uniform2iv = loadProc("glUniform2iv"); + api->DrawArraysInstancedBaseInstance = loadProc("glDrawArraysInstancedBaseInstance"); + api->VertexAttribI3ui = loadProc("glVertexAttribI3ui"); + api->DeleteSamplers = loadProc("glDeleteSamplers"); + api->GenVertexArrays = loadProc("glGenVertexArrays"); + api->GetFramebufferParameteriv = loadProc("glGetFramebufferParameteriv"); + api->PolygonMode = loadProc("glPolygonMode"); + api->ProgramUniformMatrix2x4fv = loadProc("glProgramUniformMatrix2x4fv"); + api->GetProgramResourceName = loadProc("glGetProgramResourceName"); + api->SamplerParameteriv = loadProc("glSamplerParameteriv"); + api->GetActiveSubroutineUniformiv = loadProc("glGetActiveSubroutineUniformiv"); + api->GetStringi = loadProc("glGetStringi"); + api->VertexAttribLFormat = loadProc("glVertexAttribLFormat"); + api->VertexAttrib3d = loadProc("glVertexAttrib3d"); + api->BindVertexArray = loadProc("glBindVertexArray"); + api->UnmapBuffer = loadProc("glUnmapBuffer"); + api->DrawElementsInstancedBaseInstance = loadProc("glDrawElementsInstancedBaseInstance"); + api->Uniform4uiv = loadProc("glUniform4uiv"); + api->FramebufferTexture1D = loadProc("glFramebufferTexture1D"); + api->DrawTransformFeedbackStreamInstanced = loadProc("glDrawTransformFeedbackStreamInstanced"); + api->StencilFunc = loadProc("glStencilFunc"); + api->ValidateProgram = loadProc("glValidateProgram"); + api->Flush = loadProc("glFlush"); + api->ProgramUniform3uiv = loadProc("glProgramUniform3uiv"); + api->DeleteRenderbuffers = loadProc("glDeleteRenderbuffers"); + api->VertexAttrib4fv = loadProc("glVertexAttrib4fv"); + api->UniformMatrix2dv = loadProc("glUniformMatrix2dv"); + api->GetFragDataIndex = loadProc("glGetFragDataIndex"); + api->Uniform3iv = loadProc("glUniform3iv"); + api->MinSampleShading = loadProc("glMinSampleShading"); + api->GetBooleanv = loadProc("glGetBooleanv"); + api->GetMultisamplefv = loadProc("glGetMultisamplefv"); + api->GetVertexAttribIuiv = loadProc("glGetVertexAttribIuiv"); + api->GetProgramInfoLog = loadProc("glGetProgramInfoLog"); + api->Uniform4fv = loadProc("glUniform4fv"); + api->DrawBuffer = loadProc("glDrawBuffer"); + api->Uniform1i = loadProc("glUniform1i"); + api->ProgramUniform4ui = loadProc("glProgramUniform4ui"); + api->ProgramUniformMatrix3fv = loadProc("glProgramUniformMatrix3fv"); + api->BlendEquationSeparate = loadProc("glBlendEquationSeparate"); + api->BindProgramPipeline = loadProc("glBindProgramPipeline"); + api->GetDoublei_v = loadProc("glGetDoublei_v"); + api->BufferData = loadProc("glBufferData"); + api->ClearColor = loadProc("glClearColor"); + api->ProgramUniform4i = loadProc("glProgramUniform4i"); + api->GetTexLevelParameteriv = loadProc("glGetTexLevelParameteriv"); + api->GetActiveUniformBlockiv = loadProc("glGetActiveUniformBlockiv"); + api->ProgramUniform1fv = loadProc("glProgramUniform1fv"); + api->PauseTransformFeedback = loadProc("glPauseTransformFeedback"); + api->GetBufferPointerv = loadProc("glGetBufferPointerv"); + api->InvalidateSubFramebuffer = loadProc("glInvalidateSubFramebuffer"); + api->ScissorIndexedv = loadProc("glScissorIndexedv"); + api->Uniform2ui = loadProc("glUniform2ui"); + api->BindTexture = loadProc("glBindTexture"); + api->DrawElementsInstanced = loadProc("glDrawElementsInstanced"); + api->ProgramUniform4f = loadProc("glProgramUniform4f"); + api->BindBufferBase = loadProc("glBindBufferBase"); + api->IsShader = loadProc("glIsShader"); + api->ClearBufferSubData = loadProc("glClearBufferSubData"); + api->VertexAttrib4Nuiv = loadProc("glVertexAttrib4Nuiv"); + api->DrawArraysIndirect = loadProc("glDrawArraysIndirect"); + api->VertexAttrib4usv = loadProc("glVertexAttrib4usv"); + api->Uniform1d = loadProc("glUniform1d"); + api->ClearTexImage = loadProc("glClearTexImage"); + api->Uniform1uiv = loadProc("glUniform1uiv"); + api->BindSampler = loadProc("glBindSampler"); + api->GetTexLevelParameterfv = loadProc("glGetTexLevelParameterfv"); + api->ClearBufferiv = loadProc("glClearBufferiv"); + api->LogicOp = loadProc("glLogicOp"); + api->ActiveTexture = loadProc("glActiveTexture"); + api->GetFragDataLocation = loadProc("glGetFragDataLocation"); + api->BlendColor = loadProc("glBlendColor"); + api->UniformMatrix4x3fv = loadProc("glUniformMatrix4x3fv"); + api->ProgramUniform3fv = loadProc("glProgramUniform3fv"); + api->Uniform1fv = loadProc("glUniform1fv"); + api->DrawElementsBaseVertex = loadProc("glDrawElementsBaseVertex"); + api->Uniform4f = loadProc("glUniform4f"); + api->BlendEquationSeparatei = loadProc("glBlendEquationSeparatei"); + api->BlendFuncSeparate = loadProc("glBlendFuncSeparate"); + api->ClearBufferuiv = loadProc("glClearBufferuiv"); + api->CopyTexSubImage1D = loadProc("glCopyTexSubImage1D"); + api->DrawTransformFeedback = loadProc("glDrawTransformFeedback"); + api->ReadBuffer = loadProc("glReadBuffer"); + api->CopyBufferSubData = loadProc("glCopyBufferSubData"); + api->GetUniformuiv = loadProc("glGetUniformuiv"); + api->PolygonOffset = loadProc("glPolygonOffset"); + api->DispatchCompute = loadProc("glDispatchCompute"); + api->BindImageTexture = loadProc("glBindImageTexture"); + api->UniformMatrix4x3dv = loadProc("glUniformMatrix4x3dv"); + api->GenRenderbuffers = loadProc("glGenRenderbuffers"); } void oc_gl_load_gles31(oc_gl_api* api, oc_gl_load_proc loadProc) { - api->name = "gles31"; - api->GetFloatv = loadProc("glGetFloatv"); - api->TexBufferRange = oc_glTexBufferRange_noimpl; - api->IsBuffer = loadProc("glIsBuffer"); - api->IsTexture = loadProc("glIsTexture"); - api->DepthRangef = loadProc("glDepthRangef"); - api->EndConditionalRender = oc_glEndConditionalRender_noimpl; - api->BlendFunci = oc_glBlendFunci_noimpl; - api->GetProgramPipelineiv = loadProc("glGetProgramPipelineiv"); - api->WaitSync = loadProc("glWaitSync"); - api->ProgramUniformMatrix2fv = loadProc("glProgramUniformMatrix2fv"); - api->ProgramUniformMatrix4x3dv = oc_glProgramUniformMatrix4x3dv_noimpl; - api->VertexAttrib1dv = oc_glVertexAttrib1dv_noimpl; - api->SamplerParameteri = loadProc("glSamplerParameteri"); - api->GetVertexAttribIiv = loadProc("glGetVertexAttribIiv"); - api->GetSamplerParameterfv = loadProc("glGetSamplerParameterfv"); - api->VertexAttrib1d = oc_glVertexAttrib1d_noimpl; - api->TexBuffer = oc_glTexBuffer_noimpl; - api->InvalidateBufferData = oc_glInvalidateBufferData_noimpl; - api->ProgramUniform2i = loadProc("glProgramUniform2i"); - api->Uniform4dv = oc_glUniform4dv_noimpl; - api->UseProgram = loadProc("glUseProgram"); - api->VertexAttribI3iv = oc_glVertexAttribI3iv_noimpl; - api->DrawElementsIndirect = loadProc("glDrawElementsIndirect"); - api->VertexAttrib4uiv = oc_glVertexAttrib4uiv_noimpl; - api->GetQueryObjectiv = oc_glGetQueryObjectiv_noimpl; - api->FramebufferRenderbuffer = loadProc("glFramebufferRenderbuffer"); - api->BlendEquationi = oc_glBlendEquationi_noimpl; - api->GetActiveSubroutineName = oc_glGetActiveSubroutineName_noimpl; - api->VertexAttrib2s = oc_glVertexAttrib2s_noimpl; - api->VertexAttribL1d = oc_glVertexAttribL1d_noimpl; - api->BindTextures = oc_glBindTextures_noimpl; - api->VertexAttrib3sv = oc_glVertexAttrib3sv_noimpl; - api->GetFloati_v = oc_glGetFloati_v_noimpl; - api->BeginTransformFeedback = loadProc("glBeginTransformFeedback"); - api->ClearStencil = loadProc("glClearStencil"); - api->Uniform3i = loadProc("glUniform3i"); - api->ValidateProgramPipeline = loadProc("glValidateProgramPipeline"); - api->ProgramUniformMatrix4x2fv = loadProc("glProgramUniformMatrix4x2fv"); - api->VertexAttribI4ui = loadProc("glVertexAttribI4ui"); - api->GetShaderiv = loadProc("glGetShaderiv"); - api->ReadnPixels = oc_glReadnPixels_noimpl; - api->UniformMatrix4x2fv = loadProc("glUniformMatrix4x2fv"); - api->GetShaderPrecisionFormat = loadProc("glGetShaderPrecisionFormat"); - api->ProgramUniformMatrix2x3fv = loadProc("glProgramUniformMatrix2x3fv"); - api->TexSubImage3D = loadProc("glTexSubImage3D"); - api->GetProgramResourceLocationIndex = oc_glGetProgramResourceLocationIndex_noimpl; - api->BlendFunc = loadProc("glBlendFunc"); - api->ProgramUniformMatrix3x4fv = loadProc("glProgramUniformMatrix3x4fv"); - api->Uniform3d = oc_glUniform3d_noimpl; - api->VertexAttrib1sv = oc_glVertexAttrib1sv_noimpl; - api->BindFragDataLocation = oc_glBindFragDataLocation_noimpl; - api->VertexAttrib4bv = oc_glVertexAttrib4bv_noimpl; - api->Uniform4iv = loadProc("glUniform4iv"); - api->ProgramUniform2ui = loadProc("glProgramUniform2ui"); - api->DrawArrays = loadProc("glDrawArrays"); - api->ProgramBinary = loadProc("glProgramBinary"); - api->VertexAttrib4f = loadProc("glVertexAttrib4f"); - api->VertexAttribP2uiv = oc_glVertexAttribP2uiv_noimpl; - api->UniformMatrix3fv = loadProc("glUniformMatrix3fv"); - api->Uniform2i = loadProc("glUniform2i"); - api->GetQueryObjectuiv = loadProc("glGetQueryObjectuiv"); - api->UniformBlockBinding = loadProc("glUniformBlockBinding"); - api->SampleCoverage = loadProc("glSampleCoverage"); - api->VertexAttrib4Nusv = oc_glVertexAttrib4Nusv_noimpl; - api->ProgramUniformMatrix2x4dv = oc_glProgramUniformMatrix2x4dv_noimpl; - api->Uniform3uiv = loadProc("glUniform3uiv"); - api->VertexAttrib1s = oc_glVertexAttrib1s_noimpl; - api->GetVertexAttribPointerv = loadProc("glGetVertexAttribPointerv"); - api->BlendBarrier = oc_glBlendBarrier_noimpl; - api->DrawRangeElements = loadProc("glDrawRangeElements"); - api->TexStorage3D = loadProc("glTexStorage3D"); - api->GetInternalformati64v = oc_glGetInternalformati64v_noimpl; - api->GetQueryObjecti64v = oc_glGetQueryObjecti64v_noimpl; - api->CompressedTexSubImage1D = oc_glCompressedTexSubImage1D_noimpl; - api->VertexAttrib3dv = oc_glVertexAttrib3dv_noimpl; - api->VertexBindingDivisor = loadProc("glVertexBindingDivisor"); - api->UseProgramStages = loadProc("glUseProgramStages"); - api->VertexAttribBinding = loadProc("glVertexAttribBinding"); - api->DebugMessageInsert = oc_glDebugMessageInsert_noimpl; - api->GetTexParameteriv = loadProc("glGetTexParameteriv"); - api->MultiDrawArraysIndirect = oc_glMultiDrawArraysIndirect_noimpl; - api->GetTexParameterfv = loadProc("glGetTexParameterfv"); - api->GetProgramPipelineInfoLog = loadProc("glGetProgramPipelineInfoLog"); - api->EndQuery = loadProc("glEndQuery"); - api->GetProgramResourceLocation = loadProc("glGetProgramResourceLocation"); - api->CompressedTexImage2D = loadProc("glCompressedTexImage2D"); - api->VertexAttribP2ui = oc_glVertexAttribP2ui_noimpl; - api->IsEnabledi = oc_glIsEnabledi_noimpl; - api->GetActiveAtomicCounterBufferiv = oc_glGetActiveAtomicCounterBufferiv_noimpl; - api->IsProgram = loadProc("glIsProgram"); - api->Uniform1dv = oc_glUniform1dv_noimpl; - api->TexParameteriv = loadProc("glTexParameteriv"); - api->Uniform2fv = loadProc("glUniform2fv"); - api->ReleaseShaderCompiler = loadProc("glReleaseShaderCompiler"); - api->CullFace = loadProc("glCullFace"); - api->VertexAttribI4i = loadProc("glVertexAttribI4i"); - api->GetProgramResourceIndex = loadProc("glGetProgramResourceIndex"); - api->ShaderBinary = loadProc("glShaderBinary"); - api->UniformMatrix3x2dv = oc_glUniformMatrix3x2dv_noimpl; - api->InvalidateFramebuffer = loadProc("glInvalidateFramebuffer"); - api->AttachShader = loadProc("glAttachShader"); - api->FlushMappedBufferRange = loadProc("glFlushMappedBufferRange"); - api->VertexAttribP3uiv = oc_glVertexAttribP3uiv_noimpl; - api->GetActiveUniformName = oc_glGetActiveUniformName_noimpl; - api->MapBuffer = oc_glMapBuffer_noimpl; - api->DrawBuffers = loadProc("glDrawBuffers"); - api->GetSynciv = loadProc("glGetSynciv"); - api->CopyTexSubImage2D = loadProc("glCopyTexSubImage2D"); - api->ObjectLabel = oc_glObjectLabel_noimpl; - api->BufferSubData = loadProc("glBufferSubData"); - api->Uniform2f = loadProc("glUniform2f"); - api->DebugMessageCallback = oc_glDebugMessageCallback_noimpl; - api->VertexAttribL4dv = oc_glVertexAttribL4dv_noimpl; - api->IsProgramPipeline = loadProc("glIsProgramPipeline"); - api->ResumeTransformFeedback = loadProc("glResumeTransformFeedback"); - api->VertexAttribI4iv = loadProc("glVertexAttribI4iv"); - api->GetShaderInfoLog = loadProc("glGetShaderInfoLog"); - api->GetIntegeri_v = loadProc("glGetIntegeri_v"); - api->BindVertexBuffer = loadProc("glBindVertexBuffer"); - api->BlendEquation = loadProc("glBlendEquation"); - api->VertexAttribL2dv = oc_glVertexAttribL2dv_noimpl; - api->VertexAttribI1ui = oc_glVertexAttribI1ui_noimpl; - api->VertexAttrib4Nsv = oc_glVertexAttrib4Nsv_noimpl; - api->VertexAttribL4d = oc_glVertexAttribL4d_noimpl; - api->CopyImageSubData = oc_glCopyImageSubData_noimpl; - api->GetFramebufferAttachmentParameteriv = loadProc("glGetFramebufferAttachmentParameteriv"); - api->VertexAttribL2d = oc_glVertexAttribL2d_noimpl; - api->GetSubroutineIndex = oc_glGetSubroutineIndex_noimpl; - api->VertexAttribI3uiv = oc_glVertexAttribI3uiv_noimpl; - api->VertexAttrib4iv = oc_glVertexAttrib4iv_noimpl; - api->BindVertexBuffers = oc_glBindVertexBuffers_noimpl; - api->ProgramUniformMatrix2x3dv = oc_glProgramUniformMatrix2x3dv_noimpl; - api->PrimitiveBoundingBox = oc_glPrimitiveBoundingBox_noimpl; - api->Scissor = loadProc("glScissor"); - api->ClientWaitSync = loadProc("glClientWaitSync"); - api->Uniform3ui = loadProc("glUniform3ui"); - api->VertexAttribP3ui = oc_glVertexAttribP3ui_noimpl; - api->Enable = loadProc("glEnable"); - api->StencilOpSeparate = loadProc("glStencilOpSeparate"); - api->UniformMatrix2x3dv = oc_glUniformMatrix2x3dv_noimpl; - api->ProgramUniformMatrix3dv = oc_glProgramUniformMatrix3dv_noimpl; - api->TexImage2DMultisample = oc_glTexImage2DMultisample_noimpl; - api->VertexAttrib4Nbv = oc_glVertexAttrib4Nbv_noimpl; - api->GetTexImage = oc_glGetTexImage_noimpl; - api->VertexAttrib4sv = oc_glVertexAttrib4sv_noimpl; - api->PixelStorei = loadProc("glPixelStorei"); - api->DepthMask = loadProc("glDepthMask"); - api->TexStorage2D = loadProc("glTexStorage2D"); - api->Clear = loadProc("glClear"); - api->UniformMatrix3x4dv = oc_glUniformMatrix3x4dv_noimpl; - api->DeleteTransformFeedbacks = loadProc("glDeleteTransformFeedbacks"); - api->MapBufferRange = loadProc("glMapBufferRange"); - api->MemoryBarrier = loadProc("glMemoryBarrier"); - api->ViewportIndexedf = oc_glViewportIndexedf_noimpl; - api->VertexAttrib3fv = loadProc("glVertexAttrib3fv"); - api->ObjectPtrLabel = oc_glObjectPtrLabel_noimpl; - api->TexStorage1D = oc_glTexStorage1D_noimpl; - api->CompressedTexImage3D = loadProc("glCompressedTexImage3D"); - api->VertexAttrib1fv = loadProc("glVertexAttrib1fv"); - api->VertexAttribPointer = loadProc("glVertexAttribPointer"); - api->GetQueryIndexediv = oc_glGetQueryIndexediv_noimpl; - api->CompileShader = loadProc("glCompileShader"); - api->ProgramUniform1i = loadProc("glProgramUniform1i"); - api->GetQueryiv = loadProc("glGetQueryiv"); - api->VertexAttribI1iv = oc_glVertexAttribI1iv_noimpl; - api->CopyTexImage2D = loadProc("glCopyTexImage2D"); - api->GetQueryObjectui64v = oc_glGetQueryObjectui64v_noimpl; - api->PointSize = oc_glPointSize_noimpl; - api->Disablei = oc_glDisablei_noimpl; - api->VertexAttribL1dv = oc_glVertexAttribL1dv_noimpl; - api->CreateShader = loadProc("glCreateShader"); - api->GetString = loadProc("glGetString"); - api->ViewportArrayv = oc_glViewportArrayv_noimpl; - api->ProgramUniform3d = oc_glProgramUniform3d_noimpl; - api->VertexAttrib4Nubv = oc_glVertexAttrib4Nubv_noimpl; - api->TexParameteri = loadProc("glTexParameteri"); - api->ProgramUniform4fv = loadProc("glProgramUniform4fv"); - api->GenerateMipmap = loadProc("glGenerateMipmap"); - api->CompressedTexSubImage3D = loadProc("glCompressedTexSubImage3D"); - api->Uniform3f = loadProc("glUniform3f"); - api->GetUniformIndices = loadProc("glGetUniformIndices"); - api->VertexAttribLPointer = oc_glVertexAttribLPointer_noimpl; - api->VertexAttribI2uiv = oc_glVertexAttribI2uiv_noimpl; - api->QueryCounter = oc_glQueryCounter_noimpl; - api->ActiveShaderProgram = loadProc("glActiveShaderProgram"); - api->Uniform1ui = loadProc("glUniform1ui"); - api->VertexAttribI1i = oc_glVertexAttribI1i_noimpl; - api->GetTexParameterIiv = oc_glGetTexParameterIiv_noimpl; - api->GetUniformfv = loadProc("glGetUniformfv"); - api->ProgramUniform2uiv = loadProc("glProgramUniform2uiv"); - api->GetError = loadProc("glGetError"); - api->GetActiveUniformBlockName = loadProc("glGetActiveUniformBlockName"); - api->TextureView = oc_glTextureView_noimpl; - api->GetnUniformiv = oc_glGetnUniformiv_noimpl; - api->ProgramUniform4dv = oc_glProgramUniform4dv_noimpl; - api->ViewportIndexedfv = oc_glViewportIndexedfv_noimpl; - api->Hint = loadProc("glHint"); - api->GetShaderSource = loadProc("glGetShaderSource"); - api->ProgramUniformMatrix4x3fv = loadProc("glProgramUniformMatrix4x3fv"); - api->Uniform1iv = loadProc("glUniform1iv"); - api->VertexAttribI4bv = oc_glVertexAttribI4bv_noimpl; - api->UniformMatrix4x2dv = oc_glUniformMatrix4x2dv_noimpl; - api->BufferStorage = oc_glBufferStorage_noimpl; - api->IsRenderbuffer = loadProc("glIsRenderbuffer"); - api->GetActiveSubroutineUniformName = oc_glGetActiveSubroutineUniformName_noimpl; - api->LinkProgram = loadProc("glLinkProgram"); - api->GetActiveUniformsiv = loadProc("glGetActiveUniformsiv"); - api->GetDebugMessageLog = oc_glGetDebugMessageLog_noimpl; - api->CopyTexSubImage3D = loadProc("glCopyTexSubImage3D"); - api->PointParameteri = oc_glPointParameteri_noimpl; - api->ProgramUniform3dv = oc_glProgramUniform3dv_noimpl; - api->CompressedTexImage1D = oc_glCompressedTexImage1D_noimpl; - api->UniformMatrix3x4fv = loadProc("glUniformMatrix3x4fv"); - api->GenSamplers = loadProc("glGenSamplers"); - api->GetCompressedTexImage = oc_glGetCompressedTexImage_noimpl; - api->DeleteQueries = loadProc("glDeleteQueries"); - api->GenProgramPipelines = loadProc("glGenProgramPipelines"); - api->DispatchComputeIndirect = loadProc("glDispatchComputeIndirect"); - api->VertexAttribIPointer = loadProc("glVertexAttribIPointer"); - api->CreateProgram = loadProc("glCreateProgram"); - api->ClearTexSubImage = oc_glClearTexSubImage_noimpl; - api->VertexAttrib4d = oc_glVertexAttrib4d_noimpl; - api->FrontFace = loadProc("glFrontFace"); - api->BindTransformFeedback = loadProc("glBindTransformFeedback"); - api->GetProgramStageiv = oc_glGetProgramStageiv_noimpl; - api->SamplerParameterIiv = oc_glSamplerParameterIiv_noimpl; - api->GetInteger64v = loadProc("glGetInteger64v"); - api->CreateShaderProgramv = loadProc("glCreateShaderProgramv"); - api->BindBuffersRange = oc_glBindBuffersRange_noimpl; - api->Uniform3fv = loadProc("glUniform3fv"); - api->ProgramUniformMatrix4fv = loadProc("glProgramUniformMatrix4fv"); - api->BindBuffersBase = oc_glBindBuffersBase_noimpl; - api->ClearBufferfi = loadProc("glClearBufferfi"); - api->FramebufferTexture3D = oc_glFramebufferTexture3D_noimpl; - api->Disable = loadProc("glDisable"); - api->ProgramUniform1iv = loadProc("glProgramUniform1iv"); - api->VertexAttribI2iv = oc_glVertexAttribI2iv_noimpl; - api->DepthRangeIndexed = oc_glDepthRangeIndexed_noimpl; - api->PatchParameteri = oc_glPatchParameteri_noimpl; - api->GetUniformBlockIndex = loadProc("glGetUniformBlockIndex"); - api->MultiDrawArrays = oc_glMultiDrawArrays_noimpl; - api->VertexAttribI4ubv = oc_glVertexAttribI4ubv_noimpl; - api->BindBuffer = loadProc("glBindBuffer"); - api->VertexAttribI3i = oc_glVertexAttribI3i_noimpl; - api->GetDoublev = oc_glGetDoublev_noimpl; - api->DrawTransformFeedbackStream = oc_glDrawTransformFeedbackStream_noimpl; - api->VertexAttribI4uiv = loadProc("glVertexAttribI4uiv"); - api->RenderbufferStorageMultisample = loadProc("glRenderbufferStorageMultisample"); - api->VertexAttribL3dv = oc_glVertexAttribL3dv_noimpl; - api->StencilMaskSeparate = loadProc("glStencilMaskSeparate"); - api->ProgramUniform1d = oc_glProgramUniform1d_noimpl; - api->Viewport = loadProc("glViewport"); - api->VertexAttribP1ui = oc_glVertexAttribP1ui_noimpl; - api->VertexAttrib4dv = oc_glVertexAttrib4dv_noimpl; - api->GenQueries = loadProc("glGenQueries"); - api->TexParameterIiv = oc_glTexParameterIiv_noimpl; - api->ProgramUniform2d = oc_glProgramUniform2d_noimpl; - api->ProgramUniform1uiv = loadProc("glProgramUniform1uiv"); - api->VertexAttrib4Nub = oc_glVertexAttrib4Nub_noimpl; - api->IsVertexArray = loadProc("glIsVertexArray"); - api->ProgramUniform3f = loadProc("glProgramUniform3f"); - api->ProgramUniform3iv = loadProc("glProgramUniform3iv"); - api->GetProgramBinary = loadProc("glGetProgramBinary"); - api->BindRenderbuffer = loadProc("glBindRenderbuffer"); - api->BindFragDataLocationIndexed = oc_glBindFragDataLocationIndexed_noimpl; - api->GetSamplerParameterIiv = oc_glGetSamplerParameterIiv_noimpl; - api->VertexAttribDivisor = loadProc("glVertexAttribDivisor"); - api->ProgramUniformMatrix3x2dv = oc_glProgramUniformMatrix3x2dv_noimpl; - api->FramebufferParameteri = loadProc("glFramebufferParameteri"); - api->GenTransformFeedbacks = loadProc("glGenTransformFeedbacks"); - api->DeleteSync = loadProc("glDeleteSync"); - api->ProgramUniform1ui = loadProc("glProgramUniform1ui"); - api->TexSubImage1D = oc_glTexSubImage1D_noimpl; - api->ClearDepthf = loadProc("glClearDepthf"); - api->ReadPixels = loadProc("glReadPixels"); - api->VertexAttribI2i = oc_glVertexAttribI2i_noimpl; - api->Finish = loadProc("glFinish"); - api->LineWidth = loadProc("glLineWidth"); - api->DeleteShader = loadProc("glDeleteShader"); - api->IsSampler = loadProc("glIsSampler"); - api->ProgramUniformMatrix4dv = oc_glProgramUniformMatrix4dv_noimpl; - api->TransformFeedbackVaryings = loadProc("glTransformFeedbackVaryings"); - api->BeginConditionalRender = oc_glBeginConditionalRender_noimpl; - api->BindSamplers = oc_glBindSamplers_noimpl; - api->DeleteProgramPipelines = loadProc("glDeleteProgramPipelines"); - api->ColorMask = loadProc("glColorMask"); - api->TexParameterfv = loadProc("glTexParameterfv"); - api->PushDebugGroup = oc_glPushDebugGroup_noimpl; - api->ClearBufferfv = loadProc("glClearBufferfv"); - api->IsEnabled = loadProc("glIsEnabled"); - api->VertexAttrib2f = loadProc("glVertexAttrib2f"); - api->ProgramUniform2f = loadProc("glProgramUniform2f"); - api->GetSamplerParameterIuiv = oc_glGetSamplerParameterIuiv_noimpl; - api->GetInteger64i_v = loadProc("glGetInteger64i_v"); - api->Uniform2dv = oc_glUniform2dv_noimpl; - api->GetBufferSubData = oc_glGetBufferSubData_noimpl; - api->MultiDrawElementsIndirect = oc_glMultiDrawElementsIndirect_noimpl; - api->ProgramParameteri = loadProc("glProgramParameteri"); - api->VertexAttribP4ui = oc_glVertexAttribP4ui_noimpl; - api->SamplerParameterfv = loadProc("glSamplerParameterfv"); - api->PointParameterf = oc_glPointParameterf_noimpl; - api->UniformMatrix2x4fv = loadProc("glUniformMatrix2x4fv"); - api->GenBuffers = loadProc("glGenBuffers"); - api->ProgramUniform2dv = oc_glProgramUniform2dv_noimpl; - api->VertexAttribFormat = loadProc("glVertexAttribFormat"); - api->TexSubImage2D = loadProc("glTexSubImage2D"); - api->VertexAttrib4ubv = oc_glVertexAttrib4ubv_noimpl; - api->GetGraphicsResetStatus = oc_glGetGraphicsResetStatus_noimpl; - api->GetProgramInterfaceiv = loadProc("glGetProgramInterfaceiv"); - api->VertexAttribIFormat = loadProc("glVertexAttribIFormat"); - api->GetnUniformfv = oc_glGetnUniformfv_noimpl; - api->DeleteProgram = loadProc("glDeleteProgram"); - api->ClampColor = oc_glClampColor_noimpl; - api->DrawElementsInstancedBaseVertexBaseInstance = oc_glDrawElementsInstancedBaseVertexBaseInstance_noimpl; - api->DrawElements = loadProc("glDrawElements"); - api->DebugMessageControl = oc_glDebugMessageControl_noimpl; - api->GetRenderbufferParameteriv = loadProc("glGetRenderbufferParameteriv"); - api->DetachShader = loadProc("glDetachShader"); - api->GenFramebuffers = loadProc("glGenFramebuffers"); - api->ProvokingVertex = oc_glProvokingVertex_noimpl; - api->SampleMaski = loadProc("glSampleMaski"); - api->EndQueryIndexed = oc_glEndQueryIndexed_noimpl; - api->ProgramUniform1f = loadProc("glProgramUniform1f"); - api->BindFramebuffer = loadProc("glBindFramebuffer"); - api->BeginQueryIndexed = oc_glBeginQueryIndexed_noimpl; - api->UniformSubroutinesuiv = oc_glUniformSubroutinesuiv_noimpl; - api->GetUniformiv = loadProc("glGetUniformiv"); - api->FramebufferTexture = oc_glFramebufferTexture_noimpl; - api->PointParameterfv = oc_glPointParameterfv_noimpl; - api->IsTransformFeedback = loadProc("glIsTransformFeedback"); - api->CheckFramebufferStatus = loadProc("glCheckFramebufferStatus"); - api->ShaderSource = loadProc("glShaderSource"); - api->UniformMatrix2x4dv = oc_glUniformMatrix2x4dv_noimpl; - api->BindImageTextures = oc_glBindImageTextures_noimpl; - api->CopyTexImage1D = oc_glCopyTexImage1D_noimpl; - api->UniformMatrix3dv = oc_glUniformMatrix3dv_noimpl; - api->ProgramUniform1dv = oc_glProgramUniform1dv_noimpl; - api->BlitFramebuffer = loadProc("glBlitFramebuffer"); - api->PopDebugGroup = oc_glPopDebugGroup_noimpl; - api->TexParameterIuiv = oc_glTexParameterIuiv_noimpl; - api->VertexAttrib2d = oc_glVertexAttrib2d_noimpl; - api->TexImage1D = oc_glTexImage1D_noimpl; - api->GetObjectPtrLabel = oc_glGetObjectPtrLabel_noimpl; - api->StencilMask = loadProc("glStencilMask"); - api->BeginQuery = loadProc("glBeginQuery"); - api->UniformMatrix4fv = loadProc("glUniformMatrix4fv"); - api->IsSync = loadProc("glIsSync"); - api->Uniform3dv = oc_glUniform3dv_noimpl; - api->ProgramUniform2fv = loadProc("glProgramUniform2fv"); - api->VertexAttribI4sv = oc_glVertexAttribI4sv_noimpl; - api->ScissorArrayv = oc_glScissorArrayv_noimpl; - api->VertexAttribP1uiv = oc_glVertexAttribP1uiv_noimpl; - api->Uniform2uiv = loadProc("glUniform2uiv"); - api->DeleteBuffers = loadProc("glDeleteBuffers"); - api->ProgramUniform3ui = loadProc("glProgramUniform3ui"); - api->FramebufferTextureLayer = loadProc("glFramebufferTextureLayer"); - api->EndTransformFeedback = loadProc("glEndTransformFeedback"); - api->BlendFuncSeparatei = oc_glBlendFuncSeparatei_noimpl; - api->DrawTransformFeedbackInstanced = oc_glDrawTransformFeedbackInstanced_noimpl; - api->DrawRangeElementsBaseVertex = oc_glDrawRangeElementsBaseVertex_noimpl; - api->VertexAttrib1f = loadProc("glVertexAttrib1f"); - api->GetUniformSubroutineuiv = oc_glGetUniformSubroutineuiv_noimpl; - api->DisableVertexAttribArray = loadProc("glDisableVertexAttribArray"); - api->ProgramUniformMatrix3x2fv = loadProc("glProgramUniformMatrix3x2fv"); - api->VertexAttribI4usv = oc_glVertexAttribI4usv_noimpl; - api->GetObjectLabel = oc_glGetObjectLabel_noimpl; - api->BindAttribLocation = loadProc("glBindAttribLocation"); - api->Uniform1f = loadProc("glUniform1f"); - api->GetUniformdv = oc_glGetUniformdv_noimpl; - api->GetUniformLocation = loadProc("glGetUniformLocation"); - api->GetSubroutineUniformLocation = oc_glGetSubroutineUniformLocation_noimpl; - api->GetTexParameterIuiv = oc_glGetTexParameterIuiv_noimpl; - api->SamplerParameterf = loadProc("glSamplerParameterf"); - api->VertexAttribL3d = oc_glVertexAttribL3d_noimpl; - api->TexImage3DMultisample = oc_glTexImage3DMultisample_noimpl; - api->TexImage3D = loadProc("glTexImage3D"); - api->RenderbufferStorage = loadProc("glRenderbufferStorage"); - api->EnableVertexAttribArray = loadProc("glEnableVertexAttribArray"); - api->VertexAttribP4uiv = oc_glVertexAttribP4uiv_noimpl; - api->Uniform4d = oc_glUniform4d_noimpl; - api->VertexAttrib4s = oc_glVertexAttrib4s_noimpl; - api->DrawElementsInstancedBaseVertex = oc_glDrawElementsInstancedBaseVertex_noimpl; - api->VertexAttrib3s = oc_glVertexAttrib3s_noimpl; - api->ProgramUniform2iv = loadProc("glProgramUniform2iv"); - api->StencilFuncSeparate = loadProc("glStencilFuncSeparate"); - api->DeleteFramebuffers = loadProc("glDeleteFramebuffers"); - api->DepthRange = oc_glDepthRange_noimpl; - api->UniformMatrix3x2fv = loadProc("glUniformMatrix3x2fv"); - api->ProgramUniformMatrix2dv = oc_glProgramUniformMatrix2dv_noimpl; - api->ShaderStorageBlockBinding = oc_glShaderStorageBlockBinding_noimpl; - api->ClearDepth = oc_glClearDepth_noimpl; - api->VertexAttrib2dv = oc_glVertexAttrib2dv_noimpl; - api->SamplerParameterIuiv = oc_glSamplerParameterIuiv_noimpl; - api->GetVertexAttribLdv = oc_glGetVertexAttribLdv_noimpl; - api->ProgramUniformMatrix3x4dv = oc_glProgramUniformMatrix3x4dv_noimpl; - api->DepthRangeArrayv = oc_glDepthRangeArrayv_noimpl; - api->GetActiveUniform = loadProc("glGetActiveUniform"); - api->PatchParameterfv = oc_glPatchParameterfv_noimpl; - api->InvalidateTexImage = oc_glInvalidateTexImage_noimpl; - api->VertexAttrib3f = loadProc("glVertexAttrib3f"); - api->ProgramUniform4iv = loadProc("glProgramUniform4iv"); - api->ProgramUniform4d = oc_glProgramUniform4d_noimpl; - api->IsFramebuffer = loadProc("glIsFramebuffer"); - api->PixelStoref = oc_glPixelStoref_noimpl; - api->ProgramUniform4uiv = loadProc("glProgramUniform4uiv"); - api->ProgramUniformMatrix4x2dv = oc_glProgramUniformMatrix4x2dv_noimpl; - api->FenceSync = loadProc("glFenceSync"); - api->GetBufferParameteri64v = loadProc("glGetBufferParameteri64v"); - api->StencilOp = loadProc("glStencilOp"); - api->ClearBufferData = oc_glClearBufferData_noimpl; - api->GetnUniformuiv = oc_glGetnUniformuiv_noimpl; - api->GetProgramResourceiv = loadProc("glGetProgramResourceiv"); - api->GetVertexAttribdv = oc_glGetVertexAttribdv_noimpl; - api->GetTransformFeedbackVarying = loadProc("glGetTransformFeedbackVarying"); - api->VertexAttrib2fv = loadProc("glVertexAttrib2fv"); - api->GetBooleani_v = loadProc("glGetBooleani_v"); - api->ColorMaski = oc_glColorMaski_noimpl; - api->InvalidateBufferSubData = oc_glInvalidateBufferSubData_noimpl; - api->UniformMatrix4dv = oc_glUniformMatrix4dv_noimpl; - api->IsQuery = loadProc("glIsQuery"); - api->Uniform4ui = loadProc("glUniform4ui"); - api->Uniform4i = loadProc("glUniform4i"); - api->GetSamplerParameteriv = loadProc("glGetSamplerParameteriv"); - api->MultiDrawElementsBaseVertex = oc_glMultiDrawElementsBaseVertex_noimpl; - api->VertexAttribI1uiv = oc_glVertexAttribI1uiv_noimpl; - api->GetIntegerv = loadProc("glGetIntegerv"); - api->UniformMatrix2x3fv = loadProc("glUniformMatrix2x3fv"); - api->TexImage2D = loadProc("glTexImage2D"); - api->GetAttachedShaders = loadProc("glGetAttachedShaders"); - api->Uniform2d = oc_glUniform2d_noimpl; - api->MemoryBarrierByRegion = loadProc("glMemoryBarrierByRegion"); - api->UniformMatrix2fv = loadProc("glUniformMatrix2fv"); - api->PrimitiveRestartIndex = oc_glPrimitiveRestartIndex_noimpl; - api->GetVertexAttribiv = loadProc("glGetVertexAttribiv"); - api->GetAttribLocation = loadProc("glGetAttribLocation"); - api->TexStorage2DMultisample = loadProc("glTexStorage2DMultisample"); - api->CompressedTexSubImage2D = loadProc("glCompressedTexSubImage2D"); - api->GetVertexAttribfv = loadProc("glGetVertexAttribfv"); - api->GetBufferParameteriv = loadProc("glGetBufferParameteriv"); - api->TexParameterf = loadProc("glTexParameterf"); - api->FramebufferTexture2D = loadProc("glFramebufferTexture2D"); - api->GetActiveAttrib = loadProc("glGetActiveAttrib"); - api->InvalidateTexSubImage = oc_glInvalidateTexSubImage_noimpl; - api->DeleteVertexArrays = loadProc("glDeleteVertexArrays"); - api->VertexAttribI2ui = oc_glVertexAttribI2ui_noimpl; - api->PointParameteriv = oc_glPointParameteriv_noimpl; - api->GetPointerv = oc_glGetPointerv_noimpl; - api->Enablei = oc_glEnablei_noimpl; - api->BindBufferRange = loadProc("glBindBufferRange"); - api->DrawArraysInstanced = loadProc("glDrawArraysInstanced"); - api->DeleteTextures = loadProc("glDeleteTextures"); - api->VertexAttrib4Niv = oc_glVertexAttrib4Niv_noimpl; - api->MultiDrawElements = oc_glMultiDrawElements_noimpl; - api->GetProgramiv = loadProc("glGetProgramiv"); - api->DepthFunc = loadProc("glDepthFunc"); - api->GenTextures = loadProc("glGenTextures"); - api->GetInternalformativ = loadProc("glGetInternalformativ"); - api->ProgramUniform3i = loadProc("glProgramUniform3i"); - api->ScissorIndexed = oc_glScissorIndexed_noimpl; - api->VertexAttrib2sv = oc_glVertexAttrib2sv_noimpl; - api->TexStorage3DMultisample = oc_glTexStorage3DMultisample_noimpl; - api->Uniform2iv = loadProc("glUniform2iv"); - api->DrawArraysInstancedBaseInstance = oc_glDrawArraysInstancedBaseInstance_noimpl; - api->VertexAttribI3ui = oc_glVertexAttribI3ui_noimpl; - api->DeleteSamplers = loadProc("glDeleteSamplers"); - api->GenVertexArrays = loadProc("glGenVertexArrays"); - api->GetFramebufferParameteriv = loadProc("glGetFramebufferParameteriv"); - api->PolygonMode = oc_glPolygonMode_noimpl; - api->ProgramUniformMatrix2x4fv = loadProc("glProgramUniformMatrix2x4fv"); - api->GetProgramResourceName = loadProc("glGetProgramResourceName"); - api->SamplerParameteriv = loadProc("glSamplerParameteriv"); - api->GetActiveSubroutineUniformiv = oc_glGetActiveSubroutineUniformiv_noimpl; - api->GetStringi = loadProc("glGetStringi"); - api->VertexAttribLFormat = oc_glVertexAttribLFormat_noimpl; - api->VertexAttrib3d = oc_glVertexAttrib3d_noimpl; - api->BindVertexArray = loadProc("glBindVertexArray"); - api->UnmapBuffer = loadProc("glUnmapBuffer"); - api->DrawElementsInstancedBaseInstance = oc_glDrawElementsInstancedBaseInstance_noimpl; - api->Uniform4uiv = loadProc("glUniform4uiv"); - api->FramebufferTexture1D = oc_glFramebufferTexture1D_noimpl; - api->DrawTransformFeedbackStreamInstanced = oc_glDrawTransformFeedbackStreamInstanced_noimpl; - api->StencilFunc = loadProc("glStencilFunc"); - api->ValidateProgram = loadProc("glValidateProgram"); - api->Flush = loadProc("glFlush"); - api->ProgramUniform3uiv = loadProc("glProgramUniform3uiv"); - api->DeleteRenderbuffers = loadProc("glDeleteRenderbuffers"); - api->VertexAttrib4fv = loadProc("glVertexAttrib4fv"); - api->UniformMatrix2dv = oc_glUniformMatrix2dv_noimpl; - api->GetFragDataIndex = oc_glGetFragDataIndex_noimpl; - api->Uniform3iv = loadProc("glUniform3iv"); - api->MinSampleShading = oc_glMinSampleShading_noimpl; - api->GetBooleanv = loadProc("glGetBooleanv"); - api->GetMultisamplefv = loadProc("glGetMultisamplefv"); - api->GetVertexAttribIuiv = loadProc("glGetVertexAttribIuiv"); - api->GetProgramInfoLog = loadProc("glGetProgramInfoLog"); - api->Uniform4fv = loadProc("glUniform4fv"); - api->DrawBuffer = oc_glDrawBuffer_noimpl; - api->Uniform1i = loadProc("glUniform1i"); - api->ProgramUniform4ui = loadProc("glProgramUniform4ui"); - api->ProgramUniformMatrix3fv = loadProc("glProgramUniformMatrix3fv"); - api->BlendEquationSeparate = loadProc("glBlendEquationSeparate"); - api->BindProgramPipeline = loadProc("glBindProgramPipeline"); - api->GetDoublei_v = oc_glGetDoublei_v_noimpl; - api->BufferData = loadProc("glBufferData"); - api->ClearColor = loadProc("glClearColor"); - api->ProgramUniform4i = loadProc("glProgramUniform4i"); - api->GetTexLevelParameteriv = loadProc("glGetTexLevelParameteriv"); - api->GetActiveUniformBlockiv = loadProc("glGetActiveUniformBlockiv"); - api->ProgramUniform1fv = loadProc("glProgramUniform1fv"); - api->PauseTransformFeedback = loadProc("glPauseTransformFeedback"); - api->GetBufferPointerv = loadProc("glGetBufferPointerv"); - api->InvalidateSubFramebuffer = loadProc("glInvalidateSubFramebuffer"); - api->ScissorIndexedv = oc_glScissorIndexedv_noimpl; - api->Uniform2ui = loadProc("glUniform2ui"); - api->BindTexture = loadProc("glBindTexture"); - api->DrawElementsInstanced = loadProc("glDrawElementsInstanced"); - api->ProgramUniform4f = loadProc("glProgramUniform4f"); - api->BindBufferBase = loadProc("glBindBufferBase"); - api->IsShader = loadProc("glIsShader"); - api->ClearBufferSubData = oc_glClearBufferSubData_noimpl; - api->VertexAttrib4Nuiv = oc_glVertexAttrib4Nuiv_noimpl; - api->DrawArraysIndirect = loadProc("glDrawArraysIndirect"); - api->VertexAttrib4usv = oc_glVertexAttrib4usv_noimpl; - api->Uniform1d = oc_glUniform1d_noimpl; - api->ClearTexImage = oc_glClearTexImage_noimpl; - api->Uniform1uiv = loadProc("glUniform1uiv"); - api->BindSampler = loadProc("glBindSampler"); - api->GetTexLevelParameterfv = loadProc("glGetTexLevelParameterfv"); - api->ClearBufferiv = loadProc("glClearBufferiv"); - api->LogicOp = oc_glLogicOp_noimpl; - api->ActiveTexture = loadProc("glActiveTexture"); - api->GetFragDataLocation = loadProc("glGetFragDataLocation"); - api->BlendColor = loadProc("glBlendColor"); - api->UniformMatrix4x3fv = loadProc("glUniformMatrix4x3fv"); - api->ProgramUniform3fv = loadProc("glProgramUniform3fv"); - api->Uniform1fv = loadProc("glUniform1fv"); - api->DrawElementsBaseVertex = oc_glDrawElementsBaseVertex_noimpl; - api->Uniform4f = loadProc("glUniform4f"); - api->BlendEquationSeparatei = oc_glBlendEquationSeparatei_noimpl; - api->BlendFuncSeparate = loadProc("glBlendFuncSeparate"); - api->ClearBufferuiv = loadProc("glClearBufferuiv"); - api->CopyTexSubImage1D = oc_glCopyTexSubImage1D_noimpl; - api->DrawTransformFeedback = oc_glDrawTransformFeedback_noimpl; - api->ReadBuffer = loadProc("glReadBuffer"); - api->CopyBufferSubData = loadProc("glCopyBufferSubData"); - api->GetUniformuiv = loadProc("glGetUniformuiv"); - api->PolygonOffset = loadProc("glPolygonOffset"); - api->DispatchCompute = loadProc("glDispatchCompute"); - api->BindImageTexture = loadProc("glBindImageTexture"); - api->UniformMatrix4x3dv = oc_glUniformMatrix4x3dv_noimpl; - api->GenRenderbuffers = loadProc("glGenRenderbuffers"); + api->name = "gles31"; + api->GetFloatv = loadProc("glGetFloatv"); + api->TexBufferRange = oc_glTexBufferRange_noimpl; + api->IsBuffer = loadProc("glIsBuffer"); + api->IsTexture = loadProc("glIsTexture"); + api->DepthRangef = loadProc("glDepthRangef"); + api->EndConditionalRender = oc_glEndConditionalRender_noimpl; + api->BlendFunci = oc_glBlendFunci_noimpl; + api->GetProgramPipelineiv = loadProc("glGetProgramPipelineiv"); + api->WaitSync = loadProc("glWaitSync"); + api->ProgramUniformMatrix2fv = loadProc("glProgramUniformMatrix2fv"); + api->ProgramUniformMatrix4x3dv = oc_glProgramUniformMatrix4x3dv_noimpl; + api->VertexAttrib1dv = oc_glVertexAttrib1dv_noimpl; + api->SamplerParameteri = loadProc("glSamplerParameteri"); + api->GetVertexAttribIiv = loadProc("glGetVertexAttribIiv"); + api->GetSamplerParameterfv = loadProc("glGetSamplerParameterfv"); + api->VertexAttrib1d = oc_glVertexAttrib1d_noimpl; + api->TexBuffer = oc_glTexBuffer_noimpl; + api->InvalidateBufferData = oc_glInvalidateBufferData_noimpl; + api->ProgramUniform2i = loadProc("glProgramUniform2i"); + api->Uniform4dv = oc_glUniform4dv_noimpl; + api->UseProgram = loadProc("glUseProgram"); + api->VertexAttribI3iv = oc_glVertexAttribI3iv_noimpl; + api->DrawElementsIndirect = loadProc("glDrawElementsIndirect"); + api->VertexAttrib4uiv = oc_glVertexAttrib4uiv_noimpl; + api->GetQueryObjectiv = oc_glGetQueryObjectiv_noimpl; + api->FramebufferRenderbuffer = loadProc("glFramebufferRenderbuffer"); + api->BlendEquationi = oc_glBlendEquationi_noimpl; + api->GetActiveSubroutineName = oc_glGetActiveSubroutineName_noimpl; + api->VertexAttrib2s = oc_glVertexAttrib2s_noimpl; + api->VertexAttribL1d = oc_glVertexAttribL1d_noimpl; + api->BindTextures = oc_glBindTextures_noimpl; + api->VertexAttrib3sv = oc_glVertexAttrib3sv_noimpl; + api->GetFloati_v = oc_glGetFloati_v_noimpl; + api->BeginTransformFeedback = loadProc("glBeginTransformFeedback"); + api->ClearStencil = loadProc("glClearStencil"); + api->Uniform3i = loadProc("glUniform3i"); + api->ValidateProgramPipeline = loadProc("glValidateProgramPipeline"); + api->ProgramUniformMatrix4x2fv = loadProc("glProgramUniformMatrix4x2fv"); + api->VertexAttribI4ui = loadProc("glVertexAttribI4ui"); + api->GetShaderiv = loadProc("glGetShaderiv"); + api->ReadnPixels = oc_glReadnPixels_noimpl; + api->UniformMatrix4x2fv = loadProc("glUniformMatrix4x2fv"); + api->GetShaderPrecisionFormat = loadProc("glGetShaderPrecisionFormat"); + api->ProgramUniformMatrix2x3fv = loadProc("glProgramUniformMatrix2x3fv"); + api->TexSubImage3D = loadProc("glTexSubImage3D"); + api->GetProgramResourceLocationIndex = oc_glGetProgramResourceLocationIndex_noimpl; + api->BlendFunc = loadProc("glBlendFunc"); + api->ProgramUniformMatrix3x4fv = loadProc("glProgramUniformMatrix3x4fv"); + api->Uniform3d = oc_glUniform3d_noimpl; + api->VertexAttrib1sv = oc_glVertexAttrib1sv_noimpl; + api->BindFragDataLocation = oc_glBindFragDataLocation_noimpl; + api->VertexAttrib4bv = oc_glVertexAttrib4bv_noimpl; + api->Uniform4iv = loadProc("glUniform4iv"); + api->ProgramUniform2ui = loadProc("glProgramUniform2ui"); + api->DrawArrays = loadProc("glDrawArrays"); + api->ProgramBinary = loadProc("glProgramBinary"); + api->VertexAttrib4f = loadProc("glVertexAttrib4f"); + api->VertexAttribP2uiv = oc_glVertexAttribP2uiv_noimpl; + api->UniformMatrix3fv = loadProc("glUniformMatrix3fv"); + api->Uniform2i = loadProc("glUniform2i"); + api->GetQueryObjectuiv = loadProc("glGetQueryObjectuiv"); + api->UniformBlockBinding = loadProc("glUniformBlockBinding"); + api->SampleCoverage = loadProc("glSampleCoverage"); + api->VertexAttrib4Nusv = oc_glVertexAttrib4Nusv_noimpl; + api->ProgramUniformMatrix2x4dv = oc_glProgramUniformMatrix2x4dv_noimpl; + api->Uniform3uiv = loadProc("glUniform3uiv"); + api->VertexAttrib1s = oc_glVertexAttrib1s_noimpl; + api->GetVertexAttribPointerv = loadProc("glGetVertexAttribPointerv"); + api->BlendBarrier = oc_glBlendBarrier_noimpl; + api->DrawRangeElements = loadProc("glDrawRangeElements"); + api->TexStorage3D = loadProc("glTexStorage3D"); + api->GetInternalformati64v = oc_glGetInternalformati64v_noimpl; + api->GetQueryObjecti64v = oc_glGetQueryObjecti64v_noimpl; + api->CompressedTexSubImage1D = oc_glCompressedTexSubImage1D_noimpl; + api->VertexAttrib3dv = oc_glVertexAttrib3dv_noimpl; + api->VertexBindingDivisor = loadProc("glVertexBindingDivisor"); + api->UseProgramStages = loadProc("glUseProgramStages"); + api->VertexAttribBinding = loadProc("glVertexAttribBinding"); + api->DebugMessageInsert = oc_glDebugMessageInsert_noimpl; + api->GetTexParameteriv = loadProc("glGetTexParameteriv"); + api->MultiDrawArraysIndirect = oc_glMultiDrawArraysIndirect_noimpl; + api->GetTexParameterfv = loadProc("glGetTexParameterfv"); + api->GetProgramPipelineInfoLog = loadProc("glGetProgramPipelineInfoLog"); + api->EndQuery = loadProc("glEndQuery"); + api->GetProgramResourceLocation = loadProc("glGetProgramResourceLocation"); + api->CompressedTexImage2D = loadProc("glCompressedTexImage2D"); + api->VertexAttribP2ui = oc_glVertexAttribP2ui_noimpl; + api->IsEnabledi = oc_glIsEnabledi_noimpl; + api->GetActiveAtomicCounterBufferiv = oc_glGetActiveAtomicCounterBufferiv_noimpl; + api->IsProgram = loadProc("glIsProgram"); + api->Uniform1dv = oc_glUniform1dv_noimpl; + api->TexParameteriv = loadProc("glTexParameteriv"); + api->Uniform2fv = loadProc("glUniform2fv"); + api->ReleaseShaderCompiler = loadProc("glReleaseShaderCompiler"); + api->CullFace = loadProc("glCullFace"); + api->VertexAttribI4i = loadProc("glVertexAttribI4i"); + api->GetProgramResourceIndex = loadProc("glGetProgramResourceIndex"); + api->ShaderBinary = loadProc("glShaderBinary"); + api->UniformMatrix3x2dv = oc_glUniformMatrix3x2dv_noimpl; + api->InvalidateFramebuffer = loadProc("glInvalidateFramebuffer"); + api->AttachShader = loadProc("glAttachShader"); + api->FlushMappedBufferRange = loadProc("glFlushMappedBufferRange"); + api->VertexAttribP3uiv = oc_glVertexAttribP3uiv_noimpl; + api->GetActiveUniformName = oc_glGetActiveUniformName_noimpl; + api->MapBuffer = oc_glMapBuffer_noimpl; + api->DrawBuffers = loadProc("glDrawBuffers"); + api->GetSynciv = loadProc("glGetSynciv"); + api->CopyTexSubImage2D = loadProc("glCopyTexSubImage2D"); + api->ObjectLabel = oc_glObjectLabel_noimpl; + api->BufferSubData = loadProc("glBufferSubData"); + api->Uniform2f = loadProc("glUniform2f"); + api->DebugMessageCallback = oc_glDebugMessageCallback_noimpl; + api->VertexAttribL4dv = oc_glVertexAttribL4dv_noimpl; + api->IsProgramPipeline = loadProc("glIsProgramPipeline"); + api->ResumeTransformFeedback = loadProc("glResumeTransformFeedback"); + api->VertexAttribI4iv = loadProc("glVertexAttribI4iv"); + api->GetShaderInfoLog = loadProc("glGetShaderInfoLog"); + api->GetIntegeri_v = loadProc("glGetIntegeri_v"); + api->BindVertexBuffer = loadProc("glBindVertexBuffer"); + api->BlendEquation = loadProc("glBlendEquation"); + api->VertexAttribL2dv = oc_glVertexAttribL2dv_noimpl; + api->VertexAttribI1ui = oc_glVertexAttribI1ui_noimpl; + api->VertexAttrib4Nsv = oc_glVertexAttrib4Nsv_noimpl; + api->VertexAttribL4d = oc_glVertexAttribL4d_noimpl; + api->CopyImageSubData = oc_glCopyImageSubData_noimpl; + api->GetFramebufferAttachmentParameteriv = loadProc("glGetFramebufferAttachmentParameteriv"); + api->VertexAttribL2d = oc_glVertexAttribL2d_noimpl; + api->GetSubroutineIndex = oc_glGetSubroutineIndex_noimpl; + api->VertexAttribI3uiv = oc_glVertexAttribI3uiv_noimpl; + api->VertexAttrib4iv = oc_glVertexAttrib4iv_noimpl; + api->BindVertexBuffers = oc_glBindVertexBuffers_noimpl; + api->ProgramUniformMatrix2x3dv = oc_glProgramUniformMatrix2x3dv_noimpl; + api->PrimitiveBoundingBox = oc_glPrimitiveBoundingBox_noimpl; + api->Scissor = loadProc("glScissor"); + api->ClientWaitSync = loadProc("glClientWaitSync"); + api->Uniform3ui = loadProc("glUniform3ui"); + api->VertexAttribP3ui = oc_glVertexAttribP3ui_noimpl; + api->Enable = loadProc("glEnable"); + api->StencilOpSeparate = loadProc("glStencilOpSeparate"); + api->UniformMatrix2x3dv = oc_glUniformMatrix2x3dv_noimpl; + api->ProgramUniformMatrix3dv = oc_glProgramUniformMatrix3dv_noimpl; + api->TexImage2DMultisample = oc_glTexImage2DMultisample_noimpl; + api->VertexAttrib4Nbv = oc_glVertexAttrib4Nbv_noimpl; + api->GetTexImage = oc_glGetTexImage_noimpl; + api->VertexAttrib4sv = oc_glVertexAttrib4sv_noimpl; + api->PixelStorei = loadProc("glPixelStorei"); + api->DepthMask = loadProc("glDepthMask"); + api->TexStorage2D = loadProc("glTexStorage2D"); + api->Clear = loadProc("glClear"); + api->UniformMatrix3x4dv = oc_glUniformMatrix3x4dv_noimpl; + api->DeleteTransformFeedbacks = loadProc("glDeleteTransformFeedbacks"); + api->MapBufferRange = loadProc("glMapBufferRange"); + api->MemoryBarrier = loadProc("glMemoryBarrier"); + api->ViewportIndexedf = oc_glViewportIndexedf_noimpl; + api->VertexAttrib3fv = loadProc("glVertexAttrib3fv"); + api->ObjectPtrLabel = oc_glObjectPtrLabel_noimpl; + api->TexStorage1D = oc_glTexStorage1D_noimpl; + api->CompressedTexImage3D = loadProc("glCompressedTexImage3D"); + api->VertexAttrib1fv = loadProc("glVertexAttrib1fv"); + api->VertexAttribPointer = loadProc("glVertexAttribPointer"); + api->GetQueryIndexediv = oc_glGetQueryIndexediv_noimpl; + api->CompileShader = loadProc("glCompileShader"); + api->ProgramUniform1i = loadProc("glProgramUniform1i"); + api->GetQueryiv = loadProc("glGetQueryiv"); + api->VertexAttribI1iv = oc_glVertexAttribI1iv_noimpl; + api->CopyTexImage2D = loadProc("glCopyTexImage2D"); + api->GetQueryObjectui64v = oc_glGetQueryObjectui64v_noimpl; + api->PointSize = oc_glPointSize_noimpl; + api->Disablei = oc_glDisablei_noimpl; + api->VertexAttribL1dv = oc_glVertexAttribL1dv_noimpl; + api->CreateShader = loadProc("glCreateShader"); + api->GetString = loadProc("glGetString"); + api->ViewportArrayv = oc_glViewportArrayv_noimpl; + api->ProgramUniform3d = oc_glProgramUniform3d_noimpl; + api->VertexAttrib4Nubv = oc_glVertexAttrib4Nubv_noimpl; + api->TexParameteri = loadProc("glTexParameteri"); + api->ProgramUniform4fv = loadProc("glProgramUniform4fv"); + api->GenerateMipmap = loadProc("glGenerateMipmap"); + api->CompressedTexSubImage3D = loadProc("glCompressedTexSubImage3D"); + api->Uniform3f = loadProc("glUniform3f"); + api->GetUniformIndices = loadProc("glGetUniformIndices"); + api->VertexAttribLPointer = oc_glVertexAttribLPointer_noimpl; + api->VertexAttribI2uiv = oc_glVertexAttribI2uiv_noimpl; + api->QueryCounter = oc_glQueryCounter_noimpl; + api->ActiveShaderProgram = loadProc("glActiveShaderProgram"); + api->Uniform1ui = loadProc("glUniform1ui"); + api->VertexAttribI1i = oc_glVertexAttribI1i_noimpl; + api->GetTexParameterIiv = oc_glGetTexParameterIiv_noimpl; + api->GetUniformfv = loadProc("glGetUniformfv"); + api->ProgramUniform2uiv = loadProc("glProgramUniform2uiv"); + api->GetError = loadProc("glGetError"); + api->GetActiveUniformBlockName = loadProc("glGetActiveUniformBlockName"); + api->TextureView = oc_glTextureView_noimpl; + api->GetnUniformiv = oc_glGetnUniformiv_noimpl; + api->ProgramUniform4dv = oc_glProgramUniform4dv_noimpl; + api->ViewportIndexedfv = oc_glViewportIndexedfv_noimpl; + api->Hint = loadProc("glHint"); + api->GetShaderSource = loadProc("glGetShaderSource"); + api->ProgramUniformMatrix4x3fv = loadProc("glProgramUniformMatrix4x3fv"); + api->Uniform1iv = loadProc("glUniform1iv"); + api->VertexAttribI4bv = oc_glVertexAttribI4bv_noimpl; + api->UniformMatrix4x2dv = oc_glUniformMatrix4x2dv_noimpl; + api->BufferStorage = oc_glBufferStorage_noimpl; + api->IsRenderbuffer = loadProc("glIsRenderbuffer"); + api->GetActiveSubroutineUniformName = oc_glGetActiveSubroutineUniformName_noimpl; + api->LinkProgram = loadProc("glLinkProgram"); + api->GetActiveUniformsiv = loadProc("glGetActiveUniformsiv"); + api->GetDebugMessageLog = oc_glGetDebugMessageLog_noimpl; + api->CopyTexSubImage3D = loadProc("glCopyTexSubImage3D"); + api->PointParameteri = oc_glPointParameteri_noimpl; + api->ProgramUniform3dv = oc_glProgramUniform3dv_noimpl; + api->CompressedTexImage1D = oc_glCompressedTexImage1D_noimpl; + api->UniformMatrix3x4fv = loadProc("glUniformMatrix3x4fv"); + api->GenSamplers = loadProc("glGenSamplers"); + api->GetCompressedTexImage = oc_glGetCompressedTexImage_noimpl; + api->DeleteQueries = loadProc("glDeleteQueries"); + api->GenProgramPipelines = loadProc("glGenProgramPipelines"); + api->DispatchComputeIndirect = loadProc("glDispatchComputeIndirect"); + api->VertexAttribIPointer = loadProc("glVertexAttribIPointer"); + api->CreateProgram = loadProc("glCreateProgram"); + api->ClearTexSubImage = oc_glClearTexSubImage_noimpl; + api->VertexAttrib4d = oc_glVertexAttrib4d_noimpl; + api->FrontFace = loadProc("glFrontFace"); + api->BindTransformFeedback = loadProc("glBindTransformFeedback"); + api->GetProgramStageiv = oc_glGetProgramStageiv_noimpl; + api->SamplerParameterIiv = oc_glSamplerParameterIiv_noimpl; + api->GetInteger64v = loadProc("glGetInteger64v"); + api->CreateShaderProgramv = loadProc("glCreateShaderProgramv"); + api->BindBuffersRange = oc_glBindBuffersRange_noimpl; + api->Uniform3fv = loadProc("glUniform3fv"); + api->ProgramUniformMatrix4fv = loadProc("glProgramUniformMatrix4fv"); + api->BindBuffersBase = oc_glBindBuffersBase_noimpl; + api->ClearBufferfi = loadProc("glClearBufferfi"); + api->FramebufferTexture3D = oc_glFramebufferTexture3D_noimpl; + api->Disable = loadProc("glDisable"); + api->ProgramUniform1iv = loadProc("glProgramUniform1iv"); + api->VertexAttribI2iv = oc_glVertexAttribI2iv_noimpl; + api->DepthRangeIndexed = oc_glDepthRangeIndexed_noimpl; + api->PatchParameteri = oc_glPatchParameteri_noimpl; + api->GetUniformBlockIndex = loadProc("glGetUniformBlockIndex"); + api->MultiDrawArrays = oc_glMultiDrawArrays_noimpl; + api->VertexAttribI4ubv = oc_glVertexAttribI4ubv_noimpl; + api->BindBuffer = loadProc("glBindBuffer"); + api->VertexAttribI3i = oc_glVertexAttribI3i_noimpl; + api->GetDoublev = oc_glGetDoublev_noimpl; + api->DrawTransformFeedbackStream = oc_glDrawTransformFeedbackStream_noimpl; + api->VertexAttribI4uiv = loadProc("glVertexAttribI4uiv"); + api->RenderbufferStorageMultisample = loadProc("glRenderbufferStorageMultisample"); + api->VertexAttribL3dv = oc_glVertexAttribL3dv_noimpl; + api->StencilMaskSeparate = loadProc("glStencilMaskSeparate"); + api->ProgramUniform1d = oc_glProgramUniform1d_noimpl; + api->Viewport = loadProc("glViewport"); + api->VertexAttribP1ui = oc_glVertexAttribP1ui_noimpl; + api->VertexAttrib4dv = oc_glVertexAttrib4dv_noimpl; + api->GenQueries = loadProc("glGenQueries"); + api->TexParameterIiv = oc_glTexParameterIiv_noimpl; + api->ProgramUniform2d = oc_glProgramUniform2d_noimpl; + api->ProgramUniform1uiv = loadProc("glProgramUniform1uiv"); + api->VertexAttrib4Nub = oc_glVertexAttrib4Nub_noimpl; + api->IsVertexArray = loadProc("glIsVertexArray"); + api->ProgramUniform3f = loadProc("glProgramUniform3f"); + api->ProgramUniform3iv = loadProc("glProgramUniform3iv"); + api->GetProgramBinary = loadProc("glGetProgramBinary"); + api->BindRenderbuffer = loadProc("glBindRenderbuffer"); + api->BindFragDataLocationIndexed = oc_glBindFragDataLocationIndexed_noimpl; + api->GetSamplerParameterIiv = oc_glGetSamplerParameterIiv_noimpl; + api->VertexAttribDivisor = loadProc("glVertexAttribDivisor"); + api->ProgramUniformMatrix3x2dv = oc_glProgramUniformMatrix3x2dv_noimpl; + api->FramebufferParameteri = loadProc("glFramebufferParameteri"); + api->GenTransformFeedbacks = loadProc("glGenTransformFeedbacks"); + api->DeleteSync = loadProc("glDeleteSync"); + api->ProgramUniform1ui = loadProc("glProgramUniform1ui"); + api->TexSubImage1D = oc_glTexSubImage1D_noimpl; + api->ClearDepthf = loadProc("glClearDepthf"); + api->ReadPixels = loadProc("glReadPixels"); + api->VertexAttribI2i = oc_glVertexAttribI2i_noimpl; + api->Finish = loadProc("glFinish"); + api->LineWidth = loadProc("glLineWidth"); + api->DeleteShader = loadProc("glDeleteShader"); + api->IsSampler = loadProc("glIsSampler"); + api->ProgramUniformMatrix4dv = oc_glProgramUniformMatrix4dv_noimpl; + api->TransformFeedbackVaryings = loadProc("glTransformFeedbackVaryings"); + api->BeginConditionalRender = oc_glBeginConditionalRender_noimpl; + api->BindSamplers = oc_glBindSamplers_noimpl; + api->DeleteProgramPipelines = loadProc("glDeleteProgramPipelines"); + api->ColorMask = loadProc("glColorMask"); + api->TexParameterfv = loadProc("glTexParameterfv"); + api->PushDebugGroup = oc_glPushDebugGroup_noimpl; + api->ClearBufferfv = loadProc("glClearBufferfv"); + api->IsEnabled = loadProc("glIsEnabled"); + api->VertexAttrib2f = loadProc("glVertexAttrib2f"); + api->ProgramUniform2f = loadProc("glProgramUniform2f"); + api->GetSamplerParameterIuiv = oc_glGetSamplerParameterIuiv_noimpl; + api->GetInteger64i_v = loadProc("glGetInteger64i_v"); + api->Uniform2dv = oc_glUniform2dv_noimpl; + api->GetBufferSubData = oc_glGetBufferSubData_noimpl; + api->MultiDrawElementsIndirect = oc_glMultiDrawElementsIndirect_noimpl; + api->ProgramParameteri = loadProc("glProgramParameteri"); + api->VertexAttribP4ui = oc_glVertexAttribP4ui_noimpl; + api->SamplerParameterfv = loadProc("glSamplerParameterfv"); + api->PointParameterf = oc_glPointParameterf_noimpl; + api->UniformMatrix2x4fv = loadProc("glUniformMatrix2x4fv"); + api->GenBuffers = loadProc("glGenBuffers"); + api->ProgramUniform2dv = oc_glProgramUniform2dv_noimpl; + api->VertexAttribFormat = loadProc("glVertexAttribFormat"); + api->TexSubImage2D = loadProc("glTexSubImage2D"); + api->VertexAttrib4ubv = oc_glVertexAttrib4ubv_noimpl; + api->GetGraphicsResetStatus = oc_glGetGraphicsResetStatus_noimpl; + api->GetProgramInterfaceiv = loadProc("glGetProgramInterfaceiv"); + api->VertexAttribIFormat = loadProc("glVertexAttribIFormat"); + api->GetnUniformfv = oc_glGetnUniformfv_noimpl; + api->DeleteProgram = loadProc("glDeleteProgram"); + api->ClampColor = oc_glClampColor_noimpl; + api->DrawElementsInstancedBaseVertexBaseInstance = oc_glDrawElementsInstancedBaseVertexBaseInstance_noimpl; + api->DrawElements = loadProc("glDrawElements"); + api->DebugMessageControl = oc_glDebugMessageControl_noimpl; + api->GetRenderbufferParameteriv = loadProc("glGetRenderbufferParameteriv"); + api->DetachShader = loadProc("glDetachShader"); + api->GenFramebuffers = loadProc("glGenFramebuffers"); + api->ProvokingVertex = oc_glProvokingVertex_noimpl; + api->SampleMaski = loadProc("glSampleMaski"); + api->EndQueryIndexed = oc_glEndQueryIndexed_noimpl; + api->ProgramUniform1f = loadProc("glProgramUniform1f"); + api->BindFramebuffer = loadProc("glBindFramebuffer"); + api->BeginQueryIndexed = oc_glBeginQueryIndexed_noimpl; + api->UniformSubroutinesuiv = oc_glUniformSubroutinesuiv_noimpl; + api->GetUniformiv = loadProc("glGetUniformiv"); + api->FramebufferTexture = oc_glFramebufferTexture_noimpl; + api->PointParameterfv = oc_glPointParameterfv_noimpl; + api->IsTransformFeedback = loadProc("glIsTransformFeedback"); + api->CheckFramebufferStatus = loadProc("glCheckFramebufferStatus"); + api->ShaderSource = loadProc("glShaderSource"); + api->UniformMatrix2x4dv = oc_glUniformMatrix2x4dv_noimpl; + api->BindImageTextures = oc_glBindImageTextures_noimpl; + api->CopyTexImage1D = oc_glCopyTexImage1D_noimpl; + api->UniformMatrix3dv = oc_glUniformMatrix3dv_noimpl; + api->ProgramUniform1dv = oc_glProgramUniform1dv_noimpl; + api->BlitFramebuffer = loadProc("glBlitFramebuffer"); + api->PopDebugGroup = oc_glPopDebugGroup_noimpl; + api->TexParameterIuiv = oc_glTexParameterIuiv_noimpl; + api->VertexAttrib2d = oc_glVertexAttrib2d_noimpl; + api->TexImage1D = oc_glTexImage1D_noimpl; + api->GetObjectPtrLabel = oc_glGetObjectPtrLabel_noimpl; + api->StencilMask = loadProc("glStencilMask"); + api->BeginQuery = loadProc("glBeginQuery"); + api->UniformMatrix4fv = loadProc("glUniformMatrix4fv"); + api->IsSync = loadProc("glIsSync"); + api->Uniform3dv = oc_glUniform3dv_noimpl; + api->ProgramUniform2fv = loadProc("glProgramUniform2fv"); + api->VertexAttribI4sv = oc_glVertexAttribI4sv_noimpl; + api->ScissorArrayv = oc_glScissorArrayv_noimpl; + api->VertexAttribP1uiv = oc_glVertexAttribP1uiv_noimpl; + api->Uniform2uiv = loadProc("glUniform2uiv"); + api->DeleteBuffers = loadProc("glDeleteBuffers"); + api->ProgramUniform3ui = loadProc("glProgramUniform3ui"); + api->FramebufferTextureLayer = loadProc("glFramebufferTextureLayer"); + api->EndTransformFeedback = loadProc("glEndTransformFeedback"); + api->BlendFuncSeparatei = oc_glBlendFuncSeparatei_noimpl; + api->DrawTransformFeedbackInstanced = oc_glDrawTransformFeedbackInstanced_noimpl; + api->DrawRangeElementsBaseVertex = oc_glDrawRangeElementsBaseVertex_noimpl; + api->VertexAttrib1f = loadProc("glVertexAttrib1f"); + api->GetUniformSubroutineuiv = oc_glGetUniformSubroutineuiv_noimpl; + api->DisableVertexAttribArray = loadProc("glDisableVertexAttribArray"); + api->ProgramUniformMatrix3x2fv = loadProc("glProgramUniformMatrix3x2fv"); + api->VertexAttribI4usv = oc_glVertexAttribI4usv_noimpl; + api->GetObjectLabel = oc_glGetObjectLabel_noimpl; + api->BindAttribLocation = loadProc("glBindAttribLocation"); + api->Uniform1f = loadProc("glUniform1f"); + api->GetUniformdv = oc_glGetUniformdv_noimpl; + api->GetUniformLocation = loadProc("glGetUniformLocation"); + api->GetSubroutineUniformLocation = oc_glGetSubroutineUniformLocation_noimpl; + api->GetTexParameterIuiv = oc_glGetTexParameterIuiv_noimpl; + api->SamplerParameterf = loadProc("glSamplerParameterf"); + api->VertexAttribL3d = oc_glVertexAttribL3d_noimpl; + api->TexImage3DMultisample = oc_glTexImage3DMultisample_noimpl; + api->TexImage3D = loadProc("glTexImage3D"); + api->RenderbufferStorage = loadProc("glRenderbufferStorage"); + api->EnableVertexAttribArray = loadProc("glEnableVertexAttribArray"); + api->VertexAttribP4uiv = oc_glVertexAttribP4uiv_noimpl; + api->Uniform4d = oc_glUniform4d_noimpl; + api->VertexAttrib4s = oc_glVertexAttrib4s_noimpl; + api->DrawElementsInstancedBaseVertex = oc_glDrawElementsInstancedBaseVertex_noimpl; + api->VertexAttrib3s = oc_glVertexAttrib3s_noimpl; + api->ProgramUniform2iv = loadProc("glProgramUniform2iv"); + api->StencilFuncSeparate = loadProc("glStencilFuncSeparate"); + api->DeleteFramebuffers = loadProc("glDeleteFramebuffers"); + api->DepthRange = oc_glDepthRange_noimpl; + api->UniformMatrix3x2fv = loadProc("glUniformMatrix3x2fv"); + api->ProgramUniformMatrix2dv = oc_glProgramUniformMatrix2dv_noimpl; + api->ShaderStorageBlockBinding = oc_glShaderStorageBlockBinding_noimpl; + api->ClearDepth = oc_glClearDepth_noimpl; + api->VertexAttrib2dv = oc_glVertexAttrib2dv_noimpl; + api->SamplerParameterIuiv = oc_glSamplerParameterIuiv_noimpl; + api->GetVertexAttribLdv = oc_glGetVertexAttribLdv_noimpl; + api->ProgramUniformMatrix3x4dv = oc_glProgramUniformMatrix3x4dv_noimpl; + api->DepthRangeArrayv = oc_glDepthRangeArrayv_noimpl; + api->GetActiveUniform = loadProc("glGetActiveUniform"); + api->PatchParameterfv = oc_glPatchParameterfv_noimpl; + api->InvalidateTexImage = oc_glInvalidateTexImage_noimpl; + api->VertexAttrib3f = loadProc("glVertexAttrib3f"); + api->ProgramUniform4iv = loadProc("glProgramUniform4iv"); + api->ProgramUniform4d = oc_glProgramUniform4d_noimpl; + api->IsFramebuffer = loadProc("glIsFramebuffer"); + api->PixelStoref = oc_glPixelStoref_noimpl; + api->ProgramUniform4uiv = loadProc("glProgramUniform4uiv"); + api->ProgramUniformMatrix4x2dv = oc_glProgramUniformMatrix4x2dv_noimpl; + api->FenceSync = loadProc("glFenceSync"); + api->GetBufferParameteri64v = loadProc("glGetBufferParameteri64v"); + api->StencilOp = loadProc("glStencilOp"); + api->ClearBufferData = oc_glClearBufferData_noimpl; + api->GetnUniformuiv = oc_glGetnUniformuiv_noimpl; + api->GetProgramResourceiv = loadProc("glGetProgramResourceiv"); + api->GetVertexAttribdv = oc_glGetVertexAttribdv_noimpl; + api->GetTransformFeedbackVarying = loadProc("glGetTransformFeedbackVarying"); + api->VertexAttrib2fv = loadProc("glVertexAttrib2fv"); + api->GetBooleani_v = loadProc("glGetBooleani_v"); + api->ColorMaski = oc_glColorMaski_noimpl; + api->InvalidateBufferSubData = oc_glInvalidateBufferSubData_noimpl; + api->UniformMatrix4dv = oc_glUniformMatrix4dv_noimpl; + api->IsQuery = loadProc("glIsQuery"); + api->Uniform4ui = loadProc("glUniform4ui"); + api->Uniform4i = loadProc("glUniform4i"); + api->GetSamplerParameteriv = loadProc("glGetSamplerParameteriv"); + api->MultiDrawElementsBaseVertex = oc_glMultiDrawElementsBaseVertex_noimpl; + api->VertexAttribI1uiv = oc_glVertexAttribI1uiv_noimpl; + api->GetIntegerv = loadProc("glGetIntegerv"); + api->UniformMatrix2x3fv = loadProc("glUniformMatrix2x3fv"); + api->TexImage2D = loadProc("glTexImage2D"); + api->GetAttachedShaders = loadProc("glGetAttachedShaders"); + api->Uniform2d = oc_glUniform2d_noimpl; + api->MemoryBarrierByRegion = loadProc("glMemoryBarrierByRegion"); + api->UniformMatrix2fv = loadProc("glUniformMatrix2fv"); + api->PrimitiveRestartIndex = oc_glPrimitiveRestartIndex_noimpl; + api->GetVertexAttribiv = loadProc("glGetVertexAttribiv"); + api->GetAttribLocation = loadProc("glGetAttribLocation"); + api->TexStorage2DMultisample = loadProc("glTexStorage2DMultisample"); + api->CompressedTexSubImage2D = loadProc("glCompressedTexSubImage2D"); + api->GetVertexAttribfv = loadProc("glGetVertexAttribfv"); + api->GetBufferParameteriv = loadProc("glGetBufferParameteriv"); + api->TexParameterf = loadProc("glTexParameterf"); + api->FramebufferTexture2D = loadProc("glFramebufferTexture2D"); + api->GetActiveAttrib = loadProc("glGetActiveAttrib"); + api->InvalidateTexSubImage = oc_glInvalidateTexSubImage_noimpl; + api->DeleteVertexArrays = loadProc("glDeleteVertexArrays"); + api->VertexAttribI2ui = oc_glVertexAttribI2ui_noimpl; + api->PointParameteriv = oc_glPointParameteriv_noimpl; + api->GetPointerv = oc_glGetPointerv_noimpl; + api->Enablei = oc_glEnablei_noimpl; + api->BindBufferRange = loadProc("glBindBufferRange"); + api->DrawArraysInstanced = loadProc("glDrawArraysInstanced"); + api->DeleteTextures = loadProc("glDeleteTextures"); + api->VertexAttrib4Niv = oc_glVertexAttrib4Niv_noimpl; + api->MultiDrawElements = oc_glMultiDrawElements_noimpl; + api->GetProgramiv = loadProc("glGetProgramiv"); + api->DepthFunc = loadProc("glDepthFunc"); + api->GenTextures = loadProc("glGenTextures"); + api->GetInternalformativ = loadProc("glGetInternalformativ"); + api->ProgramUniform3i = loadProc("glProgramUniform3i"); + api->ScissorIndexed = oc_glScissorIndexed_noimpl; + api->VertexAttrib2sv = oc_glVertexAttrib2sv_noimpl; + api->TexStorage3DMultisample = oc_glTexStorage3DMultisample_noimpl; + api->Uniform2iv = loadProc("glUniform2iv"); + api->DrawArraysInstancedBaseInstance = oc_glDrawArraysInstancedBaseInstance_noimpl; + api->VertexAttribI3ui = oc_glVertexAttribI3ui_noimpl; + api->DeleteSamplers = loadProc("glDeleteSamplers"); + api->GenVertexArrays = loadProc("glGenVertexArrays"); + api->GetFramebufferParameteriv = loadProc("glGetFramebufferParameteriv"); + api->PolygonMode = oc_glPolygonMode_noimpl; + api->ProgramUniformMatrix2x4fv = loadProc("glProgramUniformMatrix2x4fv"); + api->GetProgramResourceName = loadProc("glGetProgramResourceName"); + api->SamplerParameteriv = loadProc("glSamplerParameteriv"); + api->GetActiveSubroutineUniformiv = oc_glGetActiveSubroutineUniformiv_noimpl; + api->GetStringi = loadProc("glGetStringi"); + api->VertexAttribLFormat = oc_glVertexAttribLFormat_noimpl; + api->VertexAttrib3d = oc_glVertexAttrib3d_noimpl; + api->BindVertexArray = loadProc("glBindVertexArray"); + api->UnmapBuffer = loadProc("glUnmapBuffer"); + api->DrawElementsInstancedBaseInstance = oc_glDrawElementsInstancedBaseInstance_noimpl; + api->Uniform4uiv = loadProc("glUniform4uiv"); + api->FramebufferTexture1D = oc_glFramebufferTexture1D_noimpl; + api->DrawTransformFeedbackStreamInstanced = oc_glDrawTransformFeedbackStreamInstanced_noimpl; + api->StencilFunc = loadProc("glStencilFunc"); + api->ValidateProgram = loadProc("glValidateProgram"); + api->Flush = loadProc("glFlush"); + api->ProgramUniform3uiv = loadProc("glProgramUniform3uiv"); + api->DeleteRenderbuffers = loadProc("glDeleteRenderbuffers"); + api->VertexAttrib4fv = loadProc("glVertexAttrib4fv"); + api->UniformMatrix2dv = oc_glUniformMatrix2dv_noimpl; + api->GetFragDataIndex = oc_glGetFragDataIndex_noimpl; + api->Uniform3iv = loadProc("glUniform3iv"); + api->MinSampleShading = oc_glMinSampleShading_noimpl; + api->GetBooleanv = loadProc("glGetBooleanv"); + api->GetMultisamplefv = loadProc("glGetMultisamplefv"); + api->GetVertexAttribIuiv = loadProc("glGetVertexAttribIuiv"); + api->GetProgramInfoLog = loadProc("glGetProgramInfoLog"); + api->Uniform4fv = loadProc("glUniform4fv"); + api->DrawBuffer = oc_glDrawBuffer_noimpl; + api->Uniform1i = loadProc("glUniform1i"); + api->ProgramUniform4ui = loadProc("glProgramUniform4ui"); + api->ProgramUniformMatrix3fv = loadProc("glProgramUniformMatrix3fv"); + api->BlendEquationSeparate = loadProc("glBlendEquationSeparate"); + api->BindProgramPipeline = loadProc("glBindProgramPipeline"); + api->GetDoublei_v = oc_glGetDoublei_v_noimpl; + api->BufferData = loadProc("glBufferData"); + api->ClearColor = loadProc("glClearColor"); + api->ProgramUniform4i = loadProc("glProgramUniform4i"); + api->GetTexLevelParameteriv = loadProc("glGetTexLevelParameteriv"); + api->GetActiveUniformBlockiv = loadProc("glGetActiveUniformBlockiv"); + api->ProgramUniform1fv = loadProc("glProgramUniform1fv"); + api->PauseTransformFeedback = loadProc("glPauseTransformFeedback"); + api->GetBufferPointerv = loadProc("glGetBufferPointerv"); + api->InvalidateSubFramebuffer = loadProc("glInvalidateSubFramebuffer"); + api->ScissorIndexedv = oc_glScissorIndexedv_noimpl; + api->Uniform2ui = loadProc("glUniform2ui"); + api->BindTexture = loadProc("glBindTexture"); + api->DrawElementsInstanced = loadProc("glDrawElementsInstanced"); + api->ProgramUniform4f = loadProc("glProgramUniform4f"); + api->BindBufferBase = loadProc("glBindBufferBase"); + api->IsShader = loadProc("glIsShader"); + api->ClearBufferSubData = oc_glClearBufferSubData_noimpl; + api->VertexAttrib4Nuiv = oc_glVertexAttrib4Nuiv_noimpl; + api->DrawArraysIndirect = loadProc("glDrawArraysIndirect"); + api->VertexAttrib4usv = oc_glVertexAttrib4usv_noimpl; + api->Uniform1d = oc_glUniform1d_noimpl; + api->ClearTexImage = oc_glClearTexImage_noimpl; + api->Uniform1uiv = loadProc("glUniform1uiv"); + api->BindSampler = loadProc("glBindSampler"); + api->GetTexLevelParameterfv = loadProc("glGetTexLevelParameterfv"); + api->ClearBufferiv = loadProc("glClearBufferiv"); + api->LogicOp = oc_glLogicOp_noimpl; + api->ActiveTexture = loadProc("glActiveTexture"); + api->GetFragDataLocation = loadProc("glGetFragDataLocation"); + api->BlendColor = loadProc("glBlendColor"); + api->UniformMatrix4x3fv = loadProc("glUniformMatrix4x3fv"); + api->ProgramUniform3fv = loadProc("glProgramUniform3fv"); + api->Uniform1fv = loadProc("glUniform1fv"); + api->DrawElementsBaseVertex = oc_glDrawElementsBaseVertex_noimpl; + api->Uniform4f = loadProc("glUniform4f"); + api->BlendEquationSeparatei = oc_glBlendEquationSeparatei_noimpl; + api->BlendFuncSeparate = loadProc("glBlendFuncSeparate"); + api->ClearBufferuiv = loadProc("glClearBufferuiv"); + api->CopyTexSubImage1D = oc_glCopyTexSubImage1D_noimpl; + api->DrawTransformFeedback = oc_glDrawTransformFeedback_noimpl; + api->ReadBuffer = loadProc("glReadBuffer"); + api->CopyBufferSubData = loadProc("glCopyBufferSubData"); + api->GetUniformuiv = loadProc("glGetUniformuiv"); + api->PolygonOffset = loadProc("glPolygonOffset"); + api->DispatchCompute = loadProc("glDispatchCompute"); + api->BindImageTexture = loadProc("glBindImageTexture"); + api->UniformMatrix4x3dv = oc_glUniformMatrix4x3dv_noimpl; + api->GenRenderbuffers = loadProc("glGenRenderbuffers"); } void oc_gl_load_gles32(oc_gl_api* api, oc_gl_load_proc loadProc) { - api->name = "gles32"; - api->GetFloatv = loadProc("glGetFloatv"); - api->TexBufferRange = loadProc("glTexBufferRange"); - api->IsBuffer = loadProc("glIsBuffer"); - api->IsTexture = loadProc("glIsTexture"); - api->DepthRangef = loadProc("glDepthRangef"); - api->EndConditionalRender = oc_glEndConditionalRender_noimpl; - api->BlendFunci = loadProc("glBlendFunci"); - api->GetProgramPipelineiv = loadProc("glGetProgramPipelineiv"); - api->WaitSync = loadProc("glWaitSync"); - api->ProgramUniformMatrix2fv = loadProc("glProgramUniformMatrix2fv"); - api->ProgramUniformMatrix4x3dv = oc_glProgramUniformMatrix4x3dv_noimpl; - api->VertexAttrib1dv = oc_glVertexAttrib1dv_noimpl; - api->SamplerParameteri = loadProc("glSamplerParameteri"); - api->GetVertexAttribIiv = loadProc("glGetVertexAttribIiv"); - api->GetSamplerParameterfv = loadProc("glGetSamplerParameterfv"); - api->VertexAttrib1d = oc_glVertexAttrib1d_noimpl; - api->TexBuffer = loadProc("glTexBuffer"); - api->InvalidateBufferData = oc_glInvalidateBufferData_noimpl; - api->ProgramUniform2i = loadProc("glProgramUniform2i"); - api->Uniform4dv = oc_glUniform4dv_noimpl; - api->UseProgram = loadProc("glUseProgram"); - api->VertexAttribI3iv = oc_glVertexAttribI3iv_noimpl; - api->DrawElementsIndirect = loadProc("glDrawElementsIndirect"); - api->VertexAttrib4uiv = oc_glVertexAttrib4uiv_noimpl; - api->GetQueryObjectiv = oc_glGetQueryObjectiv_noimpl; - api->FramebufferRenderbuffer = loadProc("glFramebufferRenderbuffer"); - api->BlendEquationi = loadProc("glBlendEquationi"); - api->GetActiveSubroutineName = oc_glGetActiveSubroutineName_noimpl; - api->VertexAttrib2s = oc_glVertexAttrib2s_noimpl; - api->VertexAttribL1d = oc_glVertexAttribL1d_noimpl; - api->BindTextures = oc_glBindTextures_noimpl; - api->VertexAttrib3sv = oc_glVertexAttrib3sv_noimpl; - api->GetFloati_v = oc_glGetFloati_v_noimpl; - api->BeginTransformFeedback = loadProc("glBeginTransformFeedback"); - api->ClearStencil = loadProc("glClearStencil"); - api->Uniform3i = loadProc("glUniform3i"); - api->ValidateProgramPipeline = loadProc("glValidateProgramPipeline"); - api->ProgramUniformMatrix4x2fv = loadProc("glProgramUniformMatrix4x2fv"); - api->VertexAttribI4ui = loadProc("glVertexAttribI4ui"); - api->GetShaderiv = loadProc("glGetShaderiv"); - api->ReadnPixels = loadProc("glReadnPixels"); - api->UniformMatrix4x2fv = loadProc("glUniformMatrix4x2fv"); - api->GetShaderPrecisionFormat = loadProc("glGetShaderPrecisionFormat"); - api->ProgramUniformMatrix2x3fv = loadProc("glProgramUniformMatrix2x3fv"); - api->TexSubImage3D = loadProc("glTexSubImage3D"); - api->GetProgramResourceLocationIndex = oc_glGetProgramResourceLocationIndex_noimpl; - api->BlendFunc = loadProc("glBlendFunc"); - api->ProgramUniformMatrix3x4fv = loadProc("glProgramUniformMatrix3x4fv"); - api->Uniform3d = oc_glUniform3d_noimpl; - api->VertexAttrib1sv = oc_glVertexAttrib1sv_noimpl; - api->BindFragDataLocation = oc_glBindFragDataLocation_noimpl; - api->VertexAttrib4bv = oc_glVertexAttrib4bv_noimpl; - api->Uniform4iv = loadProc("glUniform4iv"); - api->ProgramUniform2ui = loadProc("glProgramUniform2ui"); - api->DrawArrays = loadProc("glDrawArrays"); - api->ProgramBinary = loadProc("glProgramBinary"); - api->VertexAttrib4f = loadProc("glVertexAttrib4f"); - api->VertexAttribP2uiv = oc_glVertexAttribP2uiv_noimpl; - api->UniformMatrix3fv = loadProc("glUniformMatrix3fv"); - api->Uniform2i = loadProc("glUniform2i"); - api->GetQueryObjectuiv = loadProc("glGetQueryObjectuiv"); - api->UniformBlockBinding = loadProc("glUniformBlockBinding"); - api->SampleCoverage = loadProc("glSampleCoverage"); - api->VertexAttrib4Nusv = oc_glVertexAttrib4Nusv_noimpl; - api->ProgramUniformMatrix2x4dv = oc_glProgramUniformMatrix2x4dv_noimpl; - api->Uniform3uiv = loadProc("glUniform3uiv"); - api->VertexAttrib1s = oc_glVertexAttrib1s_noimpl; - api->GetVertexAttribPointerv = loadProc("glGetVertexAttribPointerv"); - api->BlendBarrier = loadProc("glBlendBarrier"); - api->DrawRangeElements = loadProc("glDrawRangeElements"); - api->TexStorage3D = loadProc("glTexStorage3D"); - api->GetInternalformati64v = oc_glGetInternalformati64v_noimpl; - api->GetQueryObjecti64v = oc_glGetQueryObjecti64v_noimpl; - api->CompressedTexSubImage1D = oc_glCompressedTexSubImage1D_noimpl; - api->VertexAttrib3dv = oc_glVertexAttrib3dv_noimpl; - api->VertexBindingDivisor = loadProc("glVertexBindingDivisor"); - api->UseProgramStages = loadProc("glUseProgramStages"); - api->VertexAttribBinding = loadProc("glVertexAttribBinding"); - api->DebugMessageInsert = loadProc("glDebugMessageInsert"); - api->GetTexParameteriv = loadProc("glGetTexParameteriv"); - api->MultiDrawArraysIndirect = oc_glMultiDrawArraysIndirect_noimpl; - api->GetTexParameterfv = loadProc("glGetTexParameterfv"); - api->GetProgramPipelineInfoLog = loadProc("glGetProgramPipelineInfoLog"); - api->EndQuery = loadProc("glEndQuery"); - api->GetProgramResourceLocation = loadProc("glGetProgramResourceLocation"); - api->CompressedTexImage2D = loadProc("glCompressedTexImage2D"); - api->VertexAttribP2ui = oc_glVertexAttribP2ui_noimpl; - api->IsEnabledi = loadProc("glIsEnabledi"); - api->GetActiveAtomicCounterBufferiv = oc_glGetActiveAtomicCounterBufferiv_noimpl; - api->IsProgram = loadProc("glIsProgram"); - api->Uniform1dv = oc_glUniform1dv_noimpl; - api->TexParameteriv = loadProc("glTexParameteriv"); - api->Uniform2fv = loadProc("glUniform2fv"); - api->ReleaseShaderCompiler = loadProc("glReleaseShaderCompiler"); - api->CullFace = loadProc("glCullFace"); - api->VertexAttribI4i = loadProc("glVertexAttribI4i"); - api->GetProgramResourceIndex = loadProc("glGetProgramResourceIndex"); - api->ShaderBinary = loadProc("glShaderBinary"); - api->UniformMatrix3x2dv = oc_glUniformMatrix3x2dv_noimpl; - api->InvalidateFramebuffer = loadProc("glInvalidateFramebuffer"); - api->AttachShader = loadProc("glAttachShader"); - api->FlushMappedBufferRange = loadProc("glFlushMappedBufferRange"); - api->VertexAttribP3uiv = oc_glVertexAttribP3uiv_noimpl; - api->GetActiveUniformName = oc_glGetActiveUniformName_noimpl; - api->MapBuffer = oc_glMapBuffer_noimpl; - api->DrawBuffers = loadProc("glDrawBuffers"); - api->GetSynciv = loadProc("glGetSynciv"); - api->CopyTexSubImage2D = loadProc("glCopyTexSubImage2D"); - api->ObjectLabel = loadProc("glObjectLabel"); - api->BufferSubData = loadProc("glBufferSubData"); - api->Uniform2f = loadProc("glUniform2f"); - api->DebugMessageCallback = loadProc("glDebugMessageCallback"); - api->VertexAttribL4dv = oc_glVertexAttribL4dv_noimpl; - api->IsProgramPipeline = loadProc("glIsProgramPipeline"); - api->ResumeTransformFeedback = loadProc("glResumeTransformFeedback"); - api->VertexAttribI4iv = loadProc("glVertexAttribI4iv"); - api->GetShaderInfoLog = loadProc("glGetShaderInfoLog"); - api->GetIntegeri_v = loadProc("glGetIntegeri_v"); - api->BindVertexBuffer = loadProc("glBindVertexBuffer"); - api->BlendEquation = loadProc("glBlendEquation"); - api->VertexAttribL2dv = oc_glVertexAttribL2dv_noimpl; - api->VertexAttribI1ui = oc_glVertexAttribI1ui_noimpl; - api->VertexAttrib4Nsv = oc_glVertexAttrib4Nsv_noimpl; - api->VertexAttribL4d = oc_glVertexAttribL4d_noimpl; - api->CopyImageSubData = loadProc("glCopyImageSubData"); - api->GetFramebufferAttachmentParameteriv = loadProc("glGetFramebufferAttachmentParameteriv"); - api->VertexAttribL2d = oc_glVertexAttribL2d_noimpl; - api->GetSubroutineIndex = oc_glGetSubroutineIndex_noimpl; - api->VertexAttribI3uiv = oc_glVertexAttribI3uiv_noimpl; - api->VertexAttrib4iv = oc_glVertexAttrib4iv_noimpl; - api->BindVertexBuffers = oc_glBindVertexBuffers_noimpl; - api->ProgramUniformMatrix2x3dv = oc_glProgramUniformMatrix2x3dv_noimpl; - api->PrimitiveBoundingBox = loadProc("glPrimitiveBoundingBox"); - api->Scissor = loadProc("glScissor"); - api->ClientWaitSync = loadProc("glClientWaitSync"); - api->Uniform3ui = loadProc("glUniform3ui"); - api->VertexAttribP3ui = oc_glVertexAttribP3ui_noimpl; - api->Enable = loadProc("glEnable"); - api->StencilOpSeparate = loadProc("glStencilOpSeparate"); - api->UniformMatrix2x3dv = oc_glUniformMatrix2x3dv_noimpl; - api->ProgramUniformMatrix3dv = oc_glProgramUniformMatrix3dv_noimpl; - api->TexImage2DMultisample = oc_glTexImage2DMultisample_noimpl; - api->VertexAttrib4Nbv = oc_glVertexAttrib4Nbv_noimpl; - api->GetTexImage = oc_glGetTexImage_noimpl; - api->VertexAttrib4sv = oc_glVertexAttrib4sv_noimpl; - api->PixelStorei = loadProc("glPixelStorei"); - api->DepthMask = loadProc("glDepthMask"); - api->TexStorage2D = loadProc("glTexStorage2D"); - api->Clear = loadProc("glClear"); - api->UniformMatrix3x4dv = oc_glUniformMatrix3x4dv_noimpl; - api->DeleteTransformFeedbacks = loadProc("glDeleteTransformFeedbacks"); - api->MapBufferRange = loadProc("glMapBufferRange"); - api->MemoryBarrier = loadProc("glMemoryBarrier"); - api->ViewportIndexedf = oc_glViewportIndexedf_noimpl; - api->VertexAttrib3fv = loadProc("glVertexAttrib3fv"); - api->ObjectPtrLabel = loadProc("glObjectPtrLabel"); - api->TexStorage1D = oc_glTexStorage1D_noimpl; - api->CompressedTexImage3D = loadProc("glCompressedTexImage3D"); - api->VertexAttrib1fv = loadProc("glVertexAttrib1fv"); - api->VertexAttribPointer = loadProc("glVertexAttribPointer"); - api->GetQueryIndexediv = oc_glGetQueryIndexediv_noimpl; - api->CompileShader = loadProc("glCompileShader"); - api->ProgramUniform1i = loadProc("glProgramUniform1i"); - api->GetQueryiv = loadProc("glGetQueryiv"); - api->VertexAttribI1iv = oc_glVertexAttribI1iv_noimpl; - api->CopyTexImage2D = loadProc("glCopyTexImage2D"); - api->GetQueryObjectui64v = oc_glGetQueryObjectui64v_noimpl; - api->PointSize = oc_glPointSize_noimpl; - api->Disablei = loadProc("glDisablei"); - api->VertexAttribL1dv = oc_glVertexAttribL1dv_noimpl; - api->CreateShader = loadProc("glCreateShader"); - api->GetString = loadProc("glGetString"); - api->ViewportArrayv = oc_glViewportArrayv_noimpl; - api->ProgramUniform3d = oc_glProgramUniform3d_noimpl; - api->VertexAttrib4Nubv = oc_glVertexAttrib4Nubv_noimpl; - api->TexParameteri = loadProc("glTexParameteri"); - api->ProgramUniform4fv = loadProc("glProgramUniform4fv"); - api->GenerateMipmap = loadProc("glGenerateMipmap"); - api->CompressedTexSubImage3D = loadProc("glCompressedTexSubImage3D"); - api->Uniform3f = loadProc("glUniform3f"); - api->GetUniformIndices = loadProc("glGetUniformIndices"); - api->VertexAttribLPointer = oc_glVertexAttribLPointer_noimpl; - api->VertexAttribI2uiv = oc_glVertexAttribI2uiv_noimpl; - api->QueryCounter = oc_glQueryCounter_noimpl; - api->ActiveShaderProgram = loadProc("glActiveShaderProgram"); - api->Uniform1ui = loadProc("glUniform1ui"); - api->VertexAttribI1i = oc_glVertexAttribI1i_noimpl; - api->GetTexParameterIiv = loadProc("glGetTexParameterIiv"); - api->GetUniformfv = loadProc("glGetUniformfv"); - api->ProgramUniform2uiv = loadProc("glProgramUniform2uiv"); - api->GetError = loadProc("glGetError"); - api->GetActiveUniformBlockName = loadProc("glGetActiveUniformBlockName"); - api->TextureView = oc_glTextureView_noimpl; - api->GetnUniformiv = loadProc("glGetnUniformiv"); - api->ProgramUniform4dv = oc_glProgramUniform4dv_noimpl; - api->ViewportIndexedfv = oc_glViewportIndexedfv_noimpl; - api->Hint = loadProc("glHint"); - api->GetShaderSource = loadProc("glGetShaderSource"); - api->ProgramUniformMatrix4x3fv = loadProc("glProgramUniformMatrix4x3fv"); - api->Uniform1iv = loadProc("glUniform1iv"); - api->VertexAttribI4bv = oc_glVertexAttribI4bv_noimpl; - api->UniformMatrix4x2dv = oc_glUniformMatrix4x2dv_noimpl; - api->BufferStorage = oc_glBufferStorage_noimpl; - api->IsRenderbuffer = loadProc("glIsRenderbuffer"); - api->GetActiveSubroutineUniformName = oc_glGetActiveSubroutineUniformName_noimpl; - api->LinkProgram = loadProc("glLinkProgram"); - api->GetActiveUniformsiv = loadProc("glGetActiveUniformsiv"); - api->GetDebugMessageLog = loadProc("glGetDebugMessageLog"); - api->CopyTexSubImage3D = loadProc("glCopyTexSubImage3D"); - api->PointParameteri = oc_glPointParameteri_noimpl; - api->ProgramUniform3dv = oc_glProgramUniform3dv_noimpl; - api->CompressedTexImage1D = oc_glCompressedTexImage1D_noimpl; - api->UniformMatrix3x4fv = loadProc("glUniformMatrix3x4fv"); - api->GenSamplers = loadProc("glGenSamplers"); - api->GetCompressedTexImage = oc_glGetCompressedTexImage_noimpl; - api->DeleteQueries = loadProc("glDeleteQueries"); - api->GenProgramPipelines = loadProc("glGenProgramPipelines"); - api->DispatchComputeIndirect = loadProc("glDispatchComputeIndirect"); - api->VertexAttribIPointer = loadProc("glVertexAttribIPointer"); - api->CreateProgram = loadProc("glCreateProgram"); - api->ClearTexSubImage = oc_glClearTexSubImage_noimpl; - api->VertexAttrib4d = oc_glVertexAttrib4d_noimpl; - api->FrontFace = loadProc("glFrontFace"); - api->BindTransformFeedback = loadProc("glBindTransformFeedback"); - api->GetProgramStageiv = oc_glGetProgramStageiv_noimpl; - api->SamplerParameterIiv = loadProc("glSamplerParameterIiv"); - api->GetInteger64v = loadProc("glGetInteger64v"); - api->CreateShaderProgramv = loadProc("glCreateShaderProgramv"); - api->BindBuffersRange = oc_glBindBuffersRange_noimpl; - api->Uniform3fv = loadProc("glUniform3fv"); - api->ProgramUniformMatrix4fv = loadProc("glProgramUniformMatrix4fv"); - api->BindBuffersBase = oc_glBindBuffersBase_noimpl; - api->ClearBufferfi = loadProc("glClearBufferfi"); - api->FramebufferTexture3D = oc_glFramebufferTexture3D_noimpl; - api->Disable = loadProc("glDisable"); - api->ProgramUniform1iv = loadProc("glProgramUniform1iv"); - api->VertexAttribI2iv = oc_glVertexAttribI2iv_noimpl; - api->DepthRangeIndexed = oc_glDepthRangeIndexed_noimpl; - api->PatchParameteri = loadProc("glPatchParameteri"); - api->GetUniformBlockIndex = loadProc("glGetUniformBlockIndex"); - api->MultiDrawArrays = oc_glMultiDrawArrays_noimpl; - api->VertexAttribI4ubv = oc_glVertexAttribI4ubv_noimpl; - api->BindBuffer = loadProc("glBindBuffer"); - api->VertexAttribI3i = oc_glVertexAttribI3i_noimpl; - api->GetDoublev = oc_glGetDoublev_noimpl; - api->DrawTransformFeedbackStream = oc_glDrawTransformFeedbackStream_noimpl; - api->VertexAttribI4uiv = loadProc("glVertexAttribI4uiv"); - api->RenderbufferStorageMultisample = loadProc("glRenderbufferStorageMultisample"); - api->VertexAttribL3dv = oc_glVertexAttribL3dv_noimpl; - api->StencilMaskSeparate = loadProc("glStencilMaskSeparate"); - api->ProgramUniform1d = oc_glProgramUniform1d_noimpl; - api->Viewport = loadProc("glViewport"); - api->VertexAttribP1ui = oc_glVertexAttribP1ui_noimpl; - api->VertexAttrib4dv = oc_glVertexAttrib4dv_noimpl; - api->GenQueries = loadProc("glGenQueries"); - api->TexParameterIiv = loadProc("glTexParameterIiv"); - api->ProgramUniform2d = oc_glProgramUniform2d_noimpl; - api->ProgramUniform1uiv = loadProc("glProgramUniform1uiv"); - api->VertexAttrib4Nub = oc_glVertexAttrib4Nub_noimpl; - api->IsVertexArray = loadProc("glIsVertexArray"); - api->ProgramUniform3f = loadProc("glProgramUniform3f"); - api->ProgramUniform3iv = loadProc("glProgramUniform3iv"); - api->GetProgramBinary = loadProc("glGetProgramBinary"); - api->BindRenderbuffer = loadProc("glBindRenderbuffer"); - api->BindFragDataLocationIndexed = oc_glBindFragDataLocationIndexed_noimpl; - api->GetSamplerParameterIiv = loadProc("glGetSamplerParameterIiv"); - api->VertexAttribDivisor = loadProc("glVertexAttribDivisor"); - api->ProgramUniformMatrix3x2dv = oc_glProgramUniformMatrix3x2dv_noimpl; - api->FramebufferParameteri = loadProc("glFramebufferParameteri"); - api->GenTransformFeedbacks = loadProc("glGenTransformFeedbacks"); - api->DeleteSync = loadProc("glDeleteSync"); - api->ProgramUniform1ui = loadProc("glProgramUniform1ui"); - api->TexSubImage1D = oc_glTexSubImage1D_noimpl; - api->ClearDepthf = loadProc("glClearDepthf"); - api->ReadPixels = loadProc("glReadPixels"); - api->VertexAttribI2i = oc_glVertexAttribI2i_noimpl; - api->Finish = loadProc("glFinish"); - api->LineWidth = loadProc("glLineWidth"); - api->DeleteShader = loadProc("glDeleteShader"); - api->IsSampler = loadProc("glIsSampler"); - api->ProgramUniformMatrix4dv = oc_glProgramUniformMatrix4dv_noimpl; - api->TransformFeedbackVaryings = loadProc("glTransformFeedbackVaryings"); - api->BeginConditionalRender = oc_glBeginConditionalRender_noimpl; - api->BindSamplers = oc_glBindSamplers_noimpl; - api->DeleteProgramPipelines = loadProc("glDeleteProgramPipelines"); - api->ColorMask = loadProc("glColorMask"); - api->TexParameterfv = loadProc("glTexParameterfv"); - api->PushDebugGroup = loadProc("glPushDebugGroup"); - api->ClearBufferfv = loadProc("glClearBufferfv"); - api->IsEnabled = loadProc("glIsEnabled"); - api->VertexAttrib2f = loadProc("glVertexAttrib2f"); - api->ProgramUniform2f = loadProc("glProgramUniform2f"); - api->GetSamplerParameterIuiv = loadProc("glGetSamplerParameterIuiv"); - api->GetInteger64i_v = loadProc("glGetInteger64i_v"); - api->Uniform2dv = oc_glUniform2dv_noimpl; - api->GetBufferSubData = oc_glGetBufferSubData_noimpl; - api->MultiDrawElementsIndirect = oc_glMultiDrawElementsIndirect_noimpl; - api->ProgramParameteri = loadProc("glProgramParameteri"); - api->VertexAttribP4ui = oc_glVertexAttribP4ui_noimpl; - api->SamplerParameterfv = loadProc("glSamplerParameterfv"); - api->PointParameterf = oc_glPointParameterf_noimpl; - api->UniformMatrix2x4fv = loadProc("glUniformMatrix2x4fv"); - api->GenBuffers = loadProc("glGenBuffers"); - api->ProgramUniform2dv = oc_glProgramUniform2dv_noimpl; - api->VertexAttribFormat = loadProc("glVertexAttribFormat"); - api->TexSubImage2D = loadProc("glTexSubImage2D"); - api->VertexAttrib4ubv = oc_glVertexAttrib4ubv_noimpl; - api->GetGraphicsResetStatus = loadProc("glGetGraphicsResetStatus"); - api->GetProgramInterfaceiv = loadProc("glGetProgramInterfaceiv"); - api->VertexAttribIFormat = loadProc("glVertexAttribIFormat"); - api->GetnUniformfv = loadProc("glGetnUniformfv"); - api->DeleteProgram = loadProc("glDeleteProgram"); - api->ClampColor = oc_glClampColor_noimpl; - api->DrawElementsInstancedBaseVertexBaseInstance = oc_glDrawElementsInstancedBaseVertexBaseInstance_noimpl; - api->DrawElements = loadProc("glDrawElements"); - api->DebugMessageControl = loadProc("glDebugMessageControl"); - api->GetRenderbufferParameteriv = loadProc("glGetRenderbufferParameteriv"); - api->DetachShader = loadProc("glDetachShader"); - api->GenFramebuffers = loadProc("glGenFramebuffers"); - api->ProvokingVertex = oc_glProvokingVertex_noimpl; - api->SampleMaski = loadProc("glSampleMaski"); - api->EndQueryIndexed = oc_glEndQueryIndexed_noimpl; - api->ProgramUniform1f = loadProc("glProgramUniform1f"); - api->BindFramebuffer = loadProc("glBindFramebuffer"); - api->BeginQueryIndexed = oc_glBeginQueryIndexed_noimpl; - api->UniformSubroutinesuiv = oc_glUniformSubroutinesuiv_noimpl; - api->GetUniformiv = loadProc("glGetUniformiv"); - api->FramebufferTexture = loadProc("glFramebufferTexture"); - api->PointParameterfv = oc_glPointParameterfv_noimpl; - api->IsTransformFeedback = loadProc("glIsTransformFeedback"); - api->CheckFramebufferStatus = loadProc("glCheckFramebufferStatus"); - api->ShaderSource = loadProc("glShaderSource"); - api->UniformMatrix2x4dv = oc_glUniformMatrix2x4dv_noimpl; - api->BindImageTextures = oc_glBindImageTextures_noimpl; - api->CopyTexImage1D = oc_glCopyTexImage1D_noimpl; - api->UniformMatrix3dv = oc_glUniformMatrix3dv_noimpl; - api->ProgramUniform1dv = oc_glProgramUniform1dv_noimpl; - api->BlitFramebuffer = loadProc("glBlitFramebuffer"); - api->PopDebugGroup = loadProc("glPopDebugGroup"); - api->TexParameterIuiv = loadProc("glTexParameterIuiv"); - api->VertexAttrib2d = oc_glVertexAttrib2d_noimpl; - api->TexImage1D = oc_glTexImage1D_noimpl; - api->GetObjectPtrLabel = loadProc("glGetObjectPtrLabel"); - api->StencilMask = loadProc("glStencilMask"); - api->BeginQuery = loadProc("glBeginQuery"); - api->UniformMatrix4fv = loadProc("glUniformMatrix4fv"); - api->IsSync = loadProc("glIsSync"); - api->Uniform3dv = oc_glUniform3dv_noimpl; - api->ProgramUniform2fv = loadProc("glProgramUniform2fv"); - api->VertexAttribI4sv = oc_glVertexAttribI4sv_noimpl; - api->ScissorArrayv = oc_glScissorArrayv_noimpl; - api->VertexAttribP1uiv = oc_glVertexAttribP1uiv_noimpl; - api->Uniform2uiv = loadProc("glUniform2uiv"); - api->DeleteBuffers = loadProc("glDeleteBuffers"); - api->ProgramUniform3ui = loadProc("glProgramUniform3ui"); - api->FramebufferTextureLayer = loadProc("glFramebufferTextureLayer"); - api->EndTransformFeedback = loadProc("glEndTransformFeedback"); - api->BlendFuncSeparatei = loadProc("glBlendFuncSeparatei"); - api->DrawTransformFeedbackInstanced = oc_glDrawTransformFeedbackInstanced_noimpl; - api->DrawRangeElementsBaseVertex = loadProc("glDrawRangeElementsBaseVertex"); - api->VertexAttrib1f = loadProc("glVertexAttrib1f"); - api->GetUniformSubroutineuiv = oc_glGetUniformSubroutineuiv_noimpl; - api->DisableVertexAttribArray = loadProc("glDisableVertexAttribArray"); - api->ProgramUniformMatrix3x2fv = loadProc("glProgramUniformMatrix3x2fv"); - api->VertexAttribI4usv = oc_glVertexAttribI4usv_noimpl; - api->GetObjectLabel = loadProc("glGetObjectLabel"); - api->BindAttribLocation = loadProc("glBindAttribLocation"); - api->Uniform1f = loadProc("glUniform1f"); - api->GetUniformdv = oc_glGetUniformdv_noimpl; - api->GetUniformLocation = loadProc("glGetUniformLocation"); - api->GetSubroutineUniformLocation = oc_glGetSubroutineUniformLocation_noimpl; - api->GetTexParameterIuiv = loadProc("glGetTexParameterIuiv"); - api->SamplerParameterf = loadProc("glSamplerParameterf"); - api->VertexAttribL3d = oc_glVertexAttribL3d_noimpl; - api->TexImage3DMultisample = oc_glTexImage3DMultisample_noimpl; - api->TexImage3D = loadProc("glTexImage3D"); - api->RenderbufferStorage = loadProc("glRenderbufferStorage"); - api->EnableVertexAttribArray = loadProc("glEnableVertexAttribArray"); - api->VertexAttribP4uiv = oc_glVertexAttribP4uiv_noimpl; - api->Uniform4d = oc_glUniform4d_noimpl; - api->VertexAttrib4s = oc_glVertexAttrib4s_noimpl; - api->DrawElementsInstancedBaseVertex = loadProc("glDrawElementsInstancedBaseVertex"); - api->VertexAttrib3s = oc_glVertexAttrib3s_noimpl; - api->ProgramUniform2iv = loadProc("glProgramUniform2iv"); - api->StencilFuncSeparate = loadProc("glStencilFuncSeparate"); - api->DeleteFramebuffers = loadProc("glDeleteFramebuffers"); - api->DepthRange = oc_glDepthRange_noimpl; - api->UniformMatrix3x2fv = loadProc("glUniformMatrix3x2fv"); - api->ProgramUniformMatrix2dv = oc_glProgramUniformMatrix2dv_noimpl; - api->ShaderStorageBlockBinding = oc_glShaderStorageBlockBinding_noimpl; - api->ClearDepth = oc_glClearDepth_noimpl; - api->VertexAttrib2dv = oc_glVertexAttrib2dv_noimpl; - api->SamplerParameterIuiv = loadProc("glSamplerParameterIuiv"); - api->GetVertexAttribLdv = oc_glGetVertexAttribLdv_noimpl; - api->ProgramUniformMatrix3x4dv = oc_glProgramUniformMatrix3x4dv_noimpl; - api->DepthRangeArrayv = oc_glDepthRangeArrayv_noimpl; - api->GetActiveUniform = loadProc("glGetActiveUniform"); - api->PatchParameterfv = oc_glPatchParameterfv_noimpl; - api->InvalidateTexImage = oc_glInvalidateTexImage_noimpl; - api->VertexAttrib3f = loadProc("glVertexAttrib3f"); - api->ProgramUniform4iv = loadProc("glProgramUniform4iv"); - api->ProgramUniform4d = oc_glProgramUniform4d_noimpl; - api->IsFramebuffer = loadProc("glIsFramebuffer"); - api->PixelStoref = oc_glPixelStoref_noimpl; - api->ProgramUniform4uiv = loadProc("glProgramUniform4uiv"); - api->ProgramUniformMatrix4x2dv = oc_glProgramUniformMatrix4x2dv_noimpl; - api->FenceSync = loadProc("glFenceSync"); - api->GetBufferParameteri64v = loadProc("glGetBufferParameteri64v"); - api->StencilOp = loadProc("glStencilOp"); - api->ClearBufferData = oc_glClearBufferData_noimpl; - api->GetnUniformuiv = loadProc("glGetnUniformuiv"); - api->GetProgramResourceiv = loadProc("glGetProgramResourceiv"); - api->GetVertexAttribdv = oc_glGetVertexAttribdv_noimpl; - api->GetTransformFeedbackVarying = loadProc("glGetTransformFeedbackVarying"); - api->VertexAttrib2fv = loadProc("glVertexAttrib2fv"); - api->GetBooleani_v = loadProc("glGetBooleani_v"); - api->ColorMaski = loadProc("glColorMaski"); - api->InvalidateBufferSubData = oc_glInvalidateBufferSubData_noimpl; - api->UniformMatrix4dv = oc_glUniformMatrix4dv_noimpl; - api->IsQuery = loadProc("glIsQuery"); - api->Uniform4ui = loadProc("glUniform4ui"); - api->Uniform4i = loadProc("glUniform4i"); - api->GetSamplerParameteriv = loadProc("glGetSamplerParameteriv"); - api->MultiDrawElementsBaseVertex = oc_glMultiDrawElementsBaseVertex_noimpl; - api->VertexAttribI1uiv = oc_glVertexAttribI1uiv_noimpl; - api->GetIntegerv = loadProc("glGetIntegerv"); - api->UniformMatrix2x3fv = loadProc("glUniformMatrix2x3fv"); - api->TexImage2D = loadProc("glTexImage2D"); - api->GetAttachedShaders = loadProc("glGetAttachedShaders"); - api->Uniform2d = oc_glUniform2d_noimpl; - api->MemoryBarrierByRegion = loadProc("glMemoryBarrierByRegion"); - api->UniformMatrix2fv = loadProc("glUniformMatrix2fv"); - api->PrimitiveRestartIndex = oc_glPrimitiveRestartIndex_noimpl; - api->GetVertexAttribiv = loadProc("glGetVertexAttribiv"); - api->GetAttribLocation = loadProc("glGetAttribLocation"); - api->TexStorage2DMultisample = loadProc("glTexStorage2DMultisample"); - api->CompressedTexSubImage2D = loadProc("glCompressedTexSubImage2D"); - api->GetVertexAttribfv = loadProc("glGetVertexAttribfv"); - api->GetBufferParameteriv = loadProc("glGetBufferParameteriv"); - api->TexParameterf = loadProc("glTexParameterf"); - api->FramebufferTexture2D = loadProc("glFramebufferTexture2D"); - api->GetActiveAttrib = loadProc("glGetActiveAttrib"); - api->InvalidateTexSubImage = oc_glInvalidateTexSubImage_noimpl; - api->DeleteVertexArrays = loadProc("glDeleteVertexArrays"); - api->VertexAttribI2ui = oc_glVertexAttribI2ui_noimpl; - api->PointParameteriv = oc_glPointParameteriv_noimpl; - api->GetPointerv = loadProc("glGetPointerv"); - api->Enablei = loadProc("glEnablei"); - api->BindBufferRange = loadProc("glBindBufferRange"); - api->DrawArraysInstanced = loadProc("glDrawArraysInstanced"); - api->DeleteTextures = loadProc("glDeleteTextures"); - api->VertexAttrib4Niv = oc_glVertexAttrib4Niv_noimpl; - api->MultiDrawElements = oc_glMultiDrawElements_noimpl; - api->GetProgramiv = loadProc("glGetProgramiv"); - api->DepthFunc = loadProc("glDepthFunc"); - api->GenTextures = loadProc("glGenTextures"); - api->GetInternalformativ = loadProc("glGetInternalformativ"); - api->ProgramUniform3i = loadProc("glProgramUniform3i"); - api->ScissorIndexed = oc_glScissorIndexed_noimpl; - api->VertexAttrib2sv = oc_glVertexAttrib2sv_noimpl; - api->TexStorage3DMultisample = loadProc("glTexStorage3DMultisample"); - api->Uniform2iv = loadProc("glUniform2iv"); - api->DrawArraysInstancedBaseInstance = oc_glDrawArraysInstancedBaseInstance_noimpl; - api->VertexAttribI3ui = oc_glVertexAttribI3ui_noimpl; - api->DeleteSamplers = loadProc("glDeleteSamplers"); - api->GenVertexArrays = loadProc("glGenVertexArrays"); - api->GetFramebufferParameteriv = loadProc("glGetFramebufferParameteriv"); - api->PolygonMode = oc_glPolygonMode_noimpl; - api->ProgramUniformMatrix2x4fv = loadProc("glProgramUniformMatrix2x4fv"); - api->GetProgramResourceName = loadProc("glGetProgramResourceName"); - api->SamplerParameteriv = loadProc("glSamplerParameteriv"); - api->GetActiveSubroutineUniformiv = oc_glGetActiveSubroutineUniformiv_noimpl; - api->GetStringi = loadProc("glGetStringi"); - api->VertexAttribLFormat = oc_glVertexAttribLFormat_noimpl; - api->VertexAttrib3d = oc_glVertexAttrib3d_noimpl; - api->BindVertexArray = loadProc("glBindVertexArray"); - api->UnmapBuffer = loadProc("glUnmapBuffer"); - api->DrawElementsInstancedBaseInstance = oc_glDrawElementsInstancedBaseInstance_noimpl; - api->Uniform4uiv = loadProc("glUniform4uiv"); - api->FramebufferTexture1D = oc_glFramebufferTexture1D_noimpl; - api->DrawTransformFeedbackStreamInstanced = oc_glDrawTransformFeedbackStreamInstanced_noimpl; - api->StencilFunc = loadProc("glStencilFunc"); - api->ValidateProgram = loadProc("glValidateProgram"); - api->Flush = loadProc("glFlush"); - api->ProgramUniform3uiv = loadProc("glProgramUniform3uiv"); - api->DeleteRenderbuffers = loadProc("glDeleteRenderbuffers"); - api->VertexAttrib4fv = loadProc("glVertexAttrib4fv"); - api->UniformMatrix2dv = oc_glUniformMatrix2dv_noimpl; - api->GetFragDataIndex = oc_glGetFragDataIndex_noimpl; - api->Uniform3iv = loadProc("glUniform3iv"); - api->MinSampleShading = loadProc("glMinSampleShading"); - api->GetBooleanv = loadProc("glGetBooleanv"); - api->GetMultisamplefv = loadProc("glGetMultisamplefv"); - api->GetVertexAttribIuiv = loadProc("glGetVertexAttribIuiv"); - api->GetProgramInfoLog = loadProc("glGetProgramInfoLog"); - api->Uniform4fv = loadProc("glUniform4fv"); - api->DrawBuffer = oc_glDrawBuffer_noimpl; - api->Uniform1i = loadProc("glUniform1i"); - api->ProgramUniform4ui = loadProc("glProgramUniform4ui"); - api->ProgramUniformMatrix3fv = loadProc("glProgramUniformMatrix3fv"); - api->BlendEquationSeparate = loadProc("glBlendEquationSeparate"); - api->BindProgramPipeline = loadProc("glBindProgramPipeline"); - api->GetDoublei_v = oc_glGetDoublei_v_noimpl; - api->BufferData = loadProc("glBufferData"); - api->ClearColor = loadProc("glClearColor"); - api->ProgramUniform4i = loadProc("glProgramUniform4i"); - api->GetTexLevelParameteriv = loadProc("glGetTexLevelParameteriv"); - api->GetActiveUniformBlockiv = loadProc("glGetActiveUniformBlockiv"); - api->ProgramUniform1fv = loadProc("glProgramUniform1fv"); - api->PauseTransformFeedback = loadProc("glPauseTransformFeedback"); - api->GetBufferPointerv = loadProc("glGetBufferPointerv"); - api->InvalidateSubFramebuffer = loadProc("glInvalidateSubFramebuffer"); - api->ScissorIndexedv = oc_glScissorIndexedv_noimpl; - api->Uniform2ui = loadProc("glUniform2ui"); - api->BindTexture = loadProc("glBindTexture"); - api->DrawElementsInstanced = loadProc("glDrawElementsInstanced"); - api->ProgramUniform4f = loadProc("glProgramUniform4f"); - api->BindBufferBase = loadProc("glBindBufferBase"); - api->IsShader = loadProc("glIsShader"); - api->ClearBufferSubData = oc_glClearBufferSubData_noimpl; - api->VertexAttrib4Nuiv = oc_glVertexAttrib4Nuiv_noimpl; - api->DrawArraysIndirect = loadProc("glDrawArraysIndirect"); - api->VertexAttrib4usv = oc_glVertexAttrib4usv_noimpl; - api->Uniform1d = oc_glUniform1d_noimpl; - api->ClearTexImage = oc_glClearTexImage_noimpl; - api->Uniform1uiv = loadProc("glUniform1uiv"); - api->BindSampler = loadProc("glBindSampler"); - api->GetTexLevelParameterfv = loadProc("glGetTexLevelParameterfv"); - api->ClearBufferiv = loadProc("glClearBufferiv"); - api->LogicOp = oc_glLogicOp_noimpl; - api->ActiveTexture = loadProc("glActiveTexture"); - api->GetFragDataLocation = loadProc("glGetFragDataLocation"); - api->BlendColor = loadProc("glBlendColor"); - api->UniformMatrix4x3fv = loadProc("glUniformMatrix4x3fv"); - api->ProgramUniform3fv = loadProc("glProgramUniform3fv"); - api->Uniform1fv = loadProc("glUniform1fv"); - api->DrawElementsBaseVertex = loadProc("glDrawElementsBaseVertex"); - api->Uniform4f = loadProc("glUniform4f"); - api->BlendEquationSeparatei = loadProc("glBlendEquationSeparatei"); - api->BlendFuncSeparate = loadProc("glBlendFuncSeparate"); - api->ClearBufferuiv = loadProc("glClearBufferuiv"); - api->CopyTexSubImage1D = oc_glCopyTexSubImage1D_noimpl; - api->DrawTransformFeedback = oc_glDrawTransformFeedback_noimpl; - api->ReadBuffer = loadProc("glReadBuffer"); - api->CopyBufferSubData = loadProc("glCopyBufferSubData"); - api->GetUniformuiv = loadProc("glGetUniformuiv"); - api->PolygonOffset = loadProc("glPolygonOffset"); - api->DispatchCompute = loadProc("glDispatchCompute"); - api->BindImageTexture = loadProc("glBindImageTexture"); - api->UniformMatrix4x3dv = oc_glUniformMatrix4x3dv_noimpl; - api->GenRenderbuffers = loadProc("glGenRenderbuffers"); + api->name = "gles32"; + api->GetFloatv = loadProc("glGetFloatv"); + api->TexBufferRange = loadProc("glTexBufferRange"); + api->IsBuffer = loadProc("glIsBuffer"); + api->IsTexture = loadProc("glIsTexture"); + api->DepthRangef = loadProc("glDepthRangef"); + api->EndConditionalRender = oc_glEndConditionalRender_noimpl; + api->BlendFunci = loadProc("glBlendFunci"); + api->GetProgramPipelineiv = loadProc("glGetProgramPipelineiv"); + api->WaitSync = loadProc("glWaitSync"); + api->ProgramUniformMatrix2fv = loadProc("glProgramUniformMatrix2fv"); + api->ProgramUniformMatrix4x3dv = oc_glProgramUniformMatrix4x3dv_noimpl; + api->VertexAttrib1dv = oc_glVertexAttrib1dv_noimpl; + api->SamplerParameteri = loadProc("glSamplerParameteri"); + api->GetVertexAttribIiv = loadProc("glGetVertexAttribIiv"); + api->GetSamplerParameterfv = loadProc("glGetSamplerParameterfv"); + api->VertexAttrib1d = oc_glVertexAttrib1d_noimpl; + api->TexBuffer = loadProc("glTexBuffer"); + api->InvalidateBufferData = oc_glInvalidateBufferData_noimpl; + api->ProgramUniform2i = loadProc("glProgramUniform2i"); + api->Uniform4dv = oc_glUniform4dv_noimpl; + api->UseProgram = loadProc("glUseProgram"); + api->VertexAttribI3iv = oc_glVertexAttribI3iv_noimpl; + api->DrawElementsIndirect = loadProc("glDrawElementsIndirect"); + api->VertexAttrib4uiv = oc_glVertexAttrib4uiv_noimpl; + api->GetQueryObjectiv = oc_glGetQueryObjectiv_noimpl; + api->FramebufferRenderbuffer = loadProc("glFramebufferRenderbuffer"); + api->BlendEquationi = loadProc("glBlendEquationi"); + api->GetActiveSubroutineName = oc_glGetActiveSubroutineName_noimpl; + api->VertexAttrib2s = oc_glVertexAttrib2s_noimpl; + api->VertexAttribL1d = oc_glVertexAttribL1d_noimpl; + api->BindTextures = oc_glBindTextures_noimpl; + api->VertexAttrib3sv = oc_glVertexAttrib3sv_noimpl; + api->GetFloati_v = oc_glGetFloati_v_noimpl; + api->BeginTransformFeedback = loadProc("glBeginTransformFeedback"); + api->ClearStencil = loadProc("glClearStencil"); + api->Uniform3i = loadProc("glUniform3i"); + api->ValidateProgramPipeline = loadProc("glValidateProgramPipeline"); + api->ProgramUniformMatrix4x2fv = loadProc("glProgramUniformMatrix4x2fv"); + api->VertexAttribI4ui = loadProc("glVertexAttribI4ui"); + api->GetShaderiv = loadProc("glGetShaderiv"); + api->ReadnPixels = loadProc("glReadnPixels"); + api->UniformMatrix4x2fv = loadProc("glUniformMatrix4x2fv"); + api->GetShaderPrecisionFormat = loadProc("glGetShaderPrecisionFormat"); + api->ProgramUniformMatrix2x3fv = loadProc("glProgramUniformMatrix2x3fv"); + api->TexSubImage3D = loadProc("glTexSubImage3D"); + api->GetProgramResourceLocationIndex = oc_glGetProgramResourceLocationIndex_noimpl; + api->BlendFunc = loadProc("glBlendFunc"); + api->ProgramUniformMatrix3x4fv = loadProc("glProgramUniformMatrix3x4fv"); + api->Uniform3d = oc_glUniform3d_noimpl; + api->VertexAttrib1sv = oc_glVertexAttrib1sv_noimpl; + api->BindFragDataLocation = oc_glBindFragDataLocation_noimpl; + api->VertexAttrib4bv = oc_glVertexAttrib4bv_noimpl; + api->Uniform4iv = loadProc("glUniform4iv"); + api->ProgramUniform2ui = loadProc("glProgramUniform2ui"); + api->DrawArrays = loadProc("glDrawArrays"); + api->ProgramBinary = loadProc("glProgramBinary"); + api->VertexAttrib4f = loadProc("glVertexAttrib4f"); + api->VertexAttribP2uiv = oc_glVertexAttribP2uiv_noimpl; + api->UniformMatrix3fv = loadProc("glUniformMatrix3fv"); + api->Uniform2i = loadProc("glUniform2i"); + api->GetQueryObjectuiv = loadProc("glGetQueryObjectuiv"); + api->UniformBlockBinding = loadProc("glUniformBlockBinding"); + api->SampleCoverage = loadProc("glSampleCoverage"); + api->VertexAttrib4Nusv = oc_glVertexAttrib4Nusv_noimpl; + api->ProgramUniformMatrix2x4dv = oc_glProgramUniformMatrix2x4dv_noimpl; + api->Uniform3uiv = loadProc("glUniform3uiv"); + api->VertexAttrib1s = oc_glVertexAttrib1s_noimpl; + api->GetVertexAttribPointerv = loadProc("glGetVertexAttribPointerv"); + api->BlendBarrier = loadProc("glBlendBarrier"); + api->DrawRangeElements = loadProc("glDrawRangeElements"); + api->TexStorage3D = loadProc("glTexStorage3D"); + api->GetInternalformati64v = oc_glGetInternalformati64v_noimpl; + api->GetQueryObjecti64v = oc_glGetQueryObjecti64v_noimpl; + api->CompressedTexSubImage1D = oc_glCompressedTexSubImage1D_noimpl; + api->VertexAttrib3dv = oc_glVertexAttrib3dv_noimpl; + api->VertexBindingDivisor = loadProc("glVertexBindingDivisor"); + api->UseProgramStages = loadProc("glUseProgramStages"); + api->VertexAttribBinding = loadProc("glVertexAttribBinding"); + api->DebugMessageInsert = loadProc("glDebugMessageInsert"); + api->GetTexParameteriv = loadProc("glGetTexParameteriv"); + api->MultiDrawArraysIndirect = oc_glMultiDrawArraysIndirect_noimpl; + api->GetTexParameterfv = loadProc("glGetTexParameterfv"); + api->GetProgramPipelineInfoLog = loadProc("glGetProgramPipelineInfoLog"); + api->EndQuery = loadProc("glEndQuery"); + api->GetProgramResourceLocation = loadProc("glGetProgramResourceLocation"); + api->CompressedTexImage2D = loadProc("glCompressedTexImage2D"); + api->VertexAttribP2ui = oc_glVertexAttribP2ui_noimpl; + api->IsEnabledi = loadProc("glIsEnabledi"); + api->GetActiveAtomicCounterBufferiv = oc_glGetActiveAtomicCounterBufferiv_noimpl; + api->IsProgram = loadProc("glIsProgram"); + api->Uniform1dv = oc_glUniform1dv_noimpl; + api->TexParameteriv = loadProc("glTexParameteriv"); + api->Uniform2fv = loadProc("glUniform2fv"); + api->ReleaseShaderCompiler = loadProc("glReleaseShaderCompiler"); + api->CullFace = loadProc("glCullFace"); + api->VertexAttribI4i = loadProc("glVertexAttribI4i"); + api->GetProgramResourceIndex = loadProc("glGetProgramResourceIndex"); + api->ShaderBinary = loadProc("glShaderBinary"); + api->UniformMatrix3x2dv = oc_glUniformMatrix3x2dv_noimpl; + api->InvalidateFramebuffer = loadProc("glInvalidateFramebuffer"); + api->AttachShader = loadProc("glAttachShader"); + api->FlushMappedBufferRange = loadProc("glFlushMappedBufferRange"); + api->VertexAttribP3uiv = oc_glVertexAttribP3uiv_noimpl; + api->GetActiveUniformName = oc_glGetActiveUniformName_noimpl; + api->MapBuffer = oc_glMapBuffer_noimpl; + api->DrawBuffers = loadProc("glDrawBuffers"); + api->GetSynciv = loadProc("glGetSynciv"); + api->CopyTexSubImage2D = loadProc("glCopyTexSubImage2D"); + api->ObjectLabel = loadProc("glObjectLabel"); + api->BufferSubData = loadProc("glBufferSubData"); + api->Uniform2f = loadProc("glUniform2f"); + api->DebugMessageCallback = loadProc("glDebugMessageCallback"); + api->VertexAttribL4dv = oc_glVertexAttribL4dv_noimpl; + api->IsProgramPipeline = loadProc("glIsProgramPipeline"); + api->ResumeTransformFeedback = loadProc("glResumeTransformFeedback"); + api->VertexAttribI4iv = loadProc("glVertexAttribI4iv"); + api->GetShaderInfoLog = loadProc("glGetShaderInfoLog"); + api->GetIntegeri_v = loadProc("glGetIntegeri_v"); + api->BindVertexBuffer = loadProc("glBindVertexBuffer"); + api->BlendEquation = loadProc("glBlendEquation"); + api->VertexAttribL2dv = oc_glVertexAttribL2dv_noimpl; + api->VertexAttribI1ui = oc_glVertexAttribI1ui_noimpl; + api->VertexAttrib4Nsv = oc_glVertexAttrib4Nsv_noimpl; + api->VertexAttribL4d = oc_glVertexAttribL4d_noimpl; + api->CopyImageSubData = loadProc("glCopyImageSubData"); + api->GetFramebufferAttachmentParameteriv = loadProc("glGetFramebufferAttachmentParameteriv"); + api->VertexAttribL2d = oc_glVertexAttribL2d_noimpl; + api->GetSubroutineIndex = oc_glGetSubroutineIndex_noimpl; + api->VertexAttribI3uiv = oc_glVertexAttribI3uiv_noimpl; + api->VertexAttrib4iv = oc_glVertexAttrib4iv_noimpl; + api->BindVertexBuffers = oc_glBindVertexBuffers_noimpl; + api->ProgramUniformMatrix2x3dv = oc_glProgramUniformMatrix2x3dv_noimpl; + api->PrimitiveBoundingBox = loadProc("glPrimitiveBoundingBox"); + api->Scissor = loadProc("glScissor"); + api->ClientWaitSync = loadProc("glClientWaitSync"); + api->Uniform3ui = loadProc("glUniform3ui"); + api->VertexAttribP3ui = oc_glVertexAttribP3ui_noimpl; + api->Enable = loadProc("glEnable"); + api->StencilOpSeparate = loadProc("glStencilOpSeparate"); + api->UniformMatrix2x3dv = oc_glUniformMatrix2x3dv_noimpl; + api->ProgramUniformMatrix3dv = oc_glProgramUniformMatrix3dv_noimpl; + api->TexImage2DMultisample = oc_glTexImage2DMultisample_noimpl; + api->VertexAttrib4Nbv = oc_glVertexAttrib4Nbv_noimpl; + api->GetTexImage = oc_glGetTexImage_noimpl; + api->VertexAttrib4sv = oc_glVertexAttrib4sv_noimpl; + api->PixelStorei = loadProc("glPixelStorei"); + api->DepthMask = loadProc("glDepthMask"); + api->TexStorage2D = loadProc("glTexStorage2D"); + api->Clear = loadProc("glClear"); + api->UniformMatrix3x4dv = oc_glUniformMatrix3x4dv_noimpl; + api->DeleteTransformFeedbacks = loadProc("glDeleteTransformFeedbacks"); + api->MapBufferRange = loadProc("glMapBufferRange"); + api->MemoryBarrier = loadProc("glMemoryBarrier"); + api->ViewportIndexedf = oc_glViewportIndexedf_noimpl; + api->VertexAttrib3fv = loadProc("glVertexAttrib3fv"); + api->ObjectPtrLabel = loadProc("glObjectPtrLabel"); + api->TexStorage1D = oc_glTexStorage1D_noimpl; + api->CompressedTexImage3D = loadProc("glCompressedTexImage3D"); + api->VertexAttrib1fv = loadProc("glVertexAttrib1fv"); + api->VertexAttribPointer = loadProc("glVertexAttribPointer"); + api->GetQueryIndexediv = oc_glGetQueryIndexediv_noimpl; + api->CompileShader = loadProc("glCompileShader"); + api->ProgramUniform1i = loadProc("glProgramUniform1i"); + api->GetQueryiv = loadProc("glGetQueryiv"); + api->VertexAttribI1iv = oc_glVertexAttribI1iv_noimpl; + api->CopyTexImage2D = loadProc("glCopyTexImage2D"); + api->GetQueryObjectui64v = oc_glGetQueryObjectui64v_noimpl; + api->PointSize = oc_glPointSize_noimpl; + api->Disablei = loadProc("glDisablei"); + api->VertexAttribL1dv = oc_glVertexAttribL1dv_noimpl; + api->CreateShader = loadProc("glCreateShader"); + api->GetString = loadProc("glGetString"); + api->ViewportArrayv = oc_glViewportArrayv_noimpl; + api->ProgramUniform3d = oc_glProgramUniform3d_noimpl; + api->VertexAttrib4Nubv = oc_glVertexAttrib4Nubv_noimpl; + api->TexParameteri = loadProc("glTexParameteri"); + api->ProgramUniform4fv = loadProc("glProgramUniform4fv"); + api->GenerateMipmap = loadProc("glGenerateMipmap"); + api->CompressedTexSubImage3D = loadProc("glCompressedTexSubImage3D"); + api->Uniform3f = loadProc("glUniform3f"); + api->GetUniformIndices = loadProc("glGetUniformIndices"); + api->VertexAttribLPointer = oc_glVertexAttribLPointer_noimpl; + api->VertexAttribI2uiv = oc_glVertexAttribI2uiv_noimpl; + api->QueryCounter = oc_glQueryCounter_noimpl; + api->ActiveShaderProgram = loadProc("glActiveShaderProgram"); + api->Uniform1ui = loadProc("glUniform1ui"); + api->VertexAttribI1i = oc_glVertexAttribI1i_noimpl; + api->GetTexParameterIiv = loadProc("glGetTexParameterIiv"); + api->GetUniformfv = loadProc("glGetUniformfv"); + api->ProgramUniform2uiv = loadProc("glProgramUniform2uiv"); + api->GetError = loadProc("glGetError"); + api->GetActiveUniformBlockName = loadProc("glGetActiveUniformBlockName"); + api->TextureView = oc_glTextureView_noimpl; + api->GetnUniformiv = loadProc("glGetnUniformiv"); + api->ProgramUniform4dv = oc_glProgramUniform4dv_noimpl; + api->ViewportIndexedfv = oc_glViewportIndexedfv_noimpl; + api->Hint = loadProc("glHint"); + api->GetShaderSource = loadProc("glGetShaderSource"); + api->ProgramUniformMatrix4x3fv = loadProc("glProgramUniformMatrix4x3fv"); + api->Uniform1iv = loadProc("glUniform1iv"); + api->VertexAttribI4bv = oc_glVertexAttribI4bv_noimpl; + api->UniformMatrix4x2dv = oc_glUniformMatrix4x2dv_noimpl; + api->BufferStorage = oc_glBufferStorage_noimpl; + api->IsRenderbuffer = loadProc("glIsRenderbuffer"); + api->GetActiveSubroutineUniformName = oc_glGetActiveSubroutineUniformName_noimpl; + api->LinkProgram = loadProc("glLinkProgram"); + api->GetActiveUniformsiv = loadProc("glGetActiveUniformsiv"); + api->GetDebugMessageLog = loadProc("glGetDebugMessageLog"); + api->CopyTexSubImage3D = loadProc("glCopyTexSubImage3D"); + api->PointParameteri = oc_glPointParameteri_noimpl; + api->ProgramUniform3dv = oc_glProgramUniform3dv_noimpl; + api->CompressedTexImage1D = oc_glCompressedTexImage1D_noimpl; + api->UniformMatrix3x4fv = loadProc("glUniformMatrix3x4fv"); + api->GenSamplers = loadProc("glGenSamplers"); + api->GetCompressedTexImage = oc_glGetCompressedTexImage_noimpl; + api->DeleteQueries = loadProc("glDeleteQueries"); + api->GenProgramPipelines = loadProc("glGenProgramPipelines"); + api->DispatchComputeIndirect = loadProc("glDispatchComputeIndirect"); + api->VertexAttribIPointer = loadProc("glVertexAttribIPointer"); + api->CreateProgram = loadProc("glCreateProgram"); + api->ClearTexSubImage = oc_glClearTexSubImage_noimpl; + api->VertexAttrib4d = oc_glVertexAttrib4d_noimpl; + api->FrontFace = loadProc("glFrontFace"); + api->BindTransformFeedback = loadProc("glBindTransformFeedback"); + api->GetProgramStageiv = oc_glGetProgramStageiv_noimpl; + api->SamplerParameterIiv = loadProc("glSamplerParameterIiv"); + api->GetInteger64v = loadProc("glGetInteger64v"); + api->CreateShaderProgramv = loadProc("glCreateShaderProgramv"); + api->BindBuffersRange = oc_glBindBuffersRange_noimpl; + api->Uniform3fv = loadProc("glUniform3fv"); + api->ProgramUniformMatrix4fv = loadProc("glProgramUniformMatrix4fv"); + api->BindBuffersBase = oc_glBindBuffersBase_noimpl; + api->ClearBufferfi = loadProc("glClearBufferfi"); + api->FramebufferTexture3D = oc_glFramebufferTexture3D_noimpl; + api->Disable = loadProc("glDisable"); + api->ProgramUniform1iv = loadProc("glProgramUniform1iv"); + api->VertexAttribI2iv = oc_glVertexAttribI2iv_noimpl; + api->DepthRangeIndexed = oc_glDepthRangeIndexed_noimpl; + api->PatchParameteri = loadProc("glPatchParameteri"); + api->GetUniformBlockIndex = loadProc("glGetUniformBlockIndex"); + api->MultiDrawArrays = oc_glMultiDrawArrays_noimpl; + api->VertexAttribI4ubv = oc_glVertexAttribI4ubv_noimpl; + api->BindBuffer = loadProc("glBindBuffer"); + api->VertexAttribI3i = oc_glVertexAttribI3i_noimpl; + api->GetDoublev = oc_glGetDoublev_noimpl; + api->DrawTransformFeedbackStream = oc_glDrawTransformFeedbackStream_noimpl; + api->VertexAttribI4uiv = loadProc("glVertexAttribI4uiv"); + api->RenderbufferStorageMultisample = loadProc("glRenderbufferStorageMultisample"); + api->VertexAttribL3dv = oc_glVertexAttribL3dv_noimpl; + api->StencilMaskSeparate = loadProc("glStencilMaskSeparate"); + api->ProgramUniform1d = oc_glProgramUniform1d_noimpl; + api->Viewport = loadProc("glViewport"); + api->VertexAttribP1ui = oc_glVertexAttribP1ui_noimpl; + api->VertexAttrib4dv = oc_glVertexAttrib4dv_noimpl; + api->GenQueries = loadProc("glGenQueries"); + api->TexParameterIiv = loadProc("glTexParameterIiv"); + api->ProgramUniform2d = oc_glProgramUniform2d_noimpl; + api->ProgramUniform1uiv = loadProc("glProgramUniform1uiv"); + api->VertexAttrib4Nub = oc_glVertexAttrib4Nub_noimpl; + api->IsVertexArray = loadProc("glIsVertexArray"); + api->ProgramUniform3f = loadProc("glProgramUniform3f"); + api->ProgramUniform3iv = loadProc("glProgramUniform3iv"); + api->GetProgramBinary = loadProc("glGetProgramBinary"); + api->BindRenderbuffer = loadProc("glBindRenderbuffer"); + api->BindFragDataLocationIndexed = oc_glBindFragDataLocationIndexed_noimpl; + api->GetSamplerParameterIiv = loadProc("glGetSamplerParameterIiv"); + api->VertexAttribDivisor = loadProc("glVertexAttribDivisor"); + api->ProgramUniformMatrix3x2dv = oc_glProgramUniformMatrix3x2dv_noimpl; + api->FramebufferParameteri = loadProc("glFramebufferParameteri"); + api->GenTransformFeedbacks = loadProc("glGenTransformFeedbacks"); + api->DeleteSync = loadProc("glDeleteSync"); + api->ProgramUniform1ui = loadProc("glProgramUniform1ui"); + api->TexSubImage1D = oc_glTexSubImage1D_noimpl; + api->ClearDepthf = loadProc("glClearDepthf"); + api->ReadPixels = loadProc("glReadPixels"); + api->VertexAttribI2i = oc_glVertexAttribI2i_noimpl; + api->Finish = loadProc("glFinish"); + api->LineWidth = loadProc("glLineWidth"); + api->DeleteShader = loadProc("glDeleteShader"); + api->IsSampler = loadProc("glIsSampler"); + api->ProgramUniformMatrix4dv = oc_glProgramUniformMatrix4dv_noimpl; + api->TransformFeedbackVaryings = loadProc("glTransformFeedbackVaryings"); + api->BeginConditionalRender = oc_glBeginConditionalRender_noimpl; + api->BindSamplers = oc_glBindSamplers_noimpl; + api->DeleteProgramPipelines = loadProc("glDeleteProgramPipelines"); + api->ColorMask = loadProc("glColorMask"); + api->TexParameterfv = loadProc("glTexParameterfv"); + api->PushDebugGroup = loadProc("glPushDebugGroup"); + api->ClearBufferfv = loadProc("glClearBufferfv"); + api->IsEnabled = loadProc("glIsEnabled"); + api->VertexAttrib2f = loadProc("glVertexAttrib2f"); + api->ProgramUniform2f = loadProc("glProgramUniform2f"); + api->GetSamplerParameterIuiv = loadProc("glGetSamplerParameterIuiv"); + api->GetInteger64i_v = loadProc("glGetInteger64i_v"); + api->Uniform2dv = oc_glUniform2dv_noimpl; + api->GetBufferSubData = oc_glGetBufferSubData_noimpl; + api->MultiDrawElementsIndirect = oc_glMultiDrawElementsIndirect_noimpl; + api->ProgramParameteri = loadProc("glProgramParameteri"); + api->VertexAttribP4ui = oc_glVertexAttribP4ui_noimpl; + api->SamplerParameterfv = loadProc("glSamplerParameterfv"); + api->PointParameterf = oc_glPointParameterf_noimpl; + api->UniformMatrix2x4fv = loadProc("glUniformMatrix2x4fv"); + api->GenBuffers = loadProc("glGenBuffers"); + api->ProgramUniform2dv = oc_glProgramUniform2dv_noimpl; + api->VertexAttribFormat = loadProc("glVertexAttribFormat"); + api->TexSubImage2D = loadProc("glTexSubImage2D"); + api->VertexAttrib4ubv = oc_glVertexAttrib4ubv_noimpl; + api->GetGraphicsResetStatus = loadProc("glGetGraphicsResetStatus"); + api->GetProgramInterfaceiv = loadProc("glGetProgramInterfaceiv"); + api->VertexAttribIFormat = loadProc("glVertexAttribIFormat"); + api->GetnUniformfv = loadProc("glGetnUniformfv"); + api->DeleteProgram = loadProc("glDeleteProgram"); + api->ClampColor = oc_glClampColor_noimpl; + api->DrawElementsInstancedBaseVertexBaseInstance = oc_glDrawElementsInstancedBaseVertexBaseInstance_noimpl; + api->DrawElements = loadProc("glDrawElements"); + api->DebugMessageControl = loadProc("glDebugMessageControl"); + api->GetRenderbufferParameteriv = loadProc("glGetRenderbufferParameteriv"); + api->DetachShader = loadProc("glDetachShader"); + api->GenFramebuffers = loadProc("glGenFramebuffers"); + api->ProvokingVertex = oc_glProvokingVertex_noimpl; + api->SampleMaski = loadProc("glSampleMaski"); + api->EndQueryIndexed = oc_glEndQueryIndexed_noimpl; + api->ProgramUniform1f = loadProc("glProgramUniform1f"); + api->BindFramebuffer = loadProc("glBindFramebuffer"); + api->BeginQueryIndexed = oc_glBeginQueryIndexed_noimpl; + api->UniformSubroutinesuiv = oc_glUniformSubroutinesuiv_noimpl; + api->GetUniformiv = loadProc("glGetUniformiv"); + api->FramebufferTexture = loadProc("glFramebufferTexture"); + api->PointParameterfv = oc_glPointParameterfv_noimpl; + api->IsTransformFeedback = loadProc("glIsTransformFeedback"); + api->CheckFramebufferStatus = loadProc("glCheckFramebufferStatus"); + api->ShaderSource = loadProc("glShaderSource"); + api->UniformMatrix2x4dv = oc_glUniformMatrix2x4dv_noimpl; + api->BindImageTextures = oc_glBindImageTextures_noimpl; + api->CopyTexImage1D = oc_glCopyTexImage1D_noimpl; + api->UniformMatrix3dv = oc_glUniformMatrix3dv_noimpl; + api->ProgramUniform1dv = oc_glProgramUniform1dv_noimpl; + api->BlitFramebuffer = loadProc("glBlitFramebuffer"); + api->PopDebugGroup = loadProc("glPopDebugGroup"); + api->TexParameterIuiv = loadProc("glTexParameterIuiv"); + api->VertexAttrib2d = oc_glVertexAttrib2d_noimpl; + api->TexImage1D = oc_glTexImage1D_noimpl; + api->GetObjectPtrLabel = loadProc("glGetObjectPtrLabel"); + api->StencilMask = loadProc("glStencilMask"); + api->BeginQuery = loadProc("glBeginQuery"); + api->UniformMatrix4fv = loadProc("glUniformMatrix4fv"); + api->IsSync = loadProc("glIsSync"); + api->Uniform3dv = oc_glUniform3dv_noimpl; + api->ProgramUniform2fv = loadProc("glProgramUniform2fv"); + api->VertexAttribI4sv = oc_glVertexAttribI4sv_noimpl; + api->ScissorArrayv = oc_glScissorArrayv_noimpl; + api->VertexAttribP1uiv = oc_glVertexAttribP1uiv_noimpl; + api->Uniform2uiv = loadProc("glUniform2uiv"); + api->DeleteBuffers = loadProc("glDeleteBuffers"); + api->ProgramUniform3ui = loadProc("glProgramUniform3ui"); + api->FramebufferTextureLayer = loadProc("glFramebufferTextureLayer"); + api->EndTransformFeedback = loadProc("glEndTransformFeedback"); + api->BlendFuncSeparatei = loadProc("glBlendFuncSeparatei"); + api->DrawTransformFeedbackInstanced = oc_glDrawTransformFeedbackInstanced_noimpl; + api->DrawRangeElementsBaseVertex = loadProc("glDrawRangeElementsBaseVertex"); + api->VertexAttrib1f = loadProc("glVertexAttrib1f"); + api->GetUniformSubroutineuiv = oc_glGetUniformSubroutineuiv_noimpl; + api->DisableVertexAttribArray = loadProc("glDisableVertexAttribArray"); + api->ProgramUniformMatrix3x2fv = loadProc("glProgramUniformMatrix3x2fv"); + api->VertexAttribI4usv = oc_glVertexAttribI4usv_noimpl; + api->GetObjectLabel = loadProc("glGetObjectLabel"); + api->BindAttribLocation = loadProc("glBindAttribLocation"); + api->Uniform1f = loadProc("glUniform1f"); + api->GetUniformdv = oc_glGetUniformdv_noimpl; + api->GetUniformLocation = loadProc("glGetUniformLocation"); + api->GetSubroutineUniformLocation = oc_glGetSubroutineUniformLocation_noimpl; + api->GetTexParameterIuiv = loadProc("glGetTexParameterIuiv"); + api->SamplerParameterf = loadProc("glSamplerParameterf"); + api->VertexAttribL3d = oc_glVertexAttribL3d_noimpl; + api->TexImage3DMultisample = oc_glTexImage3DMultisample_noimpl; + api->TexImage3D = loadProc("glTexImage3D"); + api->RenderbufferStorage = loadProc("glRenderbufferStorage"); + api->EnableVertexAttribArray = loadProc("glEnableVertexAttribArray"); + api->VertexAttribP4uiv = oc_glVertexAttribP4uiv_noimpl; + api->Uniform4d = oc_glUniform4d_noimpl; + api->VertexAttrib4s = oc_glVertexAttrib4s_noimpl; + api->DrawElementsInstancedBaseVertex = loadProc("glDrawElementsInstancedBaseVertex"); + api->VertexAttrib3s = oc_glVertexAttrib3s_noimpl; + api->ProgramUniform2iv = loadProc("glProgramUniform2iv"); + api->StencilFuncSeparate = loadProc("glStencilFuncSeparate"); + api->DeleteFramebuffers = loadProc("glDeleteFramebuffers"); + api->DepthRange = oc_glDepthRange_noimpl; + api->UniformMatrix3x2fv = loadProc("glUniformMatrix3x2fv"); + api->ProgramUniformMatrix2dv = oc_glProgramUniformMatrix2dv_noimpl; + api->ShaderStorageBlockBinding = oc_glShaderStorageBlockBinding_noimpl; + api->ClearDepth = oc_glClearDepth_noimpl; + api->VertexAttrib2dv = oc_glVertexAttrib2dv_noimpl; + api->SamplerParameterIuiv = loadProc("glSamplerParameterIuiv"); + api->GetVertexAttribLdv = oc_glGetVertexAttribLdv_noimpl; + api->ProgramUniformMatrix3x4dv = oc_glProgramUniformMatrix3x4dv_noimpl; + api->DepthRangeArrayv = oc_glDepthRangeArrayv_noimpl; + api->GetActiveUniform = loadProc("glGetActiveUniform"); + api->PatchParameterfv = oc_glPatchParameterfv_noimpl; + api->InvalidateTexImage = oc_glInvalidateTexImage_noimpl; + api->VertexAttrib3f = loadProc("glVertexAttrib3f"); + api->ProgramUniform4iv = loadProc("glProgramUniform4iv"); + api->ProgramUniform4d = oc_glProgramUniform4d_noimpl; + api->IsFramebuffer = loadProc("glIsFramebuffer"); + api->PixelStoref = oc_glPixelStoref_noimpl; + api->ProgramUniform4uiv = loadProc("glProgramUniform4uiv"); + api->ProgramUniformMatrix4x2dv = oc_glProgramUniformMatrix4x2dv_noimpl; + api->FenceSync = loadProc("glFenceSync"); + api->GetBufferParameteri64v = loadProc("glGetBufferParameteri64v"); + api->StencilOp = loadProc("glStencilOp"); + api->ClearBufferData = oc_glClearBufferData_noimpl; + api->GetnUniformuiv = loadProc("glGetnUniformuiv"); + api->GetProgramResourceiv = loadProc("glGetProgramResourceiv"); + api->GetVertexAttribdv = oc_glGetVertexAttribdv_noimpl; + api->GetTransformFeedbackVarying = loadProc("glGetTransformFeedbackVarying"); + api->VertexAttrib2fv = loadProc("glVertexAttrib2fv"); + api->GetBooleani_v = loadProc("glGetBooleani_v"); + api->ColorMaski = loadProc("glColorMaski"); + api->InvalidateBufferSubData = oc_glInvalidateBufferSubData_noimpl; + api->UniformMatrix4dv = oc_glUniformMatrix4dv_noimpl; + api->IsQuery = loadProc("glIsQuery"); + api->Uniform4ui = loadProc("glUniform4ui"); + api->Uniform4i = loadProc("glUniform4i"); + api->GetSamplerParameteriv = loadProc("glGetSamplerParameteriv"); + api->MultiDrawElementsBaseVertex = oc_glMultiDrawElementsBaseVertex_noimpl; + api->VertexAttribI1uiv = oc_glVertexAttribI1uiv_noimpl; + api->GetIntegerv = loadProc("glGetIntegerv"); + api->UniformMatrix2x3fv = loadProc("glUniformMatrix2x3fv"); + api->TexImage2D = loadProc("glTexImage2D"); + api->GetAttachedShaders = loadProc("glGetAttachedShaders"); + api->Uniform2d = oc_glUniform2d_noimpl; + api->MemoryBarrierByRegion = loadProc("glMemoryBarrierByRegion"); + api->UniformMatrix2fv = loadProc("glUniformMatrix2fv"); + api->PrimitiveRestartIndex = oc_glPrimitiveRestartIndex_noimpl; + api->GetVertexAttribiv = loadProc("glGetVertexAttribiv"); + api->GetAttribLocation = loadProc("glGetAttribLocation"); + api->TexStorage2DMultisample = loadProc("glTexStorage2DMultisample"); + api->CompressedTexSubImage2D = loadProc("glCompressedTexSubImage2D"); + api->GetVertexAttribfv = loadProc("glGetVertexAttribfv"); + api->GetBufferParameteriv = loadProc("glGetBufferParameteriv"); + api->TexParameterf = loadProc("glTexParameterf"); + api->FramebufferTexture2D = loadProc("glFramebufferTexture2D"); + api->GetActiveAttrib = loadProc("glGetActiveAttrib"); + api->InvalidateTexSubImage = oc_glInvalidateTexSubImage_noimpl; + api->DeleteVertexArrays = loadProc("glDeleteVertexArrays"); + api->VertexAttribI2ui = oc_glVertexAttribI2ui_noimpl; + api->PointParameteriv = oc_glPointParameteriv_noimpl; + api->GetPointerv = loadProc("glGetPointerv"); + api->Enablei = loadProc("glEnablei"); + api->BindBufferRange = loadProc("glBindBufferRange"); + api->DrawArraysInstanced = loadProc("glDrawArraysInstanced"); + api->DeleteTextures = loadProc("glDeleteTextures"); + api->VertexAttrib4Niv = oc_glVertexAttrib4Niv_noimpl; + api->MultiDrawElements = oc_glMultiDrawElements_noimpl; + api->GetProgramiv = loadProc("glGetProgramiv"); + api->DepthFunc = loadProc("glDepthFunc"); + api->GenTextures = loadProc("glGenTextures"); + api->GetInternalformativ = loadProc("glGetInternalformativ"); + api->ProgramUniform3i = loadProc("glProgramUniform3i"); + api->ScissorIndexed = oc_glScissorIndexed_noimpl; + api->VertexAttrib2sv = oc_glVertexAttrib2sv_noimpl; + api->TexStorage3DMultisample = loadProc("glTexStorage3DMultisample"); + api->Uniform2iv = loadProc("glUniform2iv"); + api->DrawArraysInstancedBaseInstance = oc_glDrawArraysInstancedBaseInstance_noimpl; + api->VertexAttribI3ui = oc_glVertexAttribI3ui_noimpl; + api->DeleteSamplers = loadProc("glDeleteSamplers"); + api->GenVertexArrays = loadProc("glGenVertexArrays"); + api->GetFramebufferParameteriv = loadProc("glGetFramebufferParameteriv"); + api->PolygonMode = oc_glPolygonMode_noimpl; + api->ProgramUniformMatrix2x4fv = loadProc("glProgramUniformMatrix2x4fv"); + api->GetProgramResourceName = loadProc("glGetProgramResourceName"); + api->SamplerParameteriv = loadProc("glSamplerParameteriv"); + api->GetActiveSubroutineUniformiv = oc_glGetActiveSubroutineUniformiv_noimpl; + api->GetStringi = loadProc("glGetStringi"); + api->VertexAttribLFormat = oc_glVertexAttribLFormat_noimpl; + api->VertexAttrib3d = oc_glVertexAttrib3d_noimpl; + api->BindVertexArray = loadProc("glBindVertexArray"); + api->UnmapBuffer = loadProc("glUnmapBuffer"); + api->DrawElementsInstancedBaseInstance = oc_glDrawElementsInstancedBaseInstance_noimpl; + api->Uniform4uiv = loadProc("glUniform4uiv"); + api->FramebufferTexture1D = oc_glFramebufferTexture1D_noimpl; + api->DrawTransformFeedbackStreamInstanced = oc_glDrawTransformFeedbackStreamInstanced_noimpl; + api->StencilFunc = loadProc("glStencilFunc"); + api->ValidateProgram = loadProc("glValidateProgram"); + api->Flush = loadProc("glFlush"); + api->ProgramUniform3uiv = loadProc("glProgramUniform3uiv"); + api->DeleteRenderbuffers = loadProc("glDeleteRenderbuffers"); + api->VertexAttrib4fv = loadProc("glVertexAttrib4fv"); + api->UniformMatrix2dv = oc_glUniformMatrix2dv_noimpl; + api->GetFragDataIndex = oc_glGetFragDataIndex_noimpl; + api->Uniform3iv = loadProc("glUniform3iv"); + api->MinSampleShading = loadProc("glMinSampleShading"); + api->GetBooleanv = loadProc("glGetBooleanv"); + api->GetMultisamplefv = loadProc("glGetMultisamplefv"); + api->GetVertexAttribIuiv = loadProc("glGetVertexAttribIuiv"); + api->GetProgramInfoLog = loadProc("glGetProgramInfoLog"); + api->Uniform4fv = loadProc("glUniform4fv"); + api->DrawBuffer = oc_glDrawBuffer_noimpl; + api->Uniform1i = loadProc("glUniform1i"); + api->ProgramUniform4ui = loadProc("glProgramUniform4ui"); + api->ProgramUniformMatrix3fv = loadProc("glProgramUniformMatrix3fv"); + api->BlendEquationSeparate = loadProc("glBlendEquationSeparate"); + api->BindProgramPipeline = loadProc("glBindProgramPipeline"); + api->GetDoublei_v = oc_glGetDoublei_v_noimpl; + api->BufferData = loadProc("glBufferData"); + api->ClearColor = loadProc("glClearColor"); + api->ProgramUniform4i = loadProc("glProgramUniform4i"); + api->GetTexLevelParameteriv = loadProc("glGetTexLevelParameteriv"); + api->GetActiveUniformBlockiv = loadProc("glGetActiveUniformBlockiv"); + api->ProgramUniform1fv = loadProc("glProgramUniform1fv"); + api->PauseTransformFeedback = loadProc("glPauseTransformFeedback"); + api->GetBufferPointerv = loadProc("glGetBufferPointerv"); + api->InvalidateSubFramebuffer = loadProc("glInvalidateSubFramebuffer"); + api->ScissorIndexedv = oc_glScissorIndexedv_noimpl; + api->Uniform2ui = loadProc("glUniform2ui"); + api->BindTexture = loadProc("glBindTexture"); + api->DrawElementsInstanced = loadProc("glDrawElementsInstanced"); + api->ProgramUniform4f = loadProc("glProgramUniform4f"); + api->BindBufferBase = loadProc("glBindBufferBase"); + api->IsShader = loadProc("glIsShader"); + api->ClearBufferSubData = oc_glClearBufferSubData_noimpl; + api->VertexAttrib4Nuiv = oc_glVertexAttrib4Nuiv_noimpl; + api->DrawArraysIndirect = loadProc("glDrawArraysIndirect"); + api->VertexAttrib4usv = oc_glVertexAttrib4usv_noimpl; + api->Uniform1d = oc_glUniform1d_noimpl; + api->ClearTexImage = oc_glClearTexImage_noimpl; + api->Uniform1uiv = loadProc("glUniform1uiv"); + api->BindSampler = loadProc("glBindSampler"); + api->GetTexLevelParameterfv = loadProc("glGetTexLevelParameterfv"); + api->ClearBufferiv = loadProc("glClearBufferiv"); + api->LogicOp = oc_glLogicOp_noimpl; + api->ActiveTexture = loadProc("glActiveTexture"); + api->GetFragDataLocation = loadProc("glGetFragDataLocation"); + api->BlendColor = loadProc("glBlendColor"); + api->UniformMatrix4x3fv = loadProc("glUniformMatrix4x3fv"); + api->ProgramUniform3fv = loadProc("glProgramUniform3fv"); + api->Uniform1fv = loadProc("glUniform1fv"); + api->DrawElementsBaseVertex = loadProc("glDrawElementsBaseVertex"); + api->Uniform4f = loadProc("glUniform4f"); + api->BlendEquationSeparatei = loadProc("glBlendEquationSeparatei"); + api->BlendFuncSeparate = loadProc("glBlendFuncSeparate"); + api->ClearBufferuiv = loadProc("glClearBufferuiv"); + api->CopyTexSubImage1D = oc_glCopyTexSubImage1D_noimpl; + api->DrawTransformFeedback = oc_glDrawTransformFeedback_noimpl; + api->ReadBuffer = loadProc("glReadBuffer"); + api->CopyBufferSubData = loadProc("glCopyBufferSubData"); + api->GetUniformuiv = loadProc("glGetUniformuiv"); + api->PolygonOffset = loadProc("glPolygonOffset"); + api->DispatchCompute = loadProc("glDispatchCompute"); + api->BindImageTexture = loadProc("glBindImageTexture"); + api->UniformMatrix4x3dv = oc_glUniformMatrix4x3dv_noimpl; + api->GenRenderbuffers = loadProc("glGenRenderbuffers"); } -void oc_gl_select_api(oc_gl_api* api){ oc_glAPI = api; } -void oc_gl_deselect_api(){ oc_glAPI = &oc_glNoAPI; } -oc_gl_api* oc_gl_get_api(void) { return(oc_glAPI); } +void oc_gl_select_api(oc_gl_api* api) { oc_glAPI = api; } +void oc_gl_deselect_api() { oc_glAPI = &oc_glNoAPI; } + +oc_gl_api* oc_gl_get_api(void) { return (oc_glAPI); } diff --git a/src/graphics/gl_loader.h b/src/graphics/gl_loader.h index 1e0d5a2..f5f8aa5 100644 --- a/src/graphics/gl_loader.h +++ b/src/graphics/gl_loader.h @@ -8,9 +8,9 @@ #ifndef __GL_LOADER_H__ #define __GL_LOADER_H__ -#include"gl_api.h" +#include "gl_api.h" -typedef void*(*oc_gl_load_proc)(const char* name); +typedef void* (*oc_gl_load_proc)(const char* name); void oc_gl_load_gl41(oc_gl_api* api, oc_gl_load_proc loadProc); void oc_gl_load_gl43(oc_gl_api* api, oc_gl_load_proc loadProc); diff --git a/src/graphics/glsl_shaders/backprop.glsl b/src/graphics/glsl_shaders/backprop.glsl index 811e770..cde98f1 100644 --- a/src/graphics/glsl_shaders/backprop.glsl +++ b/src/graphics/glsl_shaders/backprop.glsl @@ -6,13 +6,17 @@ layout(std430) buffer; layout(binding = 0) restrict readonly buffer pathQueueBufferSSBO { - oc_gl_path_queue elements[]; -} pathQueueBuffer; + oc_gl_path_queue elements[]; +} + +pathQueueBuffer; layout(binding = 1) restrict buffer tileQueueBufferSSBO { - oc_gl_tile_queue elements[]; -} tileQueueBuffer; + oc_gl_tile_queue elements[]; +} + +tileQueueBuffer; layout(location = 0) uniform int pathQueueBufferStart; @@ -20,32 +24,32 @@ shared int nextRowIndex; void main() { - int pathIndex = int(gl_WorkGroupID.x); - int localID = int(gl_LocalInvocationID.x); + int pathIndex = int(gl_WorkGroupID.x); + int localID = int(gl_LocalInvocationID.x); - if(localID == 0) - { - nextRowIndex = 0; - } - barrier(); + if(localID == 0) + { + nextRowIndex = 0; + } + barrier(); - int rowIndex = 0; - oc_gl_path_queue pathQueue = pathQueueBuffer.elements[pathQueueBufferStart + pathIndex]; - int tileQueueBase = pathQueue.tileQueues; - int rowSize = pathQueue.area.z; - int rowCount = pathQueue.area.w; + int rowIndex = 0; + oc_gl_path_queue pathQueue = pathQueueBuffer.elements[pathQueueBufferStart + pathIndex]; + int tileQueueBase = pathQueue.tileQueues; + int rowSize = pathQueue.area.z; + int rowCount = pathQueue.area.w; - rowIndex = atomicAdd(nextRowIndex, 1); - while(rowIndex < rowCount) - { - int sum = 0; - for(int x = rowSize-1; x >= 0; x--) - { - int tileIndex = tileQueueBase + rowIndex * rowSize.x + x; - int offset = tileQueueBuffer.elements[tileIndex].windingOffset; - tileQueueBuffer.elements[tileIndex].windingOffset = sum; - sum += offset; - } - rowIndex = atomicAdd(nextRowIndex, 1); - } + rowIndex = atomicAdd(nextRowIndex, 1); + while(rowIndex < rowCount) + { + int sum = 0; + for(int x = rowSize - 1; x >= 0; x--) + { + int tileIndex = tileQueueBase + rowIndex * rowSize.x + x; + int offset = tileQueueBuffer.elements[tileIndex].windingOffset; + tileQueueBuffer.elements[tileIndex].windingOffset = sum; + sum += offset; + } + rowIndex = atomicAdd(nextRowIndex, 1); + } } diff --git a/src/graphics/glsl_shaders/balance_workgroups.glsl b/src/graphics/glsl_shaders/balance_workgroups.glsl index 790805a..36eca40 100644 --- a/src/graphics/glsl_shaders/balance_workgroups.glsl +++ b/src/graphics/glsl_shaders/balance_workgroups.glsl @@ -6,22 +6,25 @@ layout(std430) buffer; layout(binding = 0) coherent restrict readonly buffer screenTilesCountBufferSSBO { - int elements[]; -} screenTilesCountBuffer; + int elements[]; +} + +screenTilesCountBuffer; layout(binding = 1) coherent restrict writeonly buffer dispatchBufferSSBO { - oc_gl_dispatch_indirect_command elements[]; -} dispatchBuffer; + oc_gl_dispatch_indirect_command elements[]; +} +dispatchBuffer; layout(location = 0) uniform uint maxWorkGroupCount; void main() { - uint totalWorkGroupCount = screenTilesCountBuffer.elements[0]; + uint totalWorkGroupCount = screenTilesCountBuffer.elements[0]; - dispatchBuffer.elements[0].num_groups_x = totalWorkGroupCount > maxWorkGroupCount ? maxWorkGroupCount : totalWorkGroupCount; - dispatchBuffer.elements[0].num_groups_y = (totalWorkGroupCount + maxWorkGroupCount - 1) / maxWorkGroupCount; - dispatchBuffer.elements[0].num_groups_z = 1; + dispatchBuffer.elements[0].num_groups_x = totalWorkGroupCount > maxWorkGroupCount ? maxWorkGroupCount : totalWorkGroupCount; + dispatchBuffer.elements[0].num_groups_y = (totalWorkGroupCount + maxWorkGroupCount - 1) / maxWorkGroupCount; + dispatchBuffer.elements[0].num_groups_z = 1; } diff --git a/src/graphics/glsl_shaders/blit_fragment.glsl b/src/graphics/glsl_shaders/blit_fragment.glsl index 9d29fc2..f81c69b 100644 --- a/src/graphics/glsl_shaders/blit_fragment.glsl +++ b/src/graphics/glsl_shaders/blit_fragment.glsl @@ -4,9 +4,9 @@ precision mediump float; in vec2 uv; out vec4 fragColor; -layout(location=0) uniform sampler2D tex; +layout(location = 0) uniform sampler2D tex; void main() { - fragColor = texture(tex, uv); + fragColor = texture(tex, uv); } diff --git a/src/graphics/glsl_shaders/blit_vertex.glsl b/src/graphics/glsl_shaders/blit_vertex.glsl index a88b757..5a342f8 100644 --- a/src/graphics/glsl_shaders/blit_vertex.glsl +++ b/src/graphics/glsl_shaders/blit_vertex.glsl @@ -5,11 +5,11 @@ out vec2 uv; void main() { - /* generate (0, 0) (1, 0) (1, 1) (1, 1) (0, 1) (0, 0)*/ + /* generate (0, 0) (1, 0) (1, 1) (1, 1) (0, 1) (0, 0)*/ - float x = float(((uint(gl_VertexID) + 2u) / 3u)%2u); - float y = float(((uint(gl_VertexID) + 1u) / 3u)%2u); + float x = float(((uint(gl_VertexID) + 2u) / 3u) % 2u); + float y = float(((uint(gl_VertexID) + 1u) / 3u) % 2u); - gl_Position = vec4(-1.0f + x*2.0f, -1.0f+y*2.0f, 0.0f, 1.0f); - uv = vec2(x, 1-y); + gl_Position = vec4(-1.0f + x * 2.0f, -1.0f + y * 2.0f, 0.0f, 1.0f); + uv = vec2(x, 1 - y); } diff --git a/src/graphics/glsl_shaders/common.glsl b/src/graphics/glsl_shaders/common.glsl index af916d7..cd121a6 100644 --- a/src/graphics/glsl_shaders/common.glsl +++ b/src/graphics/glsl_shaders/common.glsl @@ -11,17 +11,17 @@ layout(std430) buffer; #define OC_GL_CUBIC 3 // curve config -#define OC_GL_BL 1 /* curve on bottom left */ +#define OC_GL_BL 1 /* curve on bottom left */ #define OC_GL_BR 2 /* curve on bottom right */ #define OC_GL_TL 3 /* curve on top left */ -#define OC_GL_TR 4 /* curve on top right */ +#define OC_GL_TR 4 /* curve on top right */ // Operations -#define OC_GL_OP_FILL 0 +#define OC_GL_OP_FILL 0 #define OC_GL_OP_CLIP_FILL 1 -#define OC_GL_OP_START 2 -#define OC_GL_OP_END 3 -#define OC_GL_OP_SEGMENT 4 +#define OC_GL_OP_START 2 +#define OC_GL_OP_END 3 +#define OC_GL_OP_SEGMENT 4 // MSAA #define OC_GL_MAX_SAMPLE_COUNT 8 @@ -29,158 +29,160 @@ layout(std430) buffer; struct oc_gl_path { - mat3 uvTransform; - vec4 color; - vec4 box; - vec4 clip; - int cmd; - int textureID; + mat3 uvTransform; + vec4 color; + vec4 box; + vec4 clip; + int cmd; + int textureID; }; struct oc_gl_path_elt { - vec2 p[4]; - int pathIndex; - int kind; + vec2 p[4]; + int pathIndex; + int kind; }; struct oc_gl_segment { - int kind; - int pathIndex; - int config; - int windingIncrement; - vec4 box; - mat3 implicitMatrix; - vec2 hullVertex; - float sign; + int kind; + int pathIndex; + int config; + int windingIncrement; + vec4 box; + mat3 implicitMatrix; + vec2 hullVertex; + float sign; }; struct oc_gl_path_queue { - ivec4 area; - int tileQueues; + ivec4 area; + int tileQueues; }; struct oc_gl_tile_op { - int kind; - int next; - int index; - int windingOffsetOrCrossRight; + int kind; + int next; + int index; + int windingOffsetOrCrossRight; }; struct oc_gl_tile_queue { - int windingOffset; - int first; - int last; + int windingOffset; + int first; + int last; }; struct oc_gl_screen_tile { - uvec2 tileCoord; - int first; + uvec2 tileCoord; + int first; }; struct oc_gl_dispatch_indirect_command { - uint num_groups_x; - uint num_groups_y; - uint num_groups_z; + uint num_groups_x; + uint num_groups_y; + uint num_groups_z; }; float ccw(vec2 a, vec2 b, vec2 c) { - return((b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x)); + return ((b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x)); } int side_of_segment(vec2 p, oc_gl_segment seg) { - int side = 0; - if(p.y > seg.box.w || p.y <= seg.box.y) - { - if(p.x > seg.box.x && p.x <= seg.box.z) - { - if(p.y > seg.box.w) - { - side = (seg.config == OC_GL_TL || seg.config == OC_GL_BR)? -1 : 1; - } - else - { - side = (seg.config == OC_GL_TL || seg.config == OC_GL_BR)? 1 : -1; - } - } - } - else if(p.x > seg.box.z) - { - side = 1; - } - else if(p.x <= seg.box.x) - { - side = -1; - } - else - { - vec2 a, b, c; - switch(seg.config) - { - case OC_GL_TL: - a = seg.box.xy; - b = seg.box.zw; - break; + int side = 0; + if(p.y > seg.box.w || p.y <= seg.box.y) + { + if(p.x > seg.box.x && p.x <= seg.box.z) + { + if(p.y > seg.box.w) + { + side = (seg.config == OC_GL_TL || seg.config == OC_GL_BR) ? -1 : 1; + } + else + { + side = (seg.config == OC_GL_TL || seg.config == OC_GL_BR) ? 1 : -1; + } + } + } + else if(p.x > seg.box.z) + { + side = 1; + } + else if(p.x <= seg.box.x) + { + side = -1; + } + else + { + vec2 a, b, c; + switch(seg.config) + { + case OC_GL_TL: + a = seg.box.xy; + b = seg.box.zw; + break; - case OC_GL_BR: - a = seg.box.zw; - b = seg.box.xy; - break; + case OC_GL_BR: + a = seg.box.zw; + b = seg.box.xy; + break; - case OC_GL_TR: - a = seg.box.xw; - b = seg.box.zy; - break; + case OC_GL_TR: + a = seg.box.xw; + b = seg.box.zy; + break; - case OC_GL_BL: - a = seg.box.zy; - b = seg.box.xw; - break; - } - c = seg.hullVertex; + case OC_GL_BL: + a = seg.box.zy; + b = seg.box.xw; + break; + } + c = seg.hullVertex; - if(ccw(a, b, p) < 0) - { - // other side of the diagonal - side = (seg.config == OC_GL_BR || seg.config == OC_GL_TR) ? -1 : 1; - } - else if(ccw(b, c, p) < 0 || ccw(c, a, p) < 0) - { - // same side of the diagonal, but outside curve hull - side = (seg.config == OC_GL_BL || seg.config == OC_GL_TL) ? -1 : 1; - } - else - { - // inside curve hull - switch(seg.kind) - { - case OC_GL_LINE: - side = 1; - break; + if(ccw(a, b, p) < 0) + { + // other side of the diagonal + side = (seg.config == OC_GL_BR || seg.config == OC_GL_TR) ? -1 : 1; + } + else if(ccw(b, c, p) < 0 || ccw(c, a, p) < 0) + { + // same side of the diagonal, but outside curve hull + side = (seg.config == OC_GL_BL || seg.config == OC_GL_TL) ? -1 : 1; + } + else + { + // inside curve hull + switch(seg.kind) + { + case OC_GL_LINE: + side = 1; + break; - case OC_GL_QUADRATIC: - { - vec3 ph = {p.x, p.y, 1}; - vec3 klm = seg.implicitMatrix * ph; - side = ((klm.x*klm.x - klm.y)*klm.z < 0)? -1 : 1; - } break; + case OC_GL_QUADRATIC: + { + vec3 ph = { p.x, p.y, 1 }; + vec3 klm = seg.implicitMatrix * ph; + side = ((klm.x * klm.x - klm.y) * klm.z < 0) ? -1 : 1; + } + break; - case OC_GL_CUBIC: - { - vec3 ph = {p.x, p.y, 1}; - vec3 klm = seg.implicitMatrix * ph; - side = (seg.sign*(klm.x*klm.x*klm.x - klm.y*klm.z) < 0)? -1 : 1; - } break; - } - } - } - return(side); + case OC_GL_CUBIC: + { + vec3 ph = { p.x, p.y, 1 }; + vec3 klm = seg.implicitMatrix * ph; + side = (seg.sign * (klm.x * klm.x * klm.x - klm.y * klm.z) < 0) ? -1 : 1; + } + break; + } + } + } + return (side); } diff --git a/src/graphics/glsl_shaders/merge.glsl b/src/graphics/glsl_shaders/merge.glsl index fa13683..08ff45b 100644 --- a/src/graphics/glsl_shaders/merge.glsl +++ b/src/graphics/glsl_shaders/merge.glsl @@ -6,39 +6,52 @@ layout(std430) buffer; layout(binding = 0) restrict readonly buffer pathBufferSSBO { - oc_gl_path elements[]; -} pathBuffer; + oc_gl_path elements[]; +} + +pathBuffer; layout(binding = 1) restrict readonly buffer pathQueueBufferSSBO { - oc_gl_path_queue elements[]; -} pathQueueBuffer; + oc_gl_path_queue elements[]; +} + +pathQueueBuffer; layout(binding = 2) restrict readonly buffer tileQueueBufferSSBO { - oc_gl_tile_queue elements[]; -} tileQueueBuffer; + oc_gl_tile_queue elements[]; +} + +tileQueueBuffer; layout(binding = 3) coherent restrict buffer tileOpCountBufferSSBO { - int elements[]; -} tileOpCountBuffer; + int elements[]; +} + +tileOpCountBuffer; layout(binding = 4) restrict buffer tileOpBufferSSBO { - oc_gl_tile_op elements[]; -} tileOpBuffer; + oc_gl_tile_op elements[]; +} + +tileOpBuffer; layout(binding = 5) restrict writeonly buffer screenTilesBufferSSBO { - oc_gl_screen_tile elements[]; -} screenTilesBuffer; + oc_gl_screen_tile elements[]; +} + +screenTilesBuffer; layout(binding = 6) coherent restrict buffer screenTilesCountBufferSSBO { - int elements[]; -} screenTilesCountBuffer; + int elements[]; +} +screenTilesCountBuffer; layout(location = 0) uniform int tileSize; layout(location = 1) uniform float scale; @@ -47,147 +60,147 @@ layout(location = 3) uniform int pathBufferStart; void main() { - ivec2 tileCoord = ivec2(gl_WorkGroupID.xy); - int tileIndex = -1; + ivec2 tileCoord = ivec2(gl_WorkGroupID.xy); + int tileIndex = -1; - int lastOpIndex = -1; + int lastOpIndex = -1; - for(int pathIndex = 0; pathIndex < pathCount; pathIndex++) - { - oc_gl_path_queue pathQueue = pathQueueBuffer.elements[pathIndex]; - ivec2 pathTileCoord = tileCoord - pathQueue.area.xy; + for(int pathIndex = 0; pathIndex < pathCount; pathIndex++) + { + oc_gl_path_queue pathQueue = pathQueueBuffer.elements[pathIndex]; + ivec2 pathTileCoord = tileCoord - pathQueue.area.xy; - vec4 pathBox = pathBuffer.elements[pathBufferStart + pathIndex].box; - vec4 pathClip = pathBuffer.elements[pathBufferStart + pathIndex].clip; + vec4 pathBox = pathBuffer.elements[pathBufferStart + pathIndex].box; + vec4 pathClip = pathBuffer.elements[pathBufferStart + pathIndex].clip; - float xMax = min(pathBox.z, pathClip.z); - int tileMax = int(xMax * scale) / tileSize; - int pathTileMax = tileMax - pathQueue.area.x; + float xMax = min(pathBox.z, pathClip.z); + int tileMax = int(xMax * scale) / tileSize; + int pathTileMax = tileMax - pathQueue.area.x; - if( pathTileCoord.x >= 0 - && pathTileCoord.x <= pathTileMax - && pathTileCoord.y >= 0 - && pathTileCoord.y < pathQueue.area.w) - { - if(tileIndex < 0) - { - tileIndex = int(atomicAdd(screenTilesCountBuffer.elements[0], 1)); - screenTilesBuffer.elements[tileIndex].tileCoord = uvec2(tileCoord); - screenTilesBuffer.elements[tileIndex].first = -1; - } + if(pathTileCoord.x >= 0 + && pathTileCoord.x <= pathTileMax + && pathTileCoord.y >= 0 + && pathTileCoord.y < pathQueue.area.w) + { + if(tileIndex < 0) + { + tileIndex = int(atomicAdd(screenTilesCountBuffer.elements[0], 1)); + screenTilesBuffer.elements[tileIndex].tileCoord = uvec2(tileCoord); + screenTilesBuffer.elements[tileIndex].first = -1; + } - int pathTileIndex = pathQueue.tileQueues + pathTileCoord.y * pathQueue.area.z + pathTileCoord.x; - oc_gl_tile_queue tileQueue = tileQueueBuffer.elements[pathTileIndex]; + int pathTileIndex = pathQueue.tileQueues + pathTileCoord.y * pathQueue.area.z + pathTileCoord.x; + oc_gl_tile_queue tileQueue = tileQueueBuffer.elements[pathTileIndex]; - int windingOffset = tileQueue.windingOffset; - int firstOpIndex = tileQueue.first; + int windingOffset = tileQueue.windingOffset; + int firstOpIndex = tileQueue.first; - vec4 tileBox = vec4(tileCoord.x, tileCoord.y, tileCoord.x+1, tileCoord.y+1); - tileBox *= tileSize; - vec4 clip = pathBuffer.elements[pathBufferStart + pathIndex].clip * scale; + vec4 tileBox = vec4(tileCoord.x, tileCoord.y, tileCoord.x + 1, tileCoord.y + 1); + tileBox *= tileSize; + vec4 clip = pathBuffer.elements[pathBufferStart + pathIndex].clip * scale; - if( tileBox.x >= clip.z - || tileBox.z < clip.x - || tileBox.y >= clip.w - || tileBox.w < clip.y) - { - //NOTE: tile is fully outside clip, cull it - //TODO: move that test up - } - else if(firstOpIndex == -1) - { - if((windingOffset & 1) != 0) - { - //NOTE: tile is full covered. Add path start op (with winding offset). - // Additionally if color is opaque and tile is fully inside clip, trim tile list. - int pathOpIndex = atomicAdd(tileOpCountBuffer.elements[0], 1); + if(tileBox.x >= clip.z + || tileBox.z < clip.x + || tileBox.y >= clip.w + || tileBox.w < clip.y) + { + //NOTE: tile is fully outside clip, cull it + //TODO: move that test up + } + else if(firstOpIndex == -1) + { + if((windingOffset & 1) != 0) + { + //NOTE: tile is full covered. Add path start op (with winding offset). + // Additionally if color is opaque and tile is fully inside clip, trim tile list. + int pathOpIndex = atomicAdd(tileOpCountBuffer.elements[0], 1); - if(pathOpIndex >= tileOpBuffer.elements.length()) - { - return; - } + if(pathOpIndex >= tileOpBuffer.elements.length()) + { + return; + } - tileOpBuffer.elements[pathOpIndex].kind = OC_GL_OP_CLIP_FILL; - tileOpBuffer.elements[pathOpIndex].next = -1; - tileOpBuffer.elements[pathOpIndex].index = pathIndex; - tileOpBuffer.elements[pathOpIndex].windingOffsetOrCrossRight = windingOffset; + tileOpBuffer.elements[pathOpIndex].kind = OC_GL_OP_CLIP_FILL; + tileOpBuffer.elements[pathOpIndex].next = -1; + tileOpBuffer.elements[pathOpIndex].index = pathIndex; + tileOpBuffer.elements[pathOpIndex].windingOffsetOrCrossRight = windingOffset; - if(lastOpIndex < 0) - { - screenTilesBuffer.elements[tileIndex].first = pathOpIndex; - } - else - { - tileOpBuffer.elements[lastOpIndex].next = pathOpIndex; - } + if(lastOpIndex < 0) + { + screenTilesBuffer.elements[tileIndex].first = pathOpIndex; + } + else + { + tileOpBuffer.elements[lastOpIndex].next = pathOpIndex; + } - if( tileBox.x >= clip.x - && tileBox.z < clip.z - && tileBox.y >= clip.y - && tileBox.w < clip.w) - { - tileOpBuffer.elements[pathOpIndex].kind = OC_GL_OP_FILL; + if(tileBox.x >= clip.x + && tileBox.z < clip.z + && tileBox.y >= clip.y + && tileBox.w < clip.w) + { + tileOpBuffer.elements[pathOpIndex].kind = OC_GL_OP_FILL; - if( pathBuffer.elements[pathBufferStart + pathIndex].color.a == 1 - && pathBuffer.elements[pathBufferStart + pathIndex].textureID < 0) - { - screenTilesBuffer.elements[tileIndex].first = pathOpIndex; - } - } - lastOpIndex = pathOpIndex; - } - // else, tile is fully uncovered, skip path - } - else - { - //NOTE: add path start op (with winding offset) - int startOpIndex = atomicAdd(tileOpCountBuffer.elements[0], 1); - if(startOpIndex >= tileOpBuffer.elements.length()) - { - return; - } + if(pathBuffer.elements[pathBufferStart + pathIndex].color.a == 1 + && pathBuffer.elements[pathBufferStart + pathIndex].textureID < 0) + { + screenTilesBuffer.elements[tileIndex].first = pathOpIndex; + } + } + lastOpIndex = pathOpIndex; + } + // else, tile is fully uncovered, skip path + } + else + { + //NOTE: add path start op (with winding offset) + int startOpIndex = atomicAdd(tileOpCountBuffer.elements[0], 1); + if(startOpIndex >= tileOpBuffer.elements.length()) + { + return; + } - tileOpBuffer.elements[startOpIndex].kind = OC_GL_OP_START; - tileOpBuffer.elements[startOpIndex].next = -1; - tileOpBuffer.elements[startOpIndex].index = pathIndex; - tileOpBuffer.elements[startOpIndex].windingOffsetOrCrossRight = windingOffset; + tileOpBuffer.elements[startOpIndex].kind = OC_GL_OP_START; + tileOpBuffer.elements[startOpIndex].next = -1; + tileOpBuffer.elements[startOpIndex].index = pathIndex; + tileOpBuffer.elements[startOpIndex].windingOffsetOrCrossRight = windingOffset; - if(lastOpIndex < 0) - { - screenTilesBuffer.elements[tileIndex].first = startOpIndex; - } - else - { - tileOpBuffer.elements[lastOpIndex].next = startOpIndex; - } - lastOpIndex = startOpIndex; + if(lastOpIndex < 0) + { + screenTilesBuffer.elements[tileIndex].first = startOpIndex; + } + else + { + tileOpBuffer.elements[lastOpIndex].next = startOpIndex; + } + lastOpIndex = startOpIndex; - //NOTE: chain remaining path ops to end of tile list - tileOpBuffer.elements[lastOpIndex].next = firstOpIndex; - lastOpIndex = tileQueue.last; + //NOTE: chain remaining path ops to end of tile list + tileOpBuffer.elements[lastOpIndex].next = firstOpIndex; + lastOpIndex = tileQueue.last; - //NOTE: add path end op - int endOpIndex = atomicAdd(tileOpCountBuffer.elements[0], 1); - if(endOpIndex >= tileOpBuffer.elements.length()) - { - return; - } + //NOTE: add path end op + int endOpIndex = atomicAdd(tileOpCountBuffer.elements[0], 1); + if(endOpIndex >= tileOpBuffer.elements.length()) + { + return; + } - tileOpBuffer.elements[endOpIndex].kind = OC_GL_OP_END; - tileOpBuffer.elements[endOpIndex].next = -1; - tileOpBuffer.elements[endOpIndex].index = pathIndex; - tileOpBuffer.elements[endOpIndex].windingOffsetOrCrossRight = windingOffset; + tileOpBuffer.elements[endOpIndex].kind = OC_GL_OP_END; + tileOpBuffer.elements[endOpIndex].next = -1; + tileOpBuffer.elements[endOpIndex].index = pathIndex; + tileOpBuffer.elements[endOpIndex].windingOffsetOrCrossRight = windingOffset; - if(lastOpIndex < 0) - { - screenTilesBuffer.elements[tileIndex].first = endOpIndex; - } - else - { - tileOpBuffer.elements[lastOpIndex].next = endOpIndex; - } - lastOpIndex = endOpIndex; - } - } - } + if(lastOpIndex < 0) + { + screenTilesBuffer.elements[tileIndex].first = endOpIndex; + } + else + { + tileOpBuffer.elements[lastOpIndex].next = endOpIndex; + } + lastOpIndex = endOpIndex; + } + } + } } diff --git a/src/graphics/glsl_shaders/path_setup.glsl b/src/graphics/glsl_shaders/path_setup.glsl index 01345f6..7112bd5 100644 --- a/src/graphics/glsl_shaders/path_setup.glsl +++ b/src/graphics/glsl_shaders/path_setup.glsl @@ -6,23 +6,31 @@ layout(std430) buffer; layout(binding = 0) restrict readonly buffer pathBufferSSBO { - oc_gl_path elements[]; -} pathBuffer; + oc_gl_path elements[]; +} + +pathBuffer; layout(binding = 1) restrict writeonly buffer pathQueueBufferSSBO { - oc_gl_path_queue elements[]; -} pathQueueBuffer; + oc_gl_path_queue elements[]; +} + +pathQueueBuffer; layout(binding = 2) coherent restrict buffer tileQueueCountBufferSSBO { - int elements[]; -} tileQueueCountBuffer; + int elements[]; +} + +tileQueueCountBuffer; layout(binding = 3) restrict writeonly buffer tileQueueBufferSSBO { - oc_gl_tile_queue elements[]; -} tileQueueBuffer; + oc_gl_tile_queue elements[]; +} + +tileQueueBuffer; layout(location = 0) uniform int tileSize; layout(location = 1) uniform float scale; @@ -31,40 +39,40 @@ layout(location = 3) uniform int pathQueueBufferStart; void main() { - uint pathIndex = gl_WorkGroupID.x; - const oc_gl_path path = pathBuffer.elements[pathIndex + pathBufferStart]; + uint pathIndex = gl_WorkGroupID.x; + const oc_gl_path path = pathBuffer.elements[pathIndex + pathBufferStart]; - //NOTE: we don't clip on the right, since we need those tiles to accurately compute - // the prefix sum of winding increments in the backprop pass. - vec4 clippedBox = vec4(max(path.box.x, path.clip.x), - max(path.box.y, path.clip.y), - path.box.z, - min(path.box.w, path.clip.w)); + //NOTE: we don't clip on the right, since we need those tiles to accurately compute + // the prefix sum of winding increments in the backprop pass. + vec4 clippedBox = vec4(max(path.box.x, path.clip.x), + max(path.box.y, path.clip.y), + path.box.z, + min(path.box.w, path.clip.w)); - ivec2 firstTile = ivec2(clippedBox.xy*scale)/tileSize; - ivec2 lastTile = ivec2(clippedBox.zw*scale)/tileSize; + ivec2 firstTile = ivec2(clippedBox.xy * scale) / tileSize; + ivec2 lastTile = ivec2(clippedBox.zw * scale) / tileSize; - int nTilesX = max(0, lastTile.x - firstTile.x + 1); - int nTilesY = max(0, lastTile.y - firstTile.y + 1); - int tileCount = nTilesX * nTilesY; + int nTilesX = max(0, lastTile.x - firstTile.x + 1); + int nTilesY = max(0, lastTile.y - firstTile.y + 1); + int tileCount = nTilesX * nTilesY; - int tileQueuesIndex = atomicAdd(tileQueueCountBuffer.elements[0], tileCount); + int tileQueuesIndex = atomicAdd(tileQueueCountBuffer.elements[0], tileCount); - if(tileQueuesIndex + tileCount >= tileQueueBuffer.elements.length()) - { - pathQueueBuffer.elements[pathIndex].area = ivec4(0); - pathQueueBuffer.elements[pathIndex].tileQueues = 0; - } - else - { - pathQueueBuffer.elements[pathQueueBufferStart + pathIndex].area = ivec4(firstTile.x, firstTile.y, nTilesX, nTilesY); - pathQueueBuffer.elements[pathQueueBufferStart + pathIndex].tileQueues = tileQueuesIndex; + if(tileQueuesIndex + tileCount >= tileQueueBuffer.elements.length()) + { + pathQueueBuffer.elements[pathIndex].area = ivec4(0); + pathQueueBuffer.elements[pathIndex].tileQueues = 0; + } + else + { + pathQueueBuffer.elements[pathQueueBufferStart + pathIndex].area = ivec4(firstTile.x, firstTile.y, nTilesX, nTilesY); + pathQueueBuffer.elements[pathQueueBufferStart + pathIndex].tileQueues = tileQueuesIndex; - for(int i=0; i= screenTilesCountBuffer.elements[0]) - { - return; - } + if(tileIndex >= screenTilesCountBuffer.elements[0]) + { + return; + } - uvec2 tileCoord = screenTilesBuffer.elements[tileIndex].tileCoord; - ivec2 pixelCoord = ivec2(tileCoord * gl_WorkGroupSize.x + gl_LocalInvocationID.xy); + uvec2 tileCoord = screenTilesBuffer.elements[tileIndex].tileCoord; + ivec2 pixelCoord = ivec2(tileCoord * gl_WorkGroupSize.x + gl_LocalInvocationID.xy); - vec2 centerCoord = vec2(pixelCoord) + vec2(0.5, 0.5); + vec2 centerCoord = vec2(pixelCoord) + vec2(0.5, 0.5); -/* + /* if((pixelCoord.x % 16) == 0 || (pixelCoord.y % 16) == 0) { imageStore(outTexture, pixelCoord, vec4(0, 0, 0, 1)); return; } */ - vec2 sampleCoords[OC_GL_MAX_SAMPLE_COUNT] = { - centerCoord + vec2(1, 3)/16, - centerCoord + vec2(-1, -3)/16, - centerCoord + vec2(5, -1)/16, - centerCoord + vec2(-3, 5)/16, - centerCoord + vec2(-5, -5)/16, - centerCoord + vec2(-7, 1)/16, - centerCoord + vec2(3, -7)/16, - centerCoord + vec2(7, 7)/16 - }; + vec2 sampleCoords[OC_GL_MAX_SAMPLE_COUNT] = { + centerCoord + vec2(1, 3) / 16, + centerCoord + vec2(-1, -3) / 16, + centerCoord + vec2(5, -1) / 16, + centerCoord + vec2(-3, 5) / 16, + centerCoord + vec2(-5, -5) / 16, + centerCoord + vec2(-7, 1) / 16, + centerCoord + vec2(3, -7) / 16, + centerCoord + vec2(7, 7) / 16 + }; - int sampleCount = msaaSampleCount; - if(sampleCount != 8) - { - sampleCount = 1; - sampleCoords[0] = centerCoord; - } + int sampleCount = msaaSampleCount; + if(sampleCount != 8) + { + sampleCount = 1; + sampleCoords[0] = centerCoord; + } - const int srcSampleCount = 2; + const int srcSampleCount = 2; - vec2 imgSampleCoords[OC_GL_MAX_SRC_SAMPLE_COUNT] = { - centerCoord + vec2(-0.25, 0.25), - centerCoord + vec2(+0.25, +0.25), - centerCoord + vec2(+0.25, -0.25), - centerCoord + vec2(-0.25, +0.25)}; + vec2 imgSampleCoords[OC_GL_MAX_SRC_SAMPLE_COUNT] = { + centerCoord + vec2(-0.25, 0.25), + centerCoord + vec2(+0.25, +0.25), + centerCoord + vec2(+0.25, -0.25), + centerCoord + vec2(-0.25, +0.25) + }; - vec4 color = vec4(0); - int winding[OC_GL_MAX_SAMPLE_COUNT]; + vec4 color = vec4(0); + int winding[OC_GL_MAX_SAMPLE_COUNT]; - for(int i=0; i= 0) - { - oc_gl_tile_op op = tileOpBuffer.elements[opIndex]; + while(opIndex >= 0) + { + oc_gl_tile_op op = tileOpBuffer.elements[opIndex]; - if(op.kind == OC_GL_OP_START) - { - for(int sampleIndex = 0; sampleIndex seg.box.y) - &&(sampleCoord.y <= seg.box.w) - &&(side_of_segment(sampleCoord, seg) < 0)) - { - winding[sampleIndex] += seg.windingIncrement; - } + if((sampleCoord.y > seg.box.y) + && (sampleCoord.y <= seg.box.w) + && (side_of_segment(sampleCoord, seg) < 0)) + { + winding[sampleIndex] += seg.windingIncrement; + } - if(op.windingOffsetOrCrossRight != 0) - { - if( (seg.config == OC_GL_BR || seg.config == OC_GL_TL) - &&(sampleCoord.y > seg.box.w)) - { - winding[sampleIndex] += seg.windingIncrement; - } - else if( (seg.config == OC_GL_BL || seg.config == OC_GL_TR) - &&(sampleCoord.y > seg.box.y)) - { - winding[sampleIndex] -= seg.windingIncrement; - } - } - } - } - else - { - int pathIndex = op.index; + if(op.windingOffsetOrCrossRight != 0) + { + if((seg.config == OC_GL_BR || seg.config == OC_GL_TL) + && (sampleCoord.y > seg.box.w)) + { + winding[sampleIndex] += seg.windingIncrement; + } + else if((seg.config == OC_GL_BL || seg.config == OC_GL_TR) + && (sampleCoord.y > seg.box.y)) + { + winding[sampleIndex] -= seg.windingIncrement; + } + } + } + } + else + { + int pathIndex = op.index; - vec4 nextColor = pathBuffer.elements[pathBufferStart + pathIndex].color; - nextColor.rgb *= nextColor.a; + vec4 nextColor = pathBuffer.elements[pathBufferStart + pathIndex].color; + nextColor.rgb *= nextColor.a; - int textureID = pathBuffer.elements[pathBufferStart+pathIndex].textureID; - if(textureID >= 0) - { - vec4 texColor = vec4(0); + int textureID = pathBuffer.elements[pathBufferStart + pathIndex].textureID; + if(textureID >= 0) + { + vec4 texColor = vec4(0); - for(int sampleIndex = 0; sampleIndex= clip.x - && sampleCoord.x < clip.z - && sampleCoord.y >= clip.y - && sampleCoord.y < clip.w) - { - bool filled = op.kind == OC_GL_OP_CLIP_FILL - ||(pathBuffer.elements[pathBufferStart + pathIndex].cmd == OC_GL_FILL - && ((winding[sampleIndex] & 1) != 0)) - ||(pathBuffer.elements[pathBufferStart + pathIndex].cmd == OC_GL_STROKE - && (winding[sampleIndex] != 0)); - if(filled) - { - coverage++; - } - } - winding[sampleIndex] = op.windingOffsetOrCrossRight; - } - coverage /= sampleCount; - color = coverage*(color*(1-nextColor.a) + nextColor) + (1.-coverage)*color; - } - } - opIndex = op.next; - } + if(sampleCoord.x >= clip.x + && sampleCoord.x < clip.z + && sampleCoord.y >= clip.y + && sampleCoord.y < clip.w) + { + bool filled = op.kind == OC_GL_OP_CLIP_FILL + || (pathBuffer.elements[pathBufferStart + pathIndex].cmd == OC_GL_FILL + && ((winding[sampleIndex] & 1) != 0)) + || (pathBuffer.elements[pathBufferStart + pathIndex].cmd == OC_GL_STROKE + && (winding[sampleIndex] != 0)); + if(filled) + { + coverage++; + } + } + winding[sampleIndex] = op.windingOffsetOrCrossRight; + } + coverage /= sampleCount; + color = coverage * (color * (1 - nextColor.a) + nextColor) + (1. - coverage) * color; + } + } + opIndex = op.next; + } - imageStore(outTexture, pixelCoord, color); + imageStore(outTexture, pixelCoord, color); } diff --git a/src/graphics/glsl_shaders/segment_setup.glsl b/src/graphics/glsl_shaders/segment_setup.glsl index ace7dcd..2a2a0ed 100644 --- a/src/graphics/glsl_shaders/segment_setup.glsl +++ b/src/graphics/glsl_shaders/segment_setup.glsl @@ -6,38 +6,52 @@ layout(std430) buffer; layout(binding = 0) restrict readonly buffer elementBufferSSBO { - oc_gl_path_elt elements[]; -} elementBuffer; + oc_gl_path_elt elements[]; +} + +elementBuffer; layout(binding = 1) coherent restrict buffer segmentCountBufferSSBO { - int elements[]; -} segmentCountBuffer; + int elements[]; +} + +segmentCountBuffer; layout(binding = 2) restrict buffer segmentBufferSSBO { - oc_gl_segment elements[]; -} segmentBuffer; + oc_gl_segment elements[]; +} + +segmentBuffer; layout(binding = 3) restrict buffer pathQueueBufferSSBO { - oc_gl_path_queue elements[]; -} pathQueueBuffer; + oc_gl_path_queue elements[]; +} + +pathQueueBuffer; layout(binding = 4) coherent restrict buffer tileQueueBufferSSBO { - oc_gl_tile_queue elements[]; -} tileQueueBuffer; + oc_gl_tile_queue elements[]; +} + +tileQueueBuffer; layout(binding = 5) coherent restrict buffer tileOpCountBufferSSBO { - int elements[]; -} tileOpCountBuffer; + int elements[]; +} + +tileOpCountBuffer; layout(binding = 6) restrict buffer tileOpBufferSSBO { - oc_gl_tile_op elements[]; -} tileOpBuffer; + oc_gl_tile_op elements[]; +} + +tileOpBuffer; layout(location = 0) uniform float scale; layout(location = 1) uniform uint tileSize; @@ -45,420 +59,422 @@ layout(location = 2) uniform int elementBufferStart; void bin_to_tiles(int segIndex) { - //NOTE: add segment index to the queues of tiles it overlaps with - const oc_gl_segment seg = segmentBuffer.elements[segIndex]; - const oc_gl_path_queue pathQueue = pathQueueBuffer.elements[seg.pathIndex]; + //NOTE: add segment index to the queues of tiles it overlaps with + const oc_gl_segment seg = segmentBuffer.elements[segIndex]; + const oc_gl_path_queue pathQueue = pathQueueBuffer.elements[seg.pathIndex]; - ivec4 pathArea = pathQueue.area; - ivec4 coveredTiles = ivec4(seg.box)/int(tileSize); - int xMin = max(0, coveredTiles.x - pathArea.x); - int yMin = max(0, coveredTiles.y - pathArea.y); - int xMax = min(coveredTiles.z - pathArea.x, pathArea.z-1); - int yMax = min(coveredTiles.w - pathArea.y, pathArea.w-1); + ivec4 pathArea = pathQueue.area; + ivec4 coveredTiles = ivec4(seg.box) / int(tileSize); + int xMin = max(0, coveredTiles.x - pathArea.x); + int yMin = max(0, coveredTiles.y - pathArea.y); + int xMax = min(coveredTiles.z - pathArea.x, pathArea.z - 1); + int yMax = min(coveredTiles.w - pathArea.y, pathArea.w - 1); - for(int y = yMin; y <= yMax; y++) - { - for(int x = xMin ; x <= xMax; x++) - { - vec4 tileBox = vec4(float(x + pathArea.x), - float(y + pathArea.y), - float(x + pathArea.x + 1), - float(y + pathArea.y + 1)) * float(tileSize); + for(int y = yMin; y <= yMax; y++) + { + for(int x = xMin; x <= xMax; x++) + { + vec4 tileBox = vec4(float(x + pathArea.x), + float(y + pathArea.y), + float(x + pathArea.x + 1), + float(y + pathArea.y + 1)) + * float(tileSize); - vec2 bl = {tileBox.x, tileBox.y}; - vec2 br = {tileBox.z, tileBox.y}; - vec2 tr = {tileBox.z, tileBox.w}; - vec2 tl = {tileBox.x, tileBox.w}; + vec2 bl = { tileBox.x, tileBox.y }; + vec2 br = { tileBox.z, tileBox.y }; + vec2 tr = { tileBox.z, tileBox.w }; + vec2 tl = { tileBox.x, tileBox.w }; - int sbl = side_of_segment(bl, seg); - int sbr = side_of_segment(br, seg); - int str = side_of_segment(tr, seg); - int stl = side_of_segment(tl, seg); + int sbl = side_of_segment(bl, seg); + int sbr = side_of_segment(br, seg); + int str = side_of_segment(tr, seg); + int stl = side_of_segment(tl, seg); - bool crossL = (stl*sbl < 0); - bool crossR = (str*sbr < 0); - bool crossT = (stl*str < 0); - bool crossB = (sbl*sbr < 0); + bool crossL = (stl * sbl < 0); + bool crossR = (str * sbr < 0); + bool crossT = (stl * str < 0); + bool crossB = (sbl * sbr < 0); - vec2 s0, s1; - if(seg.config == OC_GL_TL||seg.config == OC_GL_BR) - { - s0 = seg.box.xy; - s1 = seg.box.zw; - } - else - { - s0 = seg.box.xw; - s1 = seg.box.zy; - } - bool s0Inside = s0.x >= tileBox.x - && s0.x < tileBox.z - && s0.y >= tileBox.y - && s0.y < tileBox.w; + vec2 s0, s1; + if(seg.config == OC_GL_TL || seg.config == OC_GL_BR) + { + s0 = seg.box.xy; + s1 = seg.box.zw; + } + else + { + s0 = seg.box.xw; + s1 = seg.box.zy; + } + bool s0Inside = s0.x >= tileBox.x + && s0.x < tileBox.z + && s0.y >= tileBox.y + && s0.y < tileBox.w; - bool s1Inside = s1.x >= tileBox.x - && s1.x < tileBox.z - && s1.y >= tileBox.y - && s1.y < tileBox.w; + bool s1Inside = s1.x >= tileBox.x + && s1.x < tileBox.z + && s1.y >= tileBox.y + && s1.y < tileBox.w; - if(crossL || crossR || crossT || crossB || s0Inside || s1Inside) - { - int tileOpIndex = atomicAdd(tileOpCountBuffer.elements[0], 1); + if(crossL || crossR || crossT || crossB || s0Inside || s1Inside) + { + int tileOpIndex = atomicAdd(tileOpCountBuffer.elements[0], 1); - if(tileOpIndex < tileOpBuffer.elements.length()) - { - tileOpBuffer.elements[tileOpIndex].kind = OC_GL_OP_SEGMENT; - tileOpBuffer.elements[tileOpIndex].index = segIndex; - tileOpBuffer.elements[tileOpIndex].windingOffsetOrCrossRight = 0; - tileOpBuffer.elements[tileOpIndex].next = -1; + if(tileOpIndex < tileOpBuffer.elements.length()) + { + tileOpBuffer.elements[tileOpIndex].kind = OC_GL_OP_SEGMENT; + tileOpBuffer.elements[tileOpIndex].index = segIndex; + tileOpBuffer.elements[tileOpIndex].windingOffsetOrCrossRight = 0; + tileOpBuffer.elements[tileOpIndex].next = -1; - int tileQueueIndex = pathQueue.tileQueues + y*pathArea.z + x; + int tileQueueIndex = pathQueue.tileQueues + y * pathArea.z + x; - tileOpBuffer.elements[tileOpIndex].next = atomicExchange(tileQueueBuffer.elements[tileQueueIndex].first, - tileOpIndex); - if(tileOpBuffer.elements[tileOpIndex].next == -1) - { - tileQueueBuffer.elements[tileQueueIndex].last = tileOpIndex; - } + tileOpBuffer.elements[tileOpIndex].next = atomicExchange(tileQueueBuffer.elements[tileQueueIndex].first, + tileOpIndex); + if(tileOpBuffer.elements[tileOpIndex].next == -1) + { + tileQueueBuffer.elements[tileQueueIndex].last = tileOpIndex; + } - //NOTE: if the segment crosses the tile's bottom boundary, update the tile's winding offset - if(crossB) - { - atomicAdd(tileQueueBuffer.elements[tileQueueIndex].windingOffset, seg.windingIncrement); - } + //NOTE: if the segment crosses the tile's bottom boundary, update the tile's winding offset + if(crossB) + { + atomicAdd(tileQueueBuffer.elements[tileQueueIndex].windingOffset, seg.windingIncrement); + } - //NOTE: if the segment crosses the right boundary, mark it. - if(crossR) - { - tileOpBuffer.elements[tileOpIndex].windingOffsetOrCrossRight = 1; - } - } - } - } - } + //NOTE: if the segment crosses the right boundary, mark it. + if(crossR) + { + tileOpBuffer.elements[tileOpIndex].windingOffsetOrCrossRight = 1; + } + } + } + } + } } int push_segment(in vec2 p[4], int kind, int pathIndex) { - int segIndex = atomicAdd(segmentCountBuffer.elements[0], 1); + int segIndex = atomicAdd(segmentCountBuffer.elements[0], 1); - if(segIndex < segmentBuffer.elements.length()) - { - vec2 s, c, e; + if(segIndex < segmentBuffer.elements.length()) + { + vec2 s, c, e; - switch(kind) - { - case OC_GL_LINE: - s = p[0]; - c = p[0]; - e = p[1]; - break; + switch(kind) + { + case OC_GL_LINE: + s = p[0]; + c = p[0]; + e = p[1]; + break; - case OC_GL_QUADRATIC: - s = p[0]; - c = p[1]; - e = p[2]; - break; + case OC_GL_QUADRATIC: + s = p[0]; + c = p[1]; + e = p[2]; + break; - case OC_GL_CUBIC: - { - s = p[0]; - float sqrNorm0 = dot(p[1]-p[0], p[1]-p[0]); - float sqrNorm1 = dot(p[3]-p[2], p[3]-p[2]); - if(sqrNorm0 < sqrNorm1) - { - c = p[2]; - } - else - { - c = p[1]; - } - e = p[3]; - } break; - } + case OC_GL_CUBIC: + { + s = p[0]; + float sqrNorm0 = dot(p[1] - p[0], p[1] - p[0]); + float sqrNorm1 = dot(p[3] - p[2], p[3] - p[2]); + if(sqrNorm0 < sqrNorm1) + { + c = p[2]; + } + else + { + c = p[1]; + } + e = p[3]; + } + break; + } - bool goingUp = e.y >= s.y; - bool goingRight = e.x >= s.x; + bool goingUp = e.y >= s.y; + bool goingRight = e.x >= s.x; - vec4 box = vec4(min(s.x, e.x), - min(s.y, e.y), - max(s.x, e.x), - max(s.y, e.y)); + vec4 box = vec4(min(s.x, e.x), + min(s.y, e.y), + max(s.x, e.x), + max(s.y, e.y)); - segmentBuffer.elements[segIndex].kind = kind; - segmentBuffer.elements[segIndex].pathIndex = pathIndex; - segmentBuffer.elements[segIndex].windingIncrement = goingUp ? 1 : -1; - segmentBuffer.elements[segIndex].box = box; + segmentBuffer.elements[segIndex].kind = kind; + segmentBuffer.elements[segIndex].pathIndex = pathIndex; + segmentBuffer.elements[segIndex].windingIncrement = goingUp ? 1 : -1; + segmentBuffer.elements[segIndex].box = box; - float dx = c.x - box.x; - float dy = c.y - box.y; - float alpha = (box.w - box.y)/(box.z - box.x); - float ofs = box.w - box.y; + float dx = c.x - box.x; + float dy = c.y - box.y; + float alpha = (box.w - box.y) / (box.z - box.x); + float ofs = box.w - box.y; - if(goingUp == goingRight) - { - if(kind == OC_GL_LINE) - { - segmentBuffer.elements[segIndex].config = OC_GL_BR; - } - else if(dy > alpha*dx) - { - segmentBuffer.elements[segIndex].config = OC_GL_TL; - } - else - { - segmentBuffer.elements[segIndex].config = OC_GL_BR; - } - } - else - { - if(kind == OC_GL_LINE) - { - segmentBuffer.elements[segIndex].config = OC_GL_TR; - } - else if(dy < ofs - alpha*dx) - { - segmentBuffer.elements[segIndex].config = OC_GL_BL; - } - else - { - segmentBuffer.elements[segIndex].config = OC_GL_TR; - } - } - } - return(segIndex); + if(goingUp == goingRight) + { + if(kind == OC_GL_LINE) + { + segmentBuffer.elements[segIndex].config = OC_GL_BR; + } + else if(dy > alpha * dx) + { + segmentBuffer.elements[segIndex].config = OC_GL_TL; + } + else + { + segmentBuffer.elements[segIndex].config = OC_GL_BR; + } + } + else + { + if(kind == OC_GL_LINE) + { + segmentBuffer.elements[segIndex].config = OC_GL_TR; + } + else if(dy < ofs - alpha * dx) + { + segmentBuffer.elements[segIndex].config = OC_GL_BL; + } + else + { + segmentBuffer.elements[segIndex].config = OC_GL_TR; + } + } + } + return (segIndex); } -#define square(x) ((x)*(x)) -#define cube(x) ((x)*(x)*(x)) +#define square(x) ((x) * (x)) +#define cube(x) ((x) * (x) * (x)) void line_setup(vec2 p[4], int pathIndex) { - int segIndex = push_segment(p, OC_GL_LINE, pathIndex); - if(segIndex < segmentBuffer.elements.length()) - { - segmentBuffer.elements[segIndex].hullVertex = p[0]; - bin_to_tiles(segIndex); - } + int segIndex = push_segment(p, OC_GL_LINE, pathIndex); + if(segIndex < segmentBuffer.elements.length()) + { + segmentBuffer.elements[segIndex].hullVertex = p[0]; + bin_to_tiles(segIndex); + } } vec2 quadratic_blossom(vec2 p[4], float u, float v) { - vec2 b10 = u*p[1] + (1-u)*p[0]; - vec2 b11 = u*p[2] + (1-u)*p[1]; - vec2 b20 = v*b11 + (1-v)*b10; - return(b20); + vec2 b10 = u * p[1] + (1 - u) * p[0]; + vec2 b11 = u * p[2] + (1 - u) * p[1]; + vec2 b20 = v * b11 + (1 - v) * b10; + return (b20); } void quadratic_slice(vec2 p[4], float s0, float s1, out vec2 sp[4]) { - /*NOTE: using blossoms to compute sub-curve control points ensure that the fourth point + /*NOTE: using blossoms to compute sub-curve control points ensure that the fourth point of sub-curve (s0, s1) and the first point of sub-curve (s1, s3) match. However, due to numerical errors, the evaluation of B(s=0) might not be equal to p[0] (and likewise, B(s=1) might not equal p[3]). We handle that case explicitly to ensure that we don't create gaps in the paths. */ - sp[0] = (s0 == 0) ? p[0] : quadratic_blossom(p, s0, s0); - sp[1] = quadratic_blossom(p, s0, s1); - sp[2] = (s1 == 1) ? p[2] : quadratic_blossom(p, s1, s1); + sp[0] = (s0 == 0) ? p[0] : quadratic_blossom(p, s0, s0); + sp[1] = quadratic_blossom(p, s0, s1); + sp[2] = (s1 == 1) ? p[2] : quadratic_blossom(p, s1, s1); } int quadratic_monotonize(vec2 p[4], out float splits[4]) { - //NOTE: compute split points - int count = 0; - splits[0] = 0; - count++; + //NOTE: compute split points + int count = 0; + splits[0] = 0; + count++; - vec2 r = (p[0] - p[1])/(p[2] - 2*p[1] + p[0]); - if(r.x > r.y) - { - float tmp = r.x; - r.x = r.y; - r.y = tmp; - } - if(r.x > 0 && r.x < 1) - { - splits[count] = r.x; - count++; - } - if(r.y > 0 && r.y < 1) - { - splits[count] = r.y; - count++; - } - splits[count] = 1; - count++; - return(count); + vec2 r = (p[0] - p[1]) / (p[2] - 2 * p[1] + p[0]); + if(r.x > r.y) + { + float tmp = r.x; + r.x = r.y; + r.y = tmp; + } + if(r.x > 0 && r.x < 1) + { + splits[count] = r.x; + count++; + } + if(r.y > 0 && r.y < 1) + { + splits[count] = r.y; + count++; + } + splits[count] = 1; + count++; + return (count); } mat3 barycentric_matrix(vec2 v0, vec2 v1, vec2 v2) { - float det = v0.x*(v1.y-v2.y) + v1.x*(v2.y-v0.y) + v2.x*(v0.y - v1.y); - mat3 B = {{v1.y - v2.y, v2.y-v0.y, v0.y-v1.y}, - {v2.x - v1.x, v0.x-v2.x, v1.x-v0.x}, - {v1.x*v2.y-v2.x*v1.y, v2.x*v0.y-v0.x*v2.y, v0.x*v1.y-v1.x*v0.y}}; - B *= (1/det); - return(B); + float det = v0.x * (v1.y - v2.y) + v1.x * (v2.y - v0.y) + v2.x * (v0.y - v1.y); + mat3 B = { { v1.y - v2.y, v2.y - v0.y, v0.y - v1.y }, + { v2.x - v1.x, v0.x - v2.x, v1.x - v0.x }, + { v1.x * v2.y - v2.x * v1.y, v2.x * v0.y - v0.x * v2.y, v0.x * v1.y - v1.x * v0.y } }; + B *= (1 / det); + return (B); } void quadratic_emit(vec2 p[4], int pathIndex) { - int segIndex = push_segment(p, OC_GL_QUADRATIC, pathIndex); + int segIndex = push_segment(p, OC_GL_QUADRATIC, pathIndex); - if(segIndex < segmentBuffer.elements.length()) - { - //NOTE: compute implicit equation matrix - float det = p[0].x*(p[1].y-p[2].y) + p[1].x*(p[2].y-p[0].y) + p[2].x*(p[0].y - p[1].y); + if(segIndex < segmentBuffer.elements.length()) + { + //NOTE: compute implicit equation matrix + float det = p[0].x * (p[1].y - p[2].y) + p[1].x * (p[2].y - p[0].y) + p[2].x * (p[0].y - p[1].y); - float a = p[0].y - p[1].y + 0.5*(p[2].y - p[0].y); - float b = p[1].x - p[0].x + 0.5*(p[0].x - p[2].x); - float c = p[0].x*p[1].y - p[1].x*p[0].y + 0.5*(p[2].x*p[0].y - p[0].x*p[2].y); - float d = p[0].y - p[1].y; - float e = p[1].x - p[0].x; - float f = p[0].x*p[1].y - p[1].x*p[0].y; + float a = p[0].y - p[1].y + 0.5 * (p[2].y - p[0].y); + float b = p[1].x - p[0].x + 0.5 * (p[0].x - p[2].x); + float c = p[0].x * p[1].y - p[1].x * p[0].y + 0.5 * (p[2].x * p[0].y - p[0].x * p[2].y); + float d = p[0].y - p[1].y; + float e = p[1].x - p[0].x; + float f = p[0].x * p[1].y - p[1].x * p[0].y; - float flip = ( segmentBuffer.elements[segIndex].config == OC_GL_TL - || segmentBuffer.elements[segIndex].config == OC_GL_BL)? -1 : 1; + float flip = (segmentBuffer.elements[segIndex].config == OC_GL_TL + || segmentBuffer.elements[segIndex].config == OC_GL_BL) + ? -1 + : 1; - float g = flip*(p[2].x*(p[0].y - p[1].y) + p[0].x*(p[1].y - p[2].y) + p[1].x*(p[2].y - p[0].y)); + float g = flip * (p[2].x * (p[0].y - p[1].y) + p[0].x * (p[1].y - p[2].y) + p[1].x * (p[2].y - p[0].y)); - segmentBuffer.elements[segIndex].implicitMatrix = (1/det)*mat3(a, d, 0., - b, e, 0., - c, f, g); - segmentBuffer.elements[segIndex].hullVertex = p[1]; + segmentBuffer.elements[segIndex].implicitMatrix = (1 / det) * mat3(a, d, 0., b, e, 0., c, f, g); + segmentBuffer.elements[segIndex].hullVertex = p[1]; - bin_to_tiles(segIndex); - } + bin_to_tiles(segIndex); + } } void quadratic_setup(vec2 p[4], int pathIndex) { - float splits[4]; - int splitCount = quadratic_monotonize(p, splits); + float splits[4]; + int splitCount = quadratic_monotonize(p, splits); - //NOTE: produce bézier curve for each consecutive pair of roots - for(int sliceIndex=0; sliceIndex= 0) - { - count = (det == 0) ? 1 : 2; + if(det >= 0) + { + count = (det == 0) ? 1 : 2; - if(b > 0) - { - float q = b + sqrt(det); - r[0] = -c/q; - r[1] = -q/a; - } - else if(b < 0) - { - float q = -b + sqrt(det); - r[0] = q/a; - r[1] = c/q; - } - else - { - float q = sqrt(-a*c); - if(abs(a) >= abs(c)) - { - r[0] = q/a; - r[1] = -q/a; - } - else - { - r[0] = -c/q; - r[1] = c/q; - } - } - } - } - if(count>1 && r[0] > r[1]) - { - float tmp = r[0]; - r[0] = r[1]; - r[1] = tmp; - } - return(count); + if(b > 0) + { + float q = b + sqrt(det); + r[0] = -c / q; + r[1] = -q / a; + } + else if(b < 0) + { + float q = -b + sqrt(det); + r[0] = q / a; + r[1] = c / q; + } + else + { + float q = sqrt(-a * c); + if(abs(a) >= abs(c)) + { + r[0] = q / a; + r[1] = -q / a; + } + else + { + r[0] = -c / q; + r[1] = c / q; + } + } + } + } + if(count > 1 && r[0] > r[1]) + { + float tmp = r[0]; + r[0] = r[1]; + r[1] = tmp; + } + return (count); } int quadratic_roots(float a, float b, float c, out float r[2]) { - float det = square(b)/4. - a*c; - return(quadratic_roots_with_det(a, b, c, det, r)); + float det = square(b) / 4. - a * c; + return (quadratic_roots_with_det(a, b, c, det, r)); } vec2 cubic_blossom(vec2 p[4], float u, float v, float w) { - vec2 b10 = u*p[1] + (1-u)*p[0]; - vec2 b11 = u*p[2] + (1-u)*p[1]; - vec2 b12 = u*p[3] + (1-u)*p[2]; - vec2 b20 = v*b11 + (1-v)*b10; - vec2 b21 = v*b12 + (1-v)*b11; - vec2 b30 = w*b21 + (1-w)*b20; - return(b30); + vec2 b10 = u * p[1] + (1 - u) * p[0]; + vec2 b11 = u * p[2] + (1 - u) * p[1]; + vec2 b12 = u * p[3] + (1 - u) * p[2]; + vec2 b20 = v * b11 + (1 - v) * b10; + vec2 b21 = v * b12 + (1 - v) * b11; + vec2 b30 = w * b21 + (1 - w) * b20; + return (b30); } void cubic_slice(vec2 p[4], float s0, float s1, out vec2 sp[4]) { - /*NOTE: using blossoms to compute sub-curve control points ensure that the fourth point + /*NOTE: using blossoms to compute sub-curve control points ensure that the fourth point of sub-curve (s0, s1) and the first point of sub-curve (s1, s3) match. However, due to numerical errors, the evaluation of B(s=0) might not be equal to p[0] (and likewise, B(s=1) might not equal p[3]). We handle that case explicitly to ensure that we don't create gaps in the paths. */ - sp[0] = (s0 == 0) ? p[0] : cubic_blossom(p, s0, s0, s0); - sp[1] = cubic_blossom(p, s0, s0, s1); - sp[2] = cubic_blossom(p, s0, s1, s1); - sp[3] = (s1 == 1) ? p[3] : cubic_blossom(p, s1, s1, s1); + sp[0] = (s0 == 0) ? p[0] : cubic_blossom(p, s0, s0, s0); + sp[1] = cubic_blossom(p, s0, s0, s1); + sp[2] = cubic_blossom(p, s0, s1, s1); + sp[3] = (s1 == 1) ? p[3] : cubic_blossom(p, s1, s1, s1); } -#define CUBIC_ERROR 0 -#define CUBIC_SERPENTINE 1 -#define CUBIC_CUSP 2 -#define CUBIC_CUSP_INFINITY 3 -#define CUBIC_LOOP 4 +#define CUBIC_ERROR 0 +#define CUBIC_SERPENTINE 1 +#define CUBIC_CUSP 2 +#define CUBIC_CUSP_INFINITY 3 +#define CUBIC_LOOP 4 #define CUBIC_DEGENERATE_QUADRATIC 5 -#define CUBIC_DEGENERATE_LINE 6 +#define CUBIC_DEGENERATE_LINE 6 struct cubic_info { - int kind; - mat4 K; - vec2 ts[2]; - float d1; - float d2; - float d3; + int kind; + mat4 K; + vec2 ts[2]; + float d1; + float d2; + float d3; }; cubic_info cubic_classify(vec2 c[4]) { - cubic_info result; - result.kind = CUBIC_ERROR; - mat4 F; + cubic_info result; + result.kind = CUBIC_ERROR; + mat4 F; - /*NOTE(martin): + /*NOTE(martin): now, compute determinants d0, d1, d2, d3, which gives the coefficients of the inflection points polynomial: @@ -480,47 +496,47 @@ cubic_info cubic_classify(vec2 c[4]) // this may very well be an error on my part that's cancelled by flipping the signs of the d_i though! */ - float d1 = -(c[3].y*c[2].x - c[3].x*c[2].y); - float d2 = -(c[3].x*c[1].y - c[3].y*c[1].x); - float d3 = -(c[2].y*c[1].x - c[2].x*c[1].y); + float d1 = -(c[3].y * c[2].x - c[3].x * c[2].y); + float d2 = -(c[3].x * c[1].y - c[3].y * c[1].x); + float d3 = -(c[2].y * c[1].x - c[2].x * c[1].y); - result.d1 = d1; - result.d2 = d2; - result.d3 = d3; + result.d1 = d1; + result.d2 = d2; + result.d3 = d3; - //NOTE(martin): compute the second factor of the discriminant discr(I) = d1^2*(3*d2^2 - 4*d3*d1) - float discrFactor2 = 3.0*square(d2) - 4.0*d3*d1; + //NOTE(martin): compute the second factor of the discriminant discr(I) = d1^2*(3*d2^2 - 4*d3*d1) + float discrFactor2 = 3.0 * square(d2) - 4.0 * d3 * d1; - //NOTE(martin): each following case gives the number of roots, hence the category of the parametric curve - if(abs(d1) <= 1e-6 && abs(d2) <= 1e-6 && abs(d3) > 1e-6) - { - //NOTE(martin): quadratic degenerate case - //NOTE(martin): compute quadratic curve control point, which is at p0 + 1.5*(p1-p0) = 1.5*p1 - 0.5*p0 - result.kind = CUBIC_DEGENERATE_QUADRATIC; - } - else if( (discrFactor2 > 0 && abs(d1) > 1e-6) - ||(discrFactor2 == 0 && abs(d1) > 1e-6)) - { - //NOTE(martin): serpentine curve or cusp with inflection at infinity - // (these two cases are handled the same way). - //NOTE(martin): compute the solutions (tl, sl), (tm, sm), and (tn, sn) of the inflection point equation - float tmtl[2]; - quadratic_roots_with_det(1, -2*d2, (4./3.*d1*d3), (1./3.)*discrFactor2, tmtl); + //NOTE(martin): each following case gives the number of roots, hence the category of the parametric curve + if(abs(d1) <= 1e-6 && abs(d2) <= 1e-6 && abs(d3) > 1e-6) + { + //NOTE(martin): quadratic degenerate case + //NOTE(martin): compute quadratic curve control point, which is at p0 + 1.5*(p1-p0) = 1.5*p1 - 0.5*p0 + result.kind = CUBIC_DEGENERATE_QUADRATIC; + } + else if((discrFactor2 > 0 && abs(d1) > 1e-6) + || (discrFactor2 == 0 && abs(d1) > 1e-6)) + { + //NOTE(martin): serpentine curve or cusp with inflection at infinity + // (these two cases are handled the same way). + //NOTE(martin): compute the solutions (tl, sl), (tm, sm), and (tn, sn) of the inflection point equation + float tmtl[2]; + quadratic_roots_with_det(1, -2 * d2, (4. / 3. * d1 * d3), (1. / 3.) * discrFactor2, tmtl); - float tm = tmtl[0]; - float sm = 2*d1; - float tl = tmtl[1]; - float sl = 2*d1; + float tm = tmtl[0]; + float sm = 2 * d1; + float tl = tmtl[1]; + float sl = 2 * d1; - float invNorm = 1/sqrt(square(tm) + square(sm)); - tm *= invNorm; - sm *= invNorm; + float invNorm = 1 / sqrt(square(tm) + square(sm)); + tm *= invNorm; + sm *= invNorm; - invNorm = 1/sqrt(square(tl) + square(sl)); - tl *= invNorm; - sl *= invNorm; + invNorm = 1 / sqrt(square(tl) + square(sl)); + tl *= invNorm; + sl *= invNorm; - /*NOTE(martin): + /*NOTE(martin): the power basis coefficients of points k,l,m,n are collected into the rows of the 4x4 matrix F: | tl*tm tl^3 tm^3 1 | @@ -528,38 +544,38 @@ cubic_info cubic_classify(vec2 c[4]) | sl*sm 3*sl^2*tl 3*sm^2*tm 0 | | 0 -sl^3 -sm^3 0 | */ - result.kind = (discrFactor2 > 0 && d1 != 0) ? CUBIC_SERPENTINE : CUBIC_CUSP; + result.kind = (discrFactor2 > 0 && d1 != 0) ? CUBIC_SERPENTINE : CUBIC_CUSP; - F = mat4(tl*tm, -sm*tl-sl*tm, sl*sm, 0, - cube(tl), -3*sl*square(tl), 3*square(sl)*tl, -cube(sl), - cube(tm), -3*sm*square(tm), 3*square(sm)*tm, -cube(sm), - 1, 0, 0, 0); + F = mat4(tl * tm, -sm * tl - sl * tm, sl * sm, 0, + cube(tl), -3 * sl * square(tl), 3 * square(sl) * tl, -cube(sl), + cube(tm), -3 * sm * square(tm), 3 * square(sm) * tm, -cube(sm), + 1, 0, 0, 0); - result.ts[0] = vec2(tm, sm); - result.ts[1] = vec2(tl, sl); - } - else if(discrFactor2 < 0 && abs(d1) > 1e-6) - { - //NOTE(martin): loop curve - result.kind = CUBIC_LOOP; + result.ts[0] = vec2(tm, sm); + result.ts[1] = vec2(tl, sl); + } + else if(discrFactor2 < 0 && abs(d1) > 1e-6) + { + //NOTE(martin): loop curve + result.kind = CUBIC_LOOP; - float tetd[2]; - quadratic_roots_with_det(1, -2*d2, 4*(square(d2)-d1*d3), -discrFactor2, tetd); + float tetd[2]; + quadratic_roots_with_det(1, -2 * d2, 4 * (square(d2) - d1 * d3), -discrFactor2, tetd); - float td = tetd[1]; - float sd = 2*d1; - float te = tetd[0]; - float se = 2*d1; + float td = tetd[1]; + float sd = 2 * d1; + float te = tetd[0]; + float se = 2 * d1; - float invNorm = 1/sqrt(square(td) + square(sd)); - td *= invNorm; - sd *= invNorm; + float invNorm = 1 / sqrt(square(td) + square(sd)); + td *= invNorm; + sd *= invNorm; - invNorm = 1/sqrt(square(te) + square(se)); - te *= invNorm; - se *= invNorm; + invNorm = 1 / sqrt(square(te) + square(se)); + te *= invNorm; + se *= invNorm; - /*NOTE(martin): + /*NOTE(martin): the power basis coefficients of points k,l,m,n are collected into the rows of the 4x4 matrix F: | td*te td^2*te td*te^2 1 | @@ -567,25 +583,25 @@ cubic_info cubic_classify(vec2 c[4]) | sd*se te*sd^2 + 2*se*td*sd td*se^2 + 2*sd*te*se 0 | | 0 -sd^2*se -sd*se^2 0 | */ - F = mat4(td*te, -se*td-sd*te, sd*se, 0, - square(td)*te, -se*square(td)-2*sd*te*td, te*square(sd)+2*se*td*sd, -square(sd)*se, - td*square(te), -sd*square(te)-2*se*td*te, td*square(se)+2*sd*te*se, -sd*square(se), - 1, 0, 0, 0); + F = mat4(td * te, -se * td - sd * te, sd * se, 0, + square(td) * te, -se * square(td) - 2 * sd * te * td, te * square(sd) + 2 * se * td * sd, -square(sd) * se, + td * square(te), -sd * square(te) - 2 * se * td * te, td * square(se) + 2 * sd * te * se, -sd * square(se), + 1, 0, 0, 0); - result.ts[0] = vec2(td, sd); - result.ts[1] = vec2(te, se); - } - else if(d2 != 0) - { - //NOTE(martin): cusp with cusp at infinity - float tl = d3; - float sl = 3*d2; + result.ts[0] = vec2(td, sd); + result.ts[1] = vec2(te, se); + } + else if(d2 != 0) + { + //NOTE(martin): cusp with cusp at infinity + float tl = d3; + float sl = 3 * d2; - float invNorm = 1/sqrt(square(tl)+square(sl)); - tl *= invNorm; - sl *= invNorm; + float invNorm = 1 / sqrt(square(tl) + square(sl)); + tl *= invNorm; + sl *= invNorm; - /*NOTE(martin): + /*NOTE(martin): the power basis coefficients of points k,l,m,n are collected into the rows of the 4x4 matrix F: | tl tl^3 1 1 | @@ -593,23 +609,23 @@ cubic_info cubic_classify(vec2 c[4]) | 0 3*sl^2*tl 0 0 | | 0 -sl^3 0 0 | */ - result.kind = CUBIC_CUSP_INFINITY; + result.kind = CUBIC_CUSP_INFINITY; - F = mat4(tl, -sl, 0, 0, - cube(tl), -3*sl*square(tl), 3*square(sl)*tl, -cube(sl), - 1, 0, 0, 0, - 1, 0, 0, 0); + F = mat4(tl, -sl, 0, 0, + cube(tl), -3 * sl * square(tl), 3 * square(sl) * tl, -cube(sl), + 1, 0, 0, 0, + 1, 0, 0, 0); - result.ts[0] = vec2(tl, sl); - result.ts[1] = vec2(0, 0); - } - else - { - //NOTE(martin): line or point degenerate case - result.kind = CUBIC_DEGENERATE_LINE; - } + result.ts[0] = vec2(tl, sl); + result.ts[1] = vec2(0, 0); + } + else + { + //NOTE(martin): line or point degenerate case + result.kind = CUBIC_DEGENERATE_LINE; + } - /* + /* F is then multiplied by M3^(-1) on the left which yelds the bezier coefficients k, l, m, n at the control points. @@ -618,250 +634,254 @@ cubic_info cubic_classify(vec2 c[4]) | 1 2/3 1/3 0 | | 1 1 1 1 | */ - mat4 invM3 = mat4(1, 1, 1, 1, - 0, 1./3., 2./3., 1, - 0, 0, 1./3., 1, - 0, 0, 0, 1); + mat4 invM3 = mat4(1, 1, 1, 1, + 0, 1. / 3., 2. / 3., 1, + 0, 0, 1. / 3., 1, + 0, 0, 0, 1); - result.K = transpose(invM3*F); + result.K = transpose(invM3 * F); - return(result); + return (result); } vec2 select_hull_vertex(vec2 p0, vec2 p1, vec2 p2, vec2 p3) { - /*NOTE: check intersection of lines (p1-p0) and (p3-p2) + /*NOTE: check intersection of lines (p1-p0) and (p3-p2) P = p0 + u(p1-p0) P = p2 + w(p3-p2) control points are inside a right triangle so we should always find an intersection */ - vec2 pm; + vec2 pm; - float det = (p1.x - p0.x)*(p3.y - p2.y) - (p1.y - p0.y)*(p3.x - p2.x); - float sqrNorm0 = dot(p1-p0, p1-p0); - float sqrNorm1 = dot(p2-p3, p2-p3); + float det = (p1.x - p0.x) * (p3.y - p2.y) - (p1.y - p0.y) * (p3.x - p2.x); + float sqrNorm0 = dot(p1 - p0, p1 - p0); + float sqrNorm1 = dot(p2 - p3, p2 - p3); - if(abs(det) < 1e-3 || sqrNorm0 < 0.1 || sqrNorm1 < 0.1) - { - if(sqrNorm0 < sqrNorm1) - { - pm = p2; - } - else - { - pm = p1; - } - } - else - { - float u = ((p0.x - p2.x)*(p2.y - p3.y) - (p0.y - p2.y)*(p2.x - p3.x))/det; - pm = p0 + u*(p1-p0); - } - return(pm); + if(abs(det) < 1e-3 || sqrNorm0 < 0.1 || sqrNorm1 < 0.1) + { + if(sqrNorm0 < sqrNorm1) + { + pm = p2; + } + else + { + pm = p1; + } + } + else + { + float u = ((p0.x - p2.x) * (p2.y - p3.y) - (p0.y - p2.y) * (p2.x - p3.x)) / det; + pm = p0 + u * (p1 - p0); + } + return (pm); } void cubic_emit(cubic_info curve, vec2 p[4], float s0, float s1, vec2 sp[4], int pathIndex) { - int segIndex = push_segment(sp, OC_GL_CUBIC, pathIndex); + int segIndex = push_segment(sp, OC_GL_CUBIC, pathIndex); - if(segIndex < segmentBuffer.elements.length()) - { - vec2 v0 = p[0]; - vec2 v1 = p[3]; - vec2 v2; - mat3 K; + if(segIndex < segmentBuffer.elements.length()) + { + vec2 v0 = p[0]; + vec2 v1 = p[3]; + vec2 v2; + mat3 K; - //TODO: haul that up in caller - float sqrNorm0 = dot(p[1]-p[0], p[1]-p[0]); - float sqrNorm1 = dot(p[2]-p[3], p[2]-p[3]); + //TODO: haul that up in caller + float sqrNorm0 = dot(p[1] - p[0], p[1] - p[0]); + float sqrNorm1 = dot(p[2] - p[3], p[2] - p[3]); - if(dot(p[0]-p[3], p[0]-p[3]) > 1e-5) - { - if(sqrNorm0 >= sqrNorm1) - { - v2 = p[1]; - K = mat3(curve.K[0].xyz, curve.K[3].xyz, curve.K[1].xyz); - } - else - { - v2 = p[2]; - K = mat3(curve.K[0].xyz, curve.K[3].xyz, curve.K[2].xyz); - } - } - else - { - v1 = p[1]; - v2 = p[2]; - K = mat3(curve.K[0].xyz, curve.K[1].xyz, curve.K[2].xyz); - } - //NOTE: set matrices + if(dot(p[0] - p[3], p[0] - p[3]) > 1e-5) + { + if(sqrNorm0 >= sqrNorm1) + { + v2 = p[1]; + K = mat3(curve.K[0].xyz, curve.K[3].xyz, curve.K[1].xyz); + } + else + { + v2 = p[2]; + K = mat3(curve.K[0].xyz, curve.K[3].xyz, curve.K[2].xyz); + } + } + else + { + v1 = p[1]; + v2 = p[2]; + K = mat3(curve.K[0].xyz, curve.K[1].xyz, curve.K[2].xyz); + } + //NOTE: set matrices - //TODO: should we compute matrix relative to a base point to avoid loss of precision - // when computing barycentric matrix? + //TODO: should we compute matrix relative to a base point to avoid loss of precision + // when computing barycentric matrix? - mat3 B = barycentric_matrix(v0, v1, v2); + mat3 B = barycentric_matrix(v0, v1, v2); - segmentBuffer.elements[segIndex].implicitMatrix = K*B; - segmentBuffer.elements[segIndex].hullVertex = select_hull_vertex(sp[0], sp[1], sp[2], sp[3]); + segmentBuffer.elements[segIndex].implicitMatrix = K * B; + segmentBuffer.elements[segIndex].hullVertex = select_hull_vertex(sp[0], sp[1], sp[2], sp[3]); - //NOTE: compute sign flip - segmentBuffer.elements[segIndex].sign = 1; + //NOTE: compute sign flip + segmentBuffer.elements[segIndex].sign = 1; - if( curve.kind == CUBIC_SERPENTINE - || curve.kind == CUBIC_CUSP) - { - segmentBuffer.elements[segIndex].sign = (curve.d1 < 0)? -1 : 1; - } - else if(curve.kind == CUBIC_LOOP) - { - float d1 = curve.d1; - float d2 = curve.d2; - float d3 = curve.d3; + if(curve.kind == CUBIC_SERPENTINE + || curve.kind == CUBIC_CUSP) + { + segmentBuffer.elements[segIndex].sign = (curve.d1 < 0) ? -1 : 1; + } + else if(curve.kind == CUBIC_LOOP) + { + float d1 = curve.d1; + float d2 = curve.d2; + float d3 = curve.d3; - float H0 = d3*d1-square(d2) + d1*d2*s0 - square(d1)*square(s0); - float H1 = d3*d1-square(d2) + d1*d2*s1 - square(d1)*square(s1); - float H = (abs(H0) > abs(H1)) ? H0 : H1; - segmentBuffer.elements[segIndex].sign = (H*d1 > 0) ? -1 : 1; - } + float H0 = d3 * d1 - square(d2) + d1 * d2 * s0 - square(d1) * square(s0); + float H1 = d3 * d1 - square(d2) + d1 * d2 * s1 - square(d1) * square(s1); + float H = (abs(H0) > abs(H1)) ? H0 : H1; + segmentBuffer.elements[segIndex].sign = (H * d1 > 0) ? -1 : 1; + } - if(sp[3].y > sp[0].y) - { - segmentBuffer.elements[segIndex].sign *= -1; - } + if(sp[3].y > sp[0].y) + { + segmentBuffer.elements[segIndex].sign *= -1; + } - //NOTE: bin to tiles - bin_to_tiles(segIndex); - } + //NOTE: bin to tiles + bin_to_tiles(segIndex); + } } void cubic_setup(vec2 p[4], int pathIndex) { - /*NOTE(martin): first convert the control points to power basis, multiplying by M3 + /*NOTE(martin): first convert the control points to power basis, multiplying by M3 | 1 0 0 0| |p0| |c0| M3 = |-3 3 0 0|, B = |p1|, C = |c1| = M3*B | 3 -6 3 0| |p2| |c2| |-1 3 -3 1| |p3| |c3| */ - vec2 c[4] = { - p[0], - 3.0*(p[1] - p[0]), - 3.0*(p[0] + p[2] - 2*p[1]), - 3.0*(p[1] - p[2]) + p[3] - p[0]}; + vec2 c[4] = { + p[0], + 3.0 * (p[1] - p[0]), + 3.0 * (p[0] + p[2] - 2 * p[1]), + 3.0 * (p[1] - p[2]) + p[3] - p[0] + }; - //NOTE: get classification, implicit matrix, double points and inflection points - cubic_info curve = cubic_classify(c); + //NOTE: get classification, implicit matrix, double points and inflection points + cubic_info curve = cubic_classify(c); - if(curve.kind == CUBIC_DEGENERATE_LINE) - { - vec2 l[4] = {p[0], p[3], vec2(0), vec2(0)}; - line_setup(l, pathIndex); - return; - } - else if(curve.kind == CUBIC_DEGENERATE_QUADRATIC) - { - vec2 quadPoint = vec2(1.5*p[1].x - 0.5*p[0].x, 1.5*p[1].y - 0.5*p[0].y); - vec2 q[4] = {p[0], quadPoint, p[3], vec2(0)}; - quadratic_setup(q, pathIndex); - return; - } + if(curve.kind == CUBIC_DEGENERATE_LINE) + { + vec2 l[4] = { p[0], p[3], vec2(0), vec2(0) }; + line_setup(l, pathIndex); + return; + } + else if(curve.kind == CUBIC_DEGENERATE_QUADRATIC) + { + vec2 quadPoint = vec2(1.5 * p[1].x - 0.5 * p[0].x, 1.5 * p[1].y - 0.5 * p[0].y); + vec2 q[4] = { p[0], quadPoint, p[3], vec2(0) }; + quadratic_setup(q, pathIndex); + return; + } - //NOTE: get the roots of B'(s) = 3.c3.s^2 + 2.c2.s + c1 - float rootsX[2]; - int rootCountX = quadratic_roots(3*c[3].x, 2*c[2].x, c[1].x, rootsX); + //NOTE: get the roots of B'(s) = 3.c3.s^2 + 2.c2.s + c1 + float rootsX[2]; + int rootCountX = quadratic_roots(3 * c[3].x, 2 * c[2].x, c[1].x, rootsX); - float rootsY[2]; - int rootCountY = quadratic_roots(3*c[3].y, 2*c[2].y, c[1].y, rootsY); + float rootsY[2]; + int rootCountY = quadratic_roots(3 * c[3].y, 2 * c[2].y, c[1].y, rootsY); - float roots[6]; - for(int i=0; i=0 && roots[j]>tmp) - { - roots[j+1] = roots[j]; - j--; - } - roots[j+1] = tmp; - } + //NOTE: sort roots + for(int i = 1; i < rootCount; i++) + { + float tmp = roots[i]; + int j = i - 1; + while(j >= 0 && roots[j] > tmp) + { + roots[j + 1] = roots[j]; + j--; + } + roots[j + 1] = tmp; + } - //NOTE: compute split points - float splits[8]; - int splitCount = 0; - splits[0] = 0; - splitCount++; - for(int i=0; i 0 && roots[i] < 1) - { - splits[splitCount] = roots[i]; - splitCount++; - } - } - splits[splitCount] = 1; - splitCount++; + //NOTE: compute split points + float splits[8]; + int splitCount = 0; + splits[0] = 0; + splitCount++; + for(int i = 0; i < rootCount; i++) + { + if(roots[i] > 0 && roots[i] < 1) + { + splits[splitCount] = roots[i]; + splitCount++; + } + } + splits[splitCount] = 1; + splitCount++; - //NOTE: for each monotonic segment, compute hull matrix and sign, and emit segment - for(int sliceIndex=0; sliceIndex -#include"platform/platform.h" +#include "platform/platform.h" +#include #define STB_IMAGE_IMPLEMENTATION #if OC_PLATFORM_ORCA - #define STBI_NO_STDIO - #define STBI_NO_HDR + #define STBI_NO_STDIO + #define STBI_NO_HDR #endif -#include"stb/stb_image.h" +#include "stb/stb_image.h" #define STB_TRUETYPE_IMPLEMENTATION -#include"stb/stb_truetype.h" +#include "stb/stb_truetype.h" -#include"platform/platform_debug.h" -#include"platform/platform_debug.h" -#include"util/algebra.h" -#include"graphics_common.h" +#include "graphics_common.h" +#include "platform/platform_debug.h" +#include "util/algebra.h" typedef struct oc_glyph_map_entry { - oc_unicode_range range; - u32 firstGlyphIndex; + oc_unicode_range range; + u32 firstGlyphIndex; } oc_glyph_map_entry; typedef struct oc_glyph_data { - bool exists; - oc_utf32 codePoint; - oc_path_descriptor pathDescriptor; - oc_text_extents extents; - //... + bool exists; + oc_utf32 codePoint; + oc_path_descriptor pathDescriptor; + oc_text_extents extents; + //... } oc_glyph_data; enum { - OC_MATRIX_STACK_MAX_DEPTH = 64, - OC_CLIP_STACK_MAX_DEPTH = 64, - OC_MAX_PATH_ELEMENT_COUNT = 2<<20, - OC_MAX_PRIMITIVE_COUNT = 8<<10 + OC_MATRIX_STACK_MAX_DEPTH = 64, + OC_CLIP_STACK_MAX_DEPTH = 64, + OC_MAX_PATH_ELEMENT_COUNT = 2 << 20, + OC_MAX_PRIMITIVE_COUNT = 8 << 10 }; typedef struct oc_font_data { - oc_list_elt freeListElt; + oc_list_elt freeListElt; - u32 rangeCount; - u32 glyphCount; - u32 outlineCount; - oc_glyph_map_entry* glyphMap; - oc_glyph_data* glyphs; - oc_path_elt* outlines; + u32 rangeCount; + u32 glyphCount; + u32 outlineCount; + oc_glyph_map_entry* glyphMap; + oc_glyph_data* glyphs; + oc_path_elt* outlines; - f32 unitsPerEm; - oc_font_extents extents; + f32 unitsPerEm; + oc_font_extents extents; } oc_font_data; @@ -71,80 +70,82 @@ typedef struct oc_canvas_data oc_canvas_data; typedef enum oc_graphics_handle_kind { - OC_GRAPHICS_HANDLE_NONE = 0, - OC_GRAPHICS_HANDLE_SURFACE, - OC_GRAPHICS_HANDLE_CANVAS, - OC_GRAPHICS_HANDLE_FONT, - OC_GRAPHICS_HANDLE_IMAGE, - OC_GRAPHICS_HANDLE_SURFACE_SERVER, + OC_GRAPHICS_HANDLE_NONE = 0, + OC_GRAPHICS_HANDLE_SURFACE, + OC_GRAPHICS_HANDLE_CANVAS, + OC_GRAPHICS_HANDLE_FONT, + OC_GRAPHICS_HANDLE_IMAGE, + OC_GRAPHICS_HANDLE_SURFACE_SERVER, } oc_graphics_handle_kind; typedef struct oc_graphics_handle_slot { - oc_list_elt freeListElt; - u32 generation; - oc_graphics_handle_kind kind; + oc_list_elt freeListElt; + u32 generation; + oc_graphics_handle_kind kind; - void* data; + void* data; } oc_graphics_handle_slot; -enum { OC_GRAPHICS_HANDLES_MAX_COUNT = 512 }; +enum +{ + OC_GRAPHICS_HANDLES_MAX_COUNT = 512 +}; typedef struct oc_graphics_data { - bool init; + bool init; - oc_graphics_handle_slot handleArray[OC_GRAPHICS_HANDLES_MAX_COUNT]; - int handleNextIndex; - oc_list handleFreeList; + oc_graphics_handle_slot handleArray[OC_GRAPHICS_HANDLES_MAX_COUNT]; + int handleNextIndex; + oc_list handleFreeList; - oc_arena resourceArena; - oc_list canvasFreeList; - oc_list fontFreeList; + oc_arena resourceArena; + oc_list canvasFreeList; + oc_list fontFreeList; } oc_graphics_data; typedef struct oc_canvas_data { - oc_list_elt freeListElt; + oc_list_elt freeListElt; - oc_attributes attributes; - bool textFlip; + oc_attributes attributes; + bool textFlip; - oc_path_elt pathElements[OC_MAX_PATH_ELEMENT_COUNT]; - oc_path_descriptor path; - oc_vec2 subPathStartPoint; - oc_vec2 subPathLastPoint; + oc_path_elt pathElements[OC_MAX_PATH_ELEMENT_COUNT]; + oc_path_descriptor path; + oc_vec2 subPathStartPoint; + oc_vec2 subPathLastPoint; - oc_mat2x3 matrixStack[OC_MATRIX_STACK_MAX_DEPTH]; - u32 matrixStackSize; + oc_mat2x3 matrixStack[OC_MATRIX_STACK_MAX_DEPTH]; + u32 matrixStackSize; - oc_rect clipStack[OC_CLIP_STACK_MAX_DEPTH]; - u32 clipStackSize; + oc_rect clipStack[OC_CLIP_STACK_MAX_DEPTH]; + u32 clipStackSize; - u32 primitiveCount; - oc_primitive primitives[OC_MAX_PRIMITIVE_COUNT]; + u32 primitiveCount; + oc_primitive primitives[OC_MAX_PRIMITIVE_COUNT]; - //NOTE: these are used at render time - oc_color clearColor; + //NOTE: these are used at render time + oc_color clearColor; - oc_vec4 shapeExtents; - oc_vec4 shapeScreenExtents; + oc_vec4 shapeExtents; + oc_vec4 shapeScreenExtents; } oc_canvas_data; -static oc_graphics_data oc_graphicsData = {0}; - +static oc_graphics_data oc_graphicsData = { 0 }; void oc_graphics_init() { - if(!oc_graphicsData.init) - { - oc_graphicsData.handleNextIndex = 0; - oc_arena_init(&oc_graphicsData.resourceArena); - oc_graphicsData.init = true; - } + if(!oc_graphicsData.init) + { + oc_graphicsData.handleNextIndex = 0; + oc_arena_init(&oc_graphicsData.resourceArena); + oc_graphicsData.init = true; + } } //------------------------------------------------------------------------ @@ -153,69 +154,69 @@ void oc_graphics_init() u64 oc_graphics_handle_alloc(oc_graphics_handle_kind kind, void* data) { - if(!oc_graphicsData.init) - { - oc_graphics_init(); - } + if(!oc_graphicsData.init) + { + oc_graphics_init(); + } - oc_graphics_handle_slot* slot = oc_list_pop_entry(&oc_graphicsData.handleFreeList, oc_graphics_handle_slot, freeListElt); - if(!slot && oc_graphicsData.handleNextIndex < OC_GRAPHICS_HANDLES_MAX_COUNT) - { - slot = &oc_graphicsData.handleArray[oc_graphicsData.handleNextIndex]; - oc_graphicsData.handleNextIndex++; + oc_graphics_handle_slot* slot = oc_list_pop_entry(&oc_graphicsData.handleFreeList, oc_graphics_handle_slot, freeListElt); + if(!slot && oc_graphicsData.handleNextIndex < OC_GRAPHICS_HANDLES_MAX_COUNT) + { + slot = &oc_graphicsData.handleArray[oc_graphicsData.handleNextIndex]; + oc_graphicsData.handleNextIndex++; - slot->generation = 1; - } - u64 h = 0; - if(slot) - { - slot->kind = kind; - slot->data = data; + slot->generation = 1; + } + u64 h = 0; + if(slot) + { + slot->kind = kind; + slot->data = data; - h = ((u64)(slot - oc_graphicsData.handleArray))<<32 - |((u64)(slot->generation)); - } - return(h); + h = ((u64)(slot - oc_graphicsData.handleArray)) << 32 + | ((u64)(slot->generation)); + } + return (h); } void oc_graphics_handle_recycle(u64 h) { - OC_DEBUG_ASSERT(oc_graphicsData.init); + OC_DEBUG_ASSERT(oc_graphicsData.init); - u32 index = h>>32; - u32 generation = h & 0xffffffff; + u32 index = h >> 32; + u32 generation = h & 0xffffffff; - if(index*sizeof(oc_graphics_handle_slot) < oc_graphicsData.handleNextIndex) - { - oc_graphics_handle_slot* slot = &oc_graphicsData.handleArray[index]; - if(slot->generation == generation) - { - OC_DEBUG_ASSERT(slot->generation != UINT32_MAX, "surface slot generation wrap around\n"); - slot->generation++; - oc_list_push(&oc_graphicsData.handleFreeList, &slot->freeListElt); - } - } + if(index * sizeof(oc_graphics_handle_slot) < oc_graphicsData.handleNextIndex) + { + oc_graphics_handle_slot* slot = &oc_graphicsData.handleArray[index]; + if(slot->generation == generation) + { + OC_DEBUG_ASSERT(slot->generation != UINT32_MAX, "surface slot generation wrap around\n"); + slot->generation++; + oc_list_push(&oc_graphicsData.handleFreeList, &slot->freeListElt); + } + } } void* oc_graphics_data_from_handle(oc_graphics_handle_kind kind, u64 h) { - OC_DEBUG_ASSERT(oc_graphicsData.init); + OC_DEBUG_ASSERT(oc_graphicsData.init); - void* data = 0; + void* data = 0; - u32 index = h>>32; - u32 generation = h & 0xffffffff; + u32 index = h >> 32; + u32 generation = h & 0xffffffff; - if(index < oc_graphicsData.handleNextIndex) - { - oc_graphics_handle_slot* slot = &oc_graphicsData.handleArray[index]; - if( slot->generation == generation - && slot->kind == kind) - { - data = slot->data; - } - } - return(data); + if(index < oc_graphicsData.handleNextIndex) + { + oc_graphics_handle_slot* slot = &oc_graphicsData.handleArray[index]; + if(slot->generation == generation + && slot->kind == kind) + { + data = slot->data; + } + } + return (data); } //------------------------------------------------------------------------------------------ @@ -223,679 +224,681 @@ void* oc_graphics_data_from_handle(oc_graphics_handle_kind kind, u64 h) //------------------------------------------------------------------------------------------ oc_thread_local oc_canvas_data* __mgCurrentCanvas = 0; -oc_thread_local oc_canvas __mgCurrentCanvasHandle = {0}; +oc_thread_local oc_canvas __mgCurrentCanvasHandle = { 0 }; bool oc_vec2_close(oc_vec2 p0, oc_vec2 p1, f32 tolerance) { - f32 norm2 = (p1.x - p0.x)*(p1.x - p0.x) + (p1.y - p0.y)*(p1.y - p0.y); - return(fabs(norm2) < tolerance); + f32 norm2 = (p1.x - p0.x) * (p1.x - p0.x) + (p1.y - p0.y) * (p1.y - p0.y); + return (fabs(norm2) < tolerance); } oc_mat2x3 oc_matrix_stack_top(oc_canvas_data* canvas) { - if(canvas->matrixStackSize == 0) - { - return((oc_mat2x3){1, 0, 0, - 0, 1, 0}); - } - else - { - return(canvas->matrixStack[canvas->matrixStackSize-1]); - } + if(canvas->matrixStackSize == 0) + { + return ((oc_mat2x3){ 1, 0, 0, + 0, 1, 0 }); + } + else + { + return (canvas->matrixStack[canvas->matrixStackSize - 1]); + } } void oc_matrix_stack_push(oc_canvas_data* canvas, oc_mat2x3 transform) { - if(canvas->matrixStackSize >= OC_MATRIX_STACK_MAX_DEPTH) - { - oc_log_error("matrix stack overflow\n"); - } - else - { - canvas->matrixStack[canvas->matrixStackSize] = transform; - canvas->matrixStackSize++; - } + if(canvas->matrixStackSize >= OC_MATRIX_STACK_MAX_DEPTH) + { + oc_log_error("matrix stack overflow\n"); + } + else + { + canvas->matrixStack[canvas->matrixStackSize] = transform; + canvas->matrixStackSize++; + } } void oc_matrix_stack_pop(oc_canvas_data* canvas) { - if(canvas->matrixStackSize == 0) - { - oc_log_error("matrix stack underflow\n"); - } - else - { - canvas->matrixStackSize--; - oc_matrix_stack_top(canvas); - } + if(canvas->matrixStackSize == 0) + { + oc_log_error("matrix stack underflow\n"); + } + else + { + canvas->matrixStackSize--; + oc_matrix_stack_top(canvas); + } } oc_rect oc_clip_stack_top(oc_canvas_data* canvas) { - if(canvas->clipStackSize == 0) - { - return((oc_rect){-FLT_MAX/2, -FLT_MAX/2, FLT_MAX, FLT_MAX}); - } - else - { - return(canvas->clipStack[canvas->clipStackSize-1]); - } + if(canvas->clipStackSize == 0) + { + return ((oc_rect){ -FLT_MAX / 2, -FLT_MAX / 2, FLT_MAX, FLT_MAX }); + } + else + { + return (canvas->clipStack[canvas->clipStackSize - 1]); + } } void oc_clip_stack_push(oc_canvas_data* canvas, oc_rect clip) { - if(canvas->clipStackSize >= OC_CLIP_STACK_MAX_DEPTH) - { - oc_log_error("clip stack overflow\n"); - } - else - { - canvas->clipStack[canvas->clipStackSize] = clip; - canvas->clipStackSize++; - } + if(canvas->clipStackSize >= OC_CLIP_STACK_MAX_DEPTH) + { + oc_log_error("clip stack overflow\n"); + } + else + { + canvas->clipStack[canvas->clipStackSize] = clip; + canvas->clipStackSize++; + } } void oc_clip_stack_pop(oc_canvas_data* canvas) { - if(canvas->clipStackSize == 0) - { - oc_log_error("clip stack underflow\n"); - } - else - { - canvas->clipStackSize--; - } + if(canvas->clipStackSize == 0) + { + oc_log_error("clip stack underflow\n"); + } + else + { + canvas->clipStackSize--; + } } void oc_push_command(oc_canvas_data* canvas, oc_primitive primitive) { - //NOTE(martin): push primitive and updates current stream, eventually patching a pending jump. - OC_ASSERT(canvas->primitiveCount < OC_MAX_PRIMITIVE_COUNT); + //NOTE(martin): push primitive and updates current stream, eventually patching a pending jump. + OC_ASSERT(canvas->primitiveCount < OC_MAX_PRIMITIVE_COUNT); - canvas->primitives[canvas->primitiveCount] = primitive; - canvas->primitives[canvas->primitiveCount].attributes = canvas->attributes; - canvas->primitives[canvas->primitiveCount].attributes.transform = oc_matrix_stack_top(canvas); - canvas->primitives[canvas->primitiveCount].attributes.clip = oc_clip_stack_top(canvas); - canvas->primitiveCount++; + canvas->primitives[canvas->primitiveCount] = primitive; + canvas->primitives[canvas->primitiveCount].attributes = canvas->attributes; + canvas->primitives[canvas->primitiveCount].attributes.transform = oc_matrix_stack_top(canvas); + canvas->primitives[canvas->primitiveCount].attributes.clip = oc_clip_stack_top(canvas); + canvas->primitiveCount++; } void oc_new_path(oc_canvas_data* canvas) { - canvas->path.startIndex += canvas->path.count; - canvas->path.count = 0; - canvas->subPathStartPoint = canvas->subPathLastPoint; - canvas->path.startPoint = canvas->subPathStartPoint; + canvas->path.startIndex += canvas->path.count; + canvas->path.count = 0; + canvas->subPathStartPoint = canvas->subPathLastPoint; + canvas->path.startPoint = canvas->subPathStartPoint; } void oc_path_push_elements(oc_canvas_data* canvas, u32 count, oc_path_elt* elements) { - OC_ASSERT(canvas->path.count + canvas->path.startIndex + count < OC_MAX_PATH_ELEMENT_COUNT); - memcpy(canvas->pathElements + canvas->path.startIndex + canvas->path.count, elements, count*sizeof(oc_path_elt)); - canvas->path.count += count; + OC_ASSERT(canvas->path.count + canvas->path.startIndex + count < OC_MAX_PATH_ELEMENT_COUNT); + memcpy(canvas->pathElements + canvas->path.startIndex + canvas->path.count, elements, count * sizeof(oc_path_elt)); + canvas->path.count += count; - OC_ASSERT(canvas->path.count < OC_MAX_PATH_ELEMENT_COUNT); + OC_ASSERT(canvas->path.count < OC_MAX_PATH_ELEMENT_COUNT); } void oc_path_push_element(oc_canvas_data* canvas, oc_path_elt elt) { - oc_path_push_elements(canvas, 1, &elt); + oc_path_push_elements(canvas, 1, &elt); } //------------------------------------------------------------------------------------------ //NOTE(martin): fonts //------------------------------------------------------------------------------------------ -oc_font oc_font_nil() { return((oc_font){.h = 0}); } -bool oc_font_is_nil(oc_font font) { return(font.h == 0); } +oc_font oc_font_nil() { return ((oc_font){ .h = 0 }); } + +bool oc_font_is_nil(oc_font font) { return (font.h == 0); } oc_font oc_font_handle_alloc(oc_font_data* font) { - oc_font handle = {.h = oc_graphics_handle_alloc(OC_GRAPHICS_HANDLE_FONT, (void*)font) }; - return(handle); + oc_font handle = { .h = oc_graphics_handle_alloc(OC_GRAPHICS_HANDLE_FONT, (void*)font) }; + return (handle); } oc_font_data* oc_font_data_from_handle(oc_font handle) { - oc_font_data* data = oc_graphics_data_from_handle(OC_GRAPHICS_HANDLE_FONT, handle.h); - return(data); + oc_font_data* data = oc_graphics_data_from_handle(OC_GRAPHICS_HANDLE_FONT, handle.h); + return (data); } oc_font oc_font_create_from_memory(oc_str8 mem, u32 rangeCount, oc_unicode_range* ranges) { - if(!oc_graphicsData.init) - { - oc_graphics_init(); - } - oc_font fontHandle = oc_font_nil(); + if(!oc_graphicsData.init) + { + oc_graphics_init(); + } + oc_font fontHandle = oc_font_nil(); - oc_font_data* font = oc_list_pop_entry(&oc_graphicsData.fontFreeList, oc_font_data, freeListElt); - if(!font) - { - font = oc_arena_push_type(&oc_graphicsData.resourceArena, oc_font_data); - } - if(font) - { - memset(font, 0, sizeof(oc_font_data)); - fontHandle = oc_font_handle_alloc(font); + oc_font_data* font = oc_list_pop_entry(&oc_graphicsData.fontFreeList, oc_font_data, freeListElt); + if(!font) + { + font = oc_arena_push_type(&oc_graphicsData.resourceArena, oc_font_data); + } + if(font) + { + memset(font, 0, sizeof(oc_font_data)); + fontHandle = oc_font_handle_alloc(font); - stbtt_fontinfo stbttFontInfo; - stbtt_InitFont(&stbttFontInfo, (byte*)mem.ptr, 0); + stbtt_fontinfo stbttFontInfo; + stbtt_InitFont(&stbttFontInfo, (byte*)mem.ptr, 0); - //NOTE(martin): load font metrics data - font->unitsPerEm = 1./stbtt_ScaleForMappingEmToPixels(&stbttFontInfo, 1); + //NOTE(martin): load font metrics data + font->unitsPerEm = 1. / stbtt_ScaleForMappingEmToPixels(&stbttFontInfo, 1); - int ascent, descent, lineGap, x0, x1, y0, y1; - stbtt_GetFontVMetrics(&stbttFontInfo, &ascent, &descent, &lineGap); - stbtt_GetFontBoundingBox(&stbttFontInfo, &x0, &y0, &x1, &y1); + int ascent, descent, lineGap, x0, x1, y0, y1; + stbtt_GetFontVMetrics(&stbttFontInfo, &ascent, &descent, &lineGap); + stbtt_GetFontBoundingBox(&stbttFontInfo, &x0, &y0, &x1, &y1); - font->extents.ascent = ascent; - font->extents.descent = -descent; - font->extents.leading = lineGap; - font->extents.width = x1 - x0; + font->extents.ascent = ascent; + font->extents.descent = -descent; + font->extents.leading = lineGap; + font->extents.width = x1 - x0; - stbtt_GetCodepointBox(&stbttFontInfo, 'x', &x0, &y0, &x1, &y1); - font->extents.xHeight = y1 - y0; + stbtt_GetCodepointBox(&stbttFontInfo, 'x', &x0, &y0, &x1, &y1); + font->extents.xHeight = y1 - y0; - stbtt_GetCodepointBox(&stbttFontInfo, 'M', &x0, &y0, &x1, &y1); - font->extents.capHeight = y1 - y0; + stbtt_GetCodepointBox(&stbttFontInfo, 'M', &x0, &y0, &x1, &y1); + font->extents.capHeight = y1 - y0; - //NOTE(martin): load codepoint ranges - font->rangeCount = rangeCount; - font->glyphMap = oc_malloc_array(oc_glyph_map_entry, rangeCount); - font->glyphCount = 0; + //NOTE(martin): load codepoint ranges + font->rangeCount = rangeCount; + font->glyphMap = oc_malloc_array(oc_glyph_map_entry, rangeCount); + font->glyphCount = 0; - for(int i=0; iglyphMap[i].range = ranges[i]; - font->glyphMap[i].firstGlyphIndex = font->glyphCount + 1; - font->glyphCount += ranges[i].count; - } + for(int i = 0; i < rangeCount; i++) + { + //NOTE(martin): initialize the map entry. + // The glyph indices are offseted by 1, to reserve 0 as an invalid glyph index. + font->glyphMap[i].range = ranges[i]; + font->glyphMap[i].firstGlyphIndex = font->glyphCount + 1; + font->glyphCount += ranges[i].count; + } - font->glyphs = oc_malloc_array(oc_glyph_data, font->glyphCount); + font->glyphs = oc_malloc_array(oc_glyph_data, font->glyphCount); - //NOTE(martin): first do a count of outlines - int outlineCount = 0; - for(int rangeIndex=0; rangeIndexglyphMap[rangeIndex].range.firstCodePoint; - u32 firstGlyphIndex = font->glyphMap[rangeIndex].firstGlyphIndex; - u32 endGlyphIndex = firstGlyphIndex + font->glyphMap[rangeIndex].range.count; + //NOTE(martin): first do a count of outlines + int outlineCount = 0; + for(int rangeIndex = 0; rangeIndex < rangeCount; rangeIndex++) + { + oc_utf32 codePoint = font->glyphMap[rangeIndex].range.firstCodePoint; + u32 firstGlyphIndex = font->glyphMap[rangeIndex].firstGlyphIndex; + u32 endGlyphIndex = firstGlyphIndex + font->glyphMap[rangeIndex].range.count; - for(int glyphIndex = firstGlyphIndex; - glyphIndex < endGlyphIndex; glyphIndex++) - { - int stbttGlyphIndex = stbtt_FindGlyphIndex(&stbttFontInfo, codePoint); - if(stbttGlyphIndex == 0) - { - //NOTE(martin): the codepoint is not found in the font - codePoint++; - continue; - } - //NOTE(martin): load glyph outlines - stbtt_vertex* vertices = 0; - outlineCount += stbtt_GetGlyphShape(&stbttFontInfo, stbttGlyphIndex, &vertices); - stbtt_FreeShape(&stbttFontInfo, vertices); - codePoint++; - } - } - //NOTE(martin): allocate outlines - font->outlines = oc_malloc_array(oc_path_elt, outlineCount); - font->outlineCount = 0; + for(int glyphIndex = firstGlyphIndex; + glyphIndex < endGlyphIndex; glyphIndex++) + { + int stbttGlyphIndex = stbtt_FindGlyphIndex(&stbttFontInfo, codePoint); + if(stbttGlyphIndex == 0) + { + //NOTE(martin): the codepoint is not found in the font + codePoint++; + continue; + } + //NOTE(martin): load glyph outlines + stbtt_vertex* vertices = 0; + outlineCount += stbtt_GetGlyphShape(&stbttFontInfo, stbttGlyphIndex, &vertices); + stbtt_FreeShape(&stbttFontInfo, vertices); + codePoint++; + } + } + //NOTE(martin): allocate outlines + font->outlines = oc_malloc_array(oc_path_elt, outlineCount); + font->outlineCount = 0; - //NOTE(martin): load metrics and outlines - for(int rangeIndex=0; rangeIndexglyphMap[rangeIndex].range.firstCodePoint; - u32 firstGlyphIndex = font->glyphMap[rangeIndex].firstGlyphIndex; - u32 endGlyphIndex = firstGlyphIndex + font->glyphMap[rangeIndex].range.count; + //NOTE(martin): load metrics and outlines + for(int rangeIndex = 0; rangeIndex < rangeCount; rangeIndex++) + { + oc_utf32 codePoint = font->glyphMap[rangeIndex].range.firstCodePoint; + u32 firstGlyphIndex = font->glyphMap[rangeIndex].firstGlyphIndex; + u32 endGlyphIndex = firstGlyphIndex + font->glyphMap[rangeIndex].range.count; - for(int glyphIndex = firstGlyphIndex; - glyphIndex < endGlyphIndex; glyphIndex++) - { - oc_glyph_data* glyph = &(font->glyphs[glyphIndex-1]); + for(int glyphIndex = firstGlyphIndex; + glyphIndex < endGlyphIndex; glyphIndex++) + { + oc_glyph_data* glyph = &(font->glyphs[glyphIndex - 1]); - int stbttGlyphIndex = stbtt_FindGlyphIndex(&stbttFontInfo, codePoint); - if(stbttGlyphIndex == 0) - { - //NOTE(martin): the codepoint is not found in the font, we zero the glyph info - memset(glyph, 0, sizeof(*glyph)); - codePoint++; - continue; - } + int stbttGlyphIndex = stbtt_FindGlyphIndex(&stbttFontInfo, codePoint); + if(stbttGlyphIndex == 0) + { + //NOTE(martin): the codepoint is not found in the font, we zero the glyph info + memset(glyph, 0, sizeof(*glyph)); + codePoint++; + continue; + } - glyph->exists = true; - glyph->codePoint = codePoint; + glyph->exists = true; + glyph->codePoint = codePoint; - //NOTE(martin): load glyph metric - int xAdvance, xBearing, x0, y0, x1, y1; - stbtt_GetGlyphHMetrics(&stbttFontInfo, stbttGlyphIndex, &xAdvance, &xBearing); - stbtt_GetGlyphBox(&stbttFontInfo, stbttGlyphIndex, &x0, &y0, &x1, &y1); + //NOTE(martin): load glyph metric + int xAdvance, xBearing, x0, y0, x1, y1; + stbtt_GetGlyphHMetrics(&stbttFontInfo, stbttGlyphIndex, &xAdvance, &xBearing); + stbtt_GetGlyphBox(&stbttFontInfo, stbttGlyphIndex, &x0, &y0, &x1, &y1); - glyph->extents.xAdvance = (f32)xAdvance; - glyph->extents.yAdvance = 0; - glyph->extents.xBearing = (f32)xBearing; - glyph->extents.yBearing = y0; + glyph->extents.xAdvance = (f32)xAdvance; + glyph->extents.yAdvance = 0; + glyph->extents.xBearing = (f32)xBearing; + glyph->extents.yBearing = y0; - glyph->extents.width = x1 - x0; - glyph->extents.height = y1 - y0; + glyph->extents.width = x1 - x0; + glyph->extents.height = y1 - y0; - //NOTE(martin): load glyph outlines + //NOTE(martin): load glyph outlines - stbtt_vertex* vertices = 0; - int vertexCount = stbtt_GetGlyphShape(&stbttFontInfo, stbttGlyphIndex, &vertices); + stbtt_vertex* vertices = 0; + int vertexCount = stbtt_GetGlyphShape(&stbttFontInfo, stbttGlyphIndex, &vertices); - glyph->pathDescriptor = (oc_path_descriptor){.startIndex = font->outlineCount, - .count = vertexCount, - .startPoint = {0, 0}}; + glyph->pathDescriptor = (oc_path_descriptor){ .startIndex = font->outlineCount, + .count = vertexCount, + .startPoint = { 0, 0 } }; - oc_path_elt* elements = font->outlines + font->outlineCount; - font->outlineCount += vertexCount; - oc_vec2 currentPos = {0, 0}; + oc_path_elt* elements = font->outlines + font->outlineCount; + font->outlineCount += vertexCount; + oc_vec2 currentPos = { 0, 0 }; - for(int vertIndex = 0; vertIndex < vertexCount; vertIndex++) - { - f32 x = vertices[vertIndex].x; - f32 y = vertices[vertIndex].y; - f32 cx = vertices[vertIndex].cx; - f32 cy = vertices[vertIndex].cy; - f32 cx1 = vertices[vertIndex].cx1; - f32 cy1 = vertices[vertIndex].cy1; + for(int vertIndex = 0; vertIndex < vertexCount; vertIndex++) + { + f32 x = vertices[vertIndex].x; + f32 y = vertices[vertIndex].y; + f32 cx = vertices[vertIndex].cx; + f32 cy = vertices[vertIndex].cy; + f32 cx1 = vertices[vertIndex].cx1; + f32 cy1 = vertices[vertIndex].cy1; - switch(vertices[vertIndex].type) - { - case STBTT_vmove: - elements[vertIndex].type = OC_PATH_MOVE; - elements[vertIndex].p[0] = (oc_vec2){x, y}; - break; + switch(vertices[vertIndex].type) + { + case STBTT_vmove: + elements[vertIndex].type = OC_PATH_MOVE; + elements[vertIndex].p[0] = (oc_vec2){ x, y }; + break; - case STBTT_vline: - elements[vertIndex].type = OC_PATH_LINE; - elements[vertIndex].p[0] = (oc_vec2){x, y}; - break; + case STBTT_vline: + elements[vertIndex].type = OC_PATH_LINE; + elements[vertIndex].p[0] = (oc_vec2){ x, y }; + break; - case STBTT_vcurve: - { - elements[vertIndex].type = OC_PATH_QUADRATIC; - elements[vertIndex].p[0] = (oc_vec2){cx, cy}; - elements[vertIndex].p[1] = (oc_vec2){x, y}; - } break; + case STBTT_vcurve: + { + elements[vertIndex].type = OC_PATH_QUADRATIC; + elements[vertIndex].p[0] = (oc_vec2){ cx, cy }; + elements[vertIndex].p[1] = (oc_vec2){ x, y }; + } + break; - case STBTT_vcubic: - elements[vertIndex].type = OC_PATH_CUBIC; - elements[vertIndex].p[0] = (oc_vec2){cx, cy}; - elements[vertIndex].p[1] = (oc_vec2){cx1, cy1}; - elements[vertIndex].p[2] = (oc_vec2){x, y}; - break; - } - currentPos = (oc_vec2){x, y}; - } - stbtt_FreeShape(&stbttFontInfo, vertices); - codePoint++; - } - } - } - return(fontHandle); + case STBTT_vcubic: + elements[vertIndex].type = OC_PATH_CUBIC; + elements[vertIndex].p[0] = (oc_vec2){ cx, cy }; + elements[vertIndex].p[1] = (oc_vec2){ cx1, cy1 }; + elements[vertIndex].p[2] = (oc_vec2){ x, y }; + break; + } + currentPos = (oc_vec2){ x, y }; + } + stbtt_FreeShape(&stbttFontInfo, vertices); + codePoint++; + } + } + } + return (fontHandle); } void oc_font_destroy(oc_font fontHandle) { - oc_font_data* fontData = oc_font_data_from_handle(fontHandle); - if(fontData) - { - free(fontData->glyphMap); - free(fontData->glyphs); - free(fontData->outlines); + oc_font_data* fontData = oc_font_data_from_handle(fontHandle); + if(fontData) + { + free(fontData->glyphMap); + free(fontData->glyphs); + free(fontData->outlines); - oc_list_push(&oc_graphicsData.fontFreeList, &fontData->freeListElt); - oc_graphics_handle_recycle(fontHandle.h); - } + oc_list_push(&oc_graphicsData.fontFreeList, &fontData->freeListElt); + oc_graphics_handle_recycle(fontHandle.h); + } } oc_str32 oc_font_get_glyph_indices_from_font_data(oc_font_data* fontData, oc_str32 codePoints, oc_str32 backing) { - u64 count = oc_min(codePoints.len, backing.len); + u64 count = oc_min(codePoints.len, backing.len); - for(int i = 0; irangeCount; rangeIndex++) - { - if(codePoints.ptr[i] >= fontData->glyphMap[rangeIndex].range.firstCodePoint - && codePoints.ptr[i] < (fontData->glyphMap[rangeIndex].range.firstCodePoint + fontData->glyphMap[rangeIndex].range.count)) - { - u32 rangeOffset = codePoints.ptr[i] - fontData->glyphMap[rangeIndex].range.firstCodePoint; - glyphIndex = fontData->glyphMap[rangeIndex].firstGlyphIndex + rangeOffset; - break; - } - } - if(glyphIndex && !fontData->glyphs[glyphIndex].exists) - { - backing.ptr[i] = 0; - } - backing.ptr[i] = glyphIndex; - } - oc_str32 res = {.len = count, .ptr = backing.ptr}; - return(res); + for(int i = 0; i < count; i++) + { + u32 glyphIndex = 0; + for(int rangeIndex = 0; rangeIndex < fontData->rangeCount; rangeIndex++) + { + if(codePoints.ptr[i] >= fontData->glyphMap[rangeIndex].range.firstCodePoint + && codePoints.ptr[i] < (fontData->glyphMap[rangeIndex].range.firstCodePoint + fontData->glyphMap[rangeIndex].range.count)) + { + u32 rangeOffset = codePoints.ptr[i] - fontData->glyphMap[rangeIndex].range.firstCodePoint; + glyphIndex = fontData->glyphMap[rangeIndex].firstGlyphIndex + rangeOffset; + break; + } + } + if(glyphIndex && !fontData->glyphs[glyphIndex].exists) + { + backing.ptr[i] = 0; + } + backing.ptr[i] = glyphIndex; + } + oc_str32 res = { .len = count, .ptr = backing.ptr }; + return (res); } u32 oc_font_get_glyph_index_from_font_data(oc_font_data* fontData, oc_utf32 codePoint) { - u32 glyphIndex = 0; - oc_str32 codePoints = {1, &codePoint}; - oc_str32 backing = {1, &glyphIndex}; - oc_font_get_glyph_indices_from_font_data(fontData, codePoints, backing); - return(glyphIndex); + u32 glyphIndex = 0; + oc_str32 codePoints = { 1, &codePoint }; + oc_str32 backing = { 1, &glyphIndex }; + oc_font_get_glyph_indices_from_font_data(fontData, codePoints, backing); + return (glyphIndex); } oc_str32 oc_font_get_glyph_indices(oc_font font, oc_str32 codePoints, oc_str32 backing) { - oc_font_data* fontData = oc_font_data_from_handle(font); - if(!fontData) - { - return((oc_str32){0}); - } - return(oc_font_get_glyph_indices_from_font_data(fontData, codePoints, backing)); + oc_font_data* fontData = oc_font_data_from_handle(font); + if(!fontData) + { + return ((oc_str32){ 0 }); + } + return (oc_font_get_glyph_indices_from_font_data(fontData, codePoints, backing)); } oc_str32 oc_font_push_glyph_indices(oc_font font, oc_arena* arena, oc_str32 codePoints) { - u32* buffer = oc_arena_push_array(arena, u32, codePoints.len); - oc_str32 backing = {codePoints.len, buffer}; - return(oc_font_get_glyph_indices(font, codePoints, backing)); + u32* buffer = oc_arena_push_array(arena, u32, codePoints.len); + oc_str32 backing = { codePoints.len, buffer }; + return (oc_font_get_glyph_indices(font, codePoints, backing)); } u32 oc_font_get_glyph_index(oc_font font, oc_utf32 codePoint) { - u32 glyphIndex = 0; - oc_str32 codePoints = {1, &codePoint}; - oc_str32 backing = {1, &glyphIndex}; - oc_font_get_glyph_indices(font, codePoints, backing); - return(glyphIndex); + u32 glyphIndex = 0; + oc_str32 codePoints = { 1, &codePoint }; + oc_str32 backing = { 1, &glyphIndex }; + oc_font_get_glyph_indices(font, codePoints, backing); + return (glyphIndex); } oc_glyph_data* oc_font_get_glyph_data(oc_font_data* fontData, u32 glyphIndex) { - OC_DEBUG_ASSERT(glyphIndex); - OC_DEBUG_ASSERT(glyphIndex < fontData->glyphCount); - return(&(fontData->glyphs[glyphIndex-1])); + OC_DEBUG_ASSERT(glyphIndex); + OC_DEBUG_ASSERT(glyphIndex < fontData->glyphCount); + return (&(fontData->glyphs[glyphIndex - 1])); } oc_font_extents oc_font_get_extents(oc_font font) { - oc_font_data* fontData = oc_font_data_from_handle(font); - if(!fontData) - { - return((oc_font_extents){0}); - } - return(fontData->extents); + oc_font_data* fontData = oc_font_data_from_handle(font); + if(!fontData) + { + return ((oc_font_extents){ 0 }); + } + return (fontData->extents); } oc_font_extents oc_font_get_scaled_extents(oc_font font, f32 emSize) { - oc_font_data* fontData = oc_font_data_from_handle(font); - if(!fontData) - { - return((oc_font_extents){0}); - } - f32 scale = emSize/fontData->unitsPerEm; - oc_font_extents extents = fontData->extents; + oc_font_data* fontData = oc_font_data_from_handle(font); + if(!fontData) + { + return ((oc_font_extents){ 0 }); + } + f32 scale = emSize / fontData->unitsPerEm; + oc_font_extents extents = fontData->extents; - extents.ascent *= scale; - extents.descent *= scale; - extents.leading *= scale; - extents.xHeight *= scale; - extents.capHeight *= scale; - extents.width *= scale; + extents.ascent *= scale; + extents.descent *= scale; + extents.leading *= scale; + extents.xHeight *= scale; + extents.capHeight *= scale; + extents.width *= scale; - return(extents); + return (extents); } - f32 oc_font_get_scale_for_em_pixels(oc_font font, f32 emSize) { - oc_font_data* fontData = oc_font_data_from_handle(font); - if(!fontData) - { - return(0); - } - return(emSize/fontData->unitsPerEm); + oc_font_data* fontData = oc_font_data_from_handle(font); + if(!fontData) + { + return (0); + } + return (emSize / fontData->unitsPerEm); } void oc_font_get_glyph_extents_from_font_data(oc_font_data* fontData, oc_str32 glyphIndices, oc_text_extents* outExtents) { - for(int i=0; i= fontData->glyphCount) - { - continue; - } - oc_glyph_data* glyph = oc_font_get_glyph_data(fontData, glyphIndices.ptr[i]); - outExtents[i] = glyph->extents; - } + for(int i = 0; i < glyphIndices.len; i++) + { + if(!glyphIndices.ptr[i] || glyphIndices.ptr[i] >= fontData->glyphCount) + { + continue; + } + oc_glyph_data* glyph = oc_font_get_glyph_data(fontData, glyphIndices.ptr[i]); + outExtents[i] = glyph->extents; + } } int oc_font_get_glyph_extents(oc_font font, oc_str32 glyphIndices, oc_text_extents* outExtents) { - oc_font_data* fontData = oc_font_data_from_handle(font); - if(!fontData) - { - return(-1); - } - oc_font_get_glyph_extents_from_font_data(fontData, glyphIndices, outExtents); - return(0); + oc_font_data* fontData = oc_font_data_from_handle(font); + if(!fontData) + { + return (-1); + } + oc_font_get_glyph_extents_from_font_data(fontData, glyphIndices, outExtents); + return (0); } int oc_font_get_codepoint_extents(oc_font font, oc_utf32 codePoint, oc_text_extents* outExtents) { - oc_font_data* fontData = oc_font_data_from_handle(font); - if(!fontData) - { - return(-1); - } - u32 glyphIndex = 0; - oc_str32 codePoints = {1, &codePoint}; - oc_str32 backing = {1, &glyphIndex}; - oc_str32 glyphs = oc_font_get_glyph_indices_from_font_data(fontData, codePoints, backing); - oc_font_get_glyph_extents_from_font_data(fontData, glyphs, outExtents); - return(0); + oc_font_data* fontData = oc_font_data_from_handle(font); + if(!fontData) + { + return (-1); + } + u32 glyphIndex = 0; + oc_str32 codePoints = { 1, &codePoint }; + oc_str32 backing = { 1, &glyphIndex }; + oc_str32 glyphs = oc_font_get_glyph_indices_from_font_data(fontData, codePoints, backing); + oc_font_get_glyph_extents_from_font_data(fontData, glyphs, outExtents); + return (0); } oc_rect oc_text_bounding_box_utf32(oc_font font, f32 fontSize, oc_str32 codePoints) { - if(!codePoints.len || !codePoints.ptr) - { - return((oc_rect){0}); - } + if(!codePoints.len || !codePoints.ptr) + { + return ((oc_rect){ 0 }); + } - oc_font_data* fontData = oc_font_data_from_handle(font); - if(!fontData) - { - return((oc_rect){0}); - } + oc_font_data* fontData = oc_font_data_from_handle(font); + if(!fontData) + { + return ((oc_rect){ 0 }); + } - oc_arena* scratch = oc_scratch(); - oc_str32 glyphIndices = oc_font_push_glyph_indices(font, scratch, codePoints); + oc_arena* scratch = oc_scratch(); + oc_str32 glyphIndices = oc_font_push_glyph_indices(font, scratch, codePoints); - //NOTE(martin): find width of missing character - //TODO(martin): should cache that at font creation... - oc_text_extents missingGlyphExtents; - u32 missingGlyphIndex = oc_font_get_glyph_index_from_font_data(fontData, 0xfffd); + //NOTE(martin): find width of missing character + //TODO(martin): should cache that at font creation... + oc_text_extents missingGlyphExtents; + u32 missingGlyphIndex = oc_font_get_glyph_index_from_font_data(fontData, 0xfffd); - if(missingGlyphIndex) - { - oc_font_get_glyph_extents_from_font_data(fontData, (oc_str32){1, &missingGlyphIndex}, &missingGlyphExtents); - } - else - { - //NOTE(martin): could not find replacement glyph, try to get an 'x' to get a somewhat correct width - // to render an empty rectangle. Otherwise just render with the max font width - f32 boxWidth = fontData->extents.width * 0.8; - f32 xBearing = fontData->extents.width * 0.1; - f32 xAdvance = fontData->extents.width; + if(missingGlyphIndex) + { + oc_font_get_glyph_extents_from_font_data(fontData, (oc_str32){ 1, &missingGlyphIndex }, &missingGlyphExtents); + } + else + { + //NOTE(martin): could not find replacement glyph, try to get an 'x' to get a somewhat correct width + // to render an empty rectangle. Otherwise just render with the max font width + f32 boxWidth = fontData->extents.width * 0.8; + f32 xBearing = fontData->extents.width * 0.1; + f32 xAdvance = fontData->extents.width; - missingGlyphIndex = oc_font_get_glyph_index_from_font_data(fontData, 'x'); - if(missingGlyphIndex) - { - oc_font_get_glyph_extents_from_font_data(fontData, (oc_str32){1, &missingGlyphIndex}, &missingGlyphExtents); - } - else - { - missingGlyphExtents.xBearing = fontData->extents.width * 0.1; - missingGlyphExtents.yBearing = 0; - missingGlyphExtents.width = fontData->extents.width * 0.8; - missingGlyphExtents.xAdvance = fontData->extents.width; - missingGlyphExtents.yAdvance = 0; - } - } + missingGlyphIndex = oc_font_get_glyph_index_from_font_data(fontData, 'x'); + if(missingGlyphIndex) + { + oc_font_get_glyph_extents_from_font_data(fontData, (oc_str32){ 1, &missingGlyphIndex }, &missingGlyphExtents); + } + else + { + missingGlyphExtents.xBearing = fontData->extents.width * 0.1; + missingGlyphExtents.yBearing = 0; + missingGlyphExtents.width = fontData->extents.width * 0.8; + missingGlyphExtents.xAdvance = fontData->extents.width; + missingGlyphExtents.yAdvance = 0; + } + } - //NOTE(martin): accumulate text extents - f32 width = 0; - f32 x = 0; - f32 y = 0; - f32 lineHeight = fontData->extents.descent + fontData->extents.ascent; + //NOTE(martin): accumulate text extents + f32 width = 0; + f32 x = 0; + f32 y = 0; + f32 lineHeight = fontData->extents.descent + fontData->extents.ascent; - for(int i=0; i= fontData->glyphCount) - { - extents = missingGlyphExtents; - } - else - { - glyph = oc_font_get_glyph_data(fontData, glyphIndices.ptr[i]); - extents = glyph->extents; - } - x += extents.xAdvance; - y += extents.yAdvance; + oc_glyph_data* glyph = 0; + oc_text_extents extents; + if(!glyphIndices.ptr[i] || glyphIndices.ptr[i] >= fontData->glyphCount) + { + extents = missingGlyphExtents; + } + else + { + glyph = oc_font_get_glyph_data(fontData, glyphIndices.ptr[i]); + extents = glyph->extents; + } + x += extents.xAdvance; + y += extents.yAdvance; - if(glyph && glyph->codePoint == '\n') - { - width = oc_max(width, x); - x = 0; - y += lineHeight + fontData->extents.leading; - } - } - width = oc_max(width, x); + if(glyph && glyph->codePoint == '\n') + { + width = oc_max(width, x); + x = 0; + y += lineHeight + fontData->extents.leading; + } + } + width = oc_max(width, x); - f32 fontScale = oc_font_get_scale_for_em_pixels(font, fontSize); - oc_rect rect = {0, -fontData->extents.ascent * fontScale, width * fontScale, (y + lineHeight) * fontScale }; - return(rect); + f32 fontScale = oc_font_get_scale_for_em_pixels(font, fontSize); + oc_rect rect = { 0, -fontData->extents.ascent * fontScale, width * fontScale, (y + lineHeight) * fontScale }; + return (rect); } oc_rect oc_text_bounding_box(oc_font font, f32 fontSize, oc_str8 text) { - if(!text.len || !text.ptr) - { - return((oc_rect){0}); - } + if(!text.len || !text.ptr) + { + return ((oc_rect){ 0 }); + } - oc_arena* scratch = oc_scratch(); - oc_str32 codePoints = oc_utf8_push_to_codepoints(scratch, text); - return(oc_text_bounding_box_utf32(font, fontSize, codePoints)); + oc_arena* scratch = oc_scratch(); + oc_str32 codePoints = oc_utf8_push_to_codepoints(scratch, text); + return (oc_text_bounding_box_utf32(font, fontSize, codePoints)); } //------------------------------------------------------------------------------------------ //NOTE(martin): graphics canvas API //------------------------------------------------------------------------------------------ -oc_canvas oc_canvas_nil() { return((oc_canvas){.h = 0}); } -bool oc_canvas_is_nil(oc_canvas canvas) { return(canvas.h == 0); } +oc_canvas oc_canvas_nil() { return ((oc_canvas){ .h = 0 }); } + +bool oc_canvas_is_nil(oc_canvas canvas) { return (canvas.h == 0); } oc_canvas oc_canvas_handle_alloc(oc_canvas_data* canvas) { - oc_canvas handle = {.h = oc_graphics_handle_alloc(OC_GRAPHICS_HANDLE_CANVAS, (void*)canvas) }; - return(handle); + oc_canvas handle = { .h = oc_graphics_handle_alloc(OC_GRAPHICS_HANDLE_CANVAS, (void*)canvas) }; + return (handle); } oc_canvas_data* oc_canvas_data_from_handle(oc_canvas handle) { - oc_canvas_data* data = oc_graphics_data_from_handle(OC_GRAPHICS_HANDLE_CANVAS, handle.h); - return(data); + oc_canvas_data* data = oc_graphics_data_from_handle(OC_GRAPHICS_HANDLE_CANVAS, handle.h); + return (data); } oc_canvas oc_canvas_create() { - if(!oc_graphicsData.init) - { - oc_graphics_init(); - } + if(!oc_graphicsData.init) + { + oc_graphics_init(); + } - oc_canvas canvasHandle = oc_canvas_nil(); - oc_canvas_data* canvas = oc_list_pop_entry(&oc_graphicsData.canvasFreeList, oc_canvas_data, freeListElt); - if(!canvas) - { - canvas = oc_arena_push_type(&oc_graphicsData.resourceArena, oc_canvas_data); - } - if(canvas) - { - canvas->textFlip = false; - canvas->path = (oc_path_descriptor){0}; - canvas->matrixStackSize = 0; - canvas->clipStackSize = 0; - canvas->primitiveCount = 0; - canvas->clearColor = (oc_color){0, 0, 0, 0}; + oc_canvas canvasHandle = oc_canvas_nil(); + oc_canvas_data* canvas = oc_list_pop_entry(&oc_graphicsData.canvasFreeList, oc_canvas_data, freeListElt); + if(!canvas) + { + canvas = oc_arena_push_type(&oc_graphicsData.resourceArena, oc_canvas_data); + } + if(canvas) + { + canvas->textFlip = false; + canvas->path = (oc_path_descriptor){ 0 }; + canvas->matrixStackSize = 0; + canvas->clipStackSize = 0; + canvas->primitiveCount = 0; + canvas->clearColor = (oc_color){ 0, 0, 0, 0 }; - canvas->attributes = (oc_attributes){0}; - canvas->attributes.color = (oc_color){0, 0, 0, 1}; - canvas->attributes.tolerance = 1; - canvas->attributes.width = 10; - canvas->attributes.clip = (oc_rect){-FLT_MAX/2, -FLT_MAX/2, FLT_MAX, FLT_MAX}; + canvas->attributes = (oc_attributes){ 0 }; + canvas->attributes.color = (oc_color){ 0, 0, 0, 1 }; + canvas->attributes.tolerance = 1; + canvas->attributes.width = 10; + canvas->attributes.clip = (oc_rect){ -FLT_MAX / 2, -FLT_MAX / 2, FLT_MAX, FLT_MAX }; - canvasHandle = oc_canvas_handle_alloc(canvas); + canvasHandle = oc_canvas_handle_alloc(canvas); - oc_canvas_set_current(canvasHandle); - } - return(canvasHandle); + oc_canvas_set_current(canvasHandle); + } + return (canvasHandle); } void oc_canvas_destroy(oc_canvas handle) { - oc_canvas_data* canvas = oc_canvas_data_from_handle(handle); - if(canvas) - { - if(__mgCurrentCanvas == canvas) - { - __mgCurrentCanvas = 0; - __mgCurrentCanvasHandle = oc_canvas_nil(); - } - oc_list_push(&oc_graphicsData.canvasFreeList, &canvas->freeListElt); - oc_graphics_handle_recycle(handle.h); - } + oc_canvas_data* canvas = oc_canvas_data_from_handle(handle); + if(canvas) + { + if(__mgCurrentCanvas == canvas) + { + __mgCurrentCanvas = 0; + __mgCurrentCanvasHandle = oc_canvas_nil(); + } + oc_list_push(&oc_graphicsData.canvasFreeList, &canvas->freeListElt); + oc_graphics_handle_recycle(handle.h); + } } oc_canvas oc_canvas_set_current(oc_canvas canvas) { - oc_canvas old = __mgCurrentCanvasHandle; - __mgCurrentCanvasHandle = canvas; - __mgCurrentCanvas = oc_canvas_data_from_handle(canvas); - return(old); + oc_canvas old = __mgCurrentCanvasHandle; + __mgCurrentCanvasHandle = canvas; + __mgCurrentCanvas = oc_canvas_data_from_handle(canvas); + return (old); } void oc_render(oc_surface surface, oc_canvas canvas) { - oc_canvas_data* canvasData = oc_canvas_data_from_handle(canvas); - if(canvasData) - { - int eltCount = canvasData->path.startIndex + canvasData->path.count; - oc_surface_render_commands(surface, - canvasData->clearColor, - canvasData->primitiveCount, - canvasData->primitives, - eltCount, - canvasData->pathElements); + oc_canvas_data* canvasData = oc_canvas_data_from_handle(canvas); + if(canvasData) + { + int eltCount = canvasData->path.startIndex + canvasData->path.count; + oc_surface_render_commands(surface, + canvasData->clearColor, + canvasData->primitiveCount, + canvasData->primitives, + eltCount, + canvasData->pathElements); - canvasData->primitiveCount = 0; - canvasData->path.startIndex = 0; - canvasData->path.count = 0; - } + canvasData->primitiveCount = 0; + canvasData->path.startIndex = 0; + canvasData->path.count = 0; + } } //------------------------------------------------------------------------------------------ @@ -904,65 +907,65 @@ void oc_render(oc_surface surface, oc_canvas canvas) void oc_matrix_push(oc_mat2x3 matrix) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - oc_mat2x3 transform = oc_matrix_stack_top(canvas); - oc_matrix_stack_push(canvas, oc_mat2x3_mul_m(transform, matrix)); - } + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + oc_mat2x3 transform = oc_matrix_stack_top(canvas); + oc_matrix_stack_push(canvas, oc_mat2x3_mul_m(transform, matrix)); + } } void oc_matrix_pop() { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - oc_matrix_stack_pop(canvas); - } + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + oc_matrix_stack_pop(canvas); + } } void oc_clip_push(f32 x, f32 y, f32 w, f32 h) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - oc_rect clip = {x, y, w, h}; + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + oc_rect clip = { x, y, w, h }; - //NOTE(martin): transform clip - oc_mat2x3 transform = oc_matrix_stack_top(canvas); - oc_vec2 p0 = oc_mat2x3_mul(transform, (oc_vec2){clip.x, clip.y}); - oc_vec2 p1 = oc_mat2x3_mul(transform, (oc_vec2){clip.x + clip.w, clip.y}); - oc_vec2 p2 = oc_mat2x3_mul(transform, (oc_vec2){clip.x + clip.w, clip.y + clip.h}); - oc_vec2 p3 = oc_mat2x3_mul(transform, (oc_vec2){clip.x, clip.y + clip.h}); + //NOTE(martin): transform clip + oc_mat2x3 transform = oc_matrix_stack_top(canvas); + oc_vec2 p0 = oc_mat2x3_mul(transform, (oc_vec2){ clip.x, clip.y }); + oc_vec2 p1 = oc_mat2x3_mul(transform, (oc_vec2){ clip.x + clip.w, clip.y }); + oc_vec2 p2 = oc_mat2x3_mul(transform, (oc_vec2){ clip.x + clip.w, clip.y + clip.h }); + oc_vec2 p3 = oc_mat2x3_mul(transform, (oc_vec2){ clip.x, clip.y + clip.h }); - f32 x0 = oc_min(p0.x, oc_min(p1.x, oc_min(p2.x, p3.x))); - f32 y0 = oc_min(p0.y, oc_min(p1.y, oc_min(p2.y, p3.y))); - f32 x1 = oc_max(p0.x, oc_max(p1.x, oc_max(p2.x, p3.x))); - f32 y1 = oc_max(p0.y, oc_max(p1.y, oc_max(p2.y, p3.y))); + f32 x0 = oc_min(p0.x, oc_min(p1.x, oc_min(p2.x, p3.x))); + f32 y0 = oc_min(p0.y, oc_min(p1.y, oc_min(p2.y, p3.y))); + f32 x1 = oc_max(p0.x, oc_max(p1.x, oc_max(p2.x, p3.x))); + f32 y1 = oc_max(p0.y, oc_max(p1.y, oc_max(p2.y, p3.y))); - oc_rect current = oc_clip_stack_top(canvas); + oc_rect current = oc_clip_stack_top(canvas); - //NOTE(martin): intersect with current clip - x0 = oc_max(current.x, x0); - y0 = oc_max(current.y, y0); - x1 = oc_min(current.x + current.w, x1); - y1 = oc_min(current.y + current.h, y1); + //NOTE(martin): intersect with current clip + x0 = oc_max(current.x, x0); + y0 = oc_max(current.y, y0); + x1 = oc_min(current.x + current.w, x1); + y1 = oc_min(current.y + current.h, y1); - oc_rect r = {x0, y0, oc_max(0, x1-x0), oc_max(0, y1-y0)}; - oc_clip_stack_push(canvas, r); + oc_rect r = { x0, y0, oc_max(0, x1 - x0), oc_max(0, y1 - y0) }; + oc_clip_stack_push(canvas, r); - canvas->attributes.clip = r; - } + canvas->attributes.clip = r; + } } void oc_clip_pop() { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - oc_clip_stack_pop(canvas); - canvas->attributes.clip = oc_clip_stack_top(canvas); - } + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + oc_clip_stack_pop(canvas); + canvas->attributes.clip = oc_clip_stack_top(canvas); + } } //------------------------------------------------------------------------------------------ @@ -970,207 +973,207 @@ void oc_clip_pop() //------------------------------------------------------------------------------------------ void oc_set_color(oc_color color) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - canvas->attributes.color = color; - } + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + canvas->attributes.color = color; + } } void oc_set_color_rgba(f32 r, f32 g, f32 b, f32 a) { - oc_set_color((oc_color){r, g, b, a}); + oc_set_color((oc_color){ r, g, b, a }); } void oc_set_width(f32 width) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - canvas->attributes.width = width; - } + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + canvas->attributes.width = width; + } } void oc_set_tolerance(f32 tolerance) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - canvas->attributes.tolerance = tolerance; - } + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + canvas->attributes.tolerance = tolerance; + } } void oc_set_joint(oc_joint_type joint) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - canvas->attributes.joint = joint; - } + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + canvas->attributes.joint = joint; + } } void oc_set_max_joint_excursion(f32 maxJointExcursion) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - canvas->attributes.maxJointExcursion = maxJointExcursion; - } + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + canvas->attributes.maxJointExcursion = maxJointExcursion; + } } void oc_set_cap(oc_cap_type cap) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - canvas->attributes.cap = cap; - } + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + canvas->attributes.cap = cap; + } } void oc_set_font(oc_font font) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - canvas->attributes.font = font; - } + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + canvas->attributes.font = font; + } } void oc_set_font_size(f32 fontSize) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - canvas->attributes.fontSize = fontSize; - } + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + canvas->attributes.fontSize = fontSize; + } } void oc_set_text_flip(bool flip) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - canvas->textFlip = flip; - } + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + canvas->textFlip = flip; + } } void oc_set_image(oc_image image) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - canvas->attributes.image = image; - oc_vec2 size = oc_image_size(image); - canvas->attributes.srcRegion = (oc_rect){0, 0, size.x, size.y}; - } + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + canvas->attributes.image = image; + oc_vec2 size = oc_image_size(image); + canvas->attributes.srcRegion = (oc_rect){ 0, 0, size.x, size.y }; + } } void oc_set_image_source_region(oc_rect region) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - canvas->attributes.srcRegion = region; - } + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + canvas->attributes.srcRegion = region; + } } oc_color oc_get_color() { - oc_color color = {0}; - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - color = canvas->attributes.color; - } - return(color); + oc_color color = { 0 }; + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + color = canvas->attributes.color; + } + return (color); } f32 oc_get_width() { - f32 width = 0; - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - width = canvas->attributes.width; - } - return(width); + f32 width = 0; + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + width = canvas->attributes.width; + } + return (width); } f32 oc_get_tolerance() { - f32 tolerance = 0; - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - tolerance = canvas->attributes.tolerance; - } - return(tolerance); + f32 tolerance = 0; + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + tolerance = canvas->attributes.tolerance; + } + return (tolerance); } oc_joint_type oc_get_joint() { - oc_joint_type joint = 0; - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - joint = canvas->attributes.joint; - } - return(joint); + oc_joint_type joint = 0; + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + joint = canvas->attributes.joint; + } + return (joint); } f32 oc_get_max_joint_excursion() { - f32 maxJointExcursion = 0; - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - maxJointExcursion = canvas->attributes.maxJointExcursion; - } - return(maxJointExcursion); + f32 maxJointExcursion = 0; + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + maxJointExcursion = canvas->attributes.maxJointExcursion; + } + return (maxJointExcursion); } oc_cap_type oc_get_cap() { - oc_cap_type cap = 0; - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - cap = canvas->attributes.cap; - } - return(cap); + oc_cap_type cap = 0; + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + cap = canvas->attributes.cap; + } + return (cap); } oc_font oc_get_font() { - oc_font font = oc_font_nil(); - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - font = canvas->attributes.font; - } - return(font); + oc_font font = oc_font_nil(); + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + font = canvas->attributes.font; + } + return (font); } f32 oc_get_font_size() { - f32 fontSize = 0; - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - fontSize = canvas->attributes.fontSize; - } - return(fontSize); + f32 fontSize = 0; + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + fontSize = canvas->attributes.fontSize; + } + return (fontSize); } bool oc_get_text_flip() { - bool flip = false; - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - flip = canvas->textFlip; - } - return(flip); + bool flip = false; + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + flip = canvas->textFlip; + } + return (flip); } //------------------------------------------------------------------------------------------ @@ -1178,200 +1181,200 @@ bool oc_get_text_flip() //------------------------------------------------------------------------------------------ oc_vec2 oc_get_position() { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(!canvas) - { - return((oc_vec2){0, 0}); - } - return(canvas->subPathLastPoint); + oc_canvas_data* canvas = __mgCurrentCanvas; + if(!canvas) + { + return ((oc_vec2){ 0, 0 }); + } + return (canvas->subPathLastPoint); } void oc_move_to(f32 x, f32 y) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(!canvas) - { - return; - } - oc_path_push_element(canvas, ((oc_path_elt){.type = OC_PATH_MOVE, .p[0] = {x, y}})); - canvas->subPathStartPoint = (oc_vec2){x, y}; - canvas->subPathLastPoint = (oc_vec2){x, y}; + oc_canvas_data* canvas = __mgCurrentCanvas; + if(!canvas) + { + return; + } + oc_path_push_element(canvas, ((oc_path_elt){ .type = OC_PATH_MOVE, .p[0] = { x, y } })); + canvas->subPathStartPoint = (oc_vec2){ x, y }; + canvas->subPathLastPoint = (oc_vec2){ x, y }; } void oc_line_to(f32 x, f32 y) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(!canvas) - { - return; - } - oc_path_push_element(canvas, ((oc_path_elt){.type = OC_PATH_LINE, .p[0] = {x, y}})); - canvas->subPathLastPoint = (oc_vec2){x, y}; + oc_canvas_data* canvas = __mgCurrentCanvas; + if(!canvas) + { + return; + } + oc_path_push_element(canvas, ((oc_path_elt){ .type = OC_PATH_LINE, .p[0] = { x, y } })); + canvas->subPathLastPoint = (oc_vec2){ x, y }; } void oc_quadratic_to(f32 x1, f32 y1, f32 x2, f32 y2) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(!canvas) - { - return; - } - oc_path_push_element(canvas, ((oc_path_elt){.type = OC_PATH_QUADRATIC, .p = {{x1, y1}, {x2, y2}}})); - canvas->subPathLastPoint = (oc_vec2){x2, y2}; + oc_canvas_data* canvas = __mgCurrentCanvas; + if(!canvas) + { + return; + } + oc_path_push_element(canvas, ((oc_path_elt){ .type = OC_PATH_QUADRATIC, .p = { { x1, y1 }, { x2, y2 } } })); + canvas->subPathLastPoint = (oc_vec2){ x2, y2 }; } void oc_cubic_to(f32 x1, f32 y1, f32 x2, f32 y2, f32 x3, f32 y3) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(!canvas) - { - return; - } - oc_path_push_element(canvas, ((oc_path_elt){.type = OC_PATH_CUBIC, .p = {{x1, y1}, {x2, y2}, {x3, y3}}})); - canvas->subPathLastPoint = (oc_vec2){x3, y3}; + oc_canvas_data* canvas = __mgCurrentCanvas; + if(!canvas) + { + return; + } + oc_path_push_element(canvas, ((oc_path_elt){ .type = OC_PATH_CUBIC, .p = { { x1, y1 }, { x2, y2 }, { x3, y3 } } })); + canvas->subPathLastPoint = (oc_vec2){ x3, y3 }; } void oc_close_path() { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(!canvas) - { - return; - } - if( canvas->subPathStartPoint.x != canvas->subPathLastPoint.x - || canvas->subPathStartPoint.y != canvas->subPathLastPoint.y) - { - oc_line_to(canvas->subPathStartPoint.x, canvas->subPathStartPoint.y); - } - canvas->subPathStartPoint = canvas->subPathLastPoint; + oc_canvas_data* canvas = __mgCurrentCanvas; + if(!canvas) + { + return; + } + if(canvas->subPathStartPoint.x != canvas->subPathLastPoint.x + || canvas->subPathStartPoint.y != canvas->subPathLastPoint.y) + { + oc_line_to(canvas->subPathStartPoint.x, canvas->subPathStartPoint.y); + } + canvas->subPathStartPoint = canvas->subPathLastPoint; } oc_rect oc_glyph_outlines_from_font_data(oc_font_data* fontData, oc_str32 glyphIndices) { - oc_canvas_data* canvas = __mgCurrentCanvas; + oc_canvas_data* canvas = __mgCurrentCanvas; - f32 startX = canvas->subPathLastPoint.x; - f32 startY = canvas->subPathLastPoint.y; - f32 maxWidth = 0; + f32 startX = canvas->subPathLastPoint.x; + f32 startY = canvas->subPathLastPoint.y; + f32 maxWidth = 0; - f32 scale = canvas->attributes.fontSize/fontData->unitsPerEm; + f32 scale = canvas->attributes.fontSize / fontData->unitsPerEm; - for(int i=0; isubPathLastPoint.x; - f32 yOffset = canvas->subPathLastPoint.y; - f32 flip = canvas->textFlip ? 1 : -1; + f32 xOffset = canvas->subPathLastPoint.x; + f32 yOffset = canvas->subPathLastPoint.y; + f32 flip = canvas->textFlip ? 1 : -1; - if(!glyphIndex || glyphIndex >= fontData->glyphCount) - { - oc_log_warning("code point is not present in font ranges\n"); - //NOTE(martin): try to find the replacement character - glyphIndex = oc_font_get_glyph_index_from_font_data(fontData, 0xfffd); - if(!glyphIndex) - { - //NOTE(martin): could not find replacement glyph, try to get an 'x' to get a somewhat correct width - // to render an empty rectangle. Otherwise just render with the max font width - f32 boxWidth = fontData->extents.width * 0.8; - f32 xBearing = fontData->extents.width * 0.1; - f32 xAdvance = fontData->extents.width; + if(!glyphIndex || glyphIndex >= fontData->glyphCount) + { + oc_log_warning("code point is not present in font ranges\n"); + //NOTE(martin): try to find the replacement character + glyphIndex = oc_font_get_glyph_index_from_font_data(fontData, 0xfffd); + if(!glyphIndex) + { + //NOTE(martin): could not find replacement glyph, try to get an 'x' to get a somewhat correct width + // to render an empty rectangle. Otherwise just render with the max font width + f32 boxWidth = fontData->extents.width * 0.8; + f32 xBearing = fontData->extents.width * 0.1; + f32 xAdvance = fontData->extents.width; - glyphIndex = oc_font_get_glyph_index_from_font_data(fontData, 'x'); - if(glyphIndex) - { - oc_glyph_data* glyph = &(fontData->glyphs[glyphIndex]); - boxWidth = glyph->extents.width; - xBearing = glyph->extents.xBearing; - xAdvance = glyph->extents.xAdvance; - } - f32 oldStrokeWidth = canvas->attributes.width; + glyphIndex = oc_font_get_glyph_index_from_font_data(fontData, 'x'); + if(glyphIndex) + { + oc_glyph_data* glyph = &(fontData->glyphs[glyphIndex]); + boxWidth = glyph->extents.width; + xBearing = glyph->extents.xBearing; + xAdvance = glyph->extents.xAdvance; + } + f32 oldStrokeWidth = canvas->attributes.width; - oc_set_width(boxWidth*0.005); - oc_rectangle_stroke(xOffset + xBearing * scale, - yOffset, - boxWidth * scale * flip, - fontData->extents.capHeight*scale); + oc_set_width(boxWidth * 0.005); + oc_rectangle_stroke(xOffset + xBearing * scale, + yOffset, + boxWidth * scale * flip, + fontData->extents.capHeight * scale); - oc_set_width(oldStrokeWidth); - oc_move_to(xOffset + xAdvance * scale, yOffset); - maxWidth = oc_max(maxWidth, xOffset + xAdvance*scale - startX); - continue; - } - } + oc_set_width(oldStrokeWidth); + oc_move_to(xOffset + xAdvance * scale, yOffset); + maxWidth = oc_max(maxWidth, xOffset + xAdvance * scale - startX); + continue; + } + } - oc_glyph_data* glyph = oc_font_get_glyph_data(fontData, glyphIndex); + oc_glyph_data* glyph = oc_font_get_glyph_data(fontData, glyphIndex); - oc_path_push_elements(canvas, glyph->pathDescriptor.count, fontData->outlines + glyph->pathDescriptor.startIndex); + oc_path_push_elements(canvas, glyph->pathDescriptor.count, fontData->outlines + glyph->pathDescriptor.startIndex); - oc_path_elt* elements = canvas->pathElements + canvas->path.count + canvas->path.startIndex - glyph->pathDescriptor.count; - for(int eltIndex=0; eltIndexpathDescriptor.count; eltIndex++) - { - for(int pIndex = 0; pIndex < 3; pIndex++) - { - elements[eltIndex].p[pIndex].x = elements[eltIndex].p[pIndex].x * scale + xOffset; - elements[eltIndex].p[pIndex].y = elements[eltIndex].p[pIndex].y * scale * flip + yOffset; - } - } - oc_move_to(xOffset + scale*glyph->extents.xAdvance, yOffset); + oc_path_elt* elements = canvas->pathElements + canvas->path.count + canvas->path.startIndex - glyph->pathDescriptor.count; + for(int eltIndex = 0; eltIndex < glyph->pathDescriptor.count; eltIndex++) + { + for(int pIndex = 0; pIndex < 3; pIndex++) + { + elements[eltIndex].p[pIndex].x = elements[eltIndex].p[pIndex].x * scale + xOffset; + elements[eltIndex].p[pIndex].y = elements[eltIndex].p[pIndex].y * scale * flip + yOffset; + } + } + oc_move_to(xOffset + scale * glyph->extents.xAdvance, yOffset); - maxWidth = oc_max(maxWidth, xOffset + scale*glyph->extents.xAdvance - startX); - } - f32 lineHeight = (fontData->extents.ascent + fontData->extents.descent)*scale; - oc_rect box = {startX, startY, maxWidth, canvas->subPathLastPoint.y - startY + lineHeight }; - return(box); + maxWidth = oc_max(maxWidth, xOffset + scale * glyph->extents.xAdvance - startX); + } + f32 lineHeight = (fontData->extents.ascent + fontData->extents.descent) * scale; + oc_rect box = { startX, startY, maxWidth, canvas->subPathLastPoint.y - startY + lineHeight }; + return (box); } oc_rect oc_glyph_outlines(oc_str32 glyphIndices) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(!canvas) - { - return((oc_rect){0}); - } - oc_font_data* fontData = oc_font_data_from_handle(canvas->attributes.font); - if(!fontData) - { - return((oc_rect){0}); - } - return(oc_glyph_outlines_from_font_data(fontData, glyphIndices)); + oc_canvas_data* canvas = __mgCurrentCanvas; + if(!canvas) + { + return ((oc_rect){ 0 }); + } + oc_font_data* fontData = oc_font_data_from_handle(canvas->attributes.font); + if(!fontData) + { + return ((oc_rect){ 0 }); + } + return (oc_glyph_outlines_from_font_data(fontData, glyphIndices)); } void oc_codepoints_outlines(oc_str32 codePoints) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(!canvas) - { - return; - } - oc_font_data* fontData = oc_font_data_from_handle(canvas->attributes.font); - if(!fontData) - { - return; - } + oc_canvas_data* canvas = __mgCurrentCanvas; + if(!canvas) + { + return; + } + oc_font_data* fontData = oc_font_data_from_handle(canvas->attributes.font); + if(!fontData) + { + return; + } - oc_str32 glyphIndices = oc_font_push_glyph_indices(canvas->attributes.font, oc_scratch(), codePoints); - oc_glyph_outlines_from_font_data(fontData, glyphIndices); + oc_str32 glyphIndices = oc_font_push_glyph_indices(canvas->attributes.font, oc_scratch(), codePoints); + oc_glyph_outlines_from_font_data(fontData, glyphIndices); } void oc_text_outlines(oc_str8 text) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(!canvas) - { - return; - } - oc_font_data* fontData = oc_font_data_from_handle(canvas->attributes.font); - if(!fontData) - { - return; - } + oc_canvas_data* canvas = __mgCurrentCanvas; + if(!canvas) + { + return; + } + oc_font_data* fontData = oc_font_data_from_handle(canvas->attributes.font); + if(!fontData) + { + return; + } - oc_arena* scratch = oc_scratch(); - oc_str32 codePoints = oc_utf8_push_to_codepoints(scratch, text); - oc_str32 glyphIndices = oc_font_push_glyph_indices(canvas->attributes.font, scratch, codePoints); + oc_arena* scratch = oc_scratch(); + oc_str32 codePoints = oc_utf8_push_to_codepoints(scratch, text); + oc_str32 glyphIndices = oc_font_push_glyph_indices(canvas->attributes.font, scratch, codePoints); - oc_glyph_outlines_from_font_data(fontData, glyphIndices); + oc_glyph_outlines_from_font_data(fontData, glyphIndices); } //------------------------------------------------------------------------------------------ @@ -1380,32 +1383,32 @@ void oc_text_outlines(oc_str8 text) void oc_clear() { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - canvas->primitiveCount = 0; - canvas->clearColor = canvas->attributes.color; - } + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + canvas->primitiveCount = 0; + canvas->clearColor = canvas->attributes.color; + } } void oc_fill() { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas && canvas->path.count) - { - oc_push_command(canvas, (oc_primitive){.cmd = OC_CMD_FILL, .path = canvas->path}); - oc_new_path(canvas); - } + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas && canvas->path.count) + { + oc_push_command(canvas, (oc_primitive){ .cmd = OC_CMD_FILL, .path = canvas->path }); + oc_new_path(canvas); + } } void oc_stroke() { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas && canvas->path.count) - { - oc_push_command(canvas, (oc_primitive){.cmd = OC_CMD_STROKE, .path = canvas->path}); - oc_new_path(canvas); - } + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas && canvas->path.count) + { + oc_push_command(canvas, (oc_primitive){ .cmd = OC_CMD_STROKE, .path = canvas->path }); + oc_new_path(canvas); + } } //------------------------------------------------------------------------------------------ @@ -1414,217 +1417,217 @@ void oc_stroke() void oc_rectangle_path(f32 x, f32 y, f32 w, f32 h) { - oc_move_to(x, y); - oc_line_to(x+w, y); - oc_line_to(x+w, y+h); - oc_line_to(x, y+h); - oc_close_path(); + oc_move_to(x, y); + oc_line_to(x + w, y); + oc_line_to(x + w, y + h); + oc_line_to(x, y + h); + oc_close_path(); } void oc_rectangle_fill(f32 x, f32 y, f32 w, f32 h) { - oc_rectangle_path(x, y, w, h); - oc_fill(); + oc_rectangle_path(x, y, w, h); + oc_fill(); } void oc_rectangle_stroke(f32 x, f32 y, f32 w, f32 h) { - oc_rectangle_path(x, y, w, h); - oc_stroke(); + oc_rectangle_path(x, y, w, h); + oc_stroke(); } void oc_rounded_rectangle_path(f32 x, f32 y, f32 w, f32 h, f32 r) { - f32 c = r*4*(sqrt(2)-1)/3; + f32 c = r * 4 * (sqrt(2) - 1) / 3; - oc_move_to(x+r, y); - oc_line_to(x+w-r, y); - oc_cubic_to(x+w-r+c, y, x+w, y+r-c, x+w, y+r); - oc_line_to(x+w, y+h-r); - oc_cubic_to(x+w, y+h-r+c, x+w-r+c, y+h, x+w-r, y+h); - oc_line_to(x+r, y+h); - oc_cubic_to(x+r-c, y+h, x, y+h-r+c, x, y+h-r); - oc_line_to(x, y+r); - oc_cubic_to(x, y+r-c, x+r-c, y, x+r, y); + oc_move_to(x + r, y); + oc_line_to(x + w - r, y); + oc_cubic_to(x + w - r + c, y, x + w, y + r - c, x + w, y + r); + oc_line_to(x + w, y + h - r); + oc_cubic_to(x + w, y + h - r + c, x + w - r + c, y + h, x + w - r, y + h); + oc_line_to(x + r, y + h); + oc_cubic_to(x + r - c, y + h, x, y + h - r + c, x, y + h - r); + oc_line_to(x, y + r); + oc_cubic_to(x, y + r - c, x + r - c, y, x + r, y); } void oc_rounded_rectangle_fill(f32 x, f32 y, f32 w, f32 h, f32 r) { - oc_rounded_rectangle_path(x, y, w, h, r); - oc_fill(); + oc_rounded_rectangle_path(x, y, w, h, r); + oc_fill(); } void oc_rounded_rectangle_stroke(f32 x, f32 y, f32 w, f32 h, f32 r) { - oc_rounded_rectangle_path(x, y, w, h, r); - oc_stroke(); + oc_rounded_rectangle_path(x, y, w, h, r); + oc_stroke(); } void oc_ellipse_path(f32 x, f32 y, f32 rx, f32 ry) { - f32 cx = rx*4*(sqrt(2)-1)/3; - f32 cy = ry*4*(sqrt(2)-1)/3; + f32 cx = rx * 4 * (sqrt(2) - 1) / 3; + f32 cy = ry * 4 * (sqrt(2) - 1) / 3; - oc_move_to(x-rx, y); - oc_cubic_to(x-rx, y+cy, x-cx, y+ry, x, y+ry); - oc_cubic_to(x+cx, y+ry, x+rx, y+cy, x+rx, y); - oc_cubic_to(x+rx, y-cy, x+cx, y-ry, x, y-ry); - oc_cubic_to(x-cx, y-ry, x-rx, y-cy, x-rx, y); + oc_move_to(x - rx, y); + oc_cubic_to(x - rx, y + cy, x - cx, y + ry, x, y + ry); + oc_cubic_to(x + cx, y + ry, x + rx, y + cy, x + rx, y); + oc_cubic_to(x + rx, y - cy, x + cx, y - ry, x, y - ry); + oc_cubic_to(x - cx, y - ry, x - rx, y - cy, x - rx, y); } void oc_ellipse_fill(f32 x, f32 y, f32 rx, f32 ry) { - oc_ellipse_path(x, y, rx, ry); - oc_fill(); + oc_ellipse_path(x, y, rx, ry); + oc_fill(); } void oc_ellipse_stroke(f32 x, f32 y, f32 rx, f32 ry) { - oc_ellipse_path(x, y, rx, ry); - oc_stroke(); + oc_ellipse_path(x, y, rx, ry); + oc_stroke(); } void oc_circle_fill(f32 x, f32 y, f32 r) { - oc_ellipse_fill(x, y, r, r); + oc_ellipse_fill(x, y, r, r); } void oc_circle_stroke(f32 x, f32 y, f32 r) { - oc_ellipse_stroke(x, y, r, r); + oc_ellipse_stroke(x, y, r, r); } //TODO: change to arc_to? void oc_arc(f32 x, f32 y, f32 r, f32 arcAngle, f32 startAngle) { - f32 endAngle = startAngle + arcAngle; + f32 endAngle = startAngle + arcAngle; - while(startAngle < endAngle) - { - f32 smallAngle = oc_min(endAngle - startAngle, M_PI/4.); - if(smallAngle < 0.001) - { - break; - } + while(startAngle < endAngle) + { + f32 smallAngle = oc_min(endAngle - startAngle, M_PI / 4.); + if(smallAngle < 0.001) + { + break; + } - oc_vec2 v0 = {cos(smallAngle/2), sin(smallAngle/2)}; - oc_vec2 v1 = {(4-v0.x)/3, (1-v0.x)*(3-v0.x)/(3*v0.y)}; - oc_vec2 v2 = {v1.x, -v1.y}; - oc_vec2 v3 = {v0.x, -v0.y}; + oc_vec2 v0 = { cos(smallAngle / 2), sin(smallAngle / 2) }; + oc_vec2 v1 = { (4 - v0.x) / 3, (1 - v0.x) * (3 - v0.x) / (3 * v0.y) }; + oc_vec2 v2 = { v1.x, -v1.y }; + oc_vec2 v3 = { v0.x, -v0.y }; - f32 rotAngle = smallAngle/2 + startAngle; - f32 rotCos = cos(rotAngle); - f32 rotSin = sin(rotAngle); + f32 rotAngle = smallAngle / 2 + startAngle; + f32 rotCos = cos(rotAngle); + f32 rotSin = sin(rotAngle); - oc_mat2x3 t = {r*rotCos, -r*rotSin, x, - r*rotSin, r*rotCos, y}; + oc_mat2x3 t = { r * rotCos, -r * rotSin, x, + r * rotSin, r * rotCos, y }; - v0 = oc_mat2x3_mul(t, v0); - v1 = oc_mat2x3_mul(t, v1); - v2 = oc_mat2x3_mul(t, v2); - v3 = oc_mat2x3_mul(t, v3); + v0 = oc_mat2x3_mul(t, v0); + v1 = oc_mat2x3_mul(t, v1); + v2 = oc_mat2x3_mul(t, v2); + v3 = oc_mat2x3_mul(t, v3); - oc_move_to(v0.x, v0.y); - oc_cubic_to(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y); + oc_move_to(v0.x, v0.y); + oc_cubic_to(v1.x, v1.y, v2.x, v2.y, v3.x, v3.y); - startAngle += smallAngle; - } + startAngle += smallAngle; + } } //------------------------------------------------------------------------------------------ //NOTE(martin): images //------------------------------------------------------------------------------------------ -oc_image oc_image_nil() { return((oc_image){.h = 0}); } -bool oc_image_is_nil(oc_image image) { return(image.h == 0); } +oc_image oc_image_nil() { return ((oc_image){ .h = 0 }); } + +bool oc_image_is_nil(oc_image image) { return (image.h == 0); } oc_image oc_image_create_from_rgba8(oc_surface surface, u32 width, u32 height, u8* pixels) { - oc_image image = oc_image_create(surface, width, height); - if(!oc_image_is_nil(image)) - { - oc_image_upload_region_rgba8(image, (oc_rect){0, 0, width, height}, pixels); - } - return(image); + oc_image image = oc_image_create(surface, width, height); + if(!oc_image_is_nil(image)) + { + oc_image_upload_region_rgba8(image, (oc_rect){ 0, 0, width, height }, pixels); + } + return (image); } oc_image oc_image_create_from_memory(oc_surface surface, oc_str8 mem, bool flip) { - oc_image image = oc_image_nil(); - int width, height, channels; + oc_image image = oc_image_nil(); + int width, height, channels; - stbi_set_flip_vertically_on_load(flip ? 1 : 0); - u8* pixels = stbi_load_from_memory((u8*)mem.ptr, mem.len, &width, &height, &channels, 4); + stbi_set_flip_vertically_on_load(flip ? 1 : 0); + u8* pixels = stbi_load_from_memory((u8*)mem.ptr, mem.len, &width, &height, &channels, 4); - if(pixels) - { - image = oc_image_create_from_rgba8(surface, width, height, pixels); - free(pixels); - } - else - { - oc_log_error("stbi_load_from_memory() failed: %s\n", stbi_failure_reason()); - } - return(image); + if(pixels) + { + image = oc_image_create_from_rgba8(surface, width, height, pixels); + free(pixels); + } + else + { + oc_log_error("stbi_load_from_memory() failed: %s\n", stbi_failure_reason()); + } + return (image); } #if !OC_PLATFORM_ORCA oc_image oc_image_create_from_file(oc_surface surface, oc_str8 path, bool flip) { - oc_image image = oc_image_nil(); - int width, height, channels; + oc_image image = oc_image_nil(); + int width, height, channels; - const char* cpath = oc_str8_to_cstring(oc_scratch(), path); + const char* cpath = oc_str8_to_cstring(oc_scratch(), path); - stbi_set_flip_vertically_on_load(flip ? 1 : 0); - u8* pixels = stbi_load(cpath, &width, &height, &channels, 4); - if(pixels) - { - image = oc_image_create_from_rgba8(surface, width, height, pixels); - free(pixels); - } - else - { - oc_log_error("stbi_load() failed: %s\n", stbi_failure_reason()); - } - return(image); + stbi_set_flip_vertically_on_load(flip ? 1 : 0); + u8* pixels = stbi_load(cpath, &width, &height, &channels, 4); + if(pixels) + { + image = oc_image_create_from_rgba8(surface, width, height, pixels); + free(pixels); + } + else + { + oc_log_error("stbi_load() failed: %s\n", stbi_failure_reason()); + } + return (image); } #endif // !OC_PLATFORM_ORCA - void oc_image_draw_region(oc_image image, oc_rect srcRegion, oc_rect dstRegion) { - oc_canvas_data* canvas = __mgCurrentCanvas; - if(canvas) - { - oc_image oldImage = canvas->attributes.image; - oc_rect oldSrcRegion = canvas->attributes.srcRegion; - oc_color oldColor = canvas->attributes.color; + oc_canvas_data* canvas = __mgCurrentCanvas; + if(canvas) + { + oc_image oldImage = canvas->attributes.image; + oc_rect oldSrcRegion = canvas->attributes.srcRegion; + oc_color oldColor = canvas->attributes.color; - canvas->attributes.image = image; - canvas->attributes.srcRegion = srcRegion; - canvas->attributes.color = (oc_color){1, 1, 1, 1}; + canvas->attributes.image = image; + canvas->attributes.srcRegion = srcRegion; + canvas->attributes.color = (oc_color){ 1, 1, 1, 1 }; - oc_move_to(dstRegion.x, dstRegion.y); - oc_line_to(dstRegion.x+dstRegion.w, dstRegion.y); - oc_line_to(dstRegion.x+dstRegion.w, dstRegion.y+dstRegion.h); - oc_line_to(dstRegion.x, dstRegion.y+dstRegion.h); - oc_close_path(); + oc_move_to(dstRegion.x, dstRegion.y); + oc_line_to(dstRegion.x + dstRegion.w, dstRegion.y); + oc_line_to(dstRegion.x + dstRegion.w, dstRegion.y + dstRegion.h); + oc_line_to(dstRegion.x, dstRegion.y + dstRegion.h); + oc_close_path(); - oc_fill(); + oc_fill(); - canvas->attributes.image = oldImage; - canvas->attributes.srcRegion = oldSrcRegion; - canvas->attributes.color = oldColor; - } + canvas->attributes.image = oldImage; + canvas->attributes.srcRegion = oldSrcRegion; + canvas->attributes.color = oldColor; + } } void oc_image_draw(oc_image image, oc_rect rect) { - oc_vec2 size = oc_image_size(image); - oc_image_draw_region(image, (oc_rect){0, 0, size.x, size.y}, rect); + oc_vec2 size = oc_image_size(image); + oc_image_draw_region(image, (oc_rect){ 0, 0, size.x, size.y }, rect); } //------------------------------------------------------------------------------------------ @@ -1634,101 +1637,101 @@ void oc_image_draw(oc_image image, oc_rect rect) //NOTE: rectangle allocator typedef struct oc_rect_atlas { - oc_arena* arena; - oc_vec2i size; - oc_vec2i pos; - u32 lineHeight; + oc_arena* arena; + oc_vec2i size; + oc_vec2i pos; + u32 lineHeight; } oc_rect_atlas; oc_rect_atlas* oc_rect_atlas_create(oc_arena* arena, i32 width, i32 height) { - oc_rect_atlas* atlas = oc_arena_push_type(arena, oc_rect_atlas); - memset(atlas, 0, sizeof(oc_rect_atlas)); - atlas->arena = arena; - atlas->size = (oc_vec2i){width, height}; - return(atlas); + oc_rect_atlas* atlas = oc_arena_push_type(arena, oc_rect_atlas); + memset(atlas, 0, sizeof(oc_rect_atlas)); + atlas->arena = arena; + atlas->size = (oc_vec2i){ width, height }; + return (atlas); } oc_rect oc_rect_atlas_alloc(oc_rect_atlas* atlas, i32 width, i32 height) { - oc_rect rect = {0, 0, 0, 0}; - if(width > 0 && height > 0) - { - if(atlas->pos.x + width >= atlas->size.x) - { - atlas->pos.x = 0; - atlas->pos.y += (atlas->lineHeight + 1); - atlas->lineHeight = 0; - } - if( atlas->pos.x + width < atlas->size.x - && atlas->pos.y + height < atlas->size.y) - { - rect = (oc_rect){atlas->pos.x, atlas->pos.y, width, height}; + oc_rect rect = { 0, 0, 0, 0 }; + if(width > 0 && height > 0) + { + if(atlas->pos.x + width >= atlas->size.x) + { + atlas->pos.x = 0; + atlas->pos.y += (atlas->lineHeight + 1); + atlas->lineHeight = 0; + } + if(atlas->pos.x + width < atlas->size.x + && atlas->pos.y + height < atlas->size.y) + { + rect = (oc_rect){ atlas->pos.x, atlas->pos.y, width, height }; - atlas->pos.x += (width + 1); - atlas->lineHeight = oc_max(atlas->lineHeight, height); - } - } - return(rect); + atlas->pos.x += (width + 1); + atlas->lineHeight = oc_max(atlas->lineHeight, height); + } + } + return (rect); } void oc_rect_atlas_recycle(oc_rect_atlas* atlas, oc_rect rect) { - //TODO + //TODO } oc_image_region oc_image_atlas_alloc_from_rgba8(oc_rect_atlas* atlas, oc_image backingImage, u32 width, u32 height, u8* pixels) { - oc_image_region imageRgn = {0}; + oc_image_region imageRgn = { 0 }; - oc_rect rect = oc_rect_atlas_alloc(atlas, width, height); - if(rect.w == width && rect.h == height) - { - oc_image_upload_region_rgba8(backingImage, rect, pixels); - imageRgn.rect = rect; - imageRgn.image = backingImage; - } - return(imageRgn); + oc_rect rect = oc_rect_atlas_alloc(atlas, width, height); + if(rect.w == width && rect.h == height) + { + oc_image_upload_region_rgba8(backingImage, rect, pixels); + imageRgn.rect = rect; + imageRgn.image = backingImage; + } + return (imageRgn); } #if !OC_PLATFORM_ORCA oc_image_region oc_image_atlas_alloc_from_data(oc_rect_atlas* atlas, oc_image backingImage, oc_str8 data, bool flip) { - oc_image_region imageRgn = {0}; + oc_image_region imageRgn = { 0 }; - stbi_set_flip_vertically_on_load(flip ? 1 : 0); + stbi_set_flip_vertically_on_load(flip ? 1 : 0); - int width, height, channels; - u8* pixels = stbi_load_from_memory((u8*)data.ptr, data.len, &width, &height, &channels, 4); - if(pixels) - { - imageRgn = oc_image_atlas_alloc_from_rgba8(atlas, backingImage, width, height, pixels); - free(pixels); - } - return(imageRgn); + int width, height, channels; + u8* pixels = stbi_load_from_memory((u8*)data.ptr, data.len, &width, &height, &channels, 4); + if(pixels) + { + imageRgn = oc_image_atlas_alloc_from_rgba8(atlas, backingImage, width, height, pixels); + free(pixels); + } + return (imageRgn); } oc_image_region oc_image_atlas_alloc_from_file(oc_rect_atlas* atlas, oc_image backingImage, oc_str8 path, bool flip) { - oc_image_region imageRgn = {0}; + oc_image_region imageRgn = { 0 }; - stbi_set_flip_vertically_on_load(flip ? 1 : 0); + stbi_set_flip_vertically_on_load(flip ? 1 : 0); - const char* cpath = oc_str8_to_cstring(oc_scratch(), path); - int width, height, channels; - u8* pixels = stbi_load(cpath, &width, &height, &channels, 4); - if(pixels) - { - imageRgn = oc_image_atlas_alloc_from_rgba8(atlas, backingImage, width, height, pixels); - free(pixels); - } - return(imageRgn); + const char* cpath = oc_str8_to_cstring(oc_scratch(), path); + int width, height, channels; + u8* pixels = stbi_load(cpath, &width, &height, &channels, 4); + if(pixels) + { + imageRgn = oc_image_atlas_alloc_from_rgba8(atlas, backingImage, width, height, pixels); + free(pixels); + } + return (imageRgn); } #endif // !OC_PLATFORM_ORCA void oc_image_atlas_recycle(oc_rect_atlas* atlas, oc_image_region imageRgn) { - oc_rect_atlas_recycle(atlas, imageRgn.rect); + oc_rect_atlas_recycle(atlas, imageRgn.rect); } diff --git a/src/graphics/graphics_common.h b/src/graphics/graphics_common.h index 6e805e3..bd14a7b 100644 --- a/src/graphics/graphics_common.h +++ b/src/graphics/graphics_common.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: graphics_common.h * @author: Martin Fouilleul @@ -8,75 +8,80 @@ #ifndef __GRAPHICS_COMMON_H_ #define __GRAPHICS_COMMON_H_ -#include"graphics.h" +#include "graphics.h" //------------------------------------------------------------------------ // canvas structs //------------------------------------------------------------------------ -typedef enum { OC_PATH_MOVE, - OC_PATH_LINE, - OC_PATH_QUADRATIC, - OC_PATH_CUBIC } oc_path_elt_type; +typedef enum +{ + OC_PATH_MOVE, + OC_PATH_LINE, + OC_PATH_QUADRATIC, + OC_PATH_CUBIC +} oc_path_elt_type; typedef struct oc_path_elt { - oc_path_elt_type type; - oc_vec2 p[3]; + oc_path_elt_type type; + oc_vec2 p[3]; } oc_path_elt; typedef struct oc_path_descriptor { - u32 startIndex; - u32 count; - oc_vec2 startPoint; + u32 startIndex; + u32 count; + oc_vec2 startPoint; } oc_path_descriptor; typedef struct oc_attributes { - f32 width; - f32 tolerance; - oc_color color; - oc_joint_type joint; - f32 maxJointExcursion; - oc_cap_type cap; + f32 width; + f32 tolerance; + oc_color color; + oc_joint_type joint; + f32 maxJointExcursion; + oc_cap_type cap; - oc_font font; - f32 fontSize; + oc_font font; + f32 fontSize; - oc_image image; - oc_rect srcRegion; + oc_image image; + oc_rect srcRegion; - oc_mat2x3 transform; - oc_rect clip; + oc_mat2x3 transform; + oc_rect clip; } oc_attributes; -typedef enum { OC_CMD_FILL, - OC_CMD_STROKE, - OC_CMD_JUMP - } oc_primitive_cmd; +typedef enum +{ + OC_CMD_FILL, + OC_CMD_STROKE, + OC_CMD_JUMP +} oc_primitive_cmd; typedef struct oc_primitive { - oc_primitive_cmd cmd; - oc_attributes attributes; + oc_primitive_cmd cmd; + oc_attributes attributes; - union - { - oc_path_descriptor path; - oc_rect rect; - u32 jump; - }; + union + { + oc_path_descriptor path; + oc_rect rect; + u32 jump; + }; } oc_primitive; ORCA_API void oc_surface_render_commands(oc_surface surface, - oc_color clearColor, - u32 primitiveCount, - oc_primitive* primitives, - u32 eltCount, - oc_path_elt* elements); + oc_color clearColor, + u32 primitiveCount, + oc_primitive* primitives, + u32 eltCount, + oc_path_elt* elements); #endif //__GRAPHICS_COMMON_H_ diff --git a/src/graphics/graphics_surface.c b/src/graphics/graphics_surface.c index 7f32327..a022523 100644 --- a/src/graphics/graphics_surface.c +++ b/src/graphics/graphics_surface.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: graphics_surface.c * @author: Martin Fouilleul @@ -6,13 +6,13 @@ * *****************************************************************/ -#include"graphics_surface.h" +#include "graphics_surface.h" //--------------------------------------------------------------- // per-thread selected surface //--------------------------------------------------------------- -oc_thread_local oc_surface oc_selectedSurface = {0}; +oc_thread_local oc_surface oc_selectedSurface = { 0 }; //--------------------------------------------------------------- // typed handles functions @@ -20,26 +20,26 @@ oc_thread_local oc_surface oc_selectedSurface = {0}; oc_surface oc_surface_handle_alloc(oc_surface_data* surface) { - oc_surface handle = {.h = oc_graphics_handle_alloc(OC_GRAPHICS_HANDLE_SURFACE, (void*)surface) }; - return(handle); + oc_surface handle = { .h = oc_graphics_handle_alloc(OC_GRAPHICS_HANDLE_SURFACE, (void*)surface) }; + return (handle); } oc_surface_data* oc_surface_data_from_handle(oc_surface handle) { - oc_surface_data* data = oc_graphics_data_from_handle(OC_GRAPHICS_HANDLE_SURFACE, handle.h); - return(data); + oc_surface_data* data = oc_graphics_data_from_handle(OC_GRAPHICS_HANDLE_SURFACE, handle.h); + return (data); } oc_image oc_image_handle_alloc(oc_image_data* image) { - oc_image handle = {.h = oc_graphics_handle_alloc(OC_GRAPHICS_HANDLE_IMAGE, (void*)image) }; - return(handle); + oc_image handle = { .h = oc_graphics_handle_alloc(OC_GRAPHICS_HANDLE_IMAGE, (void*)image) }; + return (handle); } oc_image_data* oc_image_data_from_handle(oc_image handle) { - oc_image_data* data = oc_graphics_data_from_handle(OC_GRAPHICS_HANDLE_IMAGE, handle.h); - return(data); + oc_image_data* data = oc_graphics_data_from_handle(OC_GRAPHICS_HANDLE_IMAGE, handle.h); + return (data); } //--------------------------------------------------------------- @@ -47,304 +47,305 @@ oc_image_data* oc_image_data_from_handle(oc_image handle) //--------------------------------------------------------------- #if OC_COMPILE_GL - #if OC_PLATFORM_WINDOWS - #include"wgl_surface.h" - #define oc_gl_surface_create_for_window oc_wgl_surface_create_for_window - #endif + #if OC_PLATFORM_WINDOWS + #include "wgl_surface.h" + #define oc_gl_surface_create_for_window oc_wgl_surface_create_for_window + #endif #endif #if OC_COMPILE_GLES - #include"egl_surface.h" + #include "egl_surface.h" #endif #if OC_COMPILE_METAL - #include"mtl_surface.h" + #include "mtl_surface.h" #endif #if OC_COMPILE_CANVAS - #if OC_PLATFORM_MACOS - oc_surface_data* oc_mtl_canvas_surface_create_for_window(oc_window window); - #elif OC_PLATFORM_WINDOWS - oc_surface_data* oc_gl_canvas_surface_create_for_window(oc_window window); - #endif + #if OC_PLATFORM_MACOS +oc_surface_data* oc_mtl_canvas_surface_create_for_window(oc_window window); + #elif OC_PLATFORM_WINDOWS +oc_surface_data* oc_gl_canvas_surface_create_for_window(oc_window window); + #endif #endif bool oc_is_surface_backend_available(oc_surface_api api) { - bool result = false; - switch(api) - { - #if OC_COMPILE_METAL - case OC_METAL: - #endif + bool result = false; + switch(api) + { +#if OC_COMPILE_METAL + case OC_METAL: +#endif - #if OC_COMPILE_GL - case OC_GL: - #endif +#if OC_COMPILE_GL + case OC_GL: +#endif - #if OC_COMPILE_GLES - case OC_GLES: - #endif +#if OC_COMPILE_GLES + case OC_GLES: +#endif - #if OC_COMPILE_CANVAS - case OC_CANVAS: - #endif - result = true; - break; +#if OC_COMPILE_CANVAS + case OC_CANVAS: +#endif + result = true; + break; - default: - break; - } - return(result); + default: + break; + } + return (result); } -oc_surface oc_surface_nil() { return((oc_surface){.h = 0}); } -bool oc_surface_is_nil(oc_surface surface) { return(surface.h == 0); } +oc_surface oc_surface_nil() { return ((oc_surface){ .h = 0 }); } + +bool oc_surface_is_nil(oc_surface surface) { return (surface.h == 0); } oc_surface oc_surface_create_for_window(oc_window window, oc_surface_api api) { - if(oc_graphicsData.init) - { - oc_graphics_init(); - } - oc_surface surfaceHandle = oc_surface_nil(); - oc_surface_data* surface = 0; + if(oc_graphicsData.init) + { + oc_graphics_init(); + } + oc_surface surfaceHandle = oc_surface_nil(); + oc_surface_data* surface = 0; - switch(api) - { - #if OC_COMPILE_GL - case OC_GL: - surface = oc_gl_surface_create_for_window(window); - break; - #endif + switch(api) + { +#if OC_COMPILE_GL + case OC_GL: + surface = oc_gl_surface_create_for_window(window); + break; +#endif - #if OC_COMPILE_GLES - case OC_GLES: - surface = oc_egl_surface_create_for_window(window); - break; - #endif +#if OC_COMPILE_GLES + case OC_GLES: + surface = oc_egl_surface_create_for_window(window); + break; +#endif - #if OC_COMPILE_METAL - case OC_METAL: - surface = oc_mtl_surface_create_for_window(window); - break; - #endif +#if OC_COMPILE_METAL + case OC_METAL: + surface = oc_mtl_surface_create_for_window(window); + break; +#endif - #if OC_COMPILE_CANVAS - case OC_CANVAS: +#if OC_COMPILE_CANVAS + case OC_CANVAS: - #if OC_PLATFORM_MACOS - surface = oc_mtl_canvas_surface_create_for_window(window); - #elif OC_PLATFORM_WINDOWS - surface = oc_gl_canvas_surface_create_for_window(window); - #endif - break; - #endif + #if OC_PLATFORM_MACOS + surface = oc_mtl_canvas_surface_create_for_window(window); + #elif OC_PLATFORM_WINDOWS + surface = oc_gl_canvas_surface_create_for_window(window); + #endif + break; +#endif - default: - break; - } - if(surface) - { - surfaceHandle = oc_surface_handle_alloc(surface); - oc_surface_select(surfaceHandle); - } - return(surfaceHandle); + default: + break; + } + if(surface) + { + surfaceHandle = oc_surface_handle_alloc(surface); + oc_surface_select(surfaceHandle); + } + return (surfaceHandle); } oc_surface oc_surface_create_remote(u32 width, u32 height, oc_surface_api api) { - if(!oc_graphicsData.init) - { - oc_graphics_init(); - } - oc_surface surfaceHandle = oc_surface_nil(); - oc_surface_data* surface = 0; + if(!oc_graphicsData.init) + { + oc_graphics_init(); + } + oc_surface surfaceHandle = oc_surface_nil(); + oc_surface_data* surface = 0; - switch(api) - { - #if OC_COMPILE_GLES - case OC_GLES: - surface = oc_egl_surface_create_remote(width, height); - break; - #endif + switch(api) + { +#if OC_COMPILE_GLES + case OC_GLES: + surface = oc_egl_surface_create_remote(width, height); + break; +#endif - default: - break; - } - if(surface) - { - surfaceHandle = oc_surface_handle_alloc(surface); - oc_surface_select(surfaceHandle); - } - return(surfaceHandle); + default: + break; + } + if(surface) + { + surfaceHandle = oc_surface_handle_alloc(surface); + oc_surface_select(surfaceHandle); + } + return (surfaceHandle); } oc_surface oc_surface_create_host(oc_window window) { - if(!oc_graphicsData.init) - { - oc_graphics_init(); - } - oc_surface handle = oc_surface_nil(); - oc_surface_data* surface = 0; - #if OC_PLATFORM_MACOS - surface = oc_osx_surface_create_host(window); - #elif OC_PLATFORM_WINDOWS - surface = oc_win32_surface_create_host(window); - #endif + if(!oc_graphicsData.init) + { + oc_graphics_init(); + } + oc_surface handle = oc_surface_nil(); + oc_surface_data* surface = 0; +#if OC_PLATFORM_MACOS + surface = oc_osx_surface_create_host(window); +#elif OC_PLATFORM_WINDOWS + surface = oc_win32_surface_create_host(window); +#endif - if(surface) - { - handle = oc_surface_handle_alloc(surface); - } - return(handle); + if(surface) + { + handle = oc_surface_handle_alloc(surface); + } + return (handle); } void oc_surface_destroy(oc_surface handle) { - OC_DEBUG_ASSERT(oc_graphicsData.init); - oc_surface_data* surface = oc_surface_data_from_handle(handle); - if(surface) - { - if(oc_selectedSurface.h == handle.h) - { - oc_surface_deselect(); - } + OC_DEBUG_ASSERT(oc_graphicsData.init); + oc_surface_data* surface = oc_surface_data_from_handle(handle); + if(surface) + { + if(oc_selectedSurface.h == handle.h) + { + oc_surface_deselect(); + } - if(surface->backend && surface->backend->destroy) - { - surface->backend->destroy(surface->backend); - } - surface->destroy(surface); - oc_graphics_handle_recycle(handle.h); - } + if(surface->backend && surface->backend->destroy) + { + surface->backend->destroy(surface->backend); + } + surface->destroy(surface); + oc_graphics_handle_recycle(handle.h); + } } void oc_surface_deselect() { - OC_DEBUG_ASSERT(oc_graphicsData.init); + OC_DEBUG_ASSERT(oc_graphicsData.init); - oc_surface_data* prevSurface = oc_surface_data_from_handle(oc_selectedSurface); - if(prevSurface && prevSurface->deselect) - { - prevSurface->deselect(prevSurface); - } - oc_selectedSurface = oc_surface_nil(); + oc_surface_data* prevSurface = oc_surface_data_from_handle(oc_selectedSurface); + if(prevSurface && prevSurface->deselect) + { + prevSurface->deselect(prevSurface); + } + oc_selectedSurface = oc_surface_nil(); } void oc_surface_select(oc_surface surface) { - OC_DEBUG_ASSERT(oc_graphicsData.init); + OC_DEBUG_ASSERT(oc_graphicsData.init); - if(surface.h != oc_selectedSurface.h) - { - oc_surface_deselect(); - } + if(surface.h != oc_selectedSurface.h) + { + oc_surface_deselect(); + } - oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); - if(surfaceData && surfaceData->prepare) - { - surfaceData->prepare(surfaceData); - oc_selectedSurface = surface; - } + oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); + if(surfaceData && surfaceData->prepare) + { + surfaceData->prepare(surfaceData); + oc_selectedSurface = surface; + } } void oc_surface_present(oc_surface surface) { - OC_DEBUG_ASSERT(oc_graphicsData.init); - oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); - if(surfaceData && surfaceData->present) - { - surfaceData->present(surfaceData); - } + OC_DEBUG_ASSERT(oc_graphicsData.init); + oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); + if(surfaceData && surfaceData->present) + { + surfaceData->present(surfaceData); + } } void oc_surface_swap_interval(oc_surface surface, int swap) { - OC_DEBUG_ASSERT(oc_graphicsData.init); - oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); - if(surfaceData && surfaceData->swapInterval) - { - surfaceData->swapInterval(surfaceData, swap); - } + OC_DEBUG_ASSERT(oc_graphicsData.init); + oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); + if(surfaceData && surfaceData->swapInterval) + { + surfaceData->swapInterval(surfaceData, swap); + } } oc_vec2 oc_surface_get_size(oc_surface surface) { - OC_DEBUG_ASSERT(oc_graphicsData.init); - oc_vec2 size = {0}; - oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); - if(surfaceData && surfaceData->getSize) - { - size = surfaceData->getSize(surfaceData); - } - return(size); + OC_DEBUG_ASSERT(oc_graphicsData.init); + oc_vec2 size = { 0 }; + oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); + if(surfaceData && surfaceData->getSize) + { + size = surfaceData->getSize(surfaceData); + } + return (size); } oc_vec2 oc_surface_contents_scaling(oc_surface surface) { - OC_DEBUG_ASSERT(oc_graphicsData.init); - oc_vec2 scaling = {1, 1}; - oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); - if(surfaceData && surfaceData->contentsScaling) - { - scaling = surfaceData->contentsScaling(surfaceData); - } - return(scaling); + OC_DEBUG_ASSERT(oc_graphicsData.init); + oc_vec2 scaling = { 1, 1 }; + oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); + if(surfaceData && surfaceData->contentsScaling) + { + scaling = surfaceData->contentsScaling(surfaceData); + } + return (scaling); } void oc_surface_set_hidden(oc_surface surface, bool hidden) { - OC_DEBUG_ASSERT(oc_graphicsData.init); - oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); - if(surfaceData && surfaceData->setHidden) - { - surfaceData->setHidden(surfaceData, hidden); - } + OC_DEBUG_ASSERT(oc_graphicsData.init); + oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); + if(surfaceData && surfaceData->setHidden) + { + surfaceData->setHidden(surfaceData, hidden); + } } bool oc_surface_get_hidden(oc_surface surface) { - OC_DEBUG_ASSERT(oc_graphicsData.init); - bool res = false; - oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); - if(surfaceData && surfaceData->getHidden) - { - res = surfaceData->getHidden(surfaceData); - } - return(res); + OC_DEBUG_ASSERT(oc_graphicsData.init); + bool res = false; + oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); + if(surfaceData && surfaceData->getHidden) + { + res = surfaceData->getHidden(surfaceData); + } + return (res); } void* oc_surface_native_layer(oc_surface surface) { - void* res = 0; - oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); - if(surfaceData && surfaceData->nativeLayer) - { - res = surfaceData->nativeLayer(surfaceData); - } - return(res); + void* res = 0; + oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); + if(surfaceData && surfaceData->nativeLayer) + { + res = surfaceData->nativeLayer(surfaceData); + } + return (res); } oc_surface_id oc_surface_remote_id(oc_surface handle) { - oc_surface_id remoteId = 0; - oc_surface_data* surface = oc_surface_data_from_handle(handle); - if(surface && surface->remoteID) - { - remoteId = surface->remoteID(surface); - } - return(remoteId); + oc_surface_id remoteId = 0; + oc_surface_data* surface = oc_surface_data_from_handle(handle); + if(surface && surface->remoteID) + { + remoteId = surface->remoteID(surface); + } + return (remoteId); } void oc_surface_host_connect(oc_surface handle, oc_surface_id remoteID) { - oc_surface_data* surface = oc_surface_data_from_handle(handle); - if(surface && surface->hostConnect) - { - surface->hostConnect(surface, remoteID); - } + oc_surface_data* surface = oc_surface_data_from_handle(handle); + if(surface && surface->hostConnect) + { + surface->hostConnect(surface, remoteID); + } } void oc_surface_render_commands(oc_surface surface, @@ -354,21 +355,21 @@ void oc_surface_render_commands(oc_surface surface, u32 eltCount, oc_path_elt* elements) { - oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); + oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); - if(surface.h != oc_selectedSurface.h) - { - oc_log_error("surface is not selected. Make sure to call oc_surface_select() before drawing onto a surface.\n"); - } - else if(surfaceData && surfaceData->backend) - { - surfaceData->backend->render(surfaceData->backend, - clearColor, - primitiveCount, - primitives, - eltCount, - elements); - } + if(surface.h != oc_selectedSurface.h) + { + oc_log_error("surface is not selected. Make sure to call oc_surface_select() before drawing onto a surface.\n"); + } + else if(surfaceData && surfaceData->backend) + { + surfaceData->backend->render(surfaceData->backend, + clearColor, + primitiveCount, + primitives, + eltCount, + elements); + } } //------------------------------------------------------------------------------------------ @@ -377,78 +378,78 @@ void oc_surface_render_commands(oc_surface surface, oc_vec2 oc_image_size(oc_image image) { - oc_vec2 res = {0}; - oc_image_data* imageData = oc_image_data_from_handle(image); - if(imageData) - { - res = imageData->size; - } - return(res); + oc_vec2 res = { 0 }; + oc_image_data* imageData = oc_image_data_from_handle(image); + if(imageData) + { + res = imageData->size; + } + return (res); } oc_image oc_image_create(oc_surface surface, u32 width, u32 height) { - oc_image image = oc_image_nil(); - oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); + oc_image image = oc_image_nil(); + oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); - if(surface.h != oc_selectedSurface.h) - { - oc_log_error("surface is not selected. Make sure to call oc_surface_select() before modifying graphics resources.\n"); - } - else if(surfaceData && surfaceData->backend) - { - OC_DEBUG_ASSERT(surfaceData->api == OC_CANVAS); + if(surface.h != oc_selectedSurface.h) + { + oc_log_error("surface is not selected. Make sure to call oc_surface_select() before modifying graphics resources.\n"); + } + else if(surfaceData && surfaceData->backend) + { + OC_DEBUG_ASSERT(surfaceData->api == OC_CANVAS); - oc_image_data* imageData = surfaceData->backend->imageCreate(surfaceData->backend, (oc_vec2){width, height}); - if(imageData) - { - imageData->surface = surface; - image = oc_image_handle_alloc(imageData); - } - } - return(image); + oc_image_data* imageData = surfaceData->backend->imageCreate(surfaceData->backend, (oc_vec2){ width, height }); + if(imageData) + { + imageData->surface = surface; + image = oc_image_handle_alloc(imageData); + } + } + return (image); } void oc_image_destroy(oc_image image) { - oc_image_data* imageData = oc_image_data_from_handle(image); + oc_image_data* imageData = oc_image_data_from_handle(image); - if(imageData) - { - if(imageData->surface.h != oc_selectedSurface.h) - { - oc_log_error("surface is not selected. Make sure to call oc_surface_select() before modifying graphics resources.\n"); - } - else - { - oc_surface_data* surface = oc_surface_data_from_handle(imageData->surface); - if(surface && surface->backend) - { - surface->backend->imageDestroy(surface->backend, imageData); - oc_graphics_handle_recycle(image.h); - } - } - } + if(imageData) + { + if(imageData->surface.h != oc_selectedSurface.h) + { + oc_log_error("surface is not selected. Make sure to call oc_surface_select() before modifying graphics resources.\n"); + } + else + { + oc_surface_data* surface = oc_surface_data_from_handle(imageData->surface); + if(surface && surface->backend) + { + surface->backend->imageDestroy(surface->backend, imageData); + oc_graphics_handle_recycle(image.h); + } + } + } } void oc_image_upload_region_rgba8(oc_image image, oc_rect region, u8* pixels) { - oc_image_data* imageData = oc_image_data_from_handle(image); + oc_image_data* imageData = oc_image_data_from_handle(image); - if(imageData) - { - if(imageData->surface.h != oc_selectedSurface.h) - { - oc_log_error("surface is not selected. Make sure to call oc_surface_select() before modifying graphics resources.\n"); - } - else - { - oc_surface_data* surfaceData = oc_surface_data_from_handle(imageData->surface); - if(surfaceData) - { - OC_DEBUG_ASSERT(surfaceData->backend); - surfaceData->backend->imageUploadRegion(surfaceData->backend, imageData, region, pixels); - } - } - } + if(imageData) + { + if(imageData->surface.h != oc_selectedSurface.h) + { + oc_log_error("surface is not selected. Make sure to call oc_surface_select() before modifying graphics resources.\n"); + } + else + { + oc_surface_data* surfaceData = oc_surface_data_from_handle(imageData->surface); + if(surfaceData) + { + OC_DEBUG_ASSERT(surfaceData->backend); + surfaceData->backend->imageUploadRegion(surfaceData->backend, imageData, region, pixels); + } + } + } } diff --git a/src/graphics/graphics_surface.h b/src/graphics/graphics_surface.h index 257265f..ad059dd 100644 --- a/src/graphics/graphics_surface.h +++ b/src/graphics/graphics_surface.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: graphics_surface.h * @author: Martin Fouilleul @@ -8,102 +8,103 @@ #ifndef __GRAPHICS_SURFACE_H_ #define __GRAPHICS_SURFACE_H_ -#include"graphics_common.h" -#include"app/app_internal.h" +#include "app/app_internal.h" +#include "graphics_common.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -//--------------------------------------------------------------- -// surface interface -//--------------------------------------------------------------- -typedef struct oc_surface_data oc_surface_data; -typedef struct oc_canvas_backend oc_canvas_backend; + //--------------------------------------------------------------- + // surface interface + //--------------------------------------------------------------- + typedef struct oc_surface_data oc_surface_data; + typedef struct oc_canvas_backend oc_canvas_backend; -typedef void (*oc_surface_destroy_proc)(oc_surface_data* surface); -typedef void (*oc_surface_select_proc)(oc_surface_data* surface); -typedef void (*oc_surface_deselect_proc)(oc_surface_data* surface); -typedef void (*oc_surface_present_proc)(oc_surface_data* surface); -typedef void (*oc_surface_swap_interval_proc)(oc_surface_data* surface, int swap); -typedef oc_vec2 (*oc_surface_get_size_proc)(oc_surface_data* surface); -typedef oc_vec2 (*oc_surface_contents_scaling_proc)(oc_surface_data* surface); -typedef bool (*oc_surface_get_hidden_proc)(oc_surface_data* surface); -typedef void (*oc_surface_set_hidden_proc)(oc_surface_data* surface, bool hidden); -typedef void* (*oc_surface_native_layer_proc)(oc_surface_data* surface); -typedef oc_surface_id (*oc_surface_remote_id_proc)(oc_surface_data* surface); -typedef void (*oc_surface_host_connect_proc)(oc_surface_data* surface, oc_surface_id remoteId); + typedef void (*oc_surface_destroy_proc)(oc_surface_data* surface); + typedef void (*oc_surface_select_proc)(oc_surface_data* surface); + typedef void (*oc_surface_deselect_proc)(oc_surface_data* surface); + typedef void (*oc_surface_present_proc)(oc_surface_data* surface); + typedef void (*oc_surface_swap_interval_proc)(oc_surface_data* surface, int swap); + typedef oc_vec2 (*oc_surface_get_size_proc)(oc_surface_data* surface); + typedef oc_vec2 (*oc_surface_contents_scaling_proc)(oc_surface_data* surface); + typedef bool (*oc_surface_get_hidden_proc)(oc_surface_data* surface); + typedef void (*oc_surface_set_hidden_proc)(oc_surface_data* surface, bool hidden); + typedef void* (*oc_surface_native_layer_proc)(oc_surface_data* surface); + typedef oc_surface_id (*oc_surface_remote_id_proc)(oc_surface_data* surface); + typedef void (*oc_surface_host_connect_proc)(oc_surface_data* surface, oc_surface_id remoteId); -typedef struct oc_surface_data -{ - oc_surface_api api; - oc_layer layer; + typedef struct oc_surface_data + { + oc_surface_api api; + oc_layer layer; - oc_surface_destroy_proc destroy; - oc_surface_select_proc prepare; - oc_surface_present_proc present; - oc_surface_deselect_proc deselect; - oc_surface_swap_interval_proc swapInterval; - oc_surface_get_size_proc getSize; - oc_surface_contents_scaling_proc contentsScaling; - oc_surface_get_hidden_proc getHidden; - oc_surface_set_hidden_proc setHidden; - oc_surface_native_layer_proc nativeLayer; - oc_surface_remote_id_proc remoteID; - oc_surface_host_connect_proc hostConnect; + oc_surface_destroy_proc destroy; + oc_surface_select_proc prepare; + oc_surface_present_proc present; + oc_surface_deselect_proc deselect; + oc_surface_swap_interval_proc swapInterval; + oc_surface_get_size_proc getSize; + oc_surface_contents_scaling_proc contentsScaling; + oc_surface_get_hidden_proc getHidden; + oc_surface_set_hidden_proc setHidden; + oc_surface_native_layer_proc nativeLayer; + oc_surface_remote_id_proc remoteID; + oc_surface_host_connect_proc hostConnect; - oc_canvas_backend* backend; + oc_canvas_backend* backend; -} oc_surface_data; + } oc_surface_data; -oc_surface oc_surface_handle_alloc(oc_surface_data* surface); -oc_surface_data* oc_surface_data_from_handle(oc_surface handle); + oc_surface oc_surface_handle_alloc(oc_surface_data* surface); + oc_surface_data* oc_surface_data_from_handle(oc_surface handle); -void oc_surface_init_for_window(oc_surface_data* surface, oc_window_data* window); -void oc_surface_init_remote(oc_surface_data* surface, u32 width, u32 height); -void oc_surface_init_host(oc_surface_data* surface, oc_window_data* window); -void oc_surface_cleanup(oc_surface_data* surface); -void* oc_surface_native_layer(oc_surface surface); + void oc_surface_init_for_window(oc_surface_data* surface, oc_window_data* window); + void oc_surface_init_remote(oc_surface_data* surface, u32 width, u32 height); + void oc_surface_init_host(oc_surface_data* surface, oc_window_data* window); + void oc_surface_cleanup(oc_surface_data* surface); + void* oc_surface_native_layer(oc_surface surface); -//--------------------------------------------------------------- -// canvas backend interface -//--------------------------------------------------------------- -typedef struct oc_image_data -{ - oc_list_elt listElt; - u32 generation; - oc_surface surface; - oc_vec2 size; + //--------------------------------------------------------------- + // canvas backend interface + //--------------------------------------------------------------- + typedef struct oc_image_data + { + oc_list_elt listElt; + u32 generation; + oc_surface surface; + oc_vec2 size; -} oc_image_data; + } oc_image_data; -typedef void (*oc_canvas_backend_destroy_proc)(oc_canvas_backend* backend); + typedef void (*oc_canvas_backend_destroy_proc)(oc_canvas_backend* backend); -typedef oc_image_data* (*oc_canvas_backend_image_create_proc)(oc_canvas_backend* backend, oc_vec2 size); -typedef void (*oc_canvas_backend_image_destroy_proc)(oc_canvas_backend* backend, oc_image_data* image); -typedef void (*oc_canvas_backend_image_upload_region_proc)(oc_canvas_backend* backend, - oc_image_data* image, - oc_rect region, - u8* pixels); + typedef oc_image_data* (*oc_canvas_backend_image_create_proc)(oc_canvas_backend* backend, oc_vec2 size); + typedef void (*oc_canvas_backend_image_destroy_proc)(oc_canvas_backend* backend, oc_image_data* image); + typedef void (*oc_canvas_backend_image_upload_region_proc)(oc_canvas_backend* backend, + oc_image_data* image, + oc_rect region, + u8* pixels); -typedef void (*oc_canvas_backend_render_proc)(oc_canvas_backend* backend, - oc_color clearColor, - u32 primitiveCount, - oc_primitive* primitives, - u32 eltCount, - oc_path_elt* pathElements); + typedef void (*oc_canvas_backend_render_proc)(oc_canvas_backend* backend, + oc_color clearColor, + u32 primitiveCount, + oc_primitive* primitives, + u32 eltCount, + oc_path_elt* pathElements); -typedef struct oc_canvas_backend -{ - oc_canvas_backend_destroy_proc destroy; + typedef struct oc_canvas_backend + { + oc_canvas_backend_destroy_proc destroy; - oc_canvas_backend_image_create_proc imageCreate; - oc_canvas_backend_image_destroy_proc imageDestroy; - oc_canvas_backend_image_upload_region_proc imageUploadRegion; + oc_canvas_backend_image_create_proc imageCreate; + oc_canvas_backend_image_destroy_proc imageDestroy; + oc_canvas_backend_image_upload_region_proc imageUploadRegion; - oc_canvas_backend_render_proc render; + oc_canvas_backend_render_proc render; -} oc_canvas_backend; + } oc_canvas_backend; #ifdef __cplusplus } // extern "C" diff --git a/src/graphics/mtl_renderer.h b/src/graphics/mtl_renderer.h index e2d6dd1..ae0fdce 100644 --- a/src/graphics/mtl_renderer.h +++ b/src/graphics/mtl_renderer.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: mtl_renderer.h * @author: Martin Fouilleul @@ -9,103 +9,111 @@ #ifndef __MTL_RENDERER_H_ #define __MTL_RENDERER_H_ -#include +#include -typedef enum { - OC_MTL_FILL, - OC_MTL_STROKE, +typedef enum +{ + OC_MTL_FILL, + OC_MTL_STROKE, } oc_mtl_cmd; typedef struct oc_mtl_path { - oc_mtl_cmd cmd; - matrix_float3x3 uvTransform; - vector_float4 color; - vector_float4 box; - vector_float4 clip; - int texture; + oc_mtl_cmd cmd; + matrix_float3x3 uvTransform; + vector_float4 color; + vector_float4 box; + vector_float4 clip; + int texture; } oc_mtl_path; -typedef enum { - OC_MTL_LINE = 1, - OC_MTL_QUADRATIC, - OC_MTL_CUBIC, +typedef enum +{ + OC_MTL_LINE = 1, + OC_MTL_QUADRATIC, + OC_MTL_CUBIC, } oc_mtl_seg_kind; typedef struct oc_mtl_path_elt { - int pathIndex; - oc_mtl_seg_kind kind; - vector_float2 p[4]; + int pathIndex; + oc_mtl_seg_kind kind; + vector_float2 p[4]; } oc_mtl_path_elt; -typedef enum { - OC_MTL_BL, // curve on bottom left - OC_MTL_BR, // curve on bottom right - OC_MTL_TL, // curve on top left - OC_MTL_TR // curve on top right +typedef enum +{ + OC_MTL_BL, // curve on bottom left + OC_MTL_BR, // curve on bottom right + OC_MTL_TL, // curve on top left + OC_MTL_TR // curve on top right } oc_mtl_seg_config; typedef struct oc_mtl_segment { - oc_mtl_seg_kind kind; - int pathIndex; - oc_mtl_seg_config config; //TODO pack these - int windingIncrement; - vector_float4 box; - matrix_float3x3 implicitMatrix; - float sign; - vector_float2 hullVertex; - int debugID; + oc_mtl_seg_kind kind; + int pathIndex; + oc_mtl_seg_config config; //TODO pack these + int windingIncrement; + vector_float4 box; + matrix_float3x3 implicitMatrix; + float sign; + vector_float2 hullVertex; + int debugID; } oc_mtl_segment; typedef struct oc_mtl_path_queue { - vector_int4 area; - int tileQueues; + vector_int4 area; + int tileQueues; } oc_mtl_path_queue; #ifdef __METAL_VERSION__ - using namespace metal; +using namespace metal; #endif -typedef enum { OC_MTL_OP_FILL, - OC_MTL_OP_CLIP_FILL, - OC_MTL_OP_START, - OC_MTL_OP_END, - OC_MTL_OP_SEGMENT } oc_mtl_tile_op_kind; +typedef enum +{ + OC_MTL_OP_FILL, + OC_MTL_OP_CLIP_FILL, + OC_MTL_OP_START, + OC_MTL_OP_END, + OC_MTL_OP_SEGMENT +} oc_mtl_tile_op_kind; typedef struct oc_mtl_tile_op { - oc_mtl_tile_op_kind kind; - int index; - int next; - union - { - bool crossRight; - int windingOffset; - }; + oc_mtl_tile_op_kind kind; + int index; + int next; + + union + { + bool crossRight; + int windingOffset; + }; } oc_mtl_tile_op; typedef struct oc_mtl_tile_queue { - atomic_int windingOffset; - atomic_int first; - int last; + atomic_int windingOffset; + atomic_int first; + int last; } oc_mtl_tile_queue; typedef struct oc_mtl_screen_tile { - vector_uint2 tileCoord; - int first; + vector_uint2 tileCoord; + int first; } oc_mtl_screen_tile; -enum { - OC_MTL_MAX_IMAGES_PER_BATCH = 30 +enum +{ + OC_MTL_MAX_IMAGES_PER_BATCH = 30 }; #endif //__MTL_RENDERER_H_ diff --git a/src/graphics/mtl_renderer.m b/src/graphics/mtl_renderer.m index 0a4a908..d7b626b 100644 --- a/src/graphics/mtl_renderer.m +++ b/src/graphics/mtl_renderer.m @@ -1,1617 +1,1618 @@ -/************************************************************//** +/************************************************************/ /** * * @file: mtl_canvas.m * @author: Martin Fouilleul * @date: 12/07/2020 * @revision: 24/01/2023 * -*****************************************************************/ -#import -#import -#include - -#include"graphics_surface.h" -#include"util/macros.h" -#include"app/osx_app.h" - -#include"mtl_renderer.h" - -const int OC_MTL_INPUT_BUFFERS_COUNT = 3, - OC_MTL_TILE_SIZE = 16, - OC_MTL_MSAA_COUNT = 8; - -typedef struct oc_mtl_canvas_backend -{ - oc_canvas_backend interface; - oc_mtl_surface* surface; - - id pathPipeline; - id segmentPipeline; - id backpropPipeline; - id mergePipeline; - id rasterPipeline; - id blitPipeline; - - id outTexture; - - int bufferIndex; - dispatch_semaphore_t bufferSemaphore; - - id pathBuffer[OC_MTL_INPUT_BUFFERS_COUNT]; - id elementBuffer[OC_MTL_INPUT_BUFFERS_COUNT]; - id logBuffer[OC_MTL_INPUT_BUFFERS_COUNT]; - id logOffsetBuffer[OC_MTL_INPUT_BUFFERS_COUNT]; - - id segmentCountBuffer; - id segmentBuffer; - id pathQueueBuffer; - id tileQueueBuffer; - id tileQueueCountBuffer; - id tileOpBuffer; - id tileOpCountBuffer; - id screenTilesBuffer; - id rasterDispatchBuffer; - - int msaaCount; - oc_vec2 frameSize; - - // encoding context - int eltCap; - int eltCount; - int eltBatchStart; - - int pathCap; - int pathCount; - int pathBatchStart; - - oc_primitive* primitive; - oc_vec4 pathScreenExtents; - oc_vec4 pathUserExtents; - - int maxTileQueueCount; - int maxSegmentCount; - - int currentImageIndex; - -} oc_mtl_canvas_backend; - -typedef struct oc_mtl_image_data -{ - oc_image_data interface; - id texture; -} oc_mtl_image_data; - -void oc_mtl_print_log(int bufferIndex, id logBuffer, id logOffsetBuffer) -{ - char* log = [logBuffer contents]; - int size = *(int*)[logOffsetBuffer contents]; - - if(size) - { - oc_log_info("Log from buffer %i:\n", bufferIndex); - - int index = 0; - while(index < size) - { - int len = strlen(log+index); - printf("%s", log+index); - index += (len+1); - } - } -} - -static void oc_mtl_update_path_extents(oc_vec4* extents, oc_vec2 p) -{ - extents->x = oc_min(extents->x, p.x); - extents->y = oc_min(extents->y, p.y); - extents->z = oc_max(extents->z, p.x); - extents->w = oc_max(extents->w, p.y); -} - -id oc_mtl_grow_input_buffer(id device, id oldBuffer, int oldCopySize, int newSize) -{ - @autoreleasepool - { - MTLResourceOptions bufferOptions = MTLResourceCPUCacheModeWriteCombined - | MTLResourceStorageModeShared; - - id newBuffer = [device newBufferWithLength: newSize options: bufferOptions]; - - memcpy([newBuffer contents], [oldBuffer contents], oldCopySize); - - [oldBuffer release]; - return(newBuffer); - } -} - -void oc_mtl_canvas_encode_element(oc_mtl_canvas_backend* backend, oc_path_elt_type kind, oc_vec2* p) -{ - int bufferIndex = backend->bufferIndex; - int bufferCap = [backend->elementBuffer[bufferIndex] length] / sizeof(oc_mtl_path_elt); - if(backend->eltCount >= bufferCap) - { - int newBufferCap = (int)(bufferCap * 1.5); - int newBufferSize = newBufferCap * sizeof(oc_mtl_path_elt); - - oc_log_info("growing element buffer to %i elements\n", newBufferCap); - - backend->elementBuffer[bufferIndex] = oc_mtl_grow_input_buffer(backend->surface->device, - backend->elementBuffer[bufferIndex], - backend->eltCount * sizeof(oc_mtl_path_elt), - newBufferSize); - } - - oc_mtl_path_elt* elements = (oc_mtl_path_elt*)[backend->elementBuffer[bufferIndex] contents]; - oc_mtl_path_elt* elt = &elements[backend->eltCount]; - backend->eltCount++; - - elt->pathIndex = backend->pathCount - backend->pathBatchStart; - int count = 0; - switch(kind) - { - case OC_PATH_LINE: - backend->maxSegmentCount += 1; - elt->kind = OC_MTL_LINE; - count = 2; - break; - - case OC_PATH_QUADRATIC: - backend->maxSegmentCount += 3; - elt->kind = OC_MTL_QUADRATIC; - count = 3; - break; - - case OC_PATH_CUBIC: - backend->maxSegmentCount += 7; - elt->kind = OC_MTL_CUBIC; - count = 4; - break; - - default: - break; - } - - for(int i=0; ipathUserExtents, p[i]); - - oc_vec2 screenP = oc_mat2x3_mul(backend->primitive->attributes.transform, p[i]); - elt->p[i] = (vector_float2){screenP.x, screenP.y}; - - oc_mtl_update_path_extents(&backend->pathScreenExtents, screenP); - } -} - - -void oc_mtl_encode_path(oc_mtl_canvas_backend* backend, oc_primitive* primitive, float scale) -{ - int bufferIndex = backend->bufferIndex; - int bufferCap = [backend->pathBuffer[bufferIndex] length] / sizeof(oc_mtl_path); - if(backend->pathCount >= bufferCap) - { - int newBufferCap = (int)(bufferCap * 1.5); - int newBufferSize = newBufferCap * sizeof(oc_mtl_path); - - oc_log_info("growing path buffer to %i elements\n", newBufferCap); - - backend->pathBuffer[bufferIndex] = oc_mtl_grow_input_buffer(backend->surface->device, - backend->pathBuffer[bufferIndex], - backend->eltCount * sizeof(oc_mtl_path), - newBufferSize); - } - - oc_mtl_path* pathBufferData = (oc_mtl_path*)[backend->pathBuffer[backend->bufferIndex] contents]; - oc_mtl_path* path = &(pathBufferData[backend->pathCount]); - backend->pathCount++; - - path->cmd = (oc_mtl_cmd)primitive->cmd; - - path->box = (vector_float4){backend->pathScreenExtents.x, - backend->pathScreenExtents.y, - backend->pathScreenExtents.z, - backend->pathScreenExtents.w}; - - path->clip = (vector_float4){primitive->attributes.clip.x, - primitive->attributes.clip.y, - primitive->attributes.clip.x + primitive->attributes.clip.w, - primitive->attributes.clip.y + primitive->attributes.clip.h}; - - path->color = (vector_float4){primitive->attributes.color.r, - primitive->attributes.color.g, - primitive->attributes.color.b, - primitive->attributes.color.a}; - - oc_rect srcRegion = primitive->attributes.srcRegion; - - oc_rect destRegion = {backend->pathUserExtents.x, - backend->pathUserExtents.y, - backend->pathUserExtents.z - backend->pathUserExtents.x, - backend->pathUserExtents.w - backend->pathUserExtents.y}; - - if(!oc_image_is_nil(primitive->attributes.image)) - { - oc_vec2 texSize = oc_image_size(primitive->attributes.image); - - oc_mat2x3 srcRegionToImage = {1/texSize.x, 0, srcRegion.x/texSize.x, - 0, 1/texSize.y, srcRegion.y/texSize.y}; - - oc_mat2x3 destRegionToSrcRegion = {srcRegion.w/destRegion.w, 0, 0, - 0, srcRegion.h/destRegion.h, 0}; - - oc_mat2x3 userToDestRegion = {1, 0, -destRegion.x, - 0, 1, -destRegion.y}; - - oc_mat2x3 screenToUser = oc_mat2x3_inv(primitive->attributes.transform); - - oc_mat2x3 uvTransform = srcRegionToImage; - uvTransform = oc_mat2x3_mul_m(uvTransform, destRegionToSrcRegion); - uvTransform = oc_mat2x3_mul_m(uvTransform, userToDestRegion); - uvTransform = oc_mat2x3_mul_m(uvTransform, screenToUser); - - path->uvTransform = simd_matrix(simd_make_float3(uvTransform.m[0]/scale, uvTransform.m[3]/scale, 0), - simd_make_float3(uvTransform.m[1]/scale, uvTransform.m[4]/scale, 0), - simd_make_float3(uvTransform.m[2], uvTransform.m[5], 1)); - - } - path->texture = backend->currentImageIndex; - - int firstTileX = path->box.x*scale / OC_MTL_TILE_SIZE; - int firstTileY = path->box.y*scale / OC_MTL_TILE_SIZE; - int lastTileX = path->box.z*scale / OC_MTL_TILE_SIZE; - int lastTileY = path->box.w*scale / OC_MTL_TILE_SIZE; - - int nTilesX = lastTileX - firstTileX + 1; - int nTilesY = lastTileY - firstTileY + 1; - - backend->maxTileQueueCount += (nTilesX * nTilesY); -} - -static bool oc_intersect_hull_legs(oc_vec2 p0, oc_vec2 p1, oc_vec2 p2, oc_vec2 p3, oc_vec2* intersection) -{ - /*NOTE: check intersection of lines (p0-p1) and (p2-p3) +*****************************************************************/ +#import +#import +#include + +#include "app/osx_app.h" +#include "graphics_surface.h" +#include "util/macros.h" + +#include "mtl_renderer.h" + +const int OC_MTL_INPUT_BUFFERS_COUNT = 3, + OC_MTL_TILE_SIZE = 16, + OC_MTL_MSAA_COUNT = 8; + +typedef struct oc_mtl_canvas_backend +{ + oc_canvas_backend interface; + oc_mtl_surface* surface; + + id pathPipeline; + id segmentPipeline; + id backpropPipeline; + id mergePipeline; + id rasterPipeline; + id blitPipeline; + + id outTexture; + + int bufferIndex; + dispatch_semaphore_t bufferSemaphore; + + id pathBuffer[OC_MTL_INPUT_BUFFERS_COUNT]; + id elementBuffer[OC_MTL_INPUT_BUFFERS_COUNT]; + id logBuffer[OC_MTL_INPUT_BUFFERS_COUNT]; + id logOffsetBuffer[OC_MTL_INPUT_BUFFERS_COUNT]; + + id segmentCountBuffer; + id segmentBuffer; + id pathQueueBuffer; + id tileQueueBuffer; + id tileQueueCountBuffer; + id tileOpBuffer; + id tileOpCountBuffer; + id screenTilesBuffer; + id rasterDispatchBuffer; + + int msaaCount; + oc_vec2 frameSize; + + // encoding context + int eltCap; + int eltCount; + int eltBatchStart; + + int pathCap; + int pathCount; + int pathBatchStart; + + oc_primitive* primitive; + oc_vec4 pathScreenExtents; + oc_vec4 pathUserExtents; + + int maxTileQueueCount; + int maxSegmentCount; + + int currentImageIndex; + +} oc_mtl_canvas_backend; + +typedef struct oc_mtl_image_data +{ + oc_image_data interface; + id texture; +} oc_mtl_image_data; + +void oc_mtl_print_log(int bufferIndex, id logBuffer, id logOffsetBuffer) +{ + char* log = [logBuffer contents]; + int size = *(int*)[logOffsetBuffer contents]; + + if(size) + { + oc_log_info("Log from buffer %i:\n", bufferIndex); + + int index = 0; + while(index < size) + { + int len = strlen(log + index); + printf("%s", log + index); + index += (len + 1); + } + } +} + +static void oc_mtl_update_path_extents(oc_vec4* extents, oc_vec2 p) +{ + extents->x = oc_min(extents->x, p.x); + extents->y = oc_min(extents->y, p.y); + extents->z = oc_max(extents->z, p.x); + extents->w = oc_max(extents->w, p.y); +} + +id oc_mtl_grow_input_buffer(id device, id oldBuffer, int oldCopySize, int newSize) +{ + @autoreleasepool + { + MTLResourceOptions bufferOptions = MTLResourceCPUCacheModeWriteCombined + | MTLResourceStorageModeShared; + + id newBuffer = [device newBufferWithLength:newSize options:bufferOptions]; + + memcpy([newBuffer contents], [oldBuffer contents], oldCopySize); + + [oldBuffer release]; + return (newBuffer); + } +} + +void oc_mtl_canvas_encode_element(oc_mtl_canvas_backend* backend, oc_path_elt_type kind, oc_vec2* p) +{ + int bufferIndex = backend->bufferIndex; + int bufferCap = [backend->elementBuffer[bufferIndex] length] / sizeof(oc_mtl_path_elt); + if(backend->eltCount >= bufferCap) + { + int newBufferCap = (int)(bufferCap * 1.5); + int newBufferSize = newBufferCap * sizeof(oc_mtl_path_elt); + + oc_log_info("growing element buffer to %i elements\n", newBufferCap); + + backend->elementBuffer[bufferIndex] = oc_mtl_grow_input_buffer(backend->surface->device, + backend->elementBuffer[bufferIndex], + backend->eltCount * sizeof(oc_mtl_path_elt), + newBufferSize); + } + + oc_mtl_path_elt* elements = (oc_mtl_path_elt*)[backend->elementBuffer[bufferIndex] contents]; + oc_mtl_path_elt* elt = &elements[backend->eltCount]; + backend->eltCount++; + + elt->pathIndex = backend->pathCount - backend->pathBatchStart; + int count = 0; + switch(kind) + { + case OC_PATH_LINE: + backend->maxSegmentCount += 1; + elt->kind = OC_MTL_LINE; + count = 2; + break; + + case OC_PATH_QUADRATIC: + backend->maxSegmentCount += 3; + elt->kind = OC_MTL_QUADRATIC; + count = 3; + break; + + case OC_PATH_CUBIC: + backend->maxSegmentCount += 7; + elt->kind = OC_MTL_CUBIC; + count = 4; + break; + + default: + break; + } + + for(int i = 0; i < count; i++) + { + oc_mtl_update_path_extents(&backend->pathUserExtents, p[i]); + + oc_vec2 screenP = oc_mat2x3_mul(backend->primitive->attributes.transform, p[i]); + elt->p[i] = (vector_float2){ screenP.x, screenP.y }; + + oc_mtl_update_path_extents(&backend->pathScreenExtents, screenP); + } +} + +void oc_mtl_encode_path(oc_mtl_canvas_backend* backend, oc_primitive* primitive, float scale) +{ + int bufferIndex = backend->bufferIndex; + int bufferCap = [backend->pathBuffer[bufferIndex] length] / sizeof(oc_mtl_path); + if(backend->pathCount >= bufferCap) + { + int newBufferCap = (int)(bufferCap * 1.5); + int newBufferSize = newBufferCap * sizeof(oc_mtl_path); + + oc_log_info("growing path buffer to %i elements\n", newBufferCap); + + backend->pathBuffer[bufferIndex] = oc_mtl_grow_input_buffer(backend->surface->device, + backend->pathBuffer[bufferIndex], + backend->eltCount * sizeof(oc_mtl_path), + newBufferSize); + } + + oc_mtl_path* pathBufferData = (oc_mtl_path*)[backend->pathBuffer[backend->bufferIndex] contents]; + oc_mtl_path* path = &(pathBufferData[backend->pathCount]); + backend->pathCount++; + + path->cmd = (oc_mtl_cmd)primitive->cmd; + + path->box = (vector_float4){ backend->pathScreenExtents.x, + backend->pathScreenExtents.y, + backend->pathScreenExtents.z, + backend->pathScreenExtents.w }; + + path->clip = (vector_float4){ primitive->attributes.clip.x, + primitive->attributes.clip.y, + primitive->attributes.clip.x + primitive->attributes.clip.w, + primitive->attributes.clip.y + primitive->attributes.clip.h }; + + path->color = (vector_float4){ primitive->attributes.color.r, + primitive->attributes.color.g, + primitive->attributes.color.b, + primitive->attributes.color.a }; + + oc_rect srcRegion = primitive->attributes.srcRegion; + + oc_rect destRegion = { backend->pathUserExtents.x, + backend->pathUserExtents.y, + backend->pathUserExtents.z - backend->pathUserExtents.x, + backend->pathUserExtents.w - backend->pathUserExtents.y }; + + if(!oc_image_is_nil(primitive->attributes.image)) + { + oc_vec2 texSize = oc_image_size(primitive->attributes.image); + + oc_mat2x3 srcRegionToImage = { 1 / texSize.x, 0, srcRegion.x / texSize.x, + 0, 1 / texSize.y, srcRegion.y / texSize.y }; + + oc_mat2x3 destRegionToSrcRegion = { srcRegion.w / destRegion.w, 0, 0, + 0, srcRegion.h / destRegion.h, 0 }; + + oc_mat2x3 userToDestRegion = { 1, 0, -destRegion.x, + 0, 1, -destRegion.y }; + + oc_mat2x3 screenToUser = oc_mat2x3_inv(primitive->attributes.transform); + + oc_mat2x3 uvTransform = srcRegionToImage; + uvTransform = oc_mat2x3_mul_m(uvTransform, destRegionToSrcRegion); + uvTransform = oc_mat2x3_mul_m(uvTransform, userToDestRegion); + uvTransform = oc_mat2x3_mul_m(uvTransform, screenToUser); + + path->uvTransform = simd_matrix(simd_make_float3(uvTransform.m[0] / scale, uvTransform.m[3] / scale, 0), + simd_make_float3(uvTransform.m[1] / scale, uvTransform.m[4] / scale, 0), + simd_make_float3(uvTransform.m[2], uvTransform.m[5], 1)); + } + path->texture = backend->currentImageIndex; + + int firstTileX = path->box.x * scale / OC_MTL_TILE_SIZE; + int firstTileY = path->box.y * scale / OC_MTL_TILE_SIZE; + int lastTileX = path->box.z * scale / OC_MTL_TILE_SIZE; + int lastTileY = path->box.w * scale / OC_MTL_TILE_SIZE; + + int nTilesX = lastTileX - firstTileX + 1; + int nTilesY = lastTileY - firstTileY + 1; + + backend->maxTileQueueCount += (nTilesX * nTilesY); +} + +static bool oc_intersect_hull_legs(oc_vec2 p0, oc_vec2 p1, oc_vec2 p2, oc_vec2 p3, oc_vec2* intersection) +{ + /*NOTE: check intersection of lines (p0-p1) and (p2-p3) P = p0 + u(p1-p0) P = p2 + w(p3-p2) - */ - bool found = false; - - f32 den = (p0.x - p1.x)*(p2.y - p3.y) - (p0.y - p1.y)*(p2.x - p3.x); - if(fabs(den) > 0.0001) - { - f32 u = ((p0.x - p2.x)*(p2.y - p3.y) - (p0.y - p2.y)*(p2.x - p3.x))/den; - f32 w = ((p0.x - p2.x)*(p0.y - p1.y) - (p0.y - p2.y)*(p0.x - p1.x))/den; - - intersection->x = p0.x + u*(p1.x - p0.x); - intersection->y = p0.y + u*(p1.y - p0.y); - found = true; - } - return(found); -} - -static bool oc_offset_hull(int count, oc_vec2* p, oc_vec2* result, f32 offset) -{ - //NOTE: we should have no more than two coincident points here. This means the leg between - // those two points can't be offset, but we can set a double point at the start of first leg, - // end of first leg, or we can join the first and last leg to create a missing middle one - - oc_vec2 legs[3][2] = {0}; - bool valid[3] = {0}; - - for(int i=0; i= 1e-6) - { - n = oc_vec2_mul(offset/norm, n); - legs[i][0] = oc_vec2_add(p[i], n); - legs[i][1] = oc_vec2_add(p[i+1], n); - valid[i] = true; - } - } - - //NOTE: now we find intersections - - // first point is either the start of the first or second leg - if(valid[0]) - { - result[0] = legs[0][0]; - } - else - { - OC_ASSERT(valid[1]); - result[0] = legs[1][0]; - } - - for(int i=1; iprimitive->attributes.width; - - oc_vec2 v = {p[1].x-p[0].x, p[1].y-p[0].y}; - oc_vec2 n = {v.y, -v.x}; - f32 norm = sqrt(n.x*n.x + n.y*n.y); - oc_vec2 offset = oc_vec2_mul(0.5*width/norm, n); - - oc_vec2 left[2] = {oc_vec2_add(p[0], offset), oc_vec2_add(p[1], offset)}; - oc_vec2 right[2] = {oc_vec2_add(p[1], oc_vec2_mul(-1, offset)), oc_vec2_add(p[0], oc_vec2_mul(-1, offset))}; - oc_vec2 joint0[2] = {oc_vec2_add(p[0], oc_vec2_mul(-1, offset)), oc_vec2_add(p[0], offset)}; - oc_vec2 joint1[2] = {oc_vec2_add(p[1], offset), oc_vec2_add(p[1], oc_vec2_mul(-1, offset))}; - - oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, right); - oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, left); - oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, joint0); - oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, joint1); -} - -void oc_mtl_render_stroke_quadratic(oc_mtl_canvas_backend* backend, oc_vec2* p) -{ - f32 width = backend->primitive->attributes.width; - f32 tolerance = oc_min(backend->primitive->attributes.tolerance, 0.5 * width); - - //NOTE: check for degenerate line case - const f32 equalEps = 1e-3; - if(oc_vec2_close(p[0], p[1], equalEps)) - { - oc_mtl_render_stroke_line(backend, p+1); - return; - } - else if(oc_vec2_close(p[1], p[2], equalEps)) - { - oc_mtl_render_stroke_line(backend, p); - return; - } - - oc_vec2 leftHull[3]; - oc_vec2 rightHull[3]; - - if( !oc_offset_hull(3, p, leftHull, width/2) - || !oc_offset_hull(3, p, rightHull, -width/2)) - { - //TODO split and recurse - //NOTE: offsetting the hull failed, split the curve - oc_vec2 splitLeft[3]; - oc_vec2 splitRight[3]; - oc_quadratic_split(p, 0.5, splitLeft, splitRight); - oc_mtl_render_stroke_quadratic(backend, splitLeft); - oc_mtl_render_stroke_quadratic(backend, splitRight); - } - else - { - const int CHECK_SAMPLE_COUNT = 5; - f32 checkSamples[CHECK_SAMPLE_COUNT] = {1./6, 2./6, 3./6, 4./6, 5./6}; - - f32 d2LowBound = oc_square(0.5 * width - tolerance); - f32 d2HighBound = oc_square(0.5 * width + tolerance); - - f32 maxOvershoot = 0; - f32 maxOvershootParameter = 0; - - for(int i=0; i maxOvershoot) - { - maxOvershoot = overshoot; - maxOvershootParameter = t; - } - } - - if(maxOvershoot > 0) - { - oc_vec2 splitLeft[3]; - oc_vec2 splitRight[3]; - oc_quadratic_split(p, maxOvershootParameter, splitLeft, splitRight); - oc_mtl_render_stroke_quadratic(backend, splitLeft); - oc_mtl_render_stroke_quadratic(backend, splitRight); - } - else - { - oc_vec2 tmp = leftHull[0]; - leftHull[0] = leftHull[2]; - leftHull[2] = tmp; - - oc_mtl_canvas_encode_element(backend, OC_PATH_QUADRATIC, rightHull); - oc_mtl_canvas_encode_element(backend, OC_PATH_QUADRATIC, leftHull); - - oc_vec2 joint0[2] = {rightHull[2], leftHull[0]}; - oc_vec2 joint1[2] = {leftHull[2], rightHull[0]}; - oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, joint0); - oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, joint1); - } - } -} - -void oc_mtl_render_stroke_cubic(oc_mtl_canvas_backend* backend, oc_vec2* p) -{ - f32 width = backend->primitive->attributes.width; - f32 tolerance = oc_min(backend->primitive->attributes.tolerance, 0.5 * width); - - //NOTE: check degenerate line cases - f32 equalEps = 1e-3; - - if( (oc_vec2_close(p[0], p[1], equalEps) && oc_vec2_close(p[2], p[3], equalEps)) - ||(oc_vec2_close(p[0], p[1], equalEps) && oc_vec2_close(p[1], p[2], equalEps)) - ||(oc_vec2_close(p[1], p[2], equalEps) && oc_vec2_close(p[2], p[3], equalEps))) - { - oc_vec2 line[2] = {p[0], p[3]}; - oc_mtl_render_stroke_line(backend, line); - return; - } - else if(oc_vec2_close(p[0], p[1], equalEps) && oc_vec2_close(p[1], p[3], equalEps)) - { - oc_vec2 line[2] = {p[0], oc_vec2_add(oc_vec2_mul(5./9, p[0]), oc_vec2_mul(4./9, p[2]))}; - oc_mtl_render_stroke_line(backend, line); - return; - } - else if(oc_vec2_close(p[0], p[2], equalEps) && oc_vec2_close(p[2], p[3], equalEps)) - { - oc_vec2 line[2] = {p[0], oc_vec2_add(oc_vec2_mul(5./9, p[0]), oc_vec2_mul(4./9, p[1]))}; - oc_mtl_render_stroke_line(backend, line); - return; - } - - oc_vec2 leftHull[4]; - oc_vec2 rightHull[4]; - - if( !oc_offset_hull(4, p, leftHull, width/2) - || !oc_offset_hull(4, p, rightHull, -width/2)) - { - //TODO split and recurse - //NOTE: offsetting the hull failed, split the curve - oc_vec2 splitLeft[4]; - oc_vec2 splitRight[4]; - oc_cubic_split(p, 0.5, splitLeft, splitRight); - oc_mtl_render_stroke_cubic(backend, splitLeft); - oc_mtl_render_stroke_cubic(backend, splitRight); - } - else - { - const int CHECK_SAMPLE_COUNT = 5; - f32 checkSamples[CHECK_SAMPLE_COUNT] = {1./6, 2./6, 3./6, 4./6, 5./6}; - - f32 d2LowBound = oc_square(0.5 * width - tolerance); - f32 d2HighBound = oc_square(0.5 * width + tolerance); - - f32 maxOvershoot = 0; - f32 maxOvershootParameter = 0; - - for(int i=0; i maxOvershoot) - { - maxOvershoot = overshoot; - maxOvershootParameter = t; - } - } - - if(maxOvershoot > 0) - { - oc_vec2 splitLeft[4]; - oc_vec2 splitRight[4]; - oc_cubic_split(p, maxOvershootParameter, splitLeft, splitRight); - oc_mtl_render_stroke_cubic(backend, splitLeft); - oc_mtl_render_stroke_cubic(backend, splitRight); - } - else - { - oc_vec2 tmp = leftHull[0]; - leftHull[0] = leftHull[3]; - leftHull[3] = tmp; - tmp = leftHull[1]; - leftHull[1] = leftHull[2]; - leftHull[2] = tmp; - - oc_mtl_canvas_encode_element(backend, OC_PATH_CUBIC, rightHull); - oc_mtl_canvas_encode_element(backend, OC_PATH_CUBIC, leftHull); - - oc_vec2 joint0[2] = {rightHull[3], leftHull[0]}; - oc_vec2 joint1[2] = {leftHull[3], rightHull[0]}; - oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, joint0); - oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, joint1); - } - } -} - -void oc_mtl_render_stroke_element(oc_mtl_canvas_backend* backend, - oc_path_elt* element, - oc_vec2 currentPoint, - oc_vec2* startTangent, - oc_vec2* endTangent, - oc_vec2* endPoint) -{ - oc_vec2 controlPoints[4] = {currentPoint, element->p[0], element->p[1], element->p[2]}; - int endPointIndex = 0; - - switch(element->type) - { - case OC_PATH_LINE: - oc_mtl_render_stroke_line(backend, controlPoints); - endPointIndex = 1; - break; - - case OC_PATH_QUADRATIC: - oc_mtl_render_stroke_quadratic(backend, controlPoints); - endPointIndex = 2; - break; - - case OC_PATH_CUBIC: - oc_mtl_render_stroke_cubic(backend, controlPoints); - endPointIndex = 3; - break; - - case OC_PATH_MOVE: - OC_ASSERT(0, "should be unreachable"); - break; - } - - //NOTE: ensure tangents are properly computed even in presence of coincident points - //TODO: see if we can do this in a less hacky way - - for(int i=1; i<4; i++) - { - if( controlPoints[i].x != controlPoints[0].x - || controlPoints[i].y != controlPoints[0].y) - { - *startTangent = (oc_vec2){.x = controlPoints[i].x - controlPoints[0].x, - .y = controlPoints[i].y - controlPoints[0].y}; - break; - } - } - *endPoint = controlPoints[endPointIndex]; - - for(int i=endPointIndex-1; i>=0; i++) - { - if( controlPoints[i].x != endPoint->x - || controlPoints[i].y != endPoint->y) - { - *endTangent = (oc_vec2){.x = endPoint->x - controlPoints[i].x, - .y = endPoint->y - controlPoints[i].y}; - break; - } - } - OC_DEBUG_ASSERT(startTangent->x != 0 || startTangent->y != 0); -} - -void oc_mtl_stroke_cap(oc_mtl_canvas_backend* backend, - oc_vec2 p0, - oc_vec2 direction) -{ - oc_attributes* attributes = &backend->primitive->attributes; - - //NOTE(martin): compute the tangent and normal vectors (multiplied by half width) at the cap point - f32 dn = sqrt(oc_square(direction.x) + oc_square(direction.y)); - f32 alpha = 0.5 * attributes->width/dn; - - oc_vec2 n0 = {-alpha*direction.y, - alpha*direction.x}; - - oc_vec2 m0 = {alpha*direction.x, - alpha*direction.y}; - - oc_vec2 points[] = {{p0.x + n0.x, p0.y + n0.y}, - {p0.x + n0.x + m0.x, p0.y + n0.y + m0.y}, - {p0.x - n0.x + m0.x, p0.y - n0.y + m0.y}, - {p0.x - n0.x, p0.y - n0.y}, - {p0.x + n0.x, p0.y + n0.y}}; - - oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points); - oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points+1); - oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points+2); - oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points+3); -} - -void oc_mtl_stroke_joint(oc_mtl_canvas_backend* backend, - oc_vec2 p0, - oc_vec2 t0, - oc_vec2 t1) -{ - oc_attributes* attributes = &backend->primitive->attributes; - - //NOTE(martin): compute the normals at the joint point - f32 norm_t0 = sqrt(oc_square(t0.x) + oc_square(t0.y)); - f32 norm_t1 = sqrt(oc_square(t1.x) + oc_square(t1.y)); - - oc_vec2 n0 = {-t0.y, t0.x}; - n0.x /= norm_t0; - n0.y /= norm_t0; - - oc_vec2 n1 = {-t1.y, t1.x}; - n1.x /= norm_t1; - n1.y /= norm_t1; - - //NOTE(martin): the sign of the cross product determines if the normals are facing outwards or inwards the angle. - // we flip them to face outwards if needed - f32 crossZ = n0.x*n1.y - n0.y*n1.x; - if(crossZ > 0) - { - n0.x *= -1; - n0.y *= -1; - n1.x *= -1; - n1.y *= -1; - } - - //NOTE(martin): use the same code as hull offset to find mitter point... - /*NOTE(martin): let vector u = (n0+n1) and vector v = pIntersect - p1 + */ + bool found = false; + + f32 den = (p0.x - p1.x) * (p2.y - p3.y) - (p0.y - p1.y) * (p2.x - p3.x); + if(fabs(den) > 0.0001) + { + f32 u = ((p0.x - p2.x) * (p2.y - p3.y) - (p0.y - p2.y) * (p2.x - p3.x)) / den; + f32 w = ((p0.x - p2.x) * (p0.y - p1.y) - (p0.y - p2.y) * (p0.x - p1.x)) / den; + + intersection->x = p0.x + u * (p1.x - p0.x); + intersection->y = p0.y + u * (p1.y - p0.y); + found = true; + } + return (found); +} + +static bool oc_offset_hull(int count, oc_vec2* p, oc_vec2* result, f32 offset) +{ + //NOTE: we should have no more than two coincident points here. This means the leg between + // those two points can't be offset, but we can set a double point at the start of first leg, + // end of first leg, or we can join the first and last leg to create a missing middle one + + oc_vec2 legs[3][2] = { 0 }; + bool valid[3] = { 0 }; + + for(int i = 0; i < count - 1; i++) + { + oc_vec2 n = { p[i].y - p[i + 1].y, + p[i + 1].x - p[i].x }; + + f32 norm = sqrt(n.x * n.x + n.y * n.y); + if(norm >= 1e-6) + { + n = oc_vec2_mul(offset / norm, n); + legs[i][0] = oc_vec2_add(p[i], n); + legs[i][1] = oc_vec2_add(p[i + 1], n); + valid[i] = true; + } + } + + //NOTE: now we find intersections + + // first point is either the start of the first or second leg + if(valid[0]) + { + result[0] = legs[0][0]; + } + else + { + OC_ASSERT(valid[1]); + result[0] = legs[1][0]; + } + + for(int i = 1; i < count - 1; i++) + { + //NOTE: we're computing the control point i, at the end of leg (i-1) + + if(!valid[i - 1]) + { + OC_ASSERT(valid[i]); + result[i] = legs[i][0]; + } + else if(!valid[i]) + { + OC_ASSERT(valid[i - 1]); + result[i] = legs[i - 1][0]; + } + else + { + if(!oc_intersect_hull_legs(legs[i - 1][0], legs[i - 1][1], legs[i][0], legs[i][1], &result[i])) + { + // legs don't intersect. + return (false); + } + } + } + + if(valid[count - 2]) + { + result[count - 1] = legs[count - 2][1]; + } + else + { + OC_ASSERT(valid[count - 3]); + result[count - 1] = legs[count - 3][1]; + } + + return (true); +} + +static oc_vec2 oc_quadratic_get_point(oc_vec2 p[3], f32 t) +{ + oc_vec2 r; + + f32 oneMt = 1 - t; + f32 oneMt2 = oc_square(oneMt); + f32 t2 = oc_square(t); + + r.x = oneMt2 * p[0].x + 2 * oneMt * t * p[1].x + t2 * p[2].x; + r.y = oneMt2 * p[0].y + 2 * oneMt * t * p[1].y + t2 * p[2].y; + + return (r); +} + +static void oc_quadratic_split(oc_vec2 p[3], f32 t, oc_vec2 outLeft[3], oc_vec2 outRight[3]) +{ + //NOTE(martin): split bezier curve p at parameter t, using De Casteljau's algorithm + // the q_n are the points along the hull's segments at parameter t + // s is the split point. + + f32 oneMt = 1 - t; + + oc_vec2 q0 = { oneMt * p[0].x + t * p[1].x, + oneMt * p[0].y + t * p[1].y }; + + oc_vec2 q1 = { oneMt * p[1].x + t * p[2].x, + oneMt * p[1].y + t * p[2].y }; + + oc_vec2 s = { oneMt * q0.x + t * q1.x, + oneMt * q0.y + t * q1.y }; + + outLeft[0] = p[0]; + outLeft[1] = q0; + outLeft[2] = s; + + outRight[0] = s; + outRight[1] = q1; + outRight[2] = p[2]; +} + +static oc_vec2 oc_cubic_get_point(oc_vec2 p[4], f32 t) +{ + oc_vec2 r; + + f32 oneMt = 1 - t; + f32 oneMt2 = oc_square(oneMt); + f32 oneMt3 = oneMt2 * oneMt; + f32 t2 = oc_square(t); + f32 t3 = t2 * t; + + r.x = oneMt3 * p[0].x + 3 * oneMt2 * t * p[1].x + 3 * oneMt * t2 * p[2].x + t3 * p[3].x; + r.y = oneMt3 * p[0].y + 3 * oneMt2 * t * p[1].y + 3 * oneMt * t2 * p[2].y + t3 * p[3].y; + + return (r); +} + +static void oc_cubic_split(oc_vec2 p[4], f32 t, oc_vec2 outLeft[4], oc_vec2 outRight[4]) +{ + //NOTE(martin): split bezier curve p at parameter t, using De Casteljau's algorithm + // the q_n are the points along the hull's segments at parameter t + // the r_n are the points along the (q_n, q_n+1) segments at parameter t + // s is the split point. + + oc_vec2 q0 = { (1 - t) * p[0].x + t * p[1].x, + (1 - t) * p[0].y + t * p[1].y }; + + oc_vec2 q1 = { (1 - t) * p[1].x + t * p[2].x, + (1 - t) * p[1].y + t * p[2].y }; + + oc_vec2 q2 = { (1 - t) * p[2].x + t * p[3].x, + (1 - t) * p[2].y + t * p[3].y }; + + oc_vec2 r0 = { (1 - t) * q0.x + t * q1.x, + (1 - t) * q0.y + t * q1.y }; + + oc_vec2 r1 = { (1 - t) * q1.x + t * q2.x, + (1 - t) * q1.y + t * q2.y }; + + oc_vec2 s = { (1 - t) * r0.x + t * r1.x, + (1 - t) * r0.y + t * r1.y }; + ; + + outLeft[0] = p[0]; + outLeft[1] = q0; + outLeft[2] = r0; + outLeft[3] = s; + + outRight[0] = s; + outRight[1] = r1; + outRight[2] = q2; + outRight[3] = p[3]; +} + +void oc_mtl_render_stroke_line(oc_mtl_canvas_backend* backend, oc_vec2* p) +{ + f32 width = backend->primitive->attributes.width; + + oc_vec2 v = { p[1].x - p[0].x, p[1].y - p[0].y }; + oc_vec2 n = { v.y, -v.x }; + f32 norm = sqrt(n.x * n.x + n.y * n.y); + oc_vec2 offset = oc_vec2_mul(0.5 * width / norm, n); + + oc_vec2 left[2] = { oc_vec2_add(p[0], offset), oc_vec2_add(p[1], offset) }; + oc_vec2 right[2] = { oc_vec2_add(p[1], oc_vec2_mul(-1, offset)), oc_vec2_add(p[0], oc_vec2_mul(-1, offset)) }; + oc_vec2 joint0[2] = { oc_vec2_add(p[0], oc_vec2_mul(-1, offset)), oc_vec2_add(p[0], offset) }; + oc_vec2 joint1[2] = { oc_vec2_add(p[1], offset), oc_vec2_add(p[1], oc_vec2_mul(-1, offset)) }; + + oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, right); + oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, left); + oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, joint0); + oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, joint1); +} + +void oc_mtl_render_stroke_quadratic(oc_mtl_canvas_backend* backend, oc_vec2* p) +{ + f32 width = backend->primitive->attributes.width; + f32 tolerance = oc_min(backend->primitive->attributes.tolerance, 0.5 * width); + + //NOTE: check for degenerate line case + const f32 equalEps = 1e-3; + if(oc_vec2_close(p[0], p[1], equalEps)) + { + oc_mtl_render_stroke_line(backend, p + 1); + return; + } + else if(oc_vec2_close(p[1], p[2], equalEps)) + { + oc_mtl_render_stroke_line(backend, p); + return; + } + + oc_vec2 leftHull[3]; + oc_vec2 rightHull[3]; + + if(!oc_offset_hull(3, p, leftHull, width / 2) + || !oc_offset_hull(3, p, rightHull, -width / 2)) + { + //TODO split and recurse + //NOTE: offsetting the hull failed, split the curve + oc_vec2 splitLeft[3]; + oc_vec2 splitRight[3]; + oc_quadratic_split(p, 0.5, splitLeft, splitRight); + oc_mtl_render_stroke_quadratic(backend, splitLeft); + oc_mtl_render_stroke_quadratic(backend, splitRight); + } + else + { + const int CHECK_SAMPLE_COUNT = 5; + f32 checkSamples[CHECK_SAMPLE_COUNT] = { 1. / 6, 2. / 6, 3. / 6, 4. / 6, 5. / 6 }; + + f32 d2LowBound = oc_square(0.5 * width - tolerance); + f32 d2HighBound = oc_square(0.5 * width + tolerance); + + f32 maxOvershoot = 0; + f32 maxOvershootParameter = 0; + + for(int i = 0; i < CHECK_SAMPLE_COUNT; i++) + { + f32 t = checkSamples[i]; + + oc_vec2 c = oc_quadratic_get_point(p, t); + oc_vec2 cp = oc_quadratic_get_point(leftHull, t); + oc_vec2 cn = oc_quadratic_get_point(rightHull, t); + + f32 positiveDistSquare = oc_square(c.x - cp.x) + oc_square(c.y - cp.y); + f32 negativeDistSquare = oc_square(c.x - cn.x) + oc_square(c.y - cn.y); + + f32 positiveOvershoot = oc_max(positiveDistSquare - d2HighBound, d2LowBound - positiveDistSquare); + f32 negativeOvershoot = oc_max(negativeDistSquare - d2HighBound, d2LowBound - negativeDistSquare); + + f32 overshoot = oc_max(positiveOvershoot, negativeOvershoot); + + if(overshoot > maxOvershoot) + { + maxOvershoot = overshoot; + maxOvershootParameter = t; + } + } + + if(maxOvershoot > 0) + { + oc_vec2 splitLeft[3]; + oc_vec2 splitRight[3]; + oc_quadratic_split(p, maxOvershootParameter, splitLeft, splitRight); + oc_mtl_render_stroke_quadratic(backend, splitLeft); + oc_mtl_render_stroke_quadratic(backend, splitRight); + } + else + { + oc_vec2 tmp = leftHull[0]; + leftHull[0] = leftHull[2]; + leftHull[2] = tmp; + + oc_mtl_canvas_encode_element(backend, OC_PATH_QUADRATIC, rightHull); + oc_mtl_canvas_encode_element(backend, OC_PATH_QUADRATIC, leftHull); + + oc_vec2 joint0[2] = { rightHull[2], leftHull[0] }; + oc_vec2 joint1[2] = { leftHull[2], rightHull[0] }; + oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, joint0); + oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, joint1); + } + } +} + +void oc_mtl_render_stroke_cubic(oc_mtl_canvas_backend* backend, oc_vec2* p) +{ + f32 width = backend->primitive->attributes.width; + f32 tolerance = oc_min(backend->primitive->attributes.tolerance, 0.5 * width); + + //NOTE: check degenerate line cases + f32 equalEps = 1e-3; + + if((oc_vec2_close(p[0], p[1], equalEps) && oc_vec2_close(p[2], p[3], equalEps)) + || (oc_vec2_close(p[0], p[1], equalEps) && oc_vec2_close(p[1], p[2], equalEps)) + || (oc_vec2_close(p[1], p[2], equalEps) && oc_vec2_close(p[2], p[3], equalEps))) + { + oc_vec2 line[2] = { p[0], p[3] }; + oc_mtl_render_stroke_line(backend, line); + return; + } + else if(oc_vec2_close(p[0], p[1], equalEps) && oc_vec2_close(p[1], p[3], equalEps)) + { + oc_vec2 line[2] = { p[0], oc_vec2_add(oc_vec2_mul(5. / 9, p[0]), oc_vec2_mul(4. / 9, p[2])) }; + oc_mtl_render_stroke_line(backend, line); + return; + } + else if(oc_vec2_close(p[0], p[2], equalEps) && oc_vec2_close(p[2], p[3], equalEps)) + { + oc_vec2 line[2] = { p[0], oc_vec2_add(oc_vec2_mul(5. / 9, p[0]), oc_vec2_mul(4. / 9, p[1])) }; + oc_mtl_render_stroke_line(backend, line); + return; + } + + oc_vec2 leftHull[4]; + oc_vec2 rightHull[4]; + + if(!oc_offset_hull(4, p, leftHull, width / 2) + || !oc_offset_hull(4, p, rightHull, -width / 2)) + { + //TODO split and recurse + //NOTE: offsetting the hull failed, split the curve + oc_vec2 splitLeft[4]; + oc_vec2 splitRight[4]; + oc_cubic_split(p, 0.5, splitLeft, splitRight); + oc_mtl_render_stroke_cubic(backend, splitLeft); + oc_mtl_render_stroke_cubic(backend, splitRight); + } + else + { + const int CHECK_SAMPLE_COUNT = 5; + f32 checkSamples[CHECK_SAMPLE_COUNT] = { 1. / 6, 2. / 6, 3. / 6, 4. / 6, 5. / 6 }; + + f32 d2LowBound = oc_square(0.5 * width - tolerance); + f32 d2HighBound = oc_square(0.5 * width + tolerance); + + f32 maxOvershoot = 0; + f32 maxOvershootParameter = 0; + + for(int i = 0; i < CHECK_SAMPLE_COUNT; i++) + { + f32 t = checkSamples[i]; + + oc_vec2 c = oc_cubic_get_point(p, t); + oc_vec2 cp = oc_cubic_get_point(leftHull, t); + oc_vec2 cn = oc_cubic_get_point(rightHull, t); + + f32 positiveDistSquare = oc_square(c.x - cp.x) + oc_square(c.y - cp.y); + f32 negativeDistSquare = oc_square(c.x - cn.x) + oc_square(c.y - cn.y); + + f32 positiveOvershoot = oc_max(positiveDistSquare - d2HighBound, d2LowBound - positiveDistSquare); + f32 negativeOvershoot = oc_max(negativeDistSquare - d2HighBound, d2LowBound - negativeDistSquare); + + f32 overshoot = oc_max(positiveOvershoot, negativeOvershoot); + + if(overshoot > maxOvershoot) + { + maxOvershoot = overshoot; + maxOvershootParameter = t; + } + } + + if(maxOvershoot > 0) + { + oc_vec2 splitLeft[4]; + oc_vec2 splitRight[4]; + oc_cubic_split(p, maxOvershootParameter, splitLeft, splitRight); + oc_mtl_render_stroke_cubic(backend, splitLeft); + oc_mtl_render_stroke_cubic(backend, splitRight); + } + else + { + oc_vec2 tmp = leftHull[0]; + leftHull[0] = leftHull[3]; + leftHull[3] = tmp; + tmp = leftHull[1]; + leftHull[1] = leftHull[2]; + leftHull[2] = tmp; + + oc_mtl_canvas_encode_element(backend, OC_PATH_CUBIC, rightHull); + oc_mtl_canvas_encode_element(backend, OC_PATH_CUBIC, leftHull); + + oc_vec2 joint0[2] = { rightHull[3], leftHull[0] }; + oc_vec2 joint1[2] = { leftHull[3], rightHull[0] }; + oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, joint0); + oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, joint1); + } + } +} + +void oc_mtl_render_stroke_element(oc_mtl_canvas_backend* backend, + oc_path_elt* element, + oc_vec2 currentPoint, + oc_vec2* startTangent, + oc_vec2* endTangent, + oc_vec2* endPoint) +{ + oc_vec2 controlPoints[4] = { currentPoint, element->p[0], element->p[1], element->p[2] }; + int endPointIndex = 0; + + switch(element->type) + { + case OC_PATH_LINE: + oc_mtl_render_stroke_line(backend, controlPoints); + endPointIndex = 1; + break; + + case OC_PATH_QUADRATIC: + oc_mtl_render_stroke_quadratic(backend, controlPoints); + endPointIndex = 2; + break; + + case OC_PATH_CUBIC: + oc_mtl_render_stroke_cubic(backend, controlPoints); + endPointIndex = 3; + break; + + case OC_PATH_MOVE: + OC_ASSERT(0, "should be unreachable"); + break; + } + + //NOTE: ensure tangents are properly computed even in presence of coincident points + //TODO: see if we can do this in a less hacky way + + for(int i = 1; i < 4; i++) + { + if(controlPoints[i].x != controlPoints[0].x + || controlPoints[i].y != controlPoints[0].y) + { + *startTangent = (oc_vec2){ .x = controlPoints[i].x - controlPoints[0].x, + .y = controlPoints[i].y - controlPoints[0].y }; + break; + } + } + *endPoint = controlPoints[endPointIndex]; + + for(int i = endPointIndex - 1; i >= 0; i++) + { + if(controlPoints[i].x != endPoint->x + || controlPoints[i].y != endPoint->y) + { + *endTangent = (oc_vec2){ .x = endPoint->x - controlPoints[i].x, + .y = endPoint->y - controlPoints[i].y }; + break; + } + } + OC_DEBUG_ASSERT(startTangent->x != 0 || startTangent->y != 0); +} + +void oc_mtl_stroke_cap(oc_mtl_canvas_backend* backend, + oc_vec2 p0, + oc_vec2 direction) +{ + oc_attributes* attributes = &backend->primitive->attributes; + + //NOTE(martin): compute the tangent and normal vectors (multiplied by half width) at the cap point + f32 dn = sqrt(oc_square(direction.x) + oc_square(direction.y)); + f32 alpha = 0.5 * attributes->width / dn; + + oc_vec2 n0 = { -alpha * direction.y, + alpha * direction.x }; + + oc_vec2 m0 = { alpha * direction.x, + alpha * direction.y }; + + oc_vec2 points[] = { { p0.x + n0.x, p0.y + n0.y }, + { p0.x + n0.x + m0.x, p0.y + n0.y + m0.y }, + { p0.x - n0.x + m0.x, p0.y - n0.y + m0.y }, + { p0.x - n0.x, p0.y - n0.y }, + { p0.x + n0.x, p0.y + n0.y } }; + + oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points); + oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points + 1); + oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points + 2); + oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points + 3); +} + +void oc_mtl_stroke_joint(oc_mtl_canvas_backend* backend, + oc_vec2 p0, + oc_vec2 t0, + oc_vec2 t1) +{ + oc_attributes* attributes = &backend->primitive->attributes; + + //NOTE(martin): compute the normals at the joint point + f32 norm_t0 = sqrt(oc_square(t0.x) + oc_square(t0.y)); + f32 norm_t1 = sqrt(oc_square(t1.x) + oc_square(t1.y)); + + oc_vec2 n0 = { -t0.y, t0.x }; + n0.x /= norm_t0; + n0.y /= norm_t0; + + oc_vec2 n1 = { -t1.y, t1.x }; + n1.x /= norm_t1; + n1.y /= norm_t1; + + //NOTE(martin): the sign of the cross product determines if the normals are facing outwards or inwards the angle. + // we flip them to face outwards if needed + f32 crossZ = n0.x * n1.y - n0.y * n1.x; + if(crossZ > 0) + { + n0.x *= -1; + n0.y *= -1; + n1.x *= -1; + n1.y *= -1; + } + + //NOTE(martin): use the same code as hull offset to find mitter point... + /*NOTE(martin): let vector u = (n0+n1) and vector v = pIntersect - p1 then v = u * (2*offset / norm(u)^2) (this can be derived from writing the pythagoras theorems in the triangles of the joint) - */ - f32 halfW = 0.5 * attributes->width; - oc_vec2 u = {n0.x + n1.x, n0.y + n1.y}; - f32 uNormSquare = u.x*u.x + u.y*u.y; - f32 alpha = attributes->width / uNormSquare; - oc_vec2 v = {u.x * alpha, u.y * alpha}; - - f32 excursionSquare = uNormSquare * oc_square(alpha - attributes->width/4); - - if( attributes->joint == OC_JOINT_MITER - && excursionSquare <= oc_square(attributes->maxJointExcursion)) - { - //NOTE(martin): add a mitter joint - oc_vec2 points[] = {p0, - {p0.x + n0.x*halfW, p0.y + n0.y*halfW}, - {p0.x + v.x, p0.y + v.y}, - {p0.x + n1.x*halfW, p0.y + n1.y*halfW}, - p0}; - - oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points); - oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points+1); - oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points+2); - oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points+3); - } - else - { - //NOTE(martin): add a bevel joint - oc_vec2 points[] = {p0, - {p0.x + n0.x*halfW, p0.y + n0.y*halfW}, - {p0.x + n1.x*halfW, p0.y + n1.y*halfW}, - p0}; - - oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points); - oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points+1); - oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points+2); - } -} - -u32 oc_mtl_render_stroke_subpath(oc_mtl_canvas_backend* backend, - oc_path_elt* elements, - oc_path_descriptor* path, - u32 startIndex, - oc_vec2 startPoint) -{ - u32 eltCount = path->count; - OC_DEBUG_ASSERT(startIndex < eltCount); - - oc_vec2 currentPoint = startPoint; - oc_vec2 endPoint = {0, 0}; - oc_vec2 previousEndTangent = {0, 0}; - oc_vec2 firstTangent = {0, 0}; - oc_vec2 startTangent = {0, 0}; - oc_vec2 endTangent = {0, 0}; - - //NOTE(martin): render first element and compute first tangent - oc_mtl_render_stroke_element(backend, elements + startIndex, currentPoint, &startTangent, &endTangent, &endPoint); - - firstTangent = startTangent; - previousEndTangent = endTangent; - currentPoint = endPoint; - - //NOTE(martin): render subsequent elements along with their joints - - oc_attributes* attributes = &backend->primitive->attributes; - - u32 eltIndex = startIndex + 1; - for(; - eltIndexjoint != OC_JOINT_NONE) - { - oc_mtl_stroke_joint(backend, currentPoint, previousEndTangent, startTangent); - } - previousEndTangent = endTangent; - currentPoint = endPoint; - } - u32 subPathEltCount = eltIndex - startIndex; - - //NOTE(martin): draw end cap / joint. We ensure there's at least two segments to draw a closing joint - if( subPathEltCount > 1 - && startPoint.x == endPoint.x - && startPoint.y == endPoint.y) - { - if(attributes->joint != OC_JOINT_NONE) - { - //NOTE(martin): add a closing joint if the path is closed - oc_mtl_stroke_joint(backend, endPoint, endTangent, firstTangent); - } - } - else if(attributes->cap == OC_CAP_SQUARE) - { - //NOTE(martin): add start and end cap - oc_mtl_stroke_cap(backend, startPoint, (oc_vec2){-startTangent.x, -startTangent.y}); - oc_mtl_stroke_cap(backend, endPoint, endTangent); - } - return(eltIndex); -} - -void oc_mtl_render_stroke(oc_mtl_canvas_backend* backend, - oc_path_elt* elements, - oc_path_descriptor* path) -{ - u32 eltCount = path->count; - OC_DEBUG_ASSERT(eltCount); - - oc_vec2 startPoint = path->startPoint; - u32 startIndex = 0; - - while(startIndex < eltCount) - { - //NOTE(martin): eliminate leading moves - while(startIndex < eltCount && elements[startIndex].type == OC_PATH_MOVE) - { - startPoint = elements[startIndex].p[0]; - startIndex++; - } - if(startIndex < eltCount) - { - startIndex = oc_mtl_render_stroke_subpath(backend, elements, path, startIndex, startPoint); - } - } -} - - -void oc_mtl_grow_buffer_if_needed(oc_mtl_canvas_backend* backend, id* buffer, u64 wantedSize) -{ - u64 bufferSize = [(*buffer) length]; - if(bufferSize < wantedSize) - { - int newSize = wantedSize * 1.2; - - @autoreleasepool - { - //NOTE: MTLBuffers are retained by the command buffer, so we don't risk deallocating while the buffer is in use - [*buffer release]; - *buffer = nil; - - id device = backend->surface->device; - MTLResourceOptions bufferOptions = MTLResourceStorageModePrivate; - - *buffer = [device newBufferWithLength: newSize options: bufferOptions]; - } - } -} - -void oc_mtl_render_batch(oc_mtl_canvas_backend* backend, - oc_mtl_surface* surface, - oc_image* images, - int tileSize, - int nTilesX, - int nTilesY, - oc_vec2 viewportSize, - f32 scale) -{ - int pathBufferOffset = backend->pathBatchStart * sizeof(oc_mtl_path); - int elementBufferOffset = backend->eltBatchStart * sizeof(oc_mtl_path_elt); - int pathCount = backend->pathCount - backend->pathBatchStart; - int eltCount = backend->eltCount - backend->eltBatchStart; - - //NOTE: update intermediate buffers sizes if needed - - oc_mtl_grow_buffer_if_needed(backend, &backend->pathQueueBuffer, pathCount * sizeof(oc_mtl_path_queue)); - oc_mtl_grow_buffer_if_needed(backend, &backend->tileQueueBuffer, backend->maxTileQueueCount * sizeof(oc_mtl_tile_queue)); - oc_mtl_grow_buffer_if_needed(backend, &backend->segmentBuffer, backend->maxSegmentCount * sizeof(oc_mtl_segment)); - oc_mtl_grow_buffer_if_needed(backend, &backend->screenTilesBuffer, nTilesX * nTilesY * sizeof(oc_mtl_screen_tile)); - oc_mtl_grow_buffer_if_needed(backend, &backend->tileOpBuffer, backend->maxSegmentCount * 30 * sizeof(oc_mtl_tile_op)); - - //NOTE: encode GPU commands - @autoreleasepool - { - //NOTE: clear output texture - MTLRenderPassDescriptor* clearDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]; - clearDescriptor.colorAttachments[0].texture = backend->outTexture; - clearDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear; - clearDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 0); - clearDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; - - id clearEncoder = [surface->commandBuffer renderCommandEncoderWithDescriptor:clearDescriptor]; - clearEncoder.label = @"clear out texture pass"; - [clearEncoder endEncoding]; - - //NOTE: clear counters - id blitEncoder = [surface->commandBuffer blitCommandEncoder]; - blitEncoder.label = @"clear counters"; - [blitEncoder fillBuffer: backend->segmentCountBuffer range: NSMakeRange(0, sizeof(int)) value: 0]; - [blitEncoder fillBuffer: backend->tileQueueCountBuffer range: NSMakeRange(0, sizeof(int)) value: 0]; - [blitEncoder fillBuffer: backend->tileOpCountBuffer range: NSMakeRange(0, sizeof(int)) value: 0]; - [blitEncoder fillBuffer: backend->rasterDispatchBuffer range: NSMakeRange(0, sizeof(MTLDispatchThreadgroupsIndirectArguments)) value: 0]; - [blitEncoder endEncoding]; - - //NOTE: path setup pass - id pathEncoder = [surface->commandBuffer computeCommandEncoder]; - pathEncoder.label = @"path pass"; - [pathEncoder setComputePipelineState: backend->pathPipeline]; - - int tileQueueMax = [backend->tileQueueBuffer length] / sizeof(oc_mtl_tile_queue); - - [pathEncoder setBytes:&pathCount length:sizeof(int) atIndex:0]; - [pathEncoder setBuffer:backend->pathBuffer[backend->bufferIndex] offset:pathBufferOffset atIndex:1]; - [pathEncoder setBuffer:backend->pathQueueBuffer offset:0 atIndex:2]; - [pathEncoder setBuffer:backend->tileQueueBuffer offset:0 atIndex:3]; - [pathEncoder setBuffer:backend->tileQueueCountBuffer offset:0 atIndex:4]; - [pathEncoder setBytes:&tileQueueMax length:sizeof(int) atIndex:5]; - [pathEncoder setBytes:&tileSize length:sizeof(int) atIndex:6]; - [pathEncoder setBytes:&scale length:sizeof(int) atIndex:7]; - - MTLSize pathGridSize = MTLSizeMake(pathCount, 1, 1); - MTLSize pathGroupSize = MTLSizeMake([backend->pathPipeline maxTotalThreadsPerThreadgroup], 1, 1); - - [pathEncoder dispatchThreads: pathGridSize threadsPerThreadgroup: pathGroupSize]; - [pathEncoder endEncoding]; - - //NOTE: segment setup pass - id segmentEncoder = [surface->commandBuffer computeCommandEncoder]; - segmentEncoder.label = @"segment pass"; - [segmentEncoder setComputePipelineState: backend->segmentPipeline]; - - int tileOpMax = [backend->tileOpBuffer length] / sizeof(oc_mtl_tile_op); - int segmentMax = [backend->segmentBuffer length] / sizeof(oc_mtl_segment); - - [segmentEncoder setBytes:&eltCount length:sizeof(int) atIndex:0]; - [segmentEncoder setBuffer:backend->elementBuffer[backend->bufferIndex] offset:elementBufferOffset atIndex:1]; - [segmentEncoder setBuffer:backend->segmentCountBuffer offset:0 atIndex:2]; - [segmentEncoder setBuffer:backend->segmentBuffer offset:0 atIndex:3]; - [segmentEncoder setBuffer:backend->pathQueueBuffer offset:0 atIndex:4]; - [segmentEncoder setBuffer:backend->tileQueueBuffer offset:0 atIndex:5]; - [segmentEncoder setBuffer:backend->tileOpBuffer offset:0 atIndex:6]; - [segmentEncoder setBuffer:backend->tileOpCountBuffer offset:0 atIndex:7]; - [segmentEncoder setBytes:&tileOpMax length:sizeof(int) atIndex:8]; - [segmentEncoder setBytes:&segmentMax length:sizeof(int) atIndex:9]; - [segmentEncoder setBytes:&tileSize length:sizeof(int) atIndex:10]; - [segmentEncoder setBytes:&scale length:sizeof(int) atIndex:11]; - [segmentEncoder setBuffer:backend->logBuffer[backend->bufferIndex] offset:0 atIndex:12]; - [segmentEncoder setBuffer:backend->logOffsetBuffer[backend->bufferIndex] offset:0 atIndex:13]; - - MTLSize segmentGridSize = MTLSizeMake(eltCount, 1, 1); - MTLSize segmentGroupSize = MTLSizeMake([backend->segmentPipeline maxTotalThreadsPerThreadgroup], 1, 1); - - [segmentEncoder dispatchThreads: segmentGridSize threadsPerThreadgroup: segmentGroupSize]; - [segmentEncoder endEncoding]; - - //NOTE: backprop pass - id backpropEncoder = [surface->commandBuffer computeCommandEncoder]; - backpropEncoder.label = @"backprop pass"; - [backpropEncoder setComputePipelineState: backend->backpropPipeline]; - - [backpropEncoder setBuffer:backend->pathQueueBuffer offset:0 atIndex:0]; - [backpropEncoder setBuffer:backend->tileQueueBuffer offset:0 atIndex:1]; - [backpropEncoder setBuffer:backend->logBuffer[backend->bufferIndex] offset:0 atIndex:2]; - [backpropEncoder setBuffer:backend->logOffsetBuffer[backend->bufferIndex] offset:0 atIndex:3]; - - MTLSize backpropGroupSize = MTLSizeMake([backend->backpropPipeline maxTotalThreadsPerThreadgroup], 1, 1); - MTLSize backpropGridSize = MTLSizeMake(pathCount*backpropGroupSize.width, 1, 1); - - [backpropEncoder dispatchThreads: backpropGridSize threadsPerThreadgroup: backpropGroupSize]; - [backpropEncoder endEncoding]; - - //NOTE: merge pass - id mergeEncoder = [surface->commandBuffer computeCommandEncoder]; - mergeEncoder.label = @"merge pass"; - [mergeEncoder setComputePipelineState: backend->mergePipeline]; - - [mergeEncoder setBytes:&pathCount length:sizeof(int) atIndex:0]; - [mergeEncoder setBuffer:backend->pathBuffer[backend->bufferIndex] offset:pathBufferOffset atIndex:1]; - [mergeEncoder setBuffer:backend->pathQueueBuffer offset:0 atIndex:2]; - [mergeEncoder setBuffer:backend->tileQueueBuffer offset:0 atIndex:3]; - [mergeEncoder setBuffer:backend->tileOpBuffer offset:0 atIndex:4]; - [mergeEncoder setBuffer:backend->tileOpCountBuffer offset:0 atIndex:5]; - [mergeEncoder setBuffer:backend->rasterDispatchBuffer offset:0 atIndex:6]; - [mergeEncoder setBuffer:backend->screenTilesBuffer offset:0 atIndex:7]; - [mergeEncoder setBytes:&tileOpMax length:sizeof(int) atIndex:8]; - [mergeEncoder setBytes:&tileSize length:sizeof(int) atIndex:9]; - [mergeEncoder setBytes:&scale length:sizeof(float) atIndex:10]; - [mergeEncoder setBuffer:backend->logBuffer[backend->bufferIndex] offset:0 atIndex:11]; - [mergeEncoder setBuffer:backend->logOffsetBuffer[backend->bufferIndex] offset:0 atIndex:12]; - - MTLSize mergeGridSize = MTLSizeMake(nTilesX, nTilesY, 1); - MTLSize mergeGroupSize = MTLSizeMake(OC_MTL_TILE_SIZE, OC_MTL_TILE_SIZE, 1); - - [mergeEncoder dispatchThreads: mergeGridSize threadsPerThreadgroup: mergeGroupSize]; - [mergeEncoder endEncoding]; - - //NOTE: raster pass - id rasterEncoder = [surface->commandBuffer computeCommandEncoder]; - rasterEncoder.label = @"raster pass"; - [rasterEncoder setComputePipelineState: backend->rasterPipeline]; - - [rasterEncoder setBuffer:backend->screenTilesBuffer offset:0 atIndex:0]; - [rasterEncoder setBuffer:backend->tileOpBuffer offset:0 atIndex:1]; - [rasterEncoder setBuffer:backend->pathBuffer[backend->bufferIndex] offset:pathBufferOffset atIndex:2]; - [rasterEncoder setBuffer:backend->segmentBuffer offset:0 atIndex:3]; - [rasterEncoder setBytes:&tileSize length:sizeof(int) atIndex:4]; - [rasterEncoder setBytes:&scale length:sizeof(float) atIndex:5]; - [rasterEncoder setBytes:&backend->msaaCount length:sizeof(int) atIndex:6]; - [rasterEncoder setBuffer:backend->logBuffer[backend->bufferIndex] offset:0 atIndex:7]; - [rasterEncoder setBuffer:backend->logOffsetBuffer[backend->bufferIndex] offset:0 atIndex:8]; - - [rasterEncoder setTexture:backend->outTexture atIndex:0]; - - for(int i=0; itexture atIndex: 1+i]; - } - } - } - - MTLSize rasterGridSize = MTLSizeMake(viewportSize.x, viewportSize.y, 1); - MTLSize rasterGroupSize = MTLSizeMake(OC_MTL_TILE_SIZE, OC_MTL_TILE_SIZE, 1); - - [rasterEncoder dispatchThreadgroupsWithIndirectBuffer: backend->rasterDispatchBuffer - indirectBufferOffset: 0 - threadsPerThreadgroup: rasterGroupSize]; - - [rasterEncoder endEncoding]; - - //NOTE: blit pass - MTLViewport viewport = {0, 0, viewportSize.x, viewportSize.y, 0, 1}; - - MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]; - renderPassDescriptor.colorAttachments[0].texture = surface->drawable.texture; - renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionLoad; - renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; - - id renderEncoder = [surface->commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; - renderEncoder.label = @"blit pass"; - [renderEncoder setViewport: viewport]; - [renderEncoder setRenderPipelineState: backend->blitPipeline]; - [renderEncoder setFragmentTexture: backend->outTexture atIndex: 0]; - [renderEncoder drawPrimitives: MTLPrimitiveTypeTriangle - vertexStart: 0 - vertexCount: 3 ]; - [renderEncoder endEncoding]; - } - - backend->pathBatchStart = backend->pathCount; - backend->eltBatchStart = backend->eltCount; - - backend->maxSegmentCount = 0; - backend->maxTileQueueCount = 0; -} - -void oc_mtl_canvas_resize(oc_mtl_canvas_backend* backend, oc_vec2 size) -{ - @autoreleasepool - { - if(backend->screenTilesBuffer) - { - [backend->screenTilesBuffer release]; - backend->screenTilesBuffer = nil; - } - int tileSize = OC_MTL_TILE_SIZE; - int nTilesX = (int)(size.x + tileSize - 1)/tileSize; - int nTilesY = (int)(size.y + tileSize - 1)/tileSize; - MTLResourceOptions bufferOptions = MTLResourceStorageModePrivate; - backend->screenTilesBuffer = [backend->surface->device newBufferWithLength: nTilesX*nTilesY*sizeof(oc_mtl_screen_tile) - options: bufferOptions]; - - if(backend->outTexture) - { - [backend->outTexture release]; - backend->outTexture = nil; - } - MTLTextureDescriptor* texDesc = [[MTLTextureDescriptor alloc] init]; - texDesc.textureType = MTLTextureType2D; - texDesc.storageMode = MTLStorageModePrivate; - texDesc.usage = MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite | MTLTextureUsageRenderTarget; - texDesc.pixelFormat = MTLPixelFormatRGBA8Unorm; - texDesc.width = size.x; - texDesc.height = size.y; - - backend->outTexture = [backend->surface->device newTextureWithDescriptor:texDesc]; - - backend->surface->mtlLayer.drawableSize = (CGSize){size.x, size.y}; - - backend->frameSize = size; - } -} - -void oc_mtl_canvas_render(oc_canvas_backend* interface, - oc_color clearColor, - u32 primitiveCount, - oc_primitive* primitives, - u32 eltCount, - oc_path_elt* pathElements) -{ - oc_mtl_canvas_backend* backend = (oc_mtl_canvas_backend*)interface; - - //NOTE: update rolling input buffers - dispatch_semaphore_wait(backend->bufferSemaphore, DISPATCH_TIME_FOREVER); - backend->bufferIndex = (backend->bufferIndex + 1) % OC_MTL_INPUT_BUFFERS_COUNT; - - //NOTE: ensure screen tiles buffer is correct size - oc_mtl_surface* surface = backend->surface; - - oc_vec2 frameSize = surface->interface.getSize((oc_surface_data*)surface); - - f32 scale = surface->mtlLayer.contentsScale; - oc_vec2 viewportSize = {frameSize.x * scale, frameSize.y * scale}; - int tileSize = OC_MTL_TILE_SIZE; - int nTilesX = (int)(viewportSize.x * scale + tileSize - 1)/tileSize; - int nTilesY = (int)(viewportSize.y * scale + tileSize - 1)/tileSize; - - if(viewportSize.x != backend->frameSize.x || viewportSize.y != backend->frameSize.y) - { - oc_mtl_canvas_resize(backend, viewportSize); - } - - //NOTE: acquire metal resources for rendering - oc_mtl_surface_acquire_command_buffer(surface); - oc_mtl_surface_acquire_drawable(surface); - - @autoreleasepool - { - //NOTE: clear log counter - id blitEncoder = [surface->commandBuffer blitCommandEncoder]; - blitEncoder.label = @"clear log counter"; - [blitEncoder fillBuffer: backend->logOffsetBuffer[backend->bufferIndex] range: NSMakeRange(0, sizeof(int)) value: 0]; - [blitEncoder endEncoding]; - - //NOTE: clear screen - MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]; - renderPassDescriptor.colorAttachments[0].texture = surface->drawable.texture; - renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear; - renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clearColor.r, clearColor.g, clearColor.b, clearColor.a); - renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; - - id renderEncoder = [surface->commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; - renderEncoder.label = @"clear pass"; - [renderEncoder endEncoding]; - } - backend->pathCount = 0; - backend->pathBatchStart = 0; - backend->eltCount = 0; - backend->eltBatchStart = 0; - backend->maxSegmentCount = 0; - backend->maxTileQueueCount = 0; - - //NOTE: encode and render batches - oc_vec2 currentPos = {0}; - oc_image images[OC_MTL_MAX_IMAGES_PER_BATCH] = {0}; - int imageCount = 0; - - for(int primitiveIndex = 0; primitiveIndex < primitiveCount; primitiveIndex++) - { - oc_primitive* primitive = &primitives[primitiveIndex]; - - if(primitive->attributes.image.h != 0) - { - backend->currentImageIndex = -1; - for(int i=0; iattributes.image.h) - { - backend->currentImageIndex = i; - } - } - if(backend->currentImageIndex <= 0) - { - if(imageCountattributes.image; - backend->currentImageIndex = imageCount; - imageCount++; - } - else - { - oc_mtl_render_batch(backend, - surface, - images, - tileSize, - nTilesX, - nTilesY, - viewportSize, - scale); - - images[0] = primitive->attributes.image; - backend->currentImageIndex = 0; - imageCount = 1; - } - } - } - else - { - backend->currentImageIndex = -1; - } - - if(primitive->path.count) - { - backend->primitive = primitive; - backend->pathScreenExtents = (oc_vec4){FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX}; - backend->pathUserExtents = (oc_vec4){FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX}; - - if(primitive->cmd == OC_CMD_STROKE) - { - oc_mtl_render_stroke(backend, pathElements + primitive->path.startIndex, &primitive->path); - } - else - { - for(int eltIndex = 0; - (eltIndex < primitive->path.count) && (primitive->path.startIndex + eltIndex < eltCount); - eltIndex++) - { - oc_path_elt* elt = &pathElements[primitive->path.startIndex + eltIndex]; - - if(elt->type != OC_PATH_MOVE) - { - oc_vec2 p[4] = {currentPos, elt->p[0], elt->p[1], elt->p[2]}; - oc_mtl_canvas_encode_element(backend, elt->type, p); - } - switch(elt->type) - { - case OC_PATH_MOVE: - currentPos = elt->p[0]; - break; - - case OC_PATH_LINE: - currentPos = elt->p[0]; - break; - - case OC_PATH_QUADRATIC: - currentPos = elt->p[1]; - break; - - case OC_PATH_CUBIC: - currentPos = elt->p[2]; - break; - } - } - } - //NOTE: encode path - oc_mtl_encode_path(backend, primitive, scale); - } - } - - oc_mtl_render_batch(backend, - surface, - images, - tileSize, - nTilesX, - nTilesY, - viewportSize, - scale); - - @autoreleasepool - { - //NOTE: finalize - [surface->commandBuffer addCompletedHandler:^(id commandBuffer) - { - oc_mtl_print_log(backend->bufferIndex, backend->logBuffer[backend->bufferIndex], backend->logOffsetBuffer[backend->bufferIndex]); - dispatch_semaphore_signal(backend->bufferSemaphore); - }]; - } -} - -void oc_mtl_canvas_destroy(oc_canvas_backend* interface) -{ - oc_mtl_canvas_backend* backend = (oc_mtl_canvas_backend*)interface; - - @autoreleasepool - { - [backend->pathPipeline release]; - [backend->segmentPipeline release]; - [backend->backpropPipeline release]; - [backend->mergePipeline release]; - [backend->rasterPipeline release]; - [backend->blitPipeline release]; - - for(int i=0; ipathBuffer[i] release]; - [backend->elementBuffer[i] release]; - [backend->logBuffer[i] release]; - [backend->logOffsetBuffer[i] release]; - } - [backend->segmentCountBuffer release]; - [backend->segmentBuffer release]; - [backend->tileQueueBuffer release]; - [backend->tileQueueCountBuffer release]; - [backend->tileOpBuffer release]; - [backend->tileOpCountBuffer release]; - [backend->screenTilesBuffer release]; - } - - free(backend); -} - -oc_image_data* oc_mtl_canvas_image_create(oc_canvas_backend* interface, oc_vec2 size) -{ - oc_mtl_image_data* image = 0; - oc_mtl_canvas_backend* backend = (oc_mtl_canvas_backend*)interface; - oc_mtl_surface* surface = backend->surface; - - @autoreleasepool - { - image = oc_malloc_type(oc_mtl_image_data); - if(image) - { - MTLTextureDescriptor* texDesc = [[MTLTextureDescriptor alloc] init]; - texDesc.textureType = MTLTextureType2D; - texDesc.storageMode = MTLStorageModeManaged; - texDesc.usage = MTLTextureUsageShaderRead; - texDesc.pixelFormat = MTLPixelFormatRGBA8Unorm; - texDesc.width = size.x; - texDesc.height = size.y; - - image->texture = [surface->device newTextureWithDescriptor:texDesc]; - if(image->texture != nil) - { - [image->texture retain]; - image->interface.size = size; - } - else - { - free(image); - image = 0; - } - } - } - return((oc_image_data*)image); -} - -void oc_mtl_canvas_image_destroy(oc_canvas_backend* backendInterface, oc_image_data* imageInterface) -{ - oc_mtl_image_data* image = (oc_mtl_image_data*)imageInterface; - @autoreleasepool - { - [image->texture release]; - free(image); - } -} - -void oc_mtl_canvas_image_upload_region(oc_canvas_backend* backendInterface, oc_image_data* imageInterface, oc_rect region, u8* pixels) -{@autoreleasepool{ - oc_mtl_image_data* image = (oc_mtl_image_data*)imageInterface; - MTLRegion mtlRegion = MTLRegionMake2D(region.x, region.y, region.w, region.h); - [image->texture replaceRegion:mtlRegion - mipmapLevel:0 - withBytes:(void*)pixels - bytesPerRow: 4 * region.w]; -}} - -const u32 OC_MTL_DEFAULT_PATH_BUFFER_LEN = (4<<10), - OC_MTL_DEFAULT_ELT_BUFFER_LEN = (4<<10), - - OC_MTL_DEFAULT_SEGMENT_BUFFER_LEN = (4<<10), - OC_MTL_DEFAULT_PATH_QUEUE_BUFFER_LEN = (4<<10), - OC_MTL_DEFAULT_TILE_QUEUE_BUFFER_LEN = (4<<10), - OC_MTL_DEFAULT_TILE_OP_BUFFER_LEN = (4<<20); - -oc_canvas_backend* oc_mtl_canvas_backend_create(oc_mtl_surface* surface) -{ - oc_mtl_canvas_backend* backend = 0; - - backend = oc_malloc_type(oc_mtl_canvas_backend); - memset(backend, 0, sizeof(oc_mtl_canvas_backend)); - - backend->msaaCount = OC_MTL_MSAA_COUNT; - backend->surface = surface; - - //NOTE(martin): setup interface functions - backend->interface.destroy = oc_mtl_canvas_destroy; - backend->interface.render = oc_mtl_canvas_render; - backend->interface.imageCreate = oc_mtl_canvas_image_create; - backend->interface.imageDestroy = oc_mtl_canvas_image_destroy; - backend->interface.imageUploadRegion = oc_mtl_canvas_image_upload_region; - - @autoreleasepool{ - //NOTE: load metal library - oc_str8 shaderPath = oc_path_executable_relative(oc_scratch(), OC_STR8("mtl_renderer.metallib")); - NSString* metalFileName = [[NSString alloc] initWithBytes: shaderPath.ptr length:shaderPath.len encoding: NSUTF8StringEncoding]; - NSError* err = 0; - id library = [surface->device newLibraryWithFile: metalFileName error:&err]; - if(err != nil) - { - const char* errStr = [[err localizedDescription] UTF8String]; - oc_log_error("error : %s\n", errStr); - return(0); - } - id pathFunction = [library newFunctionWithName:@"mtl_path_setup"]; - id segmentFunction = [library newFunctionWithName:@"mtl_segment_setup"]; - id backpropFunction = [library newFunctionWithName:@"mtl_backprop"]; - id mergeFunction = [library newFunctionWithName:@"mtl_merge"]; - id rasterFunction = [library newFunctionWithName:@"mtl_raster"]; - id vertexFunction = [library newFunctionWithName:@"mtl_vertex_shader"]; - id fragmentFunction = [library newFunctionWithName:@"mtl_fragment_shader"]; - - //NOTE: create pipelines - NSError* error = NULL; - - backend->pathPipeline = [surface->device newComputePipelineStateWithFunction: pathFunction - error:&error]; - - backend->segmentPipeline = [surface->device newComputePipelineStateWithFunction: segmentFunction - error:&error]; - - backend->backpropPipeline = [surface->device newComputePipelineStateWithFunction: backpropFunction - error:&error]; - - backend->mergePipeline = [surface->device newComputePipelineStateWithFunction: mergeFunction - error:&error]; - - backend->rasterPipeline = [surface->device newComputePipelineStateWithFunction: rasterFunction - error:&error]; - - MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; - pipelineStateDescriptor.label = @"blit pipeline"; - pipelineStateDescriptor.vertexFunction = vertexFunction; - pipelineStateDescriptor.fragmentFunction = fragmentFunction; - pipelineStateDescriptor.colorAttachments[0].pixelFormat = surface->mtlLayer.pixelFormat; - pipelineStateDescriptor.colorAttachments[0].blendingEnabled = YES; - pipelineStateDescriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; - pipelineStateDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorOne; - pipelineStateDescriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha; - pipelineStateDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; - pipelineStateDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne; - pipelineStateDescriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha; - - backend->blitPipeline = [surface->device newRenderPipelineStateWithDescriptor: pipelineStateDescriptor error:&err]; - - //NOTE: create textures - oc_vec2 size = surface->interface.getSize((oc_surface_data*)surface); - f32 scale = surface->mtlLayer.contentsScale; - - backend->frameSize = (oc_vec2){size.x*scale, size.y*scale}; - - MTLTextureDescriptor* texDesc = [[MTLTextureDescriptor alloc] init]; - texDesc.textureType = MTLTextureType2D; - texDesc.storageMode = MTLStorageModePrivate; - texDesc.usage = MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite | MTLTextureUsageRenderTarget; - texDesc.pixelFormat = MTLPixelFormatRGBA8Unorm; - texDesc.width = backend->frameSize.x; - texDesc.height = backend->frameSize.y; - - backend->outTexture = [surface->device newTextureWithDescriptor:texDesc]; - - //NOTE: create buffers - - backend->bufferSemaphore = dispatch_semaphore_create(OC_MTL_INPUT_BUFFERS_COUNT); - backend->bufferIndex = 0; - - MTLResourceOptions bufferOptions = MTLResourceCPUCacheModeWriteCombined - | MTLResourceStorageModeShared; - - for(int i=0; ipathBuffer[i] = [surface->device newBufferWithLength: OC_MTL_DEFAULT_PATH_BUFFER_LEN * sizeof(oc_mtl_path) - options: bufferOptions]; - - backend->elementBuffer[i] = [surface->device newBufferWithLength: OC_MTL_DEFAULT_ELT_BUFFER_LEN * sizeof(oc_mtl_path_elt) - options: bufferOptions]; - } - - bufferOptions = MTLResourceStorageModePrivate; - backend->segmentBuffer = [surface->device newBufferWithLength: OC_MTL_DEFAULT_SEGMENT_BUFFER_LEN * sizeof(oc_mtl_segment) - options: bufferOptions]; - - backend->segmentCountBuffer = [surface->device newBufferWithLength: sizeof(int) - options: bufferOptions]; - - backend->pathQueueBuffer = [surface->device newBufferWithLength: OC_MTL_DEFAULT_PATH_QUEUE_BUFFER_LEN * sizeof(oc_mtl_path_queue) - options: bufferOptions]; - - backend->tileQueueBuffer = [surface->device newBufferWithLength: OC_MTL_DEFAULT_TILE_QUEUE_BUFFER_LEN * sizeof(oc_mtl_tile_queue) - options: bufferOptions]; - - backend->tileQueueCountBuffer = [surface->device newBufferWithLength: sizeof(int) - options: bufferOptions]; - - backend->tileOpBuffer = [surface->device newBufferWithLength: OC_MTL_DEFAULT_TILE_OP_BUFFER_LEN * sizeof(oc_mtl_tile_op) - options: bufferOptions]; - - backend->tileOpCountBuffer = [surface->device newBufferWithLength: sizeof(int) - options: bufferOptions]; - - backend->rasterDispatchBuffer = [surface->device newBufferWithLength: sizeof(MTLDispatchThreadgroupsIndirectArguments) - options: bufferOptions]; - - int tileSize = OC_MTL_TILE_SIZE; - int nTilesX = (int)(backend->frameSize.x + tileSize - 1)/tileSize; - int nTilesY = (int)(backend->frameSize.y + tileSize - 1)/tileSize; - backend->screenTilesBuffer = [surface->device newBufferWithLength: nTilesX*nTilesY*sizeof(oc_mtl_screen_tile) - options: bufferOptions]; - - bufferOptions = MTLResourceStorageModeShared; - for(int i=0; ilogBuffer[i] = [surface->device newBufferWithLength: 1<<20 - options: bufferOptions]; - - backend->logOffsetBuffer[i] = [surface->device newBufferWithLength: sizeof(int) - options: bufferOptions]; - } - } - return((oc_canvas_backend*)backend); -} - -oc_surface_data* oc_mtl_canvas_surface_create_for_window(oc_window window) -{ - oc_mtl_surface* surface = (oc_mtl_surface*)oc_mtl_surface_create_for_window(window); - - if(surface) - { - surface->interface.backend = oc_mtl_canvas_backend_create(surface); - if(surface->interface.backend) - { - surface->interface.api = OC_CANVAS; - } - else - { - surface->interface.destroy((oc_surface_data*)surface); - surface = 0; - } - } - return((oc_surface_data*)surface); -} + */ + f32 halfW = 0.5 * attributes->width; + oc_vec2 u = { n0.x + n1.x, n0.y + n1.y }; + f32 uNormSquare = u.x * u.x + u.y * u.y; + f32 alpha = attributes->width / uNormSquare; + oc_vec2 v = { u.x * alpha, u.y * alpha }; + + f32 excursionSquare = uNormSquare * oc_square(alpha - attributes->width / 4); + + if(attributes->joint == OC_JOINT_MITER + && excursionSquare <= oc_square(attributes->maxJointExcursion)) + { + //NOTE(martin): add a mitter joint + oc_vec2 points[] = { p0, + { p0.x + n0.x * halfW, p0.y + n0.y * halfW }, + { p0.x + v.x, p0.y + v.y }, + { p0.x + n1.x * halfW, p0.y + n1.y * halfW }, + p0 }; + + oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points); + oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points + 1); + oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points + 2); + oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points + 3); + } + else + { + //NOTE(martin): add a bevel joint + oc_vec2 points[] = { p0, + { p0.x + n0.x * halfW, p0.y + n0.y * halfW }, + { p0.x + n1.x * halfW, p0.y + n1.y * halfW }, + p0 }; + + oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points); + oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points + 1); + oc_mtl_canvas_encode_element(backend, OC_PATH_LINE, points + 2); + } +} + +u32 oc_mtl_render_stroke_subpath(oc_mtl_canvas_backend* backend, + oc_path_elt* elements, + oc_path_descriptor* path, + u32 startIndex, + oc_vec2 startPoint) +{ + u32 eltCount = path->count; + OC_DEBUG_ASSERT(startIndex < eltCount); + + oc_vec2 currentPoint = startPoint; + oc_vec2 endPoint = { 0, 0 }; + oc_vec2 previousEndTangent = { 0, 0 }; + oc_vec2 firstTangent = { 0, 0 }; + oc_vec2 startTangent = { 0, 0 }; + oc_vec2 endTangent = { 0, 0 }; + + //NOTE(martin): render first element and compute first tangent + oc_mtl_render_stroke_element(backend, elements + startIndex, currentPoint, &startTangent, &endTangent, &endPoint); + + firstTangent = startTangent; + previousEndTangent = endTangent; + currentPoint = endPoint; + + //NOTE(martin): render subsequent elements along with their joints + + oc_attributes* attributes = &backend->primitive->attributes; + + u32 eltIndex = startIndex + 1; + for(; + eltIndex < eltCount && elements[eltIndex].type != OC_PATH_MOVE; + eltIndex++) + { + oc_mtl_render_stroke_element(backend, elements + eltIndex, currentPoint, &startTangent, &endTangent, &endPoint); + + if(attributes->joint != OC_JOINT_NONE) + { + oc_mtl_stroke_joint(backend, currentPoint, previousEndTangent, startTangent); + } + previousEndTangent = endTangent; + currentPoint = endPoint; + } + u32 subPathEltCount = eltIndex - startIndex; + + //NOTE(martin): draw end cap / joint. We ensure there's at least two segments to draw a closing joint + if(subPathEltCount > 1 + && startPoint.x == endPoint.x + && startPoint.y == endPoint.y) + { + if(attributes->joint != OC_JOINT_NONE) + { + //NOTE(martin): add a closing joint if the path is closed + oc_mtl_stroke_joint(backend, endPoint, endTangent, firstTangent); + } + } + else if(attributes->cap == OC_CAP_SQUARE) + { + //NOTE(martin): add start and end cap + oc_mtl_stroke_cap(backend, startPoint, (oc_vec2){ -startTangent.x, -startTangent.y }); + oc_mtl_stroke_cap(backend, endPoint, endTangent); + } + return (eltIndex); +} + +void oc_mtl_render_stroke(oc_mtl_canvas_backend* backend, + oc_path_elt* elements, + oc_path_descriptor* path) +{ + u32 eltCount = path->count; + OC_DEBUG_ASSERT(eltCount); + + oc_vec2 startPoint = path->startPoint; + u32 startIndex = 0; + + while(startIndex < eltCount) + { + //NOTE(martin): eliminate leading moves + while(startIndex < eltCount && elements[startIndex].type == OC_PATH_MOVE) + { + startPoint = elements[startIndex].p[0]; + startIndex++; + } + if(startIndex < eltCount) + { + startIndex = oc_mtl_render_stroke_subpath(backend, elements, path, startIndex, startPoint); + } + } +} + +void oc_mtl_grow_buffer_if_needed(oc_mtl_canvas_backend* backend, id* buffer, u64 wantedSize) +{ + u64 bufferSize = [(*buffer) length]; + if(bufferSize < wantedSize) + { + int newSize = wantedSize * 1.2; + + @autoreleasepool + { + //NOTE: MTLBuffers are retained by the command buffer, so we don't risk deallocating while the buffer is in use + [*buffer release]; + *buffer = nil; + + id device = backend->surface->device; + MTLResourceOptions bufferOptions = MTLResourceStorageModePrivate; + + *buffer = [device newBufferWithLength:newSize options:bufferOptions]; + } + } +} + +void oc_mtl_render_batch(oc_mtl_canvas_backend* backend, + oc_mtl_surface* surface, + oc_image* images, + int tileSize, + int nTilesX, + int nTilesY, + oc_vec2 viewportSize, + f32 scale) +{ + int pathBufferOffset = backend->pathBatchStart * sizeof(oc_mtl_path); + int elementBufferOffset = backend->eltBatchStart * sizeof(oc_mtl_path_elt); + int pathCount = backend->pathCount - backend->pathBatchStart; + int eltCount = backend->eltCount - backend->eltBatchStart; + + //NOTE: update intermediate buffers sizes if needed + + oc_mtl_grow_buffer_if_needed(backend, &backend->pathQueueBuffer, pathCount * sizeof(oc_mtl_path_queue)); + oc_mtl_grow_buffer_if_needed(backend, &backend->tileQueueBuffer, backend->maxTileQueueCount * sizeof(oc_mtl_tile_queue)); + oc_mtl_grow_buffer_if_needed(backend, &backend->segmentBuffer, backend->maxSegmentCount * sizeof(oc_mtl_segment)); + oc_mtl_grow_buffer_if_needed(backend, &backend->screenTilesBuffer, nTilesX * nTilesY * sizeof(oc_mtl_screen_tile)); + oc_mtl_grow_buffer_if_needed(backend, &backend->tileOpBuffer, backend->maxSegmentCount * 30 * sizeof(oc_mtl_tile_op)); + + //NOTE: encode GPU commands + @autoreleasepool + { + //NOTE: clear output texture + MTLRenderPassDescriptor* clearDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]; + clearDescriptor.colorAttachments[0].texture = backend->outTexture; + clearDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear; + clearDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(0, 0, 0, 0); + clearDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; + + id clearEncoder = [surface->commandBuffer renderCommandEncoderWithDescriptor:clearDescriptor]; + clearEncoder.label = @"clear out texture pass"; + [clearEncoder endEncoding]; + + //NOTE: clear counters + id blitEncoder = [surface->commandBuffer blitCommandEncoder]; + blitEncoder.label = @"clear counters"; + [blitEncoder fillBuffer:backend->segmentCountBuffer range:NSMakeRange(0, sizeof(int)) value:0]; + [blitEncoder fillBuffer:backend->tileQueueCountBuffer range:NSMakeRange(0, sizeof(int)) value:0]; + [blitEncoder fillBuffer:backend->tileOpCountBuffer range:NSMakeRange(0, sizeof(int)) value:0]; + [blitEncoder fillBuffer:backend->rasterDispatchBuffer range:NSMakeRange(0, sizeof(MTLDispatchThreadgroupsIndirectArguments)) value:0]; + [blitEncoder endEncoding]; + + //NOTE: path setup pass + id pathEncoder = [surface->commandBuffer computeCommandEncoder]; + pathEncoder.label = @"path pass"; + [pathEncoder setComputePipelineState:backend->pathPipeline]; + + int tileQueueMax = [backend->tileQueueBuffer length] / sizeof(oc_mtl_tile_queue); + + [pathEncoder setBytes:&pathCount length:sizeof(int) atIndex:0]; + [pathEncoder setBuffer:backend->pathBuffer[backend->bufferIndex] offset:pathBufferOffset atIndex:1]; + [pathEncoder setBuffer:backend->pathQueueBuffer offset:0 atIndex:2]; + [pathEncoder setBuffer:backend->tileQueueBuffer offset:0 atIndex:3]; + [pathEncoder setBuffer:backend->tileQueueCountBuffer offset:0 atIndex:4]; + [pathEncoder setBytes:&tileQueueMax length:sizeof(int) atIndex:5]; + [pathEncoder setBytes:&tileSize length:sizeof(int) atIndex:6]; + [pathEncoder setBytes:&scale length:sizeof(int) atIndex:7]; + + MTLSize pathGridSize = MTLSizeMake(pathCount, 1, 1); + MTLSize pathGroupSize = MTLSizeMake([backend->pathPipeline maxTotalThreadsPerThreadgroup], 1, 1); + + [pathEncoder dispatchThreads:pathGridSize threadsPerThreadgroup:pathGroupSize]; + [pathEncoder endEncoding]; + + //NOTE: segment setup pass + id segmentEncoder = [surface->commandBuffer computeCommandEncoder]; + segmentEncoder.label = @"segment pass"; + [segmentEncoder setComputePipelineState:backend->segmentPipeline]; + + int tileOpMax = [backend->tileOpBuffer length] / sizeof(oc_mtl_tile_op); + int segmentMax = [backend->segmentBuffer length] / sizeof(oc_mtl_segment); + + [segmentEncoder setBytes:&eltCount length:sizeof(int) atIndex:0]; + [segmentEncoder setBuffer:backend->elementBuffer[backend->bufferIndex] offset:elementBufferOffset atIndex:1]; + [segmentEncoder setBuffer:backend->segmentCountBuffer offset:0 atIndex:2]; + [segmentEncoder setBuffer:backend->segmentBuffer offset:0 atIndex:3]; + [segmentEncoder setBuffer:backend->pathQueueBuffer offset:0 atIndex:4]; + [segmentEncoder setBuffer:backend->tileQueueBuffer offset:0 atIndex:5]; + [segmentEncoder setBuffer:backend->tileOpBuffer offset:0 atIndex:6]; + [segmentEncoder setBuffer:backend->tileOpCountBuffer offset:0 atIndex:7]; + [segmentEncoder setBytes:&tileOpMax length:sizeof(int) atIndex:8]; + [segmentEncoder setBytes:&segmentMax length:sizeof(int) atIndex:9]; + [segmentEncoder setBytes:&tileSize length:sizeof(int) atIndex:10]; + [segmentEncoder setBytes:&scale length:sizeof(int) atIndex:11]; + [segmentEncoder setBuffer:backend->logBuffer[backend->bufferIndex] offset:0 atIndex:12]; + [segmentEncoder setBuffer:backend->logOffsetBuffer[backend->bufferIndex] offset:0 atIndex:13]; + + MTLSize segmentGridSize = MTLSizeMake(eltCount, 1, 1); + MTLSize segmentGroupSize = MTLSizeMake([backend->segmentPipeline maxTotalThreadsPerThreadgroup], 1, 1); + + [segmentEncoder dispatchThreads:segmentGridSize threadsPerThreadgroup:segmentGroupSize]; + [segmentEncoder endEncoding]; + + //NOTE: backprop pass + id backpropEncoder = [surface->commandBuffer computeCommandEncoder]; + backpropEncoder.label = @"backprop pass"; + [backpropEncoder setComputePipelineState:backend->backpropPipeline]; + + [backpropEncoder setBuffer:backend->pathQueueBuffer offset:0 atIndex:0]; + [backpropEncoder setBuffer:backend->tileQueueBuffer offset:0 atIndex:1]; + [backpropEncoder setBuffer:backend->logBuffer[backend->bufferIndex] offset:0 atIndex:2]; + [backpropEncoder setBuffer:backend->logOffsetBuffer[backend->bufferIndex] offset:0 atIndex:3]; + + MTLSize backpropGroupSize = MTLSizeMake([backend->backpropPipeline maxTotalThreadsPerThreadgroup], 1, 1); + MTLSize backpropGridSize = MTLSizeMake(pathCount * backpropGroupSize.width, 1, 1); + + [backpropEncoder dispatchThreads:backpropGridSize threadsPerThreadgroup:backpropGroupSize]; + [backpropEncoder endEncoding]; + + //NOTE: merge pass + id mergeEncoder = [surface->commandBuffer computeCommandEncoder]; + mergeEncoder.label = @"merge pass"; + [mergeEncoder setComputePipelineState:backend->mergePipeline]; + + [mergeEncoder setBytes:&pathCount length:sizeof(int) atIndex:0]; + [mergeEncoder setBuffer:backend->pathBuffer[backend->bufferIndex] offset:pathBufferOffset atIndex:1]; + [mergeEncoder setBuffer:backend->pathQueueBuffer offset:0 atIndex:2]; + [mergeEncoder setBuffer:backend->tileQueueBuffer offset:0 atIndex:3]; + [mergeEncoder setBuffer:backend->tileOpBuffer offset:0 atIndex:4]; + [mergeEncoder setBuffer:backend->tileOpCountBuffer offset:0 atIndex:5]; + [mergeEncoder setBuffer:backend->rasterDispatchBuffer offset:0 atIndex:6]; + [mergeEncoder setBuffer:backend->screenTilesBuffer offset:0 atIndex:7]; + [mergeEncoder setBytes:&tileOpMax length:sizeof(int) atIndex:8]; + [mergeEncoder setBytes:&tileSize length:sizeof(int) atIndex:9]; + [mergeEncoder setBytes:&scale length:sizeof(float) atIndex:10]; + [mergeEncoder setBuffer:backend->logBuffer[backend->bufferIndex] offset:0 atIndex:11]; + [mergeEncoder setBuffer:backend->logOffsetBuffer[backend->bufferIndex] offset:0 atIndex:12]; + + MTLSize mergeGridSize = MTLSizeMake(nTilesX, nTilesY, 1); + MTLSize mergeGroupSize = MTLSizeMake(OC_MTL_TILE_SIZE, OC_MTL_TILE_SIZE, 1); + + [mergeEncoder dispatchThreads:mergeGridSize threadsPerThreadgroup:mergeGroupSize]; + [mergeEncoder endEncoding]; + + //NOTE: raster pass + id rasterEncoder = [surface->commandBuffer computeCommandEncoder]; + rasterEncoder.label = @"raster pass"; + [rasterEncoder setComputePipelineState:backend->rasterPipeline]; + + [rasterEncoder setBuffer:backend->screenTilesBuffer offset:0 atIndex:0]; + [rasterEncoder setBuffer:backend->tileOpBuffer offset:0 atIndex:1]; + [rasterEncoder setBuffer:backend->pathBuffer[backend->bufferIndex] offset:pathBufferOffset atIndex:2]; + [rasterEncoder setBuffer:backend->segmentBuffer offset:0 atIndex:3]; + [rasterEncoder setBytes:&tileSize length:sizeof(int) atIndex:4]; + [rasterEncoder setBytes:&scale length:sizeof(float) atIndex:5]; + [rasterEncoder setBytes:&backend->msaaCount length:sizeof(int) atIndex:6]; + [rasterEncoder setBuffer:backend->logBuffer[backend->bufferIndex] offset:0 atIndex:7]; + [rasterEncoder setBuffer:backend->logOffsetBuffer[backend->bufferIndex] offset:0 atIndex:8]; + + [rasterEncoder setTexture:backend->outTexture atIndex:0]; + + for(int i = 0; i < OC_MTL_MAX_IMAGES_PER_BATCH; i++) + { + if(images[i].h) + { + oc_mtl_image_data* image = (oc_mtl_image_data*)oc_image_data_from_handle(images[i]); + if(image) + { + [rasterEncoder setTexture:image->texture atIndex:1 + i]; + } + } + } + + MTLSize rasterGridSize = MTLSizeMake(viewportSize.x, viewportSize.y, 1); + MTLSize rasterGroupSize = MTLSizeMake(OC_MTL_TILE_SIZE, OC_MTL_TILE_SIZE, 1); + + [rasterEncoder dispatchThreadgroupsWithIndirectBuffer:backend->rasterDispatchBuffer + indirectBufferOffset:0 + threadsPerThreadgroup:rasterGroupSize]; + + [rasterEncoder endEncoding]; + + //NOTE: blit pass + MTLViewport viewport = { 0, 0, viewportSize.x, viewportSize.y, 0, 1 }; + + MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]; + renderPassDescriptor.colorAttachments[0].texture = surface->drawable.texture; + renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionLoad; + renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; + + id renderEncoder = [surface->commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; + renderEncoder.label = @"blit pass"; + [renderEncoder setViewport:viewport]; + [renderEncoder setRenderPipelineState:backend->blitPipeline]; + [renderEncoder setFragmentTexture:backend->outTexture atIndex:0]; + [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle + vertexStart:0 + vertexCount:3]; + [renderEncoder endEncoding]; + } + + backend->pathBatchStart = backend->pathCount; + backend->eltBatchStart = backend->eltCount; + + backend->maxSegmentCount = 0; + backend->maxTileQueueCount = 0; +} + +void oc_mtl_canvas_resize(oc_mtl_canvas_backend* backend, oc_vec2 size) +{ + @autoreleasepool + { + if(backend->screenTilesBuffer) + { + [backend->screenTilesBuffer release]; + backend->screenTilesBuffer = nil; + } + int tileSize = OC_MTL_TILE_SIZE; + int nTilesX = (int)(size.x + tileSize - 1) / tileSize; + int nTilesY = (int)(size.y + tileSize - 1) / tileSize; + MTLResourceOptions bufferOptions = MTLResourceStorageModePrivate; + backend->screenTilesBuffer = [backend->surface->device newBufferWithLength:nTilesX * nTilesY * sizeof(oc_mtl_screen_tile) + options:bufferOptions]; + + if(backend->outTexture) + { + [backend->outTexture release]; + backend->outTexture = nil; + } + MTLTextureDescriptor* texDesc = [[MTLTextureDescriptor alloc] init]; + texDesc.textureType = MTLTextureType2D; + texDesc.storageMode = MTLStorageModePrivate; + texDesc.usage = MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite | MTLTextureUsageRenderTarget; + texDesc.pixelFormat = MTLPixelFormatRGBA8Unorm; + texDesc.width = size.x; + texDesc.height = size.y; + + backend->outTexture = [backend->surface->device newTextureWithDescriptor:texDesc]; + + backend->surface->mtlLayer.drawableSize = (CGSize){ size.x, size.y }; + + backend->frameSize = size; + } +} + +void oc_mtl_canvas_render(oc_canvas_backend* interface, + oc_color clearColor, + u32 primitiveCount, + oc_primitive* primitives, + u32 eltCount, + oc_path_elt* pathElements) +{ + oc_mtl_canvas_backend* backend = (oc_mtl_canvas_backend*)interface; + + //NOTE: update rolling input buffers + dispatch_semaphore_wait(backend->bufferSemaphore, DISPATCH_TIME_FOREVER); + backend->bufferIndex = (backend->bufferIndex + 1) % OC_MTL_INPUT_BUFFERS_COUNT; + + //NOTE: ensure screen tiles buffer is correct size + oc_mtl_surface* surface = backend->surface; + + oc_vec2 frameSize = surface->interface.getSize((oc_surface_data*)surface); + + f32 scale = surface->mtlLayer.contentsScale; + oc_vec2 viewportSize = { frameSize.x * scale, frameSize.y * scale }; + int tileSize = OC_MTL_TILE_SIZE; + int nTilesX = (int)(viewportSize.x * scale + tileSize - 1) / tileSize; + int nTilesY = (int)(viewportSize.y * scale + tileSize - 1) / tileSize; + + if(viewportSize.x != backend->frameSize.x || viewportSize.y != backend->frameSize.y) + { + oc_mtl_canvas_resize(backend, viewportSize); + } + + //NOTE: acquire metal resources for rendering + oc_mtl_surface_acquire_command_buffer(surface); + oc_mtl_surface_acquire_drawable(surface); + + @autoreleasepool + { + //NOTE: clear log counter + id blitEncoder = [surface->commandBuffer blitCommandEncoder]; + blitEncoder.label = @"clear log counter"; + [blitEncoder fillBuffer:backend->logOffsetBuffer[backend->bufferIndex] range:NSMakeRange(0, sizeof(int)) value:0]; + [blitEncoder endEncoding]; + + //NOTE: clear screen + MTLRenderPassDescriptor* renderPassDescriptor = [MTLRenderPassDescriptor renderPassDescriptor]; + renderPassDescriptor.colorAttachments[0].texture = surface->drawable.texture; + renderPassDescriptor.colorAttachments[0].loadAction = MTLLoadActionClear; + renderPassDescriptor.colorAttachments[0].clearColor = MTLClearColorMake(clearColor.r, clearColor.g, clearColor.b, clearColor.a); + renderPassDescriptor.colorAttachments[0].storeAction = MTLStoreActionStore; + + id renderEncoder = [surface->commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; + renderEncoder.label = @"clear pass"; + [renderEncoder endEncoding]; + } + backend->pathCount = 0; + backend->pathBatchStart = 0; + backend->eltCount = 0; + backend->eltBatchStart = 0; + backend->maxSegmentCount = 0; + backend->maxTileQueueCount = 0; + + //NOTE: encode and render batches + oc_vec2 currentPos = { 0 }; + oc_image images[OC_MTL_MAX_IMAGES_PER_BATCH] = { 0 }; + int imageCount = 0; + + for(int primitiveIndex = 0; primitiveIndex < primitiveCount; primitiveIndex++) + { + oc_primitive* primitive = &primitives[primitiveIndex]; + + if(primitive->attributes.image.h != 0) + { + backend->currentImageIndex = -1; + for(int i = 0; i < imageCount; i++) + { + if(images[i].h == primitive->attributes.image.h) + { + backend->currentImageIndex = i; + } + } + if(backend->currentImageIndex <= 0) + { + if(imageCount < OC_MTL_MAX_IMAGES_PER_BATCH) + { + images[imageCount] = primitive->attributes.image; + backend->currentImageIndex = imageCount; + imageCount++; + } + else + { + oc_mtl_render_batch(backend, + surface, + images, + tileSize, + nTilesX, + nTilesY, + viewportSize, + scale); + + images[0] = primitive->attributes.image; + backend->currentImageIndex = 0; + imageCount = 1; + } + } + } + else + { + backend->currentImageIndex = -1; + } + + if(primitive->path.count) + { + backend->primitive = primitive; + backend->pathScreenExtents = (oc_vec4){ FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX }; + backend->pathUserExtents = (oc_vec4){ FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX }; + + if(primitive->cmd == OC_CMD_STROKE) + { + oc_mtl_render_stroke(backend, pathElements + primitive->path.startIndex, &primitive->path); + } + else + { + for(int eltIndex = 0; + (eltIndex < primitive->path.count) && (primitive->path.startIndex + eltIndex < eltCount); + eltIndex++) + { + oc_path_elt* elt = &pathElements[primitive->path.startIndex + eltIndex]; + + if(elt->type != OC_PATH_MOVE) + { + oc_vec2 p[4] = { currentPos, elt->p[0], elt->p[1], elt->p[2] }; + oc_mtl_canvas_encode_element(backend, elt->type, p); + } + switch(elt->type) + { + case OC_PATH_MOVE: + currentPos = elt->p[0]; + break; + + case OC_PATH_LINE: + currentPos = elt->p[0]; + break; + + case OC_PATH_QUADRATIC: + currentPos = elt->p[1]; + break; + + case OC_PATH_CUBIC: + currentPos = elt->p[2]; + break; + } + } + } + //NOTE: encode path + oc_mtl_encode_path(backend, primitive, scale); + } + } + + oc_mtl_render_batch(backend, + surface, + images, + tileSize, + nTilesX, + nTilesY, + viewportSize, + scale); + + @autoreleasepool + { + //NOTE: finalize + [surface->commandBuffer addCompletedHandler:^(id commandBuffer) { + oc_mtl_print_log(backend->bufferIndex, backend->logBuffer[backend->bufferIndex], backend->logOffsetBuffer[backend->bufferIndex]); + dispatch_semaphore_signal(backend->bufferSemaphore); + }]; + } +} + +void oc_mtl_canvas_destroy(oc_canvas_backend* interface) +{ + oc_mtl_canvas_backend* backend = (oc_mtl_canvas_backend*)interface; + + @autoreleasepool + { + [backend->pathPipeline release]; + [backend->segmentPipeline release]; + [backend->backpropPipeline release]; + [backend->mergePipeline release]; + [backend->rasterPipeline release]; + [backend->blitPipeline release]; + + for(int i = 0; i < OC_MTL_INPUT_BUFFERS_COUNT; i++) + { + [backend->pathBuffer[i] release]; + [backend->elementBuffer[i] release]; + [backend->logBuffer[i] release]; + [backend->logOffsetBuffer[i] release]; + } + [backend->segmentCountBuffer release]; + [backend->segmentBuffer release]; + [backend->tileQueueBuffer release]; + [backend->tileQueueCountBuffer release]; + [backend->tileOpBuffer release]; + [backend->tileOpCountBuffer release]; + [backend->screenTilesBuffer release]; + } + + free(backend); +} + +oc_image_data* oc_mtl_canvas_image_create(oc_canvas_backend* interface, oc_vec2 size) +{ + oc_mtl_image_data* image = 0; + oc_mtl_canvas_backend* backend = (oc_mtl_canvas_backend*)interface; + oc_mtl_surface* surface = backend->surface; + + @autoreleasepool + { + image = oc_malloc_type(oc_mtl_image_data); + if(image) + { + MTLTextureDescriptor* texDesc = [[MTLTextureDescriptor alloc] init]; + texDesc.textureType = MTLTextureType2D; + texDesc.storageMode = MTLStorageModeManaged; + texDesc.usage = MTLTextureUsageShaderRead; + texDesc.pixelFormat = MTLPixelFormatRGBA8Unorm; + texDesc.width = size.x; + texDesc.height = size.y; + + image->texture = [surface->device newTextureWithDescriptor:texDesc]; + if(image->texture != nil) + { + [image->texture retain]; + image->interface.size = size; + } + else + { + free(image); + image = 0; + } + } + } + return ((oc_image_data*)image); +} + +void oc_mtl_canvas_image_destroy(oc_canvas_backend* backendInterface, oc_image_data* imageInterface) +{ + oc_mtl_image_data* image = (oc_mtl_image_data*)imageInterface; + @autoreleasepool + { + [image->texture release]; + free(image); + } +} + +void oc_mtl_canvas_image_upload_region(oc_canvas_backend* backendInterface, oc_image_data* imageInterface, oc_rect region, u8* pixels) +{ + @autoreleasepool + { + oc_mtl_image_data* image = (oc_mtl_image_data*)imageInterface; + MTLRegion mtlRegion = MTLRegionMake2D(region.x, region.y, region.w, region.h); + [image->texture replaceRegion:mtlRegion + mipmapLevel:0 + withBytes:(void*)pixels + bytesPerRow:4 * region.w]; + } +} + +const u32 OC_MTL_DEFAULT_PATH_BUFFER_LEN = (4 << 10), + OC_MTL_DEFAULT_ELT_BUFFER_LEN = (4 << 10), + + OC_MTL_DEFAULT_SEGMENT_BUFFER_LEN = (4 << 10), + OC_MTL_DEFAULT_PATH_QUEUE_BUFFER_LEN = (4 << 10), + OC_MTL_DEFAULT_TILE_QUEUE_BUFFER_LEN = (4 << 10), + OC_MTL_DEFAULT_TILE_OP_BUFFER_LEN = (4 << 20); + +oc_canvas_backend* oc_mtl_canvas_backend_create(oc_mtl_surface* surface) +{ + oc_mtl_canvas_backend* backend = 0; + + backend = oc_malloc_type(oc_mtl_canvas_backend); + memset(backend, 0, sizeof(oc_mtl_canvas_backend)); + + backend->msaaCount = OC_MTL_MSAA_COUNT; + backend->surface = surface; + + //NOTE(martin): setup interface functions + backend->interface.destroy = oc_mtl_canvas_destroy; + backend->interface.render = oc_mtl_canvas_render; + backend->interface.imageCreate = oc_mtl_canvas_image_create; + backend->interface.imageDestroy = oc_mtl_canvas_image_destroy; + backend->interface.imageUploadRegion = oc_mtl_canvas_image_upload_region; + + @autoreleasepool + { + //NOTE: load metal library + oc_str8 shaderPath = oc_path_executable_relative(oc_scratch(), OC_STR8("mtl_renderer.metallib")); + NSString* metalFileName = [[NSString alloc] initWithBytes:shaderPath.ptr length:shaderPath.len encoding:NSUTF8StringEncoding]; + NSError* err = 0; + id library = [surface->device newLibraryWithFile:metalFileName error:&err]; + if(err != nil) + { + const char* errStr = [[err localizedDescription] UTF8String]; + oc_log_error("error : %s\n", errStr); + return (0); + } + id pathFunction = [library newFunctionWithName:@"mtl_path_setup"]; + id segmentFunction = [library newFunctionWithName:@"mtl_segment_setup"]; + id backpropFunction = [library newFunctionWithName:@"mtl_backprop"]; + id mergeFunction = [library newFunctionWithName:@"mtl_merge"]; + id rasterFunction = [library newFunctionWithName:@"mtl_raster"]; + id vertexFunction = [library newFunctionWithName:@"mtl_vertex_shader"]; + id fragmentFunction = [library newFunctionWithName:@"mtl_fragment_shader"]; + + //NOTE: create pipelines + NSError* error = NULL; + + backend->pathPipeline = [surface->device newComputePipelineStateWithFunction:pathFunction + error:&error]; + + backend->segmentPipeline = [surface->device newComputePipelineStateWithFunction:segmentFunction + error:&error]; + + backend->backpropPipeline = [surface->device newComputePipelineStateWithFunction:backpropFunction + error:&error]; + + backend->mergePipeline = [surface->device newComputePipelineStateWithFunction:mergeFunction + error:&error]; + + backend->rasterPipeline = [surface->device newComputePipelineStateWithFunction:rasterFunction + error:&error]; + + MTLRenderPipelineDescriptor* pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; + pipelineStateDescriptor.label = @"blit pipeline"; + pipelineStateDescriptor.vertexFunction = vertexFunction; + pipelineStateDescriptor.fragmentFunction = fragmentFunction; + pipelineStateDescriptor.colorAttachments[0].pixelFormat = surface->mtlLayer.pixelFormat; + pipelineStateDescriptor.colorAttachments[0].blendingEnabled = YES; + pipelineStateDescriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; + pipelineStateDescriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorOne; + pipelineStateDescriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha; + pipelineStateDescriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; + pipelineStateDescriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne; + pipelineStateDescriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha; + + backend->blitPipeline = [surface->device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor error:&err]; + + //NOTE: create textures + oc_vec2 size = surface->interface.getSize((oc_surface_data*)surface); + f32 scale = surface->mtlLayer.contentsScale; + + backend->frameSize = (oc_vec2){ size.x * scale, size.y * scale }; + + MTLTextureDescriptor* texDesc = [[MTLTextureDescriptor alloc] init]; + texDesc.textureType = MTLTextureType2D; + texDesc.storageMode = MTLStorageModePrivate; + texDesc.usage = MTLTextureUsageShaderRead | MTLTextureUsageShaderWrite | MTLTextureUsageRenderTarget; + texDesc.pixelFormat = MTLPixelFormatRGBA8Unorm; + texDesc.width = backend->frameSize.x; + texDesc.height = backend->frameSize.y; + + backend->outTexture = [surface->device newTextureWithDescriptor:texDesc]; + + //NOTE: create buffers + + backend->bufferSemaphore = dispatch_semaphore_create(OC_MTL_INPUT_BUFFERS_COUNT); + backend->bufferIndex = 0; + + MTLResourceOptions bufferOptions = MTLResourceCPUCacheModeWriteCombined + | MTLResourceStorageModeShared; + + for(int i = 0; i < OC_MTL_INPUT_BUFFERS_COUNT; i++) + { + backend->pathBuffer[i] = [surface->device newBufferWithLength:OC_MTL_DEFAULT_PATH_BUFFER_LEN * sizeof(oc_mtl_path) + options:bufferOptions]; + + backend->elementBuffer[i] = [surface->device newBufferWithLength:OC_MTL_DEFAULT_ELT_BUFFER_LEN * sizeof(oc_mtl_path_elt) + options:bufferOptions]; + } + + bufferOptions = MTLResourceStorageModePrivate; + backend->segmentBuffer = [surface->device newBufferWithLength:OC_MTL_DEFAULT_SEGMENT_BUFFER_LEN * sizeof(oc_mtl_segment) + options:bufferOptions]; + + backend->segmentCountBuffer = [surface->device newBufferWithLength:sizeof(int) + options:bufferOptions]; + + backend->pathQueueBuffer = [surface->device newBufferWithLength:OC_MTL_DEFAULT_PATH_QUEUE_BUFFER_LEN * sizeof(oc_mtl_path_queue) + options:bufferOptions]; + + backend->tileQueueBuffer = [surface->device newBufferWithLength:OC_MTL_DEFAULT_TILE_QUEUE_BUFFER_LEN * sizeof(oc_mtl_tile_queue) + options:bufferOptions]; + + backend->tileQueueCountBuffer = [surface->device newBufferWithLength:sizeof(int) + options:bufferOptions]; + + backend->tileOpBuffer = [surface->device newBufferWithLength:OC_MTL_DEFAULT_TILE_OP_BUFFER_LEN * sizeof(oc_mtl_tile_op) + options:bufferOptions]; + + backend->tileOpCountBuffer = [surface->device newBufferWithLength:sizeof(int) + options:bufferOptions]; + + backend->rasterDispatchBuffer = [surface->device newBufferWithLength:sizeof(MTLDispatchThreadgroupsIndirectArguments) + options:bufferOptions]; + + int tileSize = OC_MTL_TILE_SIZE; + int nTilesX = (int)(backend->frameSize.x + tileSize - 1) / tileSize; + int nTilesY = (int)(backend->frameSize.y + tileSize - 1) / tileSize; + backend->screenTilesBuffer = [surface->device newBufferWithLength:nTilesX * nTilesY * sizeof(oc_mtl_screen_tile) + options:bufferOptions]; + + bufferOptions = MTLResourceStorageModeShared; + for(int i = 0; i < OC_MTL_INPUT_BUFFERS_COUNT; i++) + { + backend->logBuffer[i] = [surface->device newBufferWithLength:1 << 20 + options:bufferOptions]; + + backend->logOffsetBuffer[i] = [surface->device newBufferWithLength:sizeof(int) + options:bufferOptions]; + } + } + return ((oc_canvas_backend*)backend); +} + +oc_surface_data* oc_mtl_canvas_surface_create_for_window(oc_window window) +{ + oc_mtl_surface* surface = (oc_mtl_surface*)oc_mtl_surface_create_for_window(window); + + if(surface) + { + surface->interface.backend = oc_mtl_canvas_backend_create(surface); + if(surface->interface.backend) + { + surface->interface.api = OC_CANVAS; + } + else + { + surface->interface.destroy((oc_surface_data*)surface); + surface = 0; + } + } + return ((oc_surface_data*)surface); +} diff --git a/src/graphics/mtl_renderer.metal b/src/graphics/mtl_renderer.metal index 9ec1e95..f043932 100644 --- a/src/graphics/mtl_renderer.metal +++ b/src/graphics/mtl_renderer.metal @@ -1,229 +1,227 @@ -#include -#include -#include +#include +#include +#include -#include"mtl_renderer.h" +#include "mtl_renderer.h" using namespace metal; - typedef struct mtl_log_context { - device char* buffer; - device volatile atomic_int* offset; - bool enabled; + device char* buffer; + device volatile atomic_int* offset; + bool enabled; } mtl_log_context; int strlen(const constant char* msg) { - int count = 0; - while(msg[count] != '\0') - { - count++; - } - return(count); + int count = 0; + while(msg[count] != '\0') + { + count++; + } + return (count); } int strlen(const thread char* msg) { - int count = 0; - while(msg[count] != '\0') - { - count++; - } - return(count); + int count = 0; + while(msg[count] != '\0') + { + count++; + } + return (count); } void mtl_log(mtl_log_context context, const constant char* msg) { - if(context.enabled) - { - int len = strlen(msg); - int offset = atomic_fetch_add_explicit(context.offset, len+1, memory_order_relaxed); + if(context.enabled) + { + int len = strlen(msg); + int offset = atomic_fetch_add_explicit(context.offset, len + 1, memory_order_relaxed); - for(int i=0; i= stop); + do + { + buffer[index] = '0' + (value % 10); + index--; + value /= 10; + } while(value != 0 && index >= stop); - if(zeroPad) - { - while(index >= stop) - { - buffer[index] = '0'; - index--; - } - } + if(zeroPad) + { + while(index >= stop) + { + buffer[index] = '0'; + index--; + } + } - if(minus) - { - buffer[index] = '-'; - index--; - } + if(minus) + { + buffer[index] = '-'; + index--; + } - int count = bufSize - (index+1); - return(count - 1); + int count = bufSize - (index + 1); + return (count - 1); } int mtl_itoa(int bufSize, thread char* buffer, int64_t value) { - int count = mtl_itoa_right_aligned(bufSize, buffer, value, false); - int start = bufSize - (count+1); + int count = mtl_itoa_right_aligned(bufSize, buffer, value, false); + int start = bufSize - (count + 1); - for(int i=0; i 0) - { - decimal /= 10; - width--; - } + int width = 6; + while(decimal % 10 == 0 && width > 0) + { + decimal /= 10; + width--; + } - int decSize = min(bufSize-index, width+1); - mtl_itoa_right_aligned(decSize, buffer+index, decimal, true); - } - buffer[bufSize-1] = '\0'; - mtl_log(context, buffer); + int decSize = min(bufSize - index, width + 1); + mtl_itoa_right_aligned(decSize, buffer + index, decimal, true); + } + buffer[bufSize - 1] = '\0'; + mtl_log(context, buffer); } void mtl_log_point(mtl_log_context context, float2 p) { - mtl_log(context, "("); - mtl_log_f32(context, p.x); - mtl_log(context, ", "); - mtl_log_f32(context, p.y); - mtl_log(context, ")"); + mtl_log(context, "("); + mtl_log_f32(context, p.x); + mtl_log(context, ", "); + mtl_log_f32(context, p.y); + mtl_log(context, ")"); } void log_line(thread float2* p, mtl_log_context logCtx) { - mtl_log(logCtx, "("); - mtl_log_f32(logCtx, p[0].x); - mtl_log(logCtx, ", "); - mtl_log_f32(logCtx, p[0].y); - mtl_log(logCtx, ") ("); - mtl_log_f32(logCtx, p[1].x); - mtl_log(logCtx, ", "); - mtl_log_f32(logCtx, p[1].y); - mtl_log(logCtx, ")\n"); + mtl_log(logCtx, "("); + mtl_log_f32(logCtx, p[0].x); + mtl_log(logCtx, ", "); + mtl_log_f32(logCtx, p[0].y); + mtl_log(logCtx, ") ("); + mtl_log_f32(logCtx, p[1].x); + mtl_log(logCtx, ", "); + mtl_log_f32(logCtx, p[1].y); + mtl_log(logCtx, ")\n"); } void log_quadratic_bezier(thread float2* p, mtl_log_context logCtx) { - mtl_log(logCtx, "("); - mtl_log_f32(logCtx, p[0].x); - mtl_log(logCtx, ", "); - mtl_log_f32(logCtx, p[0].y); - mtl_log(logCtx, ") ("); - mtl_log_f32(logCtx, p[1].x); - mtl_log(logCtx, ", "); - mtl_log_f32(logCtx, p[1].y); - mtl_log(logCtx, ") ("); - mtl_log_f32(logCtx, p[2].x); - mtl_log(logCtx, ", "); - mtl_log_f32(logCtx, p[2].y); - mtl_log(logCtx, ")\n"); + mtl_log(logCtx, "("); + mtl_log_f32(logCtx, p[0].x); + mtl_log(logCtx, ", "); + mtl_log_f32(logCtx, p[0].y); + mtl_log(logCtx, ") ("); + mtl_log_f32(logCtx, p[1].x); + mtl_log(logCtx, ", "); + mtl_log_f32(logCtx, p[1].y); + mtl_log(logCtx, ") ("); + mtl_log_f32(logCtx, p[2].x); + mtl_log(logCtx, ", "); + mtl_log_f32(logCtx, p[2].y); + mtl_log(logCtx, ")\n"); } - void log_cubic_bezier(thread float2* p, mtl_log_context logCtx) { - mtl_log(logCtx, "("); - mtl_log_f32(logCtx, p[0].x); - mtl_log(logCtx, ", "); - mtl_log_f32(logCtx, p[0].y); - mtl_log(logCtx, ") ("); - mtl_log_f32(logCtx, p[1].x); - mtl_log(logCtx, ", "); - mtl_log_f32(logCtx, p[1].y); - mtl_log(logCtx, ") ("); - mtl_log_f32(logCtx, p[2].x); - mtl_log(logCtx, ", "); - mtl_log_f32(logCtx, p[2].y); - mtl_log(logCtx, ") ("); - mtl_log_f32(logCtx, p[3].x); - mtl_log(logCtx, ", "); - mtl_log_f32(logCtx, p[3].y); - mtl_log(logCtx, ")\n"); + mtl_log(logCtx, "("); + mtl_log_f32(logCtx, p[0].x); + mtl_log(logCtx, ", "); + mtl_log_f32(logCtx, p[0].y); + mtl_log(logCtx, ") ("); + mtl_log_f32(logCtx, p[1].x); + mtl_log(logCtx, ", "); + mtl_log_f32(logCtx, p[1].y); + mtl_log(logCtx, ") ("); + mtl_log_f32(logCtx, p[2].x); + mtl_log(logCtx, ", "); + mtl_log_f32(logCtx, p[2].y); + mtl_log(logCtx, ") ("); + mtl_log_f32(logCtx, p[3].x); + mtl_log(logCtx, ", "); + mtl_log_f32(logCtx, p[3].y); + mtl_log(logCtx, ")\n"); } kernel void mtl_path_setup(constant int* pathCount [[buffer(0)]], @@ -236,468 +234,468 @@ kernel void mtl_path_setup(constant int* pathCount [[buffer(0)]], constant float* scale [[buffer(7)]], uint pathIndex [[thread_position_in_grid]]) { - const device oc_mtl_path* path = &pathBuffer[pathIndex]; + const device oc_mtl_path* path = &pathBuffer[pathIndex]; + //NOTE: we don't clip on the right, since we need those tiles to accurately compute + // the prefix sum of winding increments in the backprop pass. + float4 clippedBox = { max(path->box.x, path->clip.x), + max(path->box.y, path->clip.y), + path->box.z, + min(path->box.w, path->clip.w) }; - //NOTE: we don't clip on the right, since we need those tiles to accurately compute - // the prefix sum of winding increments in the backprop pass. - float4 clippedBox = {max(path->box.x, path->clip.x), - max(path->box.y, path->clip.y), - path->box.z, - min(path->box.w, path->clip.w)}; + int2 firstTile = int2(clippedBox.xy * scale[0]) / tileSize[0]; + int2 lastTile = int2(clippedBox.zw * scale[0]) / tileSize[0]; - int2 firstTile = int2(clippedBox.xy*scale[0])/tileSize[0]; - int2 lastTile = int2(clippedBox.zw*scale[0])/tileSize[0]; + int nTilesX = max(0, lastTile.x - firstTile.x + 1); + int nTilesY = max(0, lastTile.y - firstTile.y + 1); + int tileCount = nTilesX * nTilesY; - int nTilesX = max(0, lastTile.x - firstTile.x + 1); - int nTilesY = max(0, lastTile.y - firstTile.y + 1); - int tileCount = nTilesX * nTilesY; + int tileQueuesIndex = atomic_fetch_add_explicit(tileQueueCount, tileCount, memory_order_relaxed); - int tileQueuesIndex = atomic_fetch_add_explicit(tileQueueCount, tileCount, memory_order_relaxed); + if(tileQueuesIndex + tileCount >= tileQueueMax[0]) + { + pathQueueBuffer[pathIndex].area = int4(0); + pathQueueBuffer[pathIndex].tileQueues = 0; + } + else + { + pathQueueBuffer[pathIndex].area = int4(firstTile.x, firstTile.y, nTilesX, nTilesY); + pathQueueBuffer[pathIndex].tileQueues = tileQueuesIndex; - if(tileQueuesIndex + tileCount >= tileQueueMax[0]) - { - pathQueueBuffer[pathIndex].area = int4(0); - pathQueueBuffer[pathIndex].tileQueues = 0; - } - else - { - pathQueueBuffer[pathIndex].area = int4(firstTile.x, firstTile.y, nTilesX, nTilesY); - pathQueueBuffer[pathIndex].tileQueues = tileQueuesIndex; + device oc_mtl_tile_queue* tileQueues = &tileQueueBuffer[tileQueuesIndex]; - device oc_mtl_tile_queue* tileQueues = &tileQueueBuffer[tileQueuesIndex]; - - for(int i=0; i seg->box.w || p.y <= seg->box.y) - { - if(p.x > seg->box.x && p.x <= seg->box.z) - { - if(p.y > seg->box.w) - { - side = (seg->config == OC_MTL_TL || seg->config == OC_MTL_BR)? -1 : 1; - } - else - { - side = (seg->config == OC_MTL_TL || seg->config == OC_MTL_BR)? 1 : -1; - } - } - } - else if(p.x > seg->box.z) - { - side = 1; - } - else if(p.x <= seg->box.x) - { - side = -1; - } - else - { - float2 a, b, c; - switch(seg->config) - { - case OC_MTL_TL: - a = seg->box.xy; - b = seg->box.zw; - break; + int side = 0; + if(p.y > seg->box.w || p.y <= seg->box.y) + { + if(p.x > seg->box.x && p.x <= seg->box.z) + { + if(p.y > seg->box.w) + { + side = (seg->config == OC_MTL_TL || seg->config == OC_MTL_BR) ? -1 : 1; + } + else + { + side = (seg->config == OC_MTL_TL || seg->config == OC_MTL_BR) ? 1 : -1; + } + } + } + else if(p.x > seg->box.z) + { + side = 1; + } + else if(p.x <= seg->box.x) + { + side = -1; + } + else + { + float2 a, b, c; + switch(seg->config) + { + case OC_MTL_TL: + a = seg->box.xy; + b = seg->box.zw; + break; - case OC_MTL_BR: - a = seg->box.zw; - b = seg->box.xy; - break; + case OC_MTL_BR: + a = seg->box.zw; + b = seg->box.xy; + break; - case OC_MTL_TR: - a = seg->box.xw; - b = seg->box.zy; - break; + case OC_MTL_TR: + a = seg->box.xw; + b = seg->box.zy; + break; - case OC_MTL_BL: - a = seg->box.zy; - b = seg->box.xw; - break; - } - c = seg->hullVertex; + case OC_MTL_BL: + a = seg->box.zy; + b = seg->box.xw; + break; + } + c = seg->hullVertex; - if(ccw(a, b, p) < 0) - { - // other side of the diagonal - side = (seg->config == OC_MTL_BR || seg->config == OC_MTL_TR) ? -1 : 1; - } - else if(ccw(b, c, p) < 0 || ccw(c, a, p) < 0) - { - // same side of the diagonal, but outside curve hull - side = (seg->config == OC_MTL_BL || seg->config == OC_MTL_TL) ? -1 : 1; - } - else - { - // inside curve hull - switch(seg->kind) - { - case OC_MTL_LINE: - side = 1; - break; + if(ccw(a, b, p) < 0) + { + // other side of the diagonal + side = (seg->config == OC_MTL_BR || seg->config == OC_MTL_TR) ? -1 : 1; + } + else if(ccw(b, c, p) < 0 || ccw(c, a, p) < 0) + { + // same side of the diagonal, but outside curve hull + side = (seg->config == OC_MTL_BL || seg->config == OC_MTL_TL) ? -1 : 1; + } + else + { + // inside curve hull + switch(seg->kind) + { + case OC_MTL_LINE: + side = 1; + break; - case OC_MTL_QUADRATIC: - { - float3 ph = {p.x, p.y, 1}; - float3 klm = seg->implicitMatrix * ph; - side = ((klm.x*klm.x - klm.y)*klm.z < 0)? -1 : 1; - } break; + case OC_MTL_QUADRATIC: + { + float3 ph = { p.x, p.y, 1 }; + float3 klm = seg->implicitMatrix * ph; + side = ((klm.x * klm.x - klm.y) * klm.z < 0) ? -1 : 1; + } + break; - case OC_MTL_CUBIC: - { - float3 ph = {p.x, p.y, 1}; - float3 klm = seg->implicitMatrix * ph; - side = (seg->sign*(klm.x*klm.x*klm.x - klm.y*klm.z) < 0)? -1 : 1; - } break; - } - } - } - return(side); + case OC_MTL_CUBIC: + { + float3 ph = { p.x, p.y, 1 }; + float3 klm = seg->implicitMatrix * ph; + side = (seg->sign * (klm.x * klm.x * klm.x - klm.y * klm.z) < 0) ? -1 : 1; + } + break; + } + } + } + return (side); } - typedef struct mtl_segment_setup_context { - device atomic_int* segmentCount; - device oc_mtl_segment* segmentBuffer; - const device oc_mtl_path_queue* pathQueue; - device oc_mtl_tile_queue* tileQueues; - device oc_mtl_tile_op* tileOpBuffer; - device atomic_int* tileOpCount; - int tileSize; - mtl_log_context log; + device atomic_int* segmentCount; + device oc_mtl_segment* segmentBuffer; + const device oc_mtl_path_queue* pathQueue; + device oc_mtl_tile_queue* tileQueues; + device oc_mtl_tile_op* tileOpBuffer; + device atomic_int* tileOpCount; + int tileSize; + mtl_log_context log; - int pathIndex; + int pathIndex; - int tileOpMax; - int segmentMax; + int tileOpMax; + int segmentMax; } mtl_segment_setup_context; void mtl_segment_bin_to_tiles(thread mtl_segment_setup_context* context, device oc_mtl_segment* seg) { - //NOTE: add segment index to the queues of tiles it overlaps with - int segIndex = seg - context->segmentBuffer; + //NOTE: add segment index to the queues of tiles it overlaps with + int segIndex = seg - context->segmentBuffer; - int tileSize = context->tileSize; - int4 pathArea = context->pathQueue->area; - int4 coveredTiles = int4(seg->box)/tileSize; - int xMin = max(0, coveredTiles.x - pathArea.x); - int yMin = max(0, coveredTiles.y - pathArea.y); - int xMax = min(coveredTiles.z - pathArea.x, pathArea.z-1); - int yMax = min(coveredTiles.w - pathArea.y, pathArea.w-1); + int tileSize = context->tileSize; + int4 pathArea = context->pathQueue->area; + int4 coveredTiles = int4(seg->box) / tileSize; + int xMin = max(0, coveredTiles.x - pathArea.x); + int yMin = max(0, coveredTiles.y - pathArea.y); + int xMax = min(coveredTiles.z - pathArea.x, pathArea.z - 1); + int yMax = min(coveredTiles.w - pathArea.y, pathArea.w - 1); - for(int y = yMin; y <= yMax; y++) - { - for(int x = xMin ; x <= xMax; x++) - { - float4 tileBox = (float4){float(x + pathArea.x), - float(y + pathArea.y), - float(x + pathArea.x + 1), - float(y + pathArea.y + 1)} * float(tileSize); + for(int y = yMin; y <= yMax; y++) + { + for(int x = xMin; x <= xMax; x++) + { + float4 tileBox = (float4){ float(x + pathArea.x), + float(y + pathArea.y), + float(x + pathArea.x + 1), + float(y + pathArea.y + 1) } + * float(tileSize); - float2 bl = {tileBox.x, tileBox.y}; - float2 br = {tileBox.z, tileBox.y}; - float2 tr = {tileBox.z, tileBox.w}; - float2 tl = {tileBox.x, tileBox.w}; + float2 bl = { tileBox.x, tileBox.y }; + float2 br = { tileBox.z, tileBox.y }; + float2 tr = { tileBox.z, tileBox.w }; + float2 tl = { tileBox.x, tileBox.w }; - int sbl = mtl_side_of_segment(bl, seg, context->log); - int sbr = mtl_side_of_segment(br, seg, context->log); - int str = mtl_side_of_segment(tr, seg, context->log); - int stl = mtl_side_of_segment(tl, seg, context->log); + int sbl = mtl_side_of_segment(bl, seg, context->log); + int sbr = mtl_side_of_segment(br, seg, context->log); + int str = mtl_side_of_segment(tr, seg, context->log); + int stl = mtl_side_of_segment(tl, seg, context->log); - bool crossL = (stl*sbl < 0); - bool crossR = (str*sbr < 0); - bool crossT = (stl*str < 0); - bool crossB = (sbl*sbr < 0); + bool crossL = (stl * sbl < 0); + bool crossR = (str * sbr < 0); + bool crossT = (stl * str < 0); + bool crossB = (sbl * sbr < 0); - float2 s0, s1; - if(seg->config == OC_MTL_TL||seg->config == OC_MTL_BR) - { - s0 = seg->box.xy; - s1 = seg->box.zw; - } - else - { - s0 = seg->box.xw; - s1 = seg->box.zy; - } - bool s0Inside = s0.x >= tileBox.x - && s0.x < tileBox.z - && s0.y >= tileBox.y - && s0.y < tileBox.w; + float2 s0, s1; + if(seg->config == OC_MTL_TL || seg->config == OC_MTL_BR) + { + s0 = seg->box.xy; + s1 = seg->box.zw; + } + else + { + s0 = seg->box.xw; + s1 = seg->box.zy; + } + bool s0Inside = s0.x >= tileBox.x + && s0.x < tileBox.z + && s0.y >= tileBox.y + && s0.y < tileBox.w; - bool s1Inside = s1.x >= tileBox.x - && s1.x < tileBox.z - && s1.y >= tileBox.y - && s1.y < tileBox.w; + bool s1Inside = s1.x >= tileBox.x + && s1.x < tileBox.z + && s1.y >= tileBox.y + && s1.y < tileBox.w; - if(crossL || crossR || crossT || crossB || s0Inside || s1Inside) - { - int tileOpIndex = atomic_fetch_add_explicit(context->tileOpCount, 1, memory_order_relaxed); + if(crossL || crossR || crossT || crossB || s0Inside || s1Inside) + { + int tileOpIndex = atomic_fetch_add_explicit(context->tileOpCount, 1, memory_order_relaxed); - if(tileOpIndex < context->tileOpMax) - { - device oc_mtl_tile_op* op = &context->tileOpBuffer[tileOpIndex]; + if(tileOpIndex < context->tileOpMax) + { + device oc_mtl_tile_op* op = &context->tileOpBuffer[tileOpIndex]; - op->kind = OC_MTL_OP_SEGMENT; - op->index = segIndex; - op->crossRight = false; - op->next = -1; + op->kind = OC_MTL_OP_SEGMENT; + op->index = segIndex; + op->crossRight = false; + op->next = -1; - int tileIndex = y*pathArea.z + x; - device oc_mtl_tile_queue* tile = &context->tileQueues[tileIndex]; - op->next = atomic_exchange_explicit(&tile->first, tileOpIndex, memory_order_relaxed); - if(op->next == -1) - { - tile->last = tileOpIndex; - } + int tileIndex = y * pathArea.z + x; + device oc_mtl_tile_queue* tile = &context->tileQueues[tileIndex]; + op->next = atomic_exchange_explicit(&tile->first, tileOpIndex, memory_order_relaxed); + if(op->next == -1) + { + tile->last = tileOpIndex; + } - //NOTE: if the segment crosses the tile's bottom boundary, update the tile's winding offset - if(crossB) - { - mtl_log(context->log, "cross bottom boundary, increment "); - mtl_log_f32(context->log, seg->windingIncrement); - mtl_log(context->log, "\n"); - atomic_fetch_add_explicit(&tile->windingOffset, seg->windingIncrement, memory_order_relaxed); - } + //NOTE: if the segment crosses the tile's bottom boundary, update the tile's winding offset + if(crossB) + { + mtl_log(context->log, "cross bottom boundary, increment "); + mtl_log_f32(context->log, seg->windingIncrement); + mtl_log(context->log, "\n"); + atomic_fetch_add_explicit(&tile->windingOffset, seg->windingIncrement, memory_order_relaxed); + } - //NOTE: if the segment crosses the right boundary, mark it. We reuse one of the previous tests - if(crossR) - { - op->crossRight = true; - } - } - } - } - } + //NOTE: if the segment crosses the right boundary, mark it. We reuse one of the previous tests + if(crossR) + { + op->crossRight = true; + } + } + } + } + } } device oc_mtl_segment* mtl_segment_push(thread mtl_segment_setup_context* context, float2 p[4], oc_mtl_seg_kind kind) { - float2 s, e, c; + float2 s, e, c; - switch(kind) - { - case OC_MTL_LINE: - s = p[0]; - c = p[0]; - e = p[1]; - break; + switch(kind) + { + case OC_MTL_LINE: + s = p[0]; + c = p[0]; + e = p[1]; + break; - case OC_MTL_QUADRATIC: - s = p[0]; - c = p[1]; - e = p[2]; - break; + case OC_MTL_QUADRATIC: + s = p[0]; + c = p[1]; + e = p[2]; + break; - case OC_MTL_CUBIC: - { - s = p[0]; - float sqrNorm0 = length_squared(p[1]-p[0]); - float sqrNorm1 = length_squared(p[3]-p[2]); - if(sqrNorm0 < sqrNorm1) - { - c = p[2]; - } - else - { - c = p[1]; - } - e = p[3]; - } break; - } + case OC_MTL_CUBIC: + { + s = p[0]; + float sqrNorm0 = length_squared(p[1] - p[0]); + float sqrNorm1 = length_squared(p[3] - p[2]); + if(sqrNorm0 < sqrNorm1) + { + c = p[2]; + } + else + { + c = p[1]; + } + e = p[3]; + } + break; + } - device oc_mtl_segment* seg = 0; + device oc_mtl_segment* seg = 0; - int segIndex = atomic_fetch_add_explicit(context->segmentCount, 1, memory_order_relaxed); + int segIndex = atomic_fetch_add_explicit(context->segmentCount, 1, memory_order_relaxed); - if(segIndex < context->segmentMax) - { - seg = &context->segmentBuffer[segIndex]; + if(segIndex < context->segmentMax) + { + seg = &context->segmentBuffer[segIndex]; - bool goingUp = e.y >= s.y; - bool goingRight = e.x >= s.x; + bool goingUp = e.y >= s.y; + bool goingRight = e.x >= s.x; - seg->kind = kind; - seg->pathIndex = context->pathIndex; - seg->windingIncrement = goingUp? 1 : -1; + seg->kind = kind; + seg->pathIndex = context->pathIndex; + seg->windingIncrement = goingUp ? 1 : -1; - seg->box = (vector_float4){min(s.x, e.x), - min(s.y, e.y), - max(s.x, e.x), - max(s.y, e.y)}; + seg->box = (vector_float4){ min(s.x, e.x), + min(s.y, e.y), + max(s.x, e.x), + max(s.y, e.y) }; - float dx = c.x - seg->box.x; - float dy = c.y - seg->box.y; - float alpha = (seg->box.w - seg->box.y)/(seg->box.z - seg->box.x); - float ofs = seg->box.w - seg->box.y; + float dx = c.x - seg->box.x; + float dy = c.y - seg->box.y; + float alpha = (seg->box.w - seg->box.y) / (seg->box.z - seg->box.x); + float ofs = seg->box.w - seg->box.y; - if(goingUp == goingRight) - { - if(seg->kind == OC_MTL_LINE) - { - seg->config = OC_MTL_BR; - } - else if(dy > alpha*dx) - { - seg->config = OC_MTL_TL; - } - else - { - seg->config = OC_MTL_BR; - } - } - else - { - if(seg->kind == OC_MTL_LINE) - { - seg->config = OC_MTL_TR; - } - else if(dy < ofs - alpha*dx) - { - seg->config = OC_MTL_BL; - } - else - { - seg->config = OC_MTL_TR; - } - } - } - return(seg); + if(goingUp == goingRight) + { + if(seg->kind == OC_MTL_LINE) + { + seg->config = OC_MTL_BR; + } + else if(dy > alpha * dx) + { + seg->config = OC_MTL_TL; + } + else + { + seg->config = OC_MTL_BR; + } + } + else + { + if(seg->kind == OC_MTL_LINE) + { + seg->config = OC_MTL_TR; + } + else if(dy < ofs - alpha * dx) + { + seg->config = OC_MTL_BL; + } + else + { + seg->config = OC_MTL_TR; + } + } + } + return (seg); } -#define square(x) ((x)*(x)) -#define cube(x) ((x)*(x)*(x)) +#define square(x) ((x) * (x)) +#define cube(x) ((x) * (x) * (x)) void mtl_line_setup(thread mtl_segment_setup_context* context, float2 p[2]) { - device oc_mtl_segment* seg = mtl_segment_push(context, p, OC_MTL_LINE); - if(seg) - { - seg->hullVertex = p[0]; - mtl_segment_bin_to_tiles(context, seg); - } + device oc_mtl_segment* seg = mtl_segment_push(context, p, OC_MTL_LINE); + if(seg) + { + seg->hullVertex = p[0]; + mtl_segment_bin_to_tiles(context, seg); + } } float2 mtl_quadratic_blossom(float2 p[3], float u, float v) { - float2 b10 = u*p[1] + (1-u)*p[0]; - float2 b11 = u*p[2] + (1-u)*p[1]; - float2 b20 = v*b11 + (1-v)*b10; - return(b20); + float2 b10 = u * p[1] + (1 - u) * p[0]; + float2 b11 = u * p[2] + (1 - u) * p[1]; + float2 b20 = v * b11 + (1 - v) * b10; + return (b20); } void mtl_quadratic_slice(float2 p[3], float s0, float s1, float2 sp[3]) { - /*NOTE: using blossoms to compute sub-curve control points ensure that the fourth point + /*NOTE: using blossoms to compute sub-curve control points ensure that the fourth point of sub-curve (s0, s1) and the first point of sub-curve (s1, s3) match. However, due to numerical errors, the evaluation of B(s=0) might not be equal to p[0] (and likewise, B(s=1) might not equal p[3]). We handle that case explicitly to ensure that we don't create gaps in the paths. */ - sp[0] = (s0 == 0) ? p[0] : mtl_quadratic_blossom(p, s0, s0); - sp[1] = mtl_quadratic_blossom(p, s0, s1); - sp[2] = (s1 == 1) ? p[2] : mtl_quadratic_blossom(p, s1, s1); + sp[0] = (s0 == 0) ? p[0] : mtl_quadratic_blossom(p, s0, s0); + sp[1] = mtl_quadratic_blossom(p, s0, s1); + sp[2] = (s1 == 1) ? p[2] : mtl_quadratic_blossom(p, s1, s1); } int mtl_quadratic_monotonize(float2 p[3], float splits[4]) { - //NOTE: compute split points - int count = 0; - splits[0] = 0; - count++; + //NOTE: compute split points + int count = 0; + splits[0] = 0; + count++; - float2 r = (p[0] - p[1])/(p[2] - 2*p[1] + p[0]); - if(r.x > r.y) - { - float tmp = r.x; - r.x = r.y; - r.y = tmp; - } - if(r.x > 0 && r.x < 1) - { - splits[count] = r.x; - count++; - } - if(r.y > 0 && r.y < 1) - { - splits[count] = r.y; - count++; - } - splits[count] = 1; - count++; - return(count); + float2 r = (p[0] - p[1]) / (p[2] - 2 * p[1] + p[0]); + if(r.x > r.y) + { + float tmp = r.x; + r.x = r.y; + r.y = tmp; + } + if(r.x > 0 && r.x < 1) + { + splits[count] = r.x; + count++; + } + if(r.y > 0 && r.y < 1) + { + splits[count] = r.y; + count++; + } + splits[count] = 1; + count++; + return (count); } matrix_float3x3 mtl_barycentric_matrix(float2 v0, float2 v1, float2 v2) { - float det = v0.x*(v1.y-v2.y) + v1.x*(v2.y-v0.y) + v2.x*(v0.y - v1.y); - matrix_float3x3 B = {{v1.y - v2.y, v2.y-v0.y, v0.y-v1.y}, - {v2.x - v1.x, v0.x-v2.x, v1.x-v0.x}, - {v1.x*v2.y-v2.x*v1.y, v2.x*v0.y-v0.x*v2.y, v0.x*v1.y-v1.x*v0.y}}; - B *= (1/det); - return(B); + float det = v0.x * (v1.y - v2.y) + v1.x * (v2.y - v0.y) + v2.x * (v0.y - v1.y); + matrix_float3x3 B = { { v1.y - v2.y, v2.y - v0.y, v0.y - v1.y }, + { v2.x - v1.x, v0.x - v2.x, v1.x - v0.x }, + { v1.x * v2.y - v2.x * v1.y, v2.x * v0.y - v0.x * v2.y, v0.x * v1.y - v1.x * v0.y } }; + B *= (1 / det); + return (B); } void mtl_quadratic_emit(thread mtl_segment_setup_context* context, thread float2* p) { - device oc_mtl_segment* seg = mtl_segment_push(context, p, OC_MTL_QUADRATIC); + device oc_mtl_segment* seg = mtl_segment_push(context, p, OC_MTL_QUADRATIC); - if(seg) - { - //NOTE: compute implicit equation matrix - float det = p[0].x*(p[1].y-p[2].y) + p[1].x*(p[2].y-p[0].y) + p[2].x*(p[0].y - p[1].y); + if(seg) + { + //NOTE: compute implicit equation matrix + float det = p[0].x * (p[1].y - p[2].y) + p[1].x * (p[2].y - p[0].y) + p[2].x * (p[0].y - p[1].y); - float a = p[0].y - p[1].y + 0.5*(p[2].y - p[0].y); - float b = p[1].x - p[0].x + 0.5*(p[0].x - p[2].x); - float c = p[0].x*p[1].y - p[1].x*p[0].y + 0.5*(p[2].x*p[0].y - p[0].x*p[2].y); - float d = p[0].y - p[1].y; - float e = p[1].x - p[0].x; - float f = p[0].x*p[1].y - p[1].x*p[0].y; + float a = p[0].y - p[1].y + 0.5 * (p[2].y - p[0].y); + float b = p[1].x - p[0].x + 0.5 * (p[0].x - p[2].x); + float c = p[0].x * p[1].y - p[1].x * p[0].y + 0.5 * (p[2].x * p[0].y - p[0].x * p[2].y); + float d = p[0].y - p[1].y; + float e = p[1].x - p[0].x; + float f = p[0].x * p[1].y - p[1].x * p[0].y; - float flip = (seg->config == OC_MTL_TL || seg->config == OC_MTL_BL)? -1 : 1; - float g = flip*(p[2].x*(p[0].y - p[1].y) + p[0].x*(p[1].y - p[2].y) + p[1].x*(p[2].y - p[0].y)); + float flip = (seg->config == OC_MTL_TL || seg->config == OC_MTL_BL) ? -1 : 1; + float g = flip * (p[2].x * (p[0].y - p[1].y) + p[0].x * (p[1].y - p[2].y) + p[1].x * (p[2].y - p[0].y)); - seg->implicitMatrix = (1/det)*matrix_float3x3({a, d, 0.}, - {b, e, 0.}, - {c, f, g}); + seg->implicitMatrix = (1 / det) * matrix_float3x3({ a, d, 0. }, { b, e, 0. }, { c, f, g }); - seg->hullVertex = p[1]; + seg->hullVertex = p[1]; - mtl_segment_bin_to_tiles(context, seg); - } + mtl_segment_bin_to_tiles(context, seg); + } } void mtl_quadratic_setup(thread mtl_segment_setup_context* context, thread float2* p) { - float splits[4]; - int splitCount = mtl_quadratic_monotonize(p, splits); + float splits[4]; + int splitCount = mtl_quadratic_monotonize(p, splits); - //NOTE: produce bézier curve for each consecutive pair of roots - for(int sliceIndex=0; sliceIndex= 0) - { - count = (det == 0) ? 1 : 2; + if(det >= 0) + { + count = (det == 0) ? 1 : 2; - if(b > 0) - { - float q = b + sqrt(det); - r[0] = -c/q; - r[1] = -q/a; - } - else if(b < 0) - { - float q = -b + sqrt(det); - r[0] = q/a; - r[1] = c/q; - } - else - { - float q = sqrt(-a*c); - if(fabs(a) >= fabs(c)) - { - r[0] = q/a; - r[1] = -q/a; - } - else - { - r[0] = -c/q; - r[1] = c/q; - } - } - } - } - if(count>1 && r[0] > r[1]) - { - float tmp = r[0]; - r[0] = r[1]; - r[1] = tmp; - } - return(count); + if(b > 0) + { + float q = b + sqrt(det); + r[0] = -c / q; + r[1] = -q / a; + } + else if(b < 0) + { + float q = -b + sqrt(det); + r[0] = q / a; + r[1] = c / q; + } + else + { + float q = sqrt(-a * c); + if(fabs(a) >= fabs(c)) + { + r[0] = q / a; + r[1] = -q / a; + } + else + { + r[0] = -c / q; + r[1] = c / q; + } + } + } + } + if(count > 1 && r[0] > r[1]) + { + float tmp = r[0]; + r[0] = r[1]; + r[1] = tmp; + } + return (count); } -int mtl_quadratic_roots(float a, float b, float c, thread float* r, mtl_log_context log = {.enabled = false}) +int mtl_quadratic_roots(float a, float b, float c, thread float* r, mtl_log_context log = { .enabled = false }) { - //float det = diff_of_products(b, b, a, c); - float det = square(b)/4. - a*c; - return(mtl_quadratic_roots_with_det(a, b, c, det, r, log)); + //float det = diff_of_products(b, b, a, c); + float det = square(b) / 4. - a * c; + return (mtl_quadratic_roots_with_det(a, b, c, det, r, log)); } float2 mtl_cubic_blossom(float2 p[4], float u, float v, float w) { - float2 b10 = u*p[1] + (1-u)*p[0]; - float2 b11 = u*p[2] + (1-u)*p[1]; - float2 b12 = u*p[3] + (1-u)*p[2]; - float2 b20 = v*b11 + (1-v)*b10; - float2 b21 = v*b12 + (1-v)*b11; - float2 b30 = w*b21 + (1-w)*b20; - return(b30); + float2 b10 = u * p[1] + (1 - u) * p[0]; + float2 b11 = u * p[2] + (1 - u) * p[1]; + float2 b12 = u * p[3] + (1 - u) * p[2]; + float2 b20 = v * b11 + (1 - v) * b10; + float2 b21 = v * b12 + (1 - v) * b11; + float2 b30 = w * b21 + (1 - w) * b20; + return (b30); } void mtl_cubic_slice(float2 p[4], float s0, float s1, float2 sp[4]) { - /*NOTE: using blossoms to compute sub-curve control points ensure that the fourth point + /*NOTE: using blossoms to compute sub-curve control points ensure that the fourth point of sub-curve (s0, s1) and the first point of sub-curve (s1, s3) match. However, due to numerical errors, the evaluation of B(s=0) might not be equal to p[0] (and likewise, B(s=1) might not equal p[3]). We handle that case explicitly to ensure that we don't create gaps in the paths. */ - sp[0] = (s0 == 0) ? p[0] : mtl_cubic_blossom(p, s0, s0, s0); - sp[1] = mtl_cubic_blossom(p, s0, s0, s1); - sp[2] = mtl_cubic_blossom(p, s0, s1, s1); - sp[3] = (s1 == 1) ? p[3] : mtl_cubic_blossom(p, s1, s1, s1); + sp[0] = (s0 == 0) ? p[0] : mtl_cubic_blossom(p, s0, s0, s0); + sp[1] = mtl_cubic_blossom(p, s0, s0, s1); + sp[2] = mtl_cubic_blossom(p, s0, s1, s1); + sp[3] = (s1 == 1) ? p[3] : mtl_cubic_blossom(p, s1, s1, s1); } -typedef enum { - MTL_CUBIC_ERROR, - MTL_CUBIC_SERPENTINE, - MTL_CUBIC_CUSP, - MTL_CUBIC_CUSP_INFINITY, - MTL_CUBIC_LOOP, - MTL_CUBIC_DEGENERATE_QUADRATIC, - MTL_CUBIC_DEGENERATE_LINE, +typedef enum +{ + MTL_CUBIC_ERROR, + MTL_CUBIC_SERPENTINE, + MTL_CUBIC_CUSP, + MTL_CUBIC_CUSP_INFINITY, + MTL_CUBIC_LOOP, + MTL_CUBIC_DEGENERATE_QUADRATIC, + MTL_CUBIC_DEGENERATE_LINE, } mtl_cubic_kind; typedef struct mtl_cubic_info { - mtl_cubic_kind kind; - matrix_float4x4 K; - float2 ts[2]; - float d1; - float d2; - float d3; + mtl_cubic_kind kind; + matrix_float4x4 K; + float2 ts[2]; + float d1; + float d2; + float d3; } mtl_cubic_info; -mtl_cubic_info mtl_cubic_classify(thread float2* c, mtl_log_context log = {.enabled = false}) +mtl_cubic_info mtl_cubic_classify(thread float2* c, mtl_log_context log = { .enabled = false }) { - mtl_cubic_info result = {MTL_CUBIC_ERROR}; - matrix_float4x4 F; + mtl_cubic_info result = { MTL_CUBIC_ERROR }; + matrix_float4x4 F; - /*NOTE(martin): + /*NOTE(martin): now, compute determinants d0, d1, d2, d3, which gives the coefficients of the inflection points polynomial: @@ -854,57 +853,57 @@ mtl_cubic_info mtl_cubic_classify(thread float2* c, mtl_log_context log = {.enab // this may very well be an error on my part that's cancelled by flipping the signs of the d_i though! */ - float d1 = -(c[3].y*c[2].x - c[3].x*c[2].y); - float d2 = -(c[3].x*c[1].y - c[3].y*c[1].x); - float d3 = -(c[2].y*c[1].x - c[2].x*c[1].y); + float d1 = -(c[3].y * c[2].x - c[3].x * c[2].y); + float d2 = -(c[3].x * c[1].y - c[3].y * c[1].x); + float d3 = -(c[2].y * c[1].x - c[2].x * c[1].y); - result.d1 = d1; - result.d2 = d2; - result.d3 = d3; + result.d1 = d1; + result.d2 = d2; + result.d3 = d3; -// mtl_log(log, "d1 = "); -/* mtl_log_f32(log, d1); + // mtl_log(log, "d1 = "); + /* mtl_log_f32(log, d1); mtl_log(log, ", d2 = "); mtl_log_f32(log, d2); mtl_log(log, ", d3 = "); mtl_log_f32(log, d3); mtl_log(log, "\n"); */ - //NOTE(martin): compute the second factor of the discriminant discr(I) = d1^2*(3*d2^2 - 4*d3*d1) - float discrFactor2 = 3.0*square(d2) - 4.0*d3*d1; + //NOTE(martin): compute the second factor of the discriminant discr(I) = d1^2*(3*d2^2 - 4*d3*d1) + float discrFactor2 = 3.0 * square(d2) - 4.0 * d3 * d1; - //NOTE(martin): each following case gives the number of roots, hence the category of the parametric curve - if(fabs(d1) <= 1e-6 && fabs(d2) <= 1e-6 && fabs(d3) > 1e-6) - { - //NOTE(martin): quadratic degenerate case - //NOTE(martin): compute quadratic curve control point, which is at p0 + 1.5*(p1-p0) = 1.5*p1 - 0.5*p0 - result.kind = MTL_CUBIC_DEGENERATE_QUADRATIC; - } - else if( (discrFactor2 > 0 && fabs(d1) > 1e-6) - ||(discrFactor2 == 0 && fabs(d1) > 1e-6)) - { - //mtl_log(log, "cusp or serpentine\n"); + //NOTE(martin): each following case gives the number of roots, hence the category of the parametric curve + if(fabs(d1) <= 1e-6 && fabs(d2) <= 1e-6 && fabs(d3) > 1e-6) + { + //NOTE(martin): quadratic degenerate case + //NOTE(martin): compute quadratic curve control point, which is at p0 + 1.5*(p1-p0) = 1.5*p1 - 0.5*p0 + result.kind = MTL_CUBIC_DEGENERATE_QUADRATIC; + } + else if((discrFactor2 > 0 && fabs(d1) > 1e-6) + || (discrFactor2 == 0 && fabs(d1) > 1e-6)) + { + //mtl_log(log, "cusp or serpentine\n"); - //NOTE(martin): serpentine curve or cusp with inflection at infinity - // (these two cases are handled the same way). - //NOTE(martin): compute the solutions (tl, sl), (tm, sm), and (tn, sn) of the inflection point equation - float tmtl[2]; - mtl_quadratic_roots_with_det(1, -2*d2, (4./3.*d1*d3), (1./3.)*discrFactor2, tmtl); + //NOTE(martin): serpentine curve or cusp with inflection at infinity + // (these two cases are handled the same way). + //NOTE(martin): compute the solutions (tl, sl), (tm, sm), and (tn, sn) of the inflection point equation + float tmtl[2]; + mtl_quadratic_roots_with_det(1, -2 * d2, (4. / 3. * d1 * d3), (1. / 3.) * discrFactor2, tmtl); - float tm = tmtl[0]; - float sm = 2*d1; - float tl = tmtl[1]; - float sl = 2*d1; + float tm = tmtl[0]; + float sm = 2 * d1; + float tl = tmtl[1]; + float sl = 2 * d1; - float invNorm = 1/sqrt(square(tm) + square(sm)); - tm *= invNorm; - sm *= invNorm; + float invNorm = 1 / sqrt(square(tm) + square(sm)); + tm *= invNorm; + sm *= invNorm; - invNorm = 1/sqrt(square(tl) + square(sl)); - tl *= invNorm; - sl *= invNorm; + invNorm = 1 / sqrt(square(tl) + square(sl)); + tl *= invNorm; + sl *= invNorm; - /*NOTE(martin): + /*NOTE(martin): the power basis coefficients of points k,l,m,n are collected into the rows of the 4x4 matrix F: | tl*tm tl^3 tm^3 1 | @@ -912,43 +911,43 @@ mtl_cubic_info mtl_cubic_classify(thread float2* c, mtl_log_context log = {.enab | sl*sm 3*sl^2*tl 3*sm^2*tm 0 | | 0 -sl^3 -sm^3 0 | */ - result.kind = (discrFactor2 > 0 && d1 != 0) ? MTL_CUBIC_SERPENTINE : MTL_CUBIC_CUSP; + result.kind = (discrFactor2 > 0 && d1 != 0) ? MTL_CUBIC_SERPENTINE : MTL_CUBIC_CUSP; - F = (matrix_float4x4){{tl*tm, -sm*tl-sl*tm, sl*sm, 0}, - {cube(tl), -3*sl*square(tl), 3*square(sl)*tl, -cube(sl)}, - {cube(tm), -3*sm*square(tm), 3*square(sm)*tm, -cube(sm)}, - {1, 0, 0, 0}}; + F = (matrix_float4x4){ { tl * tm, -sm * tl - sl * tm, sl * sm, 0 }, + { cube(tl), -3 * sl * square(tl), 3 * square(sl) * tl, -cube(sl) }, + { cube(tm), -3 * sm * square(tm), 3 * square(sm) * tm, -cube(sm) }, + { 1, 0, 0, 0 } }; - result.ts[0] = (float2){tm, sm}; - result.ts[1] = (float2){tl, sl}; - } - else if(discrFactor2 < 0 && fabs(d1) > 1e-6) - { -// mtl_log(log, "loop\n"); + result.ts[0] = (float2){ tm, sm }; + result.ts[1] = (float2){ tl, sl }; + } + else if(discrFactor2 < 0 && fabs(d1) > 1e-6) + { + // mtl_log(log, "loop\n"); - //NOTE(martin): loop curve - result.kind = MTL_CUBIC_LOOP; + //NOTE(martin): loop curve + result.kind = MTL_CUBIC_LOOP; - float tetd[2]; - mtl_quadratic_roots_with_det(1, -2*d2, 4*(square(d2)-d1*d3), -discrFactor2, tetd, log); + float tetd[2]; + mtl_quadratic_roots_with_det(1, -2 * d2, 4 * (square(d2) - d1 * d3), -discrFactor2, tetd, log); - float td = tetd[1]; - float sd = 2*d1; - float te = tetd[0]; - float se = 2*d1; + float td = tetd[1]; + float sd = 2 * d1; + float te = tetd[0]; + float se = 2 * d1; - float invNorm = 1/sqrt(square(td) + square(sd)); - td *= invNorm; - sd *= invNorm; + float invNorm = 1 / sqrt(square(td) + square(sd)); + td *= invNorm; + sd *= invNorm; - invNorm = 1/sqrt(square(te) + square(se)); - te *= invNorm; - se *= invNorm; + invNorm = 1 / sqrt(square(te) + square(se)); + te *= invNorm; + se *= invNorm; - //NOTE(martin): if one of the parameters (td/sd) or (te/se) is in the interval [0,1], the double point - // is inside the control points convex hull and would cause a shading anomaly. If this is - // the case, subdivide the curve at that point -/* + //NOTE(martin): if one of the parameters (td/sd) or (te/se) is in the interval [0,1], the double point + // is inside the control points convex hull and would cause a shading anomaly. If this is + // the case, subdivide the curve at that point + /* mtl_log(log, "td = "); mtl_log_f32(log, td); mtl_log(log, ", sd = "); @@ -963,7 +962,7 @@ mtl_cubic_info mtl_cubic_classify(thread float2* c, mtl_log_context log = {.enab mtl_log_f32(log, te/se); mtl_log(log, "\n"); //*/ - /*NOTE(martin): + /*NOTE(martin): the power basis coefficients of points k,l,m,n are collected into the rows of the 4x4 matrix F: | td*te td^2*te td*te^2 1 | @@ -971,28 +970,28 @@ mtl_cubic_info mtl_cubic_classify(thread float2* c, mtl_log_context log = {.enab | sd*se te*sd^2 + 2*se*td*sd td*se^2 + 2*sd*te*se 0 | | 0 -sd^2*se -sd*se^2 0 | */ - F = (matrix_float4x4){{td*te, -se*td-sd*te, sd*se, 0}, - {square(td)*te, -se*square(td)-2*sd*te*td, te*square(sd)+2*se*td*sd, -square(sd)*se}, - {td*square(te), -sd*square(te)-2*se*td*te, td*square(se)+2*sd*te*se, -sd*square(se)}, - {1, 0, 0, 0}}; + F = (matrix_float4x4){ { td * te, -se * td - sd * te, sd * se, 0 }, + { square(td) * te, -se * square(td) - 2 * sd * te * td, te * square(sd) + 2 * se * td * sd, -square(sd) * se }, + { td * square(te), -sd * square(te) - 2 * se * td * te, td * square(se) + 2 * sd * te * se, -sd * square(se) }, + { 1, 0, 0, 0 } }; - result.ts[0] = (float2){td, sd}; - result.ts[1] = (float2){te, se}; - } - else if(d2 != 0) - { - //NOTE(martin): cusp with cusp at infinity + result.ts[0] = (float2){ td, sd }; + result.ts[1] = (float2){ te, se }; + } + else if(d2 != 0) + { + //NOTE(martin): cusp with cusp at infinity -// mtl_log(log, "cusp at infinity\n"); + // mtl_log(log, "cusp at infinity\n"); - float tl = d3; - float sl = 3*d2; + float tl = d3; + float sl = 3 * d2; - float invNorm = 1/sqrt(square(tl)+square(sl)); - tl *= invNorm; - sl *= invNorm; + float invNorm = 1 / sqrt(square(tl) + square(sl)); + tl *= invNorm; + sl *= invNorm; - /*NOTE(martin): + /*NOTE(martin): the power basis coefficients of points k,l,m,n are collected into the rows of the 4x4 matrix F: | tl tl^3 1 1 | @@ -1000,23 +999,23 @@ mtl_cubic_info mtl_cubic_classify(thread float2* c, mtl_log_context log = {.enab | 0 3*sl^2*tl 0 0 | | 0 -sl^3 0 0 | */ - result.kind = MTL_CUBIC_CUSP_INFINITY; + result.kind = MTL_CUBIC_CUSP_INFINITY; - F = (matrix_float4x4){{tl, -sl, 0, 0}, - {cube(tl), -3*sl*square(tl), 3*square(sl)*tl, -cube(sl)}, - {1, 0, 0, 0}, - {1, 0, 0, 0}}; + F = (matrix_float4x4){ { tl, -sl, 0, 0 }, + { cube(tl), -3 * sl * square(tl), 3 * square(sl) * tl, -cube(sl) }, + { 1, 0, 0, 0 }, + { 1, 0, 0, 0 } }; - result.ts[0] = (float2){tl, sl}; - result.ts[1] = (float2){0, 0}; - } - else - { - //NOTE(martin): line or point degenerate case - result.kind = MTL_CUBIC_DEGENERATE_LINE; - } + result.ts[0] = (float2){ tl, sl }; + result.ts[1] = (float2){ 0, 0 }; + } + else + { + //NOTE(martin): line or point degenerate case + result.kind = MTL_CUBIC_DEGENERATE_LINE; + } - /* + /* F is then multiplied by M3^(-1) on the left which yelds the bezier coefficients k, l, m, n at the control points. @@ -1025,231 +1024,231 @@ mtl_cubic_info mtl_cubic_classify(thread float2* c, mtl_log_context log = {.enab | 1 2/3 1/3 0 | | 1 1 1 1 | */ - matrix_float4x4 invM3 = {{1, 1, 1, 1}, - {0, 1./3., 2./3., 1}, - {0, 0, 1./3., 1}, - {0, 0, 0, 1}}; + matrix_float4x4 invM3 = { { 1, 1, 1, 1 }, + { 0, 1. / 3., 2. / 3., 1 }, + { 0, 0, 1. / 3., 1 }, + { 0, 0, 0, 1 } }; - result.K = transpose(invM3*F); + result.K = transpose(invM3 * F); - return(result); + return (result); } float2 mtl_select_hull_vertex(float2 p0, float2 p1, float2 p2, float2 p3, mtl_log_context log) { - /*NOTE: check intersection of lines (p1-p0) and (p3-p2) + /*NOTE: check intersection of lines (p1-p0) and (p3-p2) P = p0 + u(p1-p0) P = p2 + w(p3-p2) control points are inside a right triangle so we should always find an intersection */ - float2 pm; + float2 pm; - float det = (p1.x - p0.x)*(p3.y - p2.y) - (p1.y - p0.y)*(p3.x - p2.x); - float sqrNorm0 = length_squared(p1-p0); - float sqrNorm1 = length_squared(p2-p3); + float det = (p1.x - p0.x) * (p3.y - p2.y) - (p1.y - p0.y) * (p3.x - p2.x); + float sqrNorm0 = length_squared(p1 - p0); + float sqrNorm1 = length_squared(p2 - p3); - if(fabs(det) < 1e-3 || sqrNorm0 < 0.1 || sqrNorm1 < 0.1) - { - if(sqrNorm0 < sqrNorm1) - { - pm = p2; - } - else - { - pm = p1; - } - } - else - { - float u = ((p0.x - p2.x)*(p2.y - p3.y) - (p0.y - p2.y)*(p2.x - p3.x))/det; - pm = p0 + u*(p1-p0); - } - return(pm); + if(fabs(det) < 1e-3 || sqrNorm0 < 0.1 || sqrNorm1 < 0.1) + { + if(sqrNorm0 < sqrNorm1) + { + pm = p2; + } + else + { + pm = p1; + } + } + else + { + float u = ((p0.x - p2.x) * (p2.y - p3.y) - (p0.y - p2.y) * (p2.x - p3.x)) / det; + pm = p0 + u * (p1 - p0); + } + return (pm); } void mtl_cubic_emit(thread mtl_segment_setup_context* context, mtl_cubic_info curve, float2 p[4], float s0, float s1, float2 sp[4]) { - device oc_mtl_segment* seg = mtl_segment_push(context, sp, OC_MTL_CUBIC); + device oc_mtl_segment* seg = mtl_segment_push(context, sp, OC_MTL_CUBIC); - if(seg) - { - float2 v0 = p[0]; - float2 v1 = p[3]; - float2 v2; - matrix_float3x3 K; + if(seg) + { + float2 v0 = p[0]; + float2 v1 = p[3]; + float2 v2; + matrix_float3x3 K; - float sqrNorm0 = length_squared(p[1]-p[0]); - float sqrNorm1 = length_squared(p[2]-p[3]); + float sqrNorm0 = length_squared(p[1] - p[0]); + float sqrNorm1 = length_squared(p[2] - p[3]); - //TODO: should not be the local sub-curve, but the global curve!!! - if(length_squared(p[0]-p[3]) > 1e-5) - { - if(sqrNorm0 >= sqrNorm1) - { - v2 = p[1]; - K = {curve.K[0].xyz, curve.K[3].xyz, curve.K[1].xyz}; - } - else - { - v2 = p[2]; - K = {curve.K[0].xyz, curve.K[3].xyz, curve.K[2].xyz}; - } - } - else - { - v1 = p[1]; - v2 = p[2]; - K = {curve.K[0].xyz, curve.K[1].xyz, curve.K[2].xyz}; - } - //NOTE: set matrices + //TODO: should not be the local sub-curve, but the global curve!!! + if(length_squared(p[0] - p[3]) > 1e-5) + { + if(sqrNorm0 >= sqrNorm1) + { + v2 = p[1]; + K = { curve.K[0].xyz, curve.K[3].xyz, curve.K[1].xyz }; + } + else + { + v2 = p[2]; + K = { curve.K[0].xyz, curve.K[3].xyz, curve.K[2].xyz }; + } + } + else + { + v1 = p[1]; + v2 = p[2]; + K = { curve.K[0].xyz, curve.K[1].xyz, curve.K[2].xyz }; + } + //NOTE: set matrices - //TODO: should we compute matrix relative to a base point to avoid loss of precision - // when computing barycentric matrix? + //TODO: should we compute matrix relative to a base point to avoid loss of precision + // when computing barycentric matrix? - matrix_float3x3 B = mtl_barycentric_matrix(v0, v1, v2); - seg->implicitMatrix = K*B; - seg->hullVertex = mtl_select_hull_vertex(sp[0], sp[1], sp[2], sp[3], context->log); + matrix_float3x3 B = mtl_barycentric_matrix(v0, v1, v2); + seg->implicitMatrix = K * B; + seg->hullVertex = mtl_select_hull_vertex(sp[0], sp[1], sp[2], sp[3], context->log); - //NOTE: compute sign flip - seg->sign = 1; + //NOTE: compute sign flip + seg->sign = 1; - if(curve.kind == MTL_CUBIC_SERPENTINE - || curve.kind == MTL_CUBIC_CUSP) - { - seg->sign = (curve.d1 < 0)? -1 : 1; - } - else if(curve.kind == MTL_CUBIC_LOOP) - { - float d1 = curve.d1; - float d2 = curve.d2; - float d3 = curve.d3; + if(curve.kind == MTL_CUBIC_SERPENTINE + || curve.kind == MTL_CUBIC_CUSP) + { + seg->sign = (curve.d1 < 0) ? -1 : 1; + } + else if(curve.kind == MTL_CUBIC_LOOP) + { + float d1 = curve.d1; + float d2 = curve.d2; + float d3 = curve.d3; - float H0 = d3*d1-square(d2) + d1*d2*s0 - square(d1)*square(s0); - float H1 = d3*d1-square(d2) + d1*d2*s1 - square(d1)*square(s1); - float H = (abs(H0) > abs(H1)) ? H0 : H1; - seg->sign = (H*d1 > 0) ? -1 : 1; - } + float H0 = d3 * d1 - square(d2) + d1 * d2 * s0 - square(d1) * square(s0); + float H1 = d3 * d1 - square(d2) + d1 * d2 * s1 - square(d1) * square(s1); + float H = (abs(H0) > abs(H1)) ? H0 : H1; + seg->sign = (H * d1 > 0) ? -1 : 1; + } - if(sp[3].y > sp[0].y) - { - seg->sign *= -1; - } + if(sp[3].y > sp[0].y) + { + seg->sign *= -1; + } - //NOTE: bin to tiles - mtl_segment_bin_to_tiles(context, seg); - } + //NOTE: bin to tiles + mtl_segment_bin_to_tiles(context, seg); + } } void mtl_cubic_setup(thread mtl_segment_setup_context* context, float2 p[4]) { - /*NOTE(martin): first convert the control points to power basis, multiplying by M3 + /*NOTE(martin): first convert the control points to power basis, multiplying by M3 | 1 0 0 0| |p0| |c0| M3 = |-3 3 0 0|, B = |p1|, C = |c1| = M3*B | 3 -6 3 0| |p2| |c2| |-1 3 -3 1| |p3| |c3| */ - float2 c[4] = { - p[0], - 3.0*(p[1] - p[0]), - 3.0*(p[0] + p[2] - 2*p[1]), - 3.0*(p[1] - p[2]) + p[3] - p[0]}; + float2 c[4] = { + p[0], + 3.0 * (p[1] - p[0]), + 3.0 * (p[0] + p[2] - 2 * p[1]), + 3.0 * (p[1] - p[2]) + p[3] - p[0] + }; -/* + /* mtl_log(context->log, "bezier basis: "); log_cubic_bezier(p, context->log); mtl_log(context->log, "power basis: "); log_cubic_bezier(c, context->log); */ - //NOTE: get classification, implicit matrix, double points and inflection points - mtl_cubic_info curve = mtl_cubic_classify(c, context->log); + //NOTE: get classification, implicit matrix, double points and inflection points + mtl_cubic_info curve = mtl_cubic_classify(c, context->log); - if(curve.kind == MTL_CUBIC_DEGENERATE_LINE) - { - float2 l[2] = {p[0], p[3]}; - mtl_line_setup(context, l); - return; - } - else if(curve.kind == MTL_CUBIC_DEGENERATE_QUADRATIC) - { - float2 quadPoint = float2(1.5*p[1].x - 0.5*p[0].x, 1.5*p[1].y - 0.5*p[0].y); - float2 q[3] = {p[0], quadPoint, p[3]}; - mtl_quadratic_setup(context, q); - return; - } + if(curve.kind == MTL_CUBIC_DEGENERATE_LINE) + { + float2 l[2] = { p[0], p[3] }; + mtl_line_setup(context, l); + return; + } + else if(curve.kind == MTL_CUBIC_DEGENERATE_QUADRATIC) + { + float2 quadPoint = float2(1.5 * p[1].x - 0.5 * p[0].x, 1.5 * p[1].y - 0.5 * p[0].y); + float2 q[3] = { p[0], quadPoint, p[3] }; + mtl_quadratic_setup(context, q); + return; + } - //NOTE: get the roots of B'(s) = 3.c3.s^2 + 2.c2.s + c1 - float roots[6]; - int rootCount = mtl_quadratic_roots(3*c[3].x, 2*c[2].x, c[1].x, roots); - rootCount += mtl_quadratic_roots(3*c[3].y, 2*c[2].y, c[1].y, roots + rootCount); + //NOTE: get the roots of B'(s) = 3.c3.s^2 + 2.c2.s + c1 + float roots[6]; + int rootCount = mtl_quadratic_roots(3 * c[3].x, 2 * c[2].x, c[1].x, roots); + rootCount += mtl_quadratic_roots(3 * c[3].y, 2 * c[2].y, c[1].y, roots + rootCount); - //NOTE: add double points and inflection points to roots if finite - for(int i=0; i<2; i++) - { - if(curve.ts[i].y) - { - roots[rootCount] = curve.ts[i].x / curve.ts[i].y; - rootCount++; - } - } + //NOTE: add double points and inflection points to roots if finite + for(int i = 0; i < 2; i++) + { + if(curve.ts[i].y) + { + roots[rootCount] = curve.ts[i].x / curve.ts[i].y; + rootCount++; + } + } - //NOTE: sort roots - for(int i=1; i=0 && roots[j]>tmp) - { - roots[j+1] = roots[j]; - j--; - } - roots[j+1] = tmp; - } + //NOTE: sort roots + for(int i = 1; i < rootCount; i++) + { + float tmp = roots[i]; + int j = i - 1; + while(j >= 0 && roots[j] > tmp) + { + roots[j + 1] = roots[j]; + j--; + } + roots[j + 1] = tmp; + } - //NOTE: compute split points - float splits[8]; - int splitCount = 0; - splits[0] = 0; - splitCount++; - for(int i=0; i 0 && roots[i] < 1) - { - splits[splitCount] = roots[i]; - splitCount++; - } - } - splits[splitCount] = 1; - splitCount++; + //NOTE: compute split points + float splits[8]; + int splitCount = 0; + splits[0] = 0; + splitCount++; + for(int i = 0; i < rootCount; i++) + { + if(roots[i] > 0 && roots[i] < 1) + { + splits[splitCount] = roots[i]; + splitCount++; + } + } + splits[splitCount] = 1; + splitCount++; - mtl_log(context->log, "monotonic segment count = "); - mtl_log_i32(context->log, splitCount-1); - mtl_log(context->log, "\n"); + mtl_log(context->log, "monotonic segment count = "); + mtl_log_i32(context->log, splitCount - 1); + mtl_log(context->log, "\n"); - //NOTE: for each monotonic segment, compute hull matrix and sign, and emit segment - for(int sliceIndex=0; sliceIndexlog, "monotonic slice "); - mtl_log_i32(context->log, sliceIndex); - mtl_log(context->log, " ( "); - mtl_log_f32(context->log, s0); - mtl_log(context->log, " <= s <= "); - mtl_log_f32(context->log, s1); - mtl_log(context->log," ): "); - log_cubic_bezier(sp, context->log); + mtl_log(context->log, "monotonic slice "); + mtl_log_i32(context->log, sliceIndex); + mtl_log(context->log, " ( "); + mtl_log_f32(context->log, s0); + mtl_log(context->log, " <= s <= "); + mtl_log_f32(context->log, s1); + mtl_log(context->log, " ): "); + log_cubic_bezier(sp, context->log); - - mtl_cubic_emit(context, curve, p, s0, s1, sp); - } + mtl_cubic_emit(context, curve, p, s0, s1, sp); + } } kernel void mtl_segment_setup(constant int* elementCount [[buffer(0)]], @@ -1269,51 +1268,55 @@ kernel void mtl_segment_setup(constant int* elementCount [[buffer(0)]], device atomic_int* logOffsetBuffer [[buffer(13)]], uint eltIndex [[thread_position_in_grid]]) { - const device oc_mtl_path_elt* elt = &elementBuffer[eltIndex]; - const device oc_mtl_path_queue* pathQueue = &pathQueueBuffer[elt->pathIndex]; - device oc_mtl_tile_queue* tileQueues = &tileQueueBuffer[pathQueue->tileQueues]; + const device oc_mtl_path_elt* elt = &elementBuffer[eltIndex]; + const device oc_mtl_path_queue* pathQueue = &pathQueueBuffer[elt->pathIndex]; + device oc_mtl_tile_queue* tileQueues = &tileQueueBuffer[pathQueue->tileQueues]; - mtl_segment_setup_context setupCtx = {.pathIndex = elt->pathIndex, - .segmentCount = segmentCount, - .segmentBuffer = segmentBuffer, - .pathQueue = pathQueue, - .tileQueues = tileQueues, - .tileOpBuffer = tileOpBuffer, - .tileOpCount = tileOpCount, - .tileOpMax = tileOpMax[0], - .segmentMax = segmentMax[0], - .tileSize = tileSize[0], - .log.buffer = logBuffer, - .log.offset = logOffsetBuffer, - .log.enabled = false,}; + mtl_segment_setup_context setupCtx = { + .pathIndex = elt->pathIndex, + .segmentCount = segmentCount, + .segmentBuffer = segmentBuffer, + .pathQueue = pathQueue, + .tileQueues = tileQueues, + .tileOpBuffer = tileOpBuffer, + .tileOpCount = tileOpCount, + .tileOpMax = tileOpMax[0], + .segmentMax = segmentMax[0], + .tileSize = tileSize[0], + .log.buffer = logBuffer, + .log.offset = logOffsetBuffer, + .log.enabled = false, + }; - switch(elt->kind) - { - case OC_MTL_LINE: - { - float2 p[2] = {elt->p[0]*scale[0], elt->p[1]*scale[0]}; - mtl_log(setupCtx.log, "line: "); - log_line(p, setupCtx.log); - mtl_line_setup(&setupCtx, p); - } break; + switch(elt->kind) + { + case OC_MTL_LINE: + { + float2 p[2] = { elt->p[0] * scale[0], elt->p[1] * scale[0] }; + mtl_log(setupCtx.log, "line: "); + log_line(p, setupCtx.log); + mtl_line_setup(&setupCtx, p); + } + break; - case OC_MTL_QUADRATIC: - { - float2 p[3] = {elt->p[0]*scale[0], elt->p[1]*scale[0], elt->p[2]*scale[0]}; - mtl_log(setupCtx.log, "quadratic: "); - log_quadratic_bezier(p, setupCtx.log); - mtl_quadratic_setup(&setupCtx, p); - } break; + case OC_MTL_QUADRATIC: + { + float2 p[3] = { elt->p[0] * scale[0], elt->p[1] * scale[0], elt->p[2] * scale[0] }; + mtl_log(setupCtx.log, "quadratic: "); + log_quadratic_bezier(p, setupCtx.log); + mtl_quadratic_setup(&setupCtx, p); + } + break; - case OC_MTL_CUBIC: - { - float2 p[4] = {elt->p[0]*scale[0], elt->p[1]*scale[0], elt->p[2]*scale[0], elt->p[3]*scale[0]}; - mtl_log(setupCtx.log, "cubic: "); - log_cubic_bezier(p, setupCtx.log); - mtl_cubic_setup(&setupCtx, p); - - } break; - } + case OC_MTL_CUBIC: + { + float2 p[4] = { elt->p[0] * scale[0], elt->p[1] * scale[0], elt->p[2] * scale[0], elt->p[3] * scale[0] }; + mtl_log(setupCtx.log, "cubic: "); + log_cubic_bezier(p, setupCtx.log); + mtl_cubic_setup(&setupCtx, p); + } + break; + } } kernel void mtl_backprop(const device oc_mtl_path_queue* pathQueueBuffer [[buffer(0)]], @@ -1323,35 +1326,35 @@ kernel void mtl_backprop(const device oc_mtl_path_queue* pathQueueBuffer [[buffe uint pathIndex [[threadgroup_position_in_grid]], uint localID [[thread_position_in_threadgroup]]) { -// mtl_log_context log = {.buffer = logBuffer, .offset = logOffsetBuffer, .enabled = false}; + // mtl_log_context log = {.buffer = logBuffer, .offset = logOffsetBuffer, .enabled = false}; - threadgroup atomic_int nextRowIndex; - if(localID == 0) - { - atomic_store_explicit(&nextRowIndex, 0, memory_order_relaxed); - } - threadgroup_barrier(mem_flags::mem_threadgroup); + threadgroup atomic_int nextRowIndex; + if(localID == 0) + { + atomic_store_explicit(&nextRowIndex, 0, memory_order_relaxed); + } + threadgroup_barrier(mem_flags::mem_threadgroup); - int rowIndex = 0; - const device oc_mtl_path_queue* pathQueue = &pathQueueBuffer[pathIndex]; - device oc_mtl_tile_queue* tiles = &tileQueueBuffer[pathQueue->tileQueues]; - int rowSize = pathQueue->area.z; - int rowCount = pathQueue->area.w; + int rowIndex = 0; + const device oc_mtl_path_queue* pathQueue = &pathQueueBuffer[pathIndex]; + device oc_mtl_tile_queue* tiles = &tileQueueBuffer[pathQueue->tileQueues]; + int rowSize = pathQueue->area.z; + int rowCount = pathQueue->area.w; - rowIndex = atomic_fetch_add_explicit(&nextRowIndex, 1, memory_order_relaxed); - while(rowIndex < rowCount) - { - device oc_mtl_tile_queue* row = &tiles[rowIndex * rowSize]; - int sum = 0; - for(int x = rowSize-1; x >= 0; x--) - { - device oc_mtl_tile_queue* tile = &row[x]; - int offset = *(device int*)&tile->windingOffset; - *(device int*)(&tile->windingOffset) = sum; - sum += offset; - } - rowIndex = atomic_fetch_add_explicit(&nextRowIndex, 1, memory_order_relaxed); - } + rowIndex = atomic_fetch_add_explicit(&nextRowIndex, 1, memory_order_relaxed); + while(rowIndex < rowCount) + { + device oc_mtl_tile_queue* row = &tiles[rowIndex * rowSize]; + int sum = 0; + for(int x = rowSize - 1; x >= 0; x--) + { + device oc_mtl_tile_queue* tile = &row[x]; + int offset = *(device int*)&tile->windingOffset; + *(device int*)(&tile->windingOffset) = sum; + sum += offset; + } + rowIndex = atomic_fetch_add_explicit(&nextRowIndex, 1, memory_order_relaxed); + } } kernel void mtl_merge(constant int* pathCount [[buffer(0)]], @@ -1370,137 +1373,136 @@ kernel void mtl_merge(constant int* pathCount [[buffer(0)]], uint2 threadCoord [[thread_position_in_grid]], uint2 gridSize [[threads_per_grid]]) { - int2 tileCoord = int2(threadCoord); - int tileIndex = -1; - device int* nextLink = 0; + int2 tileCoord = int2(threadCoord); + int tileIndex = -1; + device int* nextLink = 0; -/* + /* mtl_log_context log = {.buffer = logBuffer, .offset = logOffsetBuffer, .enabled = true}; */ - dispatchBuffer[0].threadgroupsPerGrid[1] = 1; - dispatchBuffer[0].threadgroupsPerGrid[2] = 1; + dispatchBuffer[0].threadgroupsPerGrid[1] = 1; + dispatchBuffer[0].threadgroupsPerGrid[2] = 1; - for(int pathIndex = 0; pathIndex < pathCount[0]; pathIndex++) - { - const device oc_mtl_path_queue* pathQueue = &pathQueueBuffer[pathIndex]; - int2 pathTileCoord = tileCoord - pathQueue->area.xy; + for(int pathIndex = 0; pathIndex < pathCount[0]; pathIndex++) + { + const device oc_mtl_path_queue* pathQueue = &pathQueueBuffer[pathIndex]; + int2 pathTileCoord = tileCoord - pathQueue->area.xy; - const device oc_mtl_path* path = &pathBuffer[pathIndex]; - float xMax = min(path->box.z, path->clip.z); - int tileMaxX = xMax * scale[0] / tileSize[0]; - int pathTileMaxX = tileMaxX - pathQueue->area.x; + const device oc_mtl_path* path = &pathBuffer[pathIndex]; + float xMax = min(path->box.z, path->clip.z); + int tileMaxX = xMax * scale[0] / tileSize[0]; + int pathTileMaxX = tileMaxX - pathQueue->area.x; - if( pathTileCoord.x >= 0 - && pathTileCoord.x <= pathTileMaxX - && pathTileCoord.y >= 0 - && pathTileCoord.y < pathQueue->area.w) - { - if(tileIndex < 0) - { - tileIndex = atomic_fetch_add_explicit((device atomic_uint*)&dispatchBuffer[0].threadgroupsPerGrid[0], 1, memory_order_relaxed); - screenTilesBuffer[tileIndex].tileCoord = uint2(tileCoord); - nextLink = &screenTilesBuffer[tileIndex].first; - *nextLink = -1; - } + if(pathTileCoord.x >= 0 + && pathTileCoord.x <= pathTileMaxX + && pathTileCoord.y >= 0 + && pathTileCoord.y < pathQueue->area.w) + { + if(tileIndex < 0) + { + tileIndex = atomic_fetch_add_explicit((device atomic_uint*)&dispatchBuffer[0].threadgroupsPerGrid[0], 1, memory_order_relaxed); + screenTilesBuffer[tileIndex].tileCoord = uint2(tileCoord); + nextLink = &screenTilesBuffer[tileIndex].first; + *nextLink = -1; + } - int pathTileIndex = pathTileCoord.y * pathQueue->area.z + pathTileCoord.x; - const device oc_mtl_tile_queue* tileQueue = &tileQueueBuffer[pathQueue->tileQueues + pathTileIndex]; + int pathTileIndex = pathTileCoord.y * pathQueue->area.z + pathTileCoord.x; + const device oc_mtl_tile_queue* tileQueue = &tileQueueBuffer[pathQueue->tileQueues + pathTileIndex]; - int windingOffset = atomic_load_explicit(&tileQueue->windingOffset, memory_order_relaxed); - int firstOpIndex = atomic_load_explicit(&tileQueue->first, memory_order_relaxed); + int windingOffset = atomic_load_explicit(&tileQueue->windingOffset, memory_order_relaxed); + int firstOpIndex = atomic_load_explicit(&tileQueue->first, memory_order_relaxed); - float4 tileBox = float4(tileCoord.x, tileCoord.y, tileCoord.x+1, tileCoord.y+1); - tileBox *= tileSize[0]; - float4 clip = pathBuffer[pathIndex].clip * scale[0]; + float4 tileBox = float4(tileCoord.x, tileCoord.y, tileCoord.x + 1, tileCoord.y + 1); + tileBox *= tileSize[0]; + float4 clip = pathBuffer[pathIndex].clip * scale[0]; - if( tileBox.x >= clip.z - || tileBox.z < clip.x - || tileBox.y >= clip.w - || tileBox.w < clip.y) - { - //NOTE: tile is fully outside clip, cull it - } - else if(firstOpIndex == -1) - { - if(windingOffset & 1) - { - //NOTE: tile is full covered. Add path start op (with winding offset). - // Additionally if color is opaque and tile is fully inside clip, trim tile list. - int pathOpIndex = atomic_fetch_add_explicit(tileOpCount, 1, memory_order_relaxed); + if(tileBox.x >= clip.z + || tileBox.z < clip.x + || tileBox.y >= clip.w + || tileBox.w < clip.y) + { + //NOTE: tile is fully outside clip, cull it + } + else if(firstOpIndex == -1) + { + if(windingOffset & 1) + { + //NOTE: tile is full covered. Add path start op (with winding offset). + // Additionally if color is opaque and tile is fully inside clip, trim tile list. + int pathOpIndex = atomic_fetch_add_explicit(tileOpCount, 1, memory_order_relaxed); - if(pathOpIndex >= tileOpMax[0]) - { - return; - } + if(pathOpIndex >= tileOpMax[0]) + { + return; + } - device oc_mtl_tile_op* pathOp = &tileOpBuffer[pathOpIndex]; - pathOp->kind = OC_MTL_OP_CLIP_FILL; - pathOp->next = -1; - pathOp->index = pathIndex; - pathOp->windingOffset = windingOffset; + device oc_mtl_tile_op* pathOp = &tileOpBuffer[pathOpIndex]; + pathOp->kind = OC_MTL_OP_CLIP_FILL; + pathOp->next = -1; + pathOp->index = pathIndex; + pathOp->windingOffset = windingOffset; - *nextLink = pathOpIndex; + *nextLink = pathOpIndex; - if(tileBox.x >= clip.x - && tileBox.z < clip.z - && tileBox.y >= clip.y - && tileBox.w < clip.w) - { - pathOp->kind = OC_MTL_OP_FILL; + if(tileBox.x >= clip.x + && tileBox.z < clip.z + && tileBox.y >= clip.y + && tileBox.w < clip.w) + { + pathOp->kind = OC_MTL_OP_FILL; - if(pathBuffer[pathIndex].color.a == 1 && pathBuffer[pathIndex].texture < 0) - { - screenTilesBuffer[tileIndex].first = pathOpIndex; - } - } - nextLink = &pathOp->next; - } - // else, tile is fully uncovered, skip path - } - else - { - //NOTE: add path start op (with winding offset) - int startOpIndex = atomic_fetch_add_explicit(tileOpCount, 1, memory_order_relaxed); - if(startOpIndex >= tileOpMax[0]) - { - return; - } + if(pathBuffer[pathIndex].color.a == 1 && pathBuffer[pathIndex].texture < 0) + { + screenTilesBuffer[tileIndex].first = pathOpIndex; + } + } + nextLink = &pathOp->next; + } + // else, tile is fully uncovered, skip path + } + else + { + //NOTE: add path start op (with winding offset) + int startOpIndex = atomic_fetch_add_explicit(tileOpCount, 1, memory_order_relaxed); + if(startOpIndex >= tileOpMax[0]) + { + return; + } - device oc_mtl_tile_op* startOp = &tileOpBuffer[startOpIndex]; - startOp->kind = OC_MTL_OP_START; - startOp->next = -1; - startOp->index = pathIndex; - startOp->windingOffset = windingOffset; + device oc_mtl_tile_op* startOp = &tileOpBuffer[startOpIndex]; + startOp->kind = OC_MTL_OP_START; + startOp->next = -1; + startOp->index = pathIndex; + startOp->windingOffset = windingOffset; - *nextLink = startOpIndex; - nextLink = &startOp->next; + *nextLink = startOpIndex; + nextLink = &startOp->next; - //NOTE: chain remaining path ops to end of tile list - int lastOpIndex = tileQueue->last; - device oc_mtl_tile_op* lastOp = &tileOpBuffer[lastOpIndex]; - *nextLink = firstOpIndex; - nextLink = &lastOp->next; + //NOTE: chain remaining path ops to end of tile list + int lastOpIndex = tileQueue->last; + device oc_mtl_tile_op* lastOp = &tileOpBuffer[lastOpIndex]; + *nextLink = firstOpIndex; + nextLink = &lastOp->next; + //NOTE: add path end op + int endOpIndex = atomic_fetch_add_explicit(tileOpCount, 1, memory_order_relaxed); + if(endOpIndex >= tileOpMax[0]) + { + return; + } - //NOTE: add path end op - int endOpIndex = atomic_fetch_add_explicit(tileOpCount, 1, memory_order_relaxed); - if(endOpIndex >= tileOpMax[0]) - { - return; - } + device oc_mtl_tile_op* endOp = &tileOpBuffer[endOpIndex]; + endOp->kind = OC_MTL_OP_END; + endOp->next = -1; + endOp->index = pathIndex; - device oc_mtl_tile_op* endOp = &tileOpBuffer[endOpIndex]; - endOp->kind = OC_MTL_OP_END; - endOp->next = -1; - endOp->index = pathIndex; - - *nextLink = endOpIndex; - nextLink = &endOp->next; - } - } - } + *nextLink = endOpIndex; + nextLink = &endOp->next; + } + } + } } kernel void mtl_raster(const device oc_mtl_screen_tile* screenTilesBuffer [[buffer(0)]], @@ -1514,162 +1516,163 @@ kernel void mtl_raster(const device oc_mtl_screen_tile* screenTilesBuffer [[buff device atomic_int* logOffsetBuffer [[buffer(8)]], texture2d outTexture [[texture(0)]], array, OC_MTL_MAX_IMAGES_PER_BATCH> srcTextures [[texture(1)]], - uint2 threadGroupCoord [[threadgroup_position_in_grid]], + uint2 threadGroupCoord [[threadgroup_position_in_grid]], uint2 localCoord [[thread_position_in_threadgroup]]) { -/* + /* mtl_log_context log = {.buffer = logBuffer, .offset = logOffsetBuffer, .enabled = true}; */ - int tileIndex = int(threadGroupCoord.x); - uint2 tileCoord = screenTilesBuffer[tileIndex].tileCoord; - uint2 pixelCoord = tileCoord*tileSize[0] + localCoord.xy; + int tileIndex = int(threadGroupCoord.x); + uint2 tileCoord = screenTilesBuffer[tileIndex].tileCoord; + uint2 pixelCoord = tileCoord * tileSize[0] + localCoord.xy; - int opIndex = screenTilesBuffer[tileIndex].first; + int opIndex = screenTilesBuffer[tileIndex].first; - const int OC_MTL_MAX_SAMPLE_COUNT = 8; - float2 sampleCoords[OC_MTL_MAX_SAMPLE_COUNT]; - int sampleCount = sampleCountBuffer[0]; - float2 centerCoord = float2(pixelCoord) + float2(0.5, 0.5); + const int OC_MTL_MAX_SAMPLE_COUNT = 8; + float2 sampleCoords[OC_MTL_MAX_SAMPLE_COUNT]; + int sampleCount = sampleCountBuffer[0]; + float2 centerCoord = float2(pixelCoord) + float2(0.5, 0.5); - if(sampleCount == 8) - { - sampleCount = 8; - sampleCoords[0] = centerCoord + float2(1, 3)/16; - sampleCoords[1] = centerCoord + float2(-1, -3)/16; - sampleCoords[2] = centerCoord + float2(5, -1)/16; - sampleCoords[3] = centerCoord + float2(-3, 5)/16; - sampleCoords[4] = centerCoord + float2(-5, -5)/16; - sampleCoords[5] = centerCoord + float2(-7, 1)/16; - sampleCoords[6] = centerCoord + float2(3, -7)/16; - sampleCoords[7] = centerCoord + float2(7, 7)/16; - } - else - { - sampleCount = 1; - sampleCoords[0] = centerCoord; - } + if(sampleCount == 8) + { + sampleCount = 8; + sampleCoords[0] = centerCoord + float2(1, 3) / 16; + sampleCoords[1] = centerCoord + float2(-1, -3) / 16; + sampleCoords[2] = centerCoord + float2(5, -1) / 16; + sampleCoords[3] = centerCoord + float2(-3, 5) / 16; + sampleCoords[4] = centerCoord + float2(-5, -5) / 16; + sampleCoords[5] = centerCoord + float2(-7, 1) / 16; + sampleCoords[6] = centerCoord + float2(3, -7) / 16; + sampleCoords[7] = centerCoord + float2(7, 7) / 16; + } + else + { + sampleCount = 1; + sampleCoords[0] = centerCoord; + } - const int OC_MTL_MAX_SRC_SAMPLE_COUNT = 4; - const int srcSampleCount = 2; + const int OC_MTL_MAX_SRC_SAMPLE_COUNT = 4; + const int srcSampleCount = 2; - const float2 imgSampleCoords[OC_MTL_MAX_SRC_SAMPLE_COUNT] = { - centerCoord + float2(-0.25, 0.25), - centerCoord + float2(+0.25, +0.25), - centerCoord + float2(+0.25, -0.25), - centerCoord + float2(-0.25, +0.25)}; + const float2 imgSampleCoords[OC_MTL_MAX_SRC_SAMPLE_COUNT] = { + centerCoord + float2(-0.25, 0.25), + centerCoord + float2(+0.25, +0.25), + centerCoord + float2(+0.25, -0.25), + centerCoord + float2(-0.25, +0.25) + }; - float4 color = {0}; - int winding[OC_MTL_MAX_SAMPLE_COUNT] = {0}; + float4 color = { 0 }; + int winding[OC_MTL_MAX_SAMPLE_COUNT] = { 0 }; - while(opIndex != -1) - { - const device oc_mtl_tile_op* op = &tileOpBuffer[opIndex]; - int pathIndex = op->index; + while(opIndex != -1) + { + const device oc_mtl_tile_op* op = &tileOpBuffer[opIndex]; + int pathIndex = op->index; - if(op->kind == OC_MTL_OP_START) - { - for(int sampleIndex=0; sampleIndexwindingOffset; - } - } - else if(op->kind == OC_MTL_OP_SEGMENT) - { - const device oc_mtl_segment* seg = &segmentBuffer[op->index]; + if(op->kind == OC_MTL_OP_START) + { + for(int sampleIndex = 0; sampleIndex < sampleCount; sampleIndex++) + { + winding[sampleIndex] = op->windingOffset; + } + } + else if(op->kind == OC_MTL_OP_SEGMENT) + { + const device oc_mtl_segment* seg = &segmentBuffer[op->index]; - for(int sampleIndex=0; sampleIndex seg->box.y) - &&(sampleCoord.y <= seg->box.w) - &&(mtl_side_of_segment(sampleCoord, seg) < 0)) - { - winding[sampleIndex] += seg->windingIncrement; - } + if((sampleCoord.y > seg->box.y) + && (sampleCoord.y <= seg->box.w) + && (mtl_side_of_segment(sampleCoord, seg) < 0)) + { + winding[sampleIndex] += seg->windingIncrement; + } - if(op->crossRight) - { - if( (seg->config == OC_MTL_BR || seg->config == OC_MTL_TL) - &&(sampleCoord.y > seg->box.w)) - { - winding[sampleIndex] += seg->windingIncrement; - } - else if( (seg->config == OC_MTL_BL || seg->config == OC_MTL_TR) - &&(sampleCoord.y > seg->box.y)) - { - winding[sampleIndex] -= seg->windingIncrement; - } - } - } - } - else - { - float4 nextColor = pathBuffer[pathIndex].color; - nextColor.rgb *= nextColor.a; + if(op->crossRight) + { + if((seg->config == OC_MTL_BR || seg->config == OC_MTL_TL) + && (sampleCoord.y > seg->box.w)) + { + winding[sampleIndex] += seg->windingIncrement; + } + else if((seg->config == OC_MTL_BL || seg->config == OC_MTL_TR) + && (sampleCoord.y > seg->box.y)) + { + winding[sampleIndex] -= seg->windingIncrement; + } + } + } + } + else + { + float4 nextColor = pathBuffer[pathIndex].color; + nextColor.rgb *= nextColor.a; - int textureIndex = pathBuffer[pathIndex].texture; - if(textureIndex >= 0 && textureIndex < OC_MTL_MAX_IMAGES_PER_BATCH) - { - constexpr sampler smp(mip_filter::nearest, mag_filter::linear, min_filter::linear); + int textureIndex = pathBuffer[pathIndex].texture; + if(textureIndex >= 0 && textureIndex < OC_MTL_MAX_IMAGES_PER_BATCH) + { + constexpr sampler smp(mip_filter::nearest, mag_filter::linear, min_filter::linear); - float4 texColor = {0}; - for(int sampleIndex=0; sampleIndexkind == OC_MTL_OP_FILL) - { - color = color*(1-nextColor.a) + nextColor; - } - else - { - float4 clip = pathBuffer[pathIndex].clip * scale[0]; - float coverage = 0; + if(op->kind == OC_MTL_OP_FILL) + { + color = color * (1 - nextColor.a) + nextColor; + } + else + { + float4 clip = pathBuffer[pathIndex].clip * scale[0]; + float coverage = 0; - for(int sampleIndex=0; sampleIndex= clip.x - && sampleCoord.x < clip.z - && sampleCoord.y >= clip.y - && sampleCoord.y < clip.w) - { - bool filled = op->kind == OC_MTL_OP_CLIP_FILL - ||(pathBuffer[pathIndex].cmd == OC_MTL_FILL && (winding[sampleIndex] & 1)) - ||(pathBuffer[pathIndex].cmd == OC_MTL_STROKE && (winding[sampleIndex] != 0)); - if(filled) - { - coverage++; - } - } - } - coverage /= sampleCount; - color = coverage*(color*(1-nextColor.a) + nextColor) + (1-coverage)*color; - } - } - opIndex = op->next; - } + if(sampleCoord.x >= clip.x + && sampleCoord.x < clip.z + && sampleCoord.y >= clip.y + && sampleCoord.y < clip.w) + { + bool filled = op->kind == OC_MTL_OP_CLIP_FILL + || (pathBuffer[pathIndex].cmd == OC_MTL_FILL && (winding[sampleIndex] & 1)) + || (pathBuffer[pathIndex].cmd == OC_MTL_STROKE && (winding[sampleIndex] != 0)); + if(filled) + { + coverage++; + } + } + } + coverage /= sampleCount; + color = coverage * (color * (1 - nextColor.a) + nextColor) + (1 - coverage) * color; + } + } + opIndex = op->next; + } -/* + /* if((pixelCoord.x % tileSize[0] == 0) || (pixelCoord.y % tileSize[0] == 0)) { color = float4(0, 0, 0, 1); } //*/ - outTexture.write(color, pixelCoord); + outTexture.write(color, pixelCoord); } //------------------------------------------------------------------------------------ @@ -1683,14 +1686,14 @@ struct vs_out vertex vs_out mtl_vertex_shader(ushort vid [[vertex_id]]) { - vs_out out; - out.uv = float2((vid << 1) & 2, vid & 2); - out.pos = float4(out.uv * float2(2, -2) + float2(-1, 1), 0, 1); - return(out); + vs_out out; + out.uv = float2((vid << 1) & 2, vid & 2); + out.pos = float4(out.uv * float2(2, -2) + float2(-1, 1), 0, 1); + return (out); } fragment float4 mtl_fragment_shader(vs_out i [[stage_in]], texture2d tex [[texture(0)]]) { - constexpr sampler smp(mip_filter::nearest, mag_filter::linear, min_filter::linear); - return(tex.sample(smp, i.uv)); + constexpr sampler smp(mip_filter::nearest, mag_filter::linear, min_filter::linear); + return (tex.sample(smp, i.uv)); } diff --git a/src/graphics/mtl_surface.h b/src/graphics/mtl_surface.h index 337fab7..ceb0f18 100644 --- a/src/graphics/mtl_surface.h +++ b/src/graphics/mtl_surface.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: mtl_surface.h * @author: Martin Fouilleul @@ -9,10 +9,10 @@ #ifndef __MTL_SURFACE_H_ #define __MTL_SURFACE_H_ -#include"graphics_surface.h" +#include "graphics_surface.h" #ifdef __OBJC__ - #import + #import #endif oc_surface_data* oc_mtl_surface_create_for_window(oc_window window); diff --git a/src/graphics/mtl_surface.m b/src/graphics/mtl_surface.m index 33ef730..2d40083 100644 --- a/src/graphics/mtl_surface.m +++ b/src/graphics/mtl_surface.m @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: mtl_surface.m * @author: Martin Fouilleul @@ -6,63 +6,65 @@ * @revision: * *****************************************************************/ -#import +#import +#import #import -#import -#include +#include -#include"graphics_surface.h" -#include"util/macros.h" -#include"app/osx_app.h" +#include "app/osx_app.h" +#include "graphics_surface.h" +#include "util/macros.h" typedef struct oc_mtl_surface { - oc_surface_data interface; + oc_surface_data interface; - // permanent mtl resources - id device; - CAMetalLayer* mtlLayer; - id commandQueue; + // permanent mtl resources + id device; + CAMetalLayer* mtlLayer; + id commandQueue; - // transient metal resources - id drawable; - id commandBuffer; + // transient metal resources + id drawable; + id commandBuffer; } oc_mtl_surface; void oc_mtl_surface_destroy(oc_surface_data* interface) { - oc_mtl_surface* surface = (oc_mtl_surface*)interface; + oc_mtl_surface* surface = (oc_mtl_surface*)interface; - @autoreleasepool - { - //NOTE: when GPU frame capture is enabled, if we release resources before all work is completed, - // libMetalCapture crashes... the following hack avoids this crash by enqueuing a last (empty) - // command buffer and waiting for it to complete, ensuring all previous buffers have completed - id endBuffer = [surface->commandQueue commandBuffer]; - [endBuffer commit]; - [endBuffer waitUntilCompleted]; + @autoreleasepool + { + //NOTE: when GPU frame capture is enabled, if we release resources before all work is completed, + // libMetalCapture crashes... the following hack avoids this crash by enqueuing a last (empty) + // command buffer and waiting for it to complete, ensuring all previous buffers have completed + id endBuffer = [surface->commandQueue commandBuffer]; + [endBuffer commit]; + [endBuffer waitUntilCompleted]; - [surface->commandQueue release]; - [surface->mtlLayer removeFromSuperlayer]; - [surface->mtlLayer release]; - [surface->device release]; - } - //NOTE: we don't use oc_layer_cleanup here, because the CAMetalLayer is taken care off by the surface itself + [surface->commandQueue release]; + [surface->mtlLayer removeFromSuperlayer]; + [surface->mtlLayer release]; + [surface->device release]; + } + //NOTE: we don't use oc_layer_cleanup here, because the CAMetalLayer is taken care off by the surface itself } void oc_mtl_surface_acquire_command_buffer(oc_mtl_surface* surface) { - if(surface->commandBuffer == nil) - { - surface->commandBuffer = [surface->commandQueue commandBuffer]; - [surface->commandBuffer retain]; - } + if(surface->commandBuffer == nil) + { + surface->commandBuffer = [surface->commandQueue commandBuffer]; + [surface->commandBuffer retain]; + } } void oc_mtl_surface_acquire_drawable(oc_mtl_surface* surface) -{@autoreleasepool{ - /*WARN(martin): +{ + @autoreleasepool + { + /*WARN(martin): //TODO: we should stop trying to render if we detect that the app is in the background or occluded @@ -70,50 +72,51 @@ void oc_mtl_surface_acquire_drawable(oc_mtl_surface* surface) for too long. */ - //NOTE: returned drawable could be nil if we stall for more than 1s, although that never seem to happen in practice? - if(surface->drawable == nil) - { - surface->drawable = [surface->mtlLayer nextDrawable]; - if(surface->drawable) - { - [surface->drawable retain]; - } - } -}} + //NOTE: returned drawable could be nil if we stall for more than 1s, although that never seem to happen in practice? + if(surface->drawable == nil) + { + surface->drawable = [surface->mtlLayer nextDrawable]; + if(surface->drawable) + { + [surface->drawable retain]; + } + } + } +} void oc_mtl_surface_prepare(oc_surface_data* interface) { - oc_mtl_surface* surface = (oc_mtl_surface*)interface; - oc_mtl_surface_acquire_command_buffer(surface); + oc_mtl_surface* surface = (oc_mtl_surface*)interface; + oc_mtl_surface_acquire_command_buffer(surface); } void oc_mtl_surface_present(oc_surface_data* interface) { - oc_mtl_surface* surface = (oc_mtl_surface*)interface; - @autoreleasepool - { - if(surface->commandBuffer != nil) - { - if(surface->drawable != nil) - { - [surface->commandBuffer presentDrawable: surface->drawable]; - [surface->drawable release]; - surface->drawable = nil; - } - [surface->commandBuffer commit]; - [surface->commandBuffer release]; - surface->commandBuffer = nil; - } - } + oc_mtl_surface* surface = (oc_mtl_surface*)interface; + @autoreleasepool + { + if(surface->commandBuffer != nil) + { + if(surface->drawable != nil) + { + [surface->commandBuffer presentDrawable:surface->drawable]; + [surface->drawable release]; + surface->drawable = nil; + } + [surface->commandBuffer commit]; + [surface->commandBuffer release]; + surface->commandBuffer = nil; + } + } } void oc_mtl_surface_swap_interval(oc_surface_data* interface, int swap) { - oc_mtl_surface* surface = (oc_mtl_surface*)interface; - @autoreleasepool - { - [surface->mtlLayer setDisplaySyncEnabled: (swap ? YES : NO)]; - } + oc_mtl_surface* surface = (oc_mtl_surface*)interface; + @autoreleasepool + { + [surface->mtlLayer setDisplaySyncEnabled:(swap ? YES : NO)]; + } } /* @@ -138,7 +141,6 @@ void oc_mtl_surface_set_frame(oc_surface_data* interface, oc_rect frame) } */ - //TODO fix that according to real scaling, depending on the monitor settings static const f32 OC_MTL_SURFACE_CONTENTS_SCALING = 2; @@ -148,135 +150,134 @@ static const int OC_MTL_MAX_FRAMES_IN_FLIGHT = 2; oc_surface_data* oc_mtl_surface_create_for_window(oc_window window) { - oc_mtl_surface* surface = 0; - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - surface = (oc_mtl_surface*)malloc(sizeof(oc_mtl_surface)); + oc_mtl_surface* surface = 0; + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + surface = (oc_mtl_surface*)malloc(sizeof(oc_mtl_surface)); - oc_surface_init_for_window((oc_surface_data*)surface, windowData); + oc_surface_init_for_window((oc_surface_data*)surface, windowData); - //NOTE(martin): setup interface functions - surface->interface.api = OC_METAL; - surface->interface.destroy = oc_mtl_surface_destroy; - surface->interface.prepare = oc_mtl_surface_prepare; - surface->interface.deselect = 0; - surface->interface.present = oc_mtl_surface_present; - surface->interface.swapInterval = oc_mtl_surface_swap_interval; + //NOTE(martin): setup interface functions + surface->interface.api = OC_METAL; + surface->interface.destroy = oc_mtl_surface_destroy; + surface->interface.prepare = oc_mtl_surface_prepare; + surface->interface.deselect = 0; + surface->interface.present = oc_mtl_surface_present; + surface->interface.swapInterval = oc_mtl_surface_swap_interval; - @autoreleasepool - { - //----------------------------------------------------------- - //NOTE(martin): create a mtl device and a mtl layer and - //----------------------------------------------------------- + @autoreleasepool + { + //----------------------------------------------------------- + //NOTE(martin): create a mtl device and a mtl layer and + //----------------------------------------------------------- - /*WARN(martin): + /*WARN(martin): Calling MTLCreateDefaultSystemDevice(), as advised by the doc, hangs Discord's screen sharing... The workaround I found, which doesn't make sense, is to set the mtlLayer.device to mtlLayer.preferredDevice, even if mtlLayer.preferredDevice is the same value as returned by MTLCreateDefaultSystemDevice(). This works for now and allows screen sharing while using orca, but we'll have to revisit this when we want more control over what GPU gets used. */ - surface->device = nil; + surface->device = nil; - //Select a discrete GPU, if possible - NSArray>* devices = MTLCopyAllDevices(); - for(id device in devices) - { - if(!device.isRemovable && !device.isLowPower) - { - surface->device = device; - break; - } - } - if(surface->device == nil) - { - oc_log_warning("Couldn't select a discrete GPU, using first available device\n"); - surface->device = devices[0]; - } + //Select a discrete GPU, if possible + NSArray>* devices = MTLCopyAllDevices(); + for(id device in devices) + { + if(!device.isRemovable && !device.isLowPower) + { + surface->device = device; + break; + } + } + if(surface->device == nil) + { + oc_log_warning("Couldn't select a discrete GPU, using first available device\n"); + surface->device = devices[0]; + } - //surface->device = MTLCreateSystemDefaultDevice(); + //surface->device = MTLCreateSystemDefaultDevice(); - surface->mtlLayer = [CAMetalLayer layer]; - [surface->mtlLayer retain]; - surface->mtlLayer.device = surface->device; + surface->mtlLayer = [CAMetalLayer layer]; + [surface->mtlLayer retain]; + surface->mtlLayer.device = surface->device; + [surface->mtlLayer setOpaque:NO]; + surface->mtlLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; + [surface->interface.layer.caLayer addSublayer:(CALayer*)surface->mtlLayer]; - [surface->mtlLayer setOpaque:NO]; - surface->mtlLayer.autoresizingMask = kCALayerWidthSizable | kCALayerHeightSizable; - [surface->interface.layer.caLayer addSublayer: (CALayer*)surface->mtlLayer]; + //----------------------------------------------------------- + //NOTE(martin): set the size and scaling + //----------------------------------------------------------- + NSRect frame = [[windowData->osx.nsWindow contentView] frame]; + CGSize size = frame.size; + surface->mtlLayer.frame = (CGRect){ { 0, 0 }, size }; + size.width *= OC_MTL_SURFACE_CONTENTS_SCALING; + size.height *= OC_MTL_SURFACE_CONTENTS_SCALING; + surface->mtlLayer.drawableSize = size; + surface->mtlLayer.contentsScale = OC_MTL_SURFACE_CONTENTS_SCALING; - //----------------------------------------------------------- - //NOTE(martin): set the size and scaling - //----------------------------------------------------------- - NSRect frame = [[windowData->osx.nsWindow contentView] frame]; - CGSize size = frame.size; - surface->mtlLayer.frame = (CGRect){{0, 0}, size}; - size.width *= OC_MTL_SURFACE_CONTENTS_SCALING; - size.height *= OC_MTL_SURFACE_CONTENTS_SCALING; - surface->mtlLayer.drawableSize = size; - surface->mtlLayer.contentsScale = OC_MTL_SURFACE_CONTENTS_SCALING; + surface->mtlLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; - surface->mtlLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; + //NOTE(martin): handling resizing + // surface->mtlLayer.autoresizingMask = kCALayerHeightSizable | kCALayerWidthSizable; + // surface->mtlLayer.needsDisplayOnBoundsChange = YES; - //NOTE(martin): handling resizing -// surface->mtlLayer.autoresizingMask = kCALayerHeightSizable | kCALayerWidthSizable; -// surface->mtlLayer.needsDisplayOnBoundsChange = YES; + //----------------------------------------------------------- + //NOTE(martin): create a command queue + //----------------------------------------------------------- + surface->commandQueue = [surface->device newCommandQueue]; + [surface->commandQueue retain]; - //----------------------------------------------------------- - //NOTE(martin): create a command queue - //----------------------------------------------------------- - surface->commandQueue = [surface->device newCommandQueue]; - [surface->commandQueue retain]; - - //NOTE(martin): command buffer and drawable are set on demand and at the end of each present() call - surface->drawable = nil; - surface->commandBuffer = nil; - } - } - return((oc_surface_data*)surface); + //NOTE(martin): command buffer and drawable are set on demand and at the end of each present() call + surface->drawable = nil; + surface->commandBuffer = nil; + } + } + return ((oc_surface_data*)surface); } void* oc_mtl_surface_layer(oc_surface surface) { - oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); - if(surfaceData && surfaceData->api == OC_METAL) - { - oc_mtl_surface* mtlSurface = (oc_mtl_surface*)surfaceData; - return(mtlSurface->mtlLayer); - } - else - { - return(nil); - } + oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); + if(surfaceData && surfaceData->api == OC_METAL) + { + oc_mtl_surface* mtlSurface = (oc_mtl_surface*)surfaceData; + return (mtlSurface->mtlLayer); + } + else + { + return (nil); + } } void* oc_mtl_surface_drawable(oc_surface surface) { - oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); - if(surfaceData && surfaceData->api == OC_METAL) - { - oc_mtl_surface* mtlSurface = (oc_mtl_surface*)surfaceData; - oc_mtl_surface_acquire_drawable(mtlSurface); - return(mtlSurface->drawable); - } - else - { - return(nil); - } + oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); + if(surfaceData && surfaceData->api == OC_METAL) + { + oc_mtl_surface* mtlSurface = (oc_mtl_surface*)surfaceData; + oc_mtl_surface_acquire_drawable(mtlSurface); + return (mtlSurface->drawable); + } + else + { + return (nil); + } } void* oc_mtl_surface_command_buffer(oc_surface surface) { - oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); - if(surfaceData && surfaceData->api == OC_METAL) - { - oc_mtl_surface* mtlSurface = (oc_mtl_surface*)surfaceData; - oc_mtl_surface_acquire_command_buffer(mtlSurface); - return(mtlSurface->commandBuffer); - } - else - { - return(nil); - } + oc_surface_data* surfaceData = oc_surface_data_from_handle(surface); + if(surfaceData && surfaceData->api == OC_METAL) + { + oc_mtl_surface* mtlSurface = (oc_mtl_surface*)surfaceData; + oc_mtl_surface_acquire_command_buffer(mtlSurface); + return (mtlSurface->commandBuffer); + } + else + { + return (nil); + } } diff --git a/src/graphics/wgl_surface.c b/src/graphics/wgl_surface.c index b12060c..e510c1c 100644 --- a/src/graphics/wgl_surface.c +++ b/src/graphics/wgl_surface.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: wgl_surface.c * @author: Martin Fouilleul @@ -6,273 +6,272 @@ * @revision: * *****************************************************************/ -#include"app/win32_app.h" -#include"graphics_surface.h" -#include"gl_loader.h" +#include "app/win32_app.h" +#include "gl_loader.h" +#include "graphics_surface.h" -#include -#include"util/macros.h" +#include "util/macros.h" +#include -#define OC_WGL_PROC_LIST \ - OC_WGL_PROC(WGLCHOOSEPIXELFORMATARB, wglChoosePixelFormatARB) \ - OC_WGL_PROC(WGLCREATECONTEXTATTRIBSARB, wglCreateContextAttribsARB) \ - OC_WGL_PROC(WGLMAKECONTEXTCURRENTARB, wglMakeContextCurrentARB) \ - OC_WGL_PROC(WGLSWAPINTERVALEXT, wglSwapIntervalEXT) \ +#define OC_WGL_PROC_LIST \ + OC_WGL_PROC(WGLCHOOSEPIXELFORMATARB, wglChoosePixelFormatARB) \ + OC_WGL_PROC(WGLCREATECONTEXTATTRIBSARB, wglCreateContextAttribsARB) \ + OC_WGL_PROC(WGLMAKECONTEXTCURRENTARB, wglMakeContextCurrentARB) \ + OC_WGL_PROC(WGLSWAPINTERVALEXT, wglSwapIntervalEXT) //NOTE: wgl function pointers declarations #define OC_WGL_PROC(type, name) OC_CAT3(PFN, type, PROC) name = 0; - OC_WGL_PROC_LIST +OC_WGL_PROC_LIST #undef OC_WGL_PROC //NOTE: wgl loader typedef struct oc_wgl_dummy_context { - bool init; - HWND hWnd; - HDC hDC; - HGLRC glContext; + bool init; + HWND hWnd; + HDC hDC; + HGLRC glContext; } oc_wgl_dummy_context; -static oc_wgl_dummy_context oc_wglDummyContext = {0}; +static oc_wgl_dummy_context oc_wglDummyContext = { 0 }; static void oc_wgl_init() { - if(!oc_wglDummyContext.init) - { - //NOTE: create a dummy window - WNDCLASS windowClass = {.style = CS_OWNDC, - .lpfnWndProc = DefWindowProc, - .hInstance = GetModuleHandleW(NULL), - .lpszClassName = "oc_wgl_helper_window_class", - .hCursor = LoadCursor(0, IDC_ARROW)}; + if(!oc_wglDummyContext.init) + { + //NOTE: create a dummy window + WNDCLASS windowClass = { .style = CS_OWNDC, + .lpfnWndProc = DefWindowProc, + .hInstance = GetModuleHandleW(NULL), + .lpszClassName = "oc_wgl_helper_window_class", + .hCursor = LoadCursor(0, IDC_ARROW) }; - if(!RegisterClass(&windowClass)) - { - //TODO: error - goto quit; - } + if(!RegisterClass(&windowClass)) + { + //TODO: error + goto quit; + } - oc_wglDummyContext.hWnd = CreateWindow("oc_wgl_helper_window_class", - "dummy", - WS_OVERLAPPEDWINDOW, - 0, 0, 100, 100, - 0, 0, windowClass.hInstance, 0); + oc_wglDummyContext.hWnd = CreateWindow("oc_wgl_helper_window_class", + "dummy", + WS_OVERLAPPEDWINDOW, + 0, 0, 100, 100, + 0, 0, windowClass.hInstance, 0); - if(!oc_wglDummyContext.hWnd) - { - //TODO: error - goto quit; - } - oc_wglDummyContext.hDC = GetDC(oc_wglDummyContext.hWnd); + if(!oc_wglDummyContext.hWnd) + { + //TODO: error + goto quit; + } + oc_wglDummyContext.hDC = GetDC(oc_wglDummyContext.hWnd); - PIXELFORMATDESCRIPTOR pixelFormatDesc = - { - sizeof(PIXELFORMATDESCRIPTOR), - 1, - PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags - PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette. - 32, // Colordepth of the framebuffer. - 0, 0, 0, 0, 0, 0, - 0, - 0, - 0, - 0, 0, 0, 0, - 24, // Number of bits for the depthbuffer - 8, // Number of bits for the stencilbuffer - 0, // Number of Aux buffers in the framebuffer. - PFD_MAIN_PLANE, - 0, - 0, 0, 0 - }; + PIXELFORMATDESCRIPTOR pixelFormatDesc = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags + PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette. + 32, // Colordepth of the framebuffer. + 0, 0, 0, 0, 0, 0, + 0, + 0, + 0, + 0, 0, 0, 0, + 24, // Number of bits for the depthbuffer + 8, // Number of bits for the stencilbuffer + 0, // Number of Aux buffers in the framebuffer. + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; - int pixelFormat = ChoosePixelFormat(oc_wglDummyContext.hDC, &pixelFormatDesc); - SetPixelFormat(oc_wglDummyContext.hDC, pixelFormat, &pixelFormatDesc); + int pixelFormat = ChoosePixelFormat(oc_wglDummyContext.hDC, &pixelFormatDesc); + SetPixelFormat(oc_wglDummyContext.hDC, pixelFormat, &pixelFormatDesc); - oc_wglDummyContext.glContext = wglCreateContext(oc_wglDummyContext.hDC); - wglMakeCurrent(oc_wglDummyContext.hDC, oc_wglDummyContext.glContext); + oc_wglDummyContext.glContext = wglCreateContext(oc_wglDummyContext.hDC); + wglMakeCurrent(oc_wglDummyContext.hDC, oc_wglDummyContext.glContext); - //NOTE(martin): now load WGL extension functions - #define OC_WGL_PROC(type, name) name = (OC_CAT3(PFN, type, PROC))wglGetProcAddress( #name ); - OC_WGL_PROC_LIST - #undef OC_WGL_PROC +//NOTE(martin): now load WGL extension functions +#define OC_WGL_PROC(type, name) name = (OC_CAT3(PFN, type, PROC))wglGetProcAddress(#name); + OC_WGL_PROC_LIST +#undef OC_WGL_PROC - oc_wglDummyContext.init = true; - } - else - { - wglMakeCurrent(oc_wglDummyContext.hDC, oc_wglDummyContext.glContext); - } - quit:; + oc_wglDummyContext.init = true; + } + else + { + wglMakeCurrent(oc_wglDummyContext.hDC, oc_wglDummyContext.glContext); + } +quit:; } #undef OC_WGL_PROC_LIST - typedef struct oc_wgl_surface { - oc_surface_data interface; + oc_surface_data interface; - HDC hDC; - HGLRC glContext; + HDC hDC; + HGLRC glContext; - //NOTE: this may be a bit wasteful to have one api struct per surface, but win32 docs says that loading procs - // from different contexts might select different implementations (eg. depending on context version/pixel format) - oc_gl_api api; + //NOTE: this may be a bit wasteful to have one api struct per surface, but win32 docs says that loading procs + // from different contexts might select different implementations (eg. depending on context version/pixel format) + oc_gl_api api; } oc_wgl_surface; void oc_wgl_surface_destroy(oc_surface_data* interface) { - oc_wgl_surface* surface = (oc_wgl_surface*)interface; + oc_wgl_surface* surface = (oc_wgl_surface*)interface; - if(surface->glContext == wglGetCurrentContext()) - { - wglMakeCurrent(NULL, NULL); - } - wglDeleteContext(surface->glContext); + if(surface->glContext == wglGetCurrentContext()) + { + wglMakeCurrent(NULL, NULL); + } + wglDeleteContext(surface->glContext); - oc_surface_cleanup(interface); + oc_surface_cleanup(interface); - free(surface); + free(surface); } void oc_wgl_surface_prepare(oc_surface_data* interface) { - oc_wgl_surface* surface = (oc_wgl_surface*)interface; + oc_wgl_surface* surface = (oc_wgl_surface*)interface; - wglMakeCurrent(surface->hDC, surface->glContext); - oc_gl_select_api(&surface->api); + wglMakeCurrent(surface->hDC, surface->glContext); + oc_gl_select_api(&surface->api); } void oc_wgl_surface_present(oc_surface_data* interface) { - oc_wgl_surface* surface = (oc_wgl_surface*)interface; + oc_wgl_surface* surface = (oc_wgl_surface*)interface; - SwapBuffers(surface->hDC); + SwapBuffers(surface->hDC); } void oc_wgl_surface_deselect(oc_surface_data* interface) { - wglMakeCurrent(NULL, NULL); - oc_gl_deselect_api(); + wglMakeCurrent(NULL, NULL); + oc_gl_deselect_api(); } void oc_wgl_surface_swap_interval(oc_surface_data* interface, int swap) { - oc_wgl_surface* surface = (oc_wgl_surface*)interface; - wglSwapIntervalEXT(swap); + oc_wgl_surface* surface = (oc_wgl_surface*)interface; + wglSwapIntervalEXT(swap); } void* oc_wgl_get_proc(const char* name) { - void* p = wglGetProcAddress(name); - if( p == 0 - || p == (void*)0x01 - || p == (void*)0x02 - || p == (void*)0x03 - || p == (void*)(-1)) - { - //TODO: should we avoid re-loading every time? - HMODULE module = LoadLibrary("opengl32.dll"); - p = (void*)GetProcAddress(module, name); - } - return(p); + void* p = wglGetProcAddress(name); + if(p == 0 + || p == (void*)0x01 + || p == (void*)0x02 + || p == (void*)0x03 + || p == (void*)(-1)) + { + //TODO: should we avoid re-loading every time? + HMODULE module = LoadLibrary("opengl32.dll"); + p = (void*)GetProcAddress(module, name); + } + return (p); } oc_surface_data* oc_wgl_surface_create_for_window(oc_window window) { - oc_wgl_surface* surface = 0; + oc_wgl_surface* surface = 0; - oc_window_data* windowData = oc_window_ptr_from_handle(window); - if(windowData) - { - oc_wgl_init(); + oc_window_data* windowData = oc_window_ptr_from_handle(window); + if(windowData) + { + oc_wgl_init(); - //NOTE: fill surface data and load api - surface = oc_malloc_type(oc_wgl_surface); - if(surface) - { - memset(surface, 0, sizeof(oc_wgl_surface)); - oc_surface_init_for_window((oc_surface_data*)surface, windowData); + //NOTE: fill surface data and load api + surface = oc_malloc_type(oc_wgl_surface); + if(surface) + { + memset(surface, 0, sizeof(oc_wgl_surface)); + oc_surface_init_for_window((oc_surface_data*)surface, windowData); - surface->interface.api = OC_GL; - surface->interface.destroy = oc_wgl_surface_destroy; - surface->interface.prepare = oc_wgl_surface_prepare; - surface->interface.present = oc_wgl_surface_present; - surface->interface.swapInterval = oc_wgl_surface_swap_interval; - surface->interface.deselect = oc_wgl_surface_deselect; + surface->interface.api = OC_GL; + surface->interface.destroy = oc_wgl_surface_destroy; + surface->interface.prepare = oc_wgl_surface_prepare; + surface->interface.present = oc_wgl_surface_present; + surface->interface.swapInterval = oc_wgl_surface_swap_interval; + surface->interface.deselect = oc_wgl_surface_deselect; - surface->hDC = GetDC(surface->interface.layer.hWnd); + surface->hDC = GetDC(surface->interface.layer.hWnd); - //NOTE(martin): create the pixel format and gl context - PIXELFORMATDESCRIPTOR pixelFormatDesc = - { - sizeof(PIXELFORMATDESCRIPTOR), - 1, - PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags - PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette. - 32, // Colordepth of the framebuffer. - 0, 0, 0, 0, 0, 0, - 0, - 0, - 0, - 0, 0, 0, 0, - 24, // Number of bits for the depthbuffer - 8, // Number of bits for the stencilbuffer - 0, // Number of Aux buffers in the framebuffer. - PFD_MAIN_PLANE, - 0, - 0, 0, 0 - }; + //NOTE(martin): create the pixel format and gl context + PIXELFORMATDESCRIPTOR pixelFormatDesc = { + sizeof(PIXELFORMATDESCRIPTOR), + 1, + PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER, // Flags + PFD_TYPE_RGBA, // The kind of framebuffer. RGBA or palette. + 32, // Colordepth of the framebuffer. + 0, 0, 0, 0, 0, 0, + 0, + 0, + 0, + 0, 0, 0, 0, + 24, // Number of bits for the depthbuffer + 8, // Number of bits for the stencilbuffer + 0, // Number of Aux buffers in the framebuffer. + PFD_MAIN_PLANE, + 0, + 0, 0, 0 + }; - int pixelFormatAttrs[] = { - WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, - WGL_SUPPORT_OPENGL_ARB, GL_TRUE, - WGL_DOUBLE_BUFFER_ARB, GL_TRUE, - WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, - WGL_TRANSPARENT_ARB, TRUE, - WGL_COLOR_BITS_ARB, 32, - WGL_RED_BITS_ARB, 8, - WGL_GREEN_BITS_ARB, 8, - WGL_BLUE_BITS_ARB, 8, - WGL_ALPHA_BITS_ARB, 8, - WGL_DEPTH_BITS_ARB, 24, - WGL_STENCIL_BITS_ARB, 8, - 0}; + int pixelFormatAttrs[] = { + WGL_DRAW_TO_WINDOW_ARB, GL_TRUE, + WGL_SUPPORT_OPENGL_ARB, GL_TRUE, + WGL_DOUBLE_BUFFER_ARB, GL_TRUE, + WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB, + WGL_TRANSPARENT_ARB, TRUE, + WGL_COLOR_BITS_ARB, 32, + WGL_RED_BITS_ARB, 8, + WGL_GREEN_BITS_ARB, 8, + WGL_BLUE_BITS_ARB, 8, + WGL_ALPHA_BITS_ARB, 8, + WGL_DEPTH_BITS_ARB, 24, + WGL_STENCIL_BITS_ARB, 8, + 0 + }; - u32 numFormats = 0; - int pixelFormat = 0; + u32 numFormats = 0; + int pixelFormat = 0; - wglChoosePixelFormatARB(surface->hDC, pixelFormatAttrs, 0, 1, &pixelFormat, &numFormats); + wglChoosePixelFormatARB(surface->hDC, pixelFormatAttrs, 0, 1, &pixelFormat, &numFormats); - if(!pixelFormat) - { - //TODO: error - } - SetPixelFormat(surface->hDC, pixelFormat, &pixelFormatDesc); + if(!pixelFormat) + { + //TODO: error + } + SetPixelFormat(surface->hDC, pixelFormat, &pixelFormatDesc); - int contextAttrs[] = { - WGL_CONTEXT_MAJOR_VERSION_ARB, 4, - WGL_CONTEXT_MINOR_VERSION_ARB, 4, - WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, - 0}; + int contextAttrs[] = { + WGL_CONTEXT_MAJOR_VERSION_ARB, 4, + WGL_CONTEXT_MINOR_VERSION_ARB, 4, + WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, + 0 + }; - surface->glContext = wglCreateContextAttribsARB(surface->hDC, oc_wglDummyContext.glContext, contextAttrs); + surface->glContext = wglCreateContextAttribsARB(surface->hDC, oc_wglDummyContext.glContext, contextAttrs); - if(!surface->glContext) - { - //TODO error - int error = GetLastError(); - printf("error: %i\n", error); - } + if(!surface->glContext) + { + //TODO error + int error = GetLastError(); + printf("error: %i\n", error); + } - //NOTE: make gl context current and load api - wglMakeCurrent(surface->hDC, surface->glContext); - wglSwapIntervalEXT(1); - oc_gl_load_gl44(&surface->api, oc_wgl_get_proc); - } - } - return((oc_surface_data*)surface); + //NOTE: make gl context current and load api + wglMakeCurrent(surface->hDC, surface->glContext); + wglSwapIntervalEXT(1); + oc_gl_load_gl44(&surface->api, oc_wgl_get_proc); + } + } + return ((oc_surface_data*)surface); } diff --git a/src/graphics/wgl_surface.h b/src/graphics/wgl_surface.h index fb7333c..91c3d61 100644 --- a/src/graphics/wgl_surface.h +++ b/src/graphics/wgl_surface.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: wgl_surface.c * @author: Martin Fouilleul @@ -9,7 +9,7 @@ #ifndef __WGL_SURFACE_H_ #define __WGL_SURFACE_H_ -#include"graphics_surface.h" +#include "graphics_surface.h" oc_surface_data* oc_wgl_surface_create_for_window(oc_window window); diff --git a/src/libc-shim/include/assert.h b/src/libc-shim/include/assert.h index 39fe22a..e537bf3 100644 --- a/src/libc-shim/include/assert.h +++ b/src/libc-shim/include/assert.h @@ -1,14 +1,14 @@ +#include "platform/platform_debug.h" #include -#include"platform/platform_debug.h" #undef assert #ifdef NDEBUG -#define assert(x) (void)0 + #define assert(x) (void)0 #else -#define assert(x) OC_ASSERT(x) + #define assert(x) OC_ASSERT(x) #endif #if __STDC_VERSION__ >= 201112L && !defined(__cplusplus) -#define static_assert _Static_assert + #define static_assert _Static_assert #endif diff --git a/src/libc-shim/include/bits/errno.h b/src/libc-shim/include/bits/errno.h index d2e1eee..b9ebc31 100644 --- a/src/libc-shim/include/bits/errno.h +++ b/src/libc-shim/include/bits/errno.h @@ -1,134 +1,134 @@ -#define EPERM 1 -#define ENOENT 2 -#define ESRCH 3 -#define EINTR 4 -#define EIO 5 -#define ENXIO 6 -#define E2BIG 7 -#define ENOEXEC 8 -#define EBADF 9 -#define ECHILD 10 -#define EAGAIN 11 -#define ENOMEM 12 -#define EACCES 13 -#define EFAULT 14 -#define ENOTBLK 15 -#define EBUSY 16 -#define EEXIST 17 -#define EXDEV 18 -#define ENODEV 19 -#define ENOTDIR 20 -#define EISDIR 21 -#define EINVAL 22 -#define ENFILE 23 -#define EMFILE 24 -#define ENOTTY 25 -#define ETXTBSY 26 -#define EFBIG 27 -#define ENOSPC 28 -#define ESPIPE 29 -#define EROFS 30 -#define EMLINK 31 -#define EPIPE 32 -#define EDOM 33 -#define ERANGE 34 -#define EDEADLK 35 -#define ENAMETOOLONG 36 -#define ENOLCK 37 -#define ENOSYS 38 -#define ENOTEMPTY 39 -#define ELOOP 40 -#define EWOULDBLOCK EAGAIN -#define ENOMSG 42 -#define EIDRM 43 -#define ECHRNG 44 -#define EL2NSYNC 45 -#define EL3HLT 46 -#define EL3RST 47 -#define ELNRNG 48 -#define EUNATCH 49 -#define ENOCSI 50 -#define EL2HLT 51 -#define EBADE 52 -#define EBADR 53 -#define EXFULL 54 -#define ENOANO 55 -#define EBADRQC 56 -#define EBADSLT 57 -#define EDEADLOCK EDEADLK -#define EBFONT 59 -#define ENOSTR 60 -#define ENODATA 61 -#define ETIME 62 -#define ENOSR 63 -#define ENONET 64 -#define ENOPKG 65 -#define EREMOTE 66 -#define ENOLINK 67 -#define EADV 68 -#define ESRMNT 69 -#define ECOMM 70 -#define EPROTO 71 -#define EMULTIHOP 72 -#define EDOTDOT 73 -#define EBADMSG 74 -#define EOVERFLOW 75 -#define ENOTUNIQ 76 -#define EBADFD 77 -#define EREMCHG 78 -#define ELIBACC 79 -#define ELIBBAD 80 -#define ELIBSCN 81 -#define ELIBMAX 82 -#define ELIBEXEC 83 -#define EILSEQ 84 -#define ERESTART 85 -#define ESTRPIPE 86 -#define EUSERS 87 -#define ENOTSOCK 88 -#define EDESTADDRREQ 89 -#define EMSGSIZE 90 -#define EPROTOTYPE 91 -#define ENOPROTOOPT 92 +#define EPERM 1 +#define ENOENT 2 +#define ESRCH 3 +#define EINTR 4 +#define EIO 5 +#define ENXIO 6 +#define E2BIG 7 +#define ENOEXEC 8 +#define EBADF 9 +#define ECHILD 10 +#define EAGAIN 11 +#define ENOMEM 12 +#define EACCES 13 +#define EFAULT 14 +#define ENOTBLK 15 +#define EBUSY 16 +#define EEXIST 17 +#define EXDEV 18 +#define ENODEV 19 +#define ENOTDIR 20 +#define EISDIR 21 +#define EINVAL 22 +#define ENFILE 23 +#define EMFILE 24 +#define ENOTTY 25 +#define ETXTBSY 26 +#define EFBIG 27 +#define ENOSPC 28 +#define ESPIPE 29 +#define EROFS 30 +#define EMLINK 31 +#define EPIPE 32 +#define EDOM 33 +#define ERANGE 34 +#define EDEADLK 35 +#define ENAMETOOLONG 36 +#define ENOLCK 37 +#define ENOSYS 38 +#define ENOTEMPTY 39 +#define ELOOP 40 +#define EWOULDBLOCK EAGAIN +#define ENOMSG 42 +#define EIDRM 43 +#define ECHRNG 44 +#define EL2NSYNC 45 +#define EL3HLT 46 +#define EL3RST 47 +#define ELNRNG 48 +#define EUNATCH 49 +#define ENOCSI 50 +#define EL2HLT 51 +#define EBADE 52 +#define EBADR 53 +#define EXFULL 54 +#define ENOANO 55 +#define EBADRQC 56 +#define EBADSLT 57 +#define EDEADLOCK EDEADLK +#define EBFONT 59 +#define ENOSTR 60 +#define ENODATA 61 +#define ETIME 62 +#define ENOSR 63 +#define ENONET 64 +#define ENOPKG 65 +#define EREMOTE 66 +#define ENOLINK 67 +#define EADV 68 +#define ESRMNT 69 +#define ECOMM 70 +#define EPROTO 71 +#define EMULTIHOP 72 +#define EDOTDOT 73 +#define EBADMSG 74 +#define EOVERFLOW 75 +#define ENOTUNIQ 76 +#define EBADFD 77 +#define EREMCHG 78 +#define ELIBACC 79 +#define ELIBBAD 80 +#define ELIBSCN 81 +#define ELIBMAX 82 +#define ELIBEXEC 83 +#define EILSEQ 84 +#define ERESTART 85 +#define ESTRPIPE 86 +#define EUSERS 87 +#define ENOTSOCK 88 +#define EDESTADDRREQ 89 +#define EMSGSIZE 90 +#define EPROTOTYPE 91 +#define ENOPROTOOPT 92 #define EPROTONOSUPPORT 93 #define ESOCKTNOSUPPORT 94 -#define EOPNOTSUPP 95 -#define ENOTSUP EOPNOTSUPP -#define EPFNOSUPPORT 96 -#define EAFNOSUPPORT 97 -#define EADDRINUSE 98 -#define EADDRNOTAVAIL 99 -#define ENETDOWN 100 -#define ENETUNREACH 101 -#define ENETRESET 102 -#define ECONNABORTED 103 -#define ECONNRESET 104 -#define ENOBUFS 105 -#define EISCONN 106 -#define ENOTCONN 107 -#define ESHUTDOWN 108 -#define ETOOMANYREFS 109 -#define ETIMEDOUT 110 -#define ECONNREFUSED 111 -#define EHOSTDOWN 112 -#define EHOSTUNREACH 113 -#define EALREADY 114 -#define EINPROGRESS 115 -#define ESTALE 116 -#define EUCLEAN 117 -#define ENOTNAM 118 -#define ENAVAIL 119 -#define EISNAM 120 -#define EREMOTEIO 121 -#define EDQUOT 122 -#define ENOMEDIUM 123 -#define EMEDIUMTYPE 124 -#define ECANCELED 125 -#define ENOKEY 126 -#define EKEYEXPIRED 127 -#define EKEYREVOKED 128 -#define EKEYREJECTED 129 -#define EOWNERDEAD 130 +#define EOPNOTSUPP 95 +#define ENOTSUP EOPNOTSUPP +#define EPFNOSUPPORT 96 +#define EAFNOSUPPORT 97 +#define EADDRINUSE 98 +#define EADDRNOTAVAIL 99 +#define ENETDOWN 100 +#define ENETUNREACH 101 +#define ENETRESET 102 +#define ECONNABORTED 103 +#define ECONNRESET 104 +#define ENOBUFS 105 +#define EISCONN 106 +#define ENOTCONN 107 +#define ESHUTDOWN 108 +#define ETOOMANYREFS 109 +#define ETIMEDOUT 110 +#define ECONNREFUSED 111 +#define EHOSTDOWN 112 +#define EHOSTUNREACH 113 +#define EALREADY 114 +#define EINPROGRESS 115 +#define ESTALE 116 +#define EUCLEAN 117 +#define ENOTNAM 118 +#define ENAVAIL 119 +#define EISNAM 120 +#define EREMOTEIO 121 +#define EDQUOT 122 +#define ENOMEDIUM 123 +#define EMEDIUMTYPE 124 +#define ECANCELED 125 +#define ENOKEY 126 +#define EKEYEXPIRED 127 +#define EKEYREVOKED 128 +#define EKEYREJECTED 129 +#define EOWNERDEAD 130 #define ENOTRECOVERABLE 131 -#define ERFKILL 132 -#define EHWPOISON 133 +#define ERFKILL 132 +#define EHWPOISON 133 diff --git a/src/libc-shim/include/errno.h b/src/libc-shim/include/errno.h index 0361b33..20e06bc 100644 --- a/src/libc-shim/include/errno.h +++ b/src/libc-shim/include/errno.h @@ -1,8 +1,9 @@ -#ifndef _ERRNO_H +#ifndef _ERRNO_H #define _ERRNO_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #include @@ -10,13 +11,14 @@ extern "C" { #include #ifdef __GNUC__ -__attribute__((const)) + __attribute__((const)) #endif -int *__errno_location(void); + int* + __errno_location(void); #define errno (*__errno_location()) #ifdef _GNU_SOURCE -extern char *program_invocation_short_name, *program_invocation_name; + extern char *program_invocation_short_name, *program_invocation_name; #endif #ifdef __cplusplus @@ -24,4 +26,3 @@ extern char *program_invocation_short_name, *program_invocation_name; #endif #endif - diff --git a/src/libc-shim/include/float.h b/src/libc-shim/include/float.h index 713aadb..671f1ae 100644 --- a/src/libc-shim/include/float.h +++ b/src/libc-shim/include/float.h @@ -2,10 +2,11 @@ #define _FLOAT_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int __flt_rounds(void); + int __flt_rounds(void); #define FLT_ROUNDS (__flt_rounds()) #define FLT_RADIX 2 diff --git a/src/libc-shim/include/math.h b/src/libc-shim/include/math.h index 58c2697..6d33075 100644 --- a/src/libc-shim/include/math.h +++ b/src/libc-shim/include/math.h @@ -2,90 +2,99 @@ #define _MATH_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -// NOTE(orca): not doing anything fancy for float_t and double_t -typedef float float_t; -typedef double double_t; + // NOTE(orca): not doing anything fancy for float_t and double_t + typedef float float_t; + typedef double double_t; -#define NAN __builtin_nanf("") -#define INFINITY __builtin_inff() +#define NAN __builtin_nanf("") +#define INFINITY __builtin_inff() -#define FP_NAN 0 -#define FP_INFINITE 1 -#define FP_ZERO 2 +#define FP_NAN 0 +#define FP_INFINITE 1 +#define FP_ZERO 2 #define FP_SUBNORMAL 3 -#define FP_NORMAL 4 +#define FP_NORMAL 4 -int __fpclassify(double); -int __fpclassifyf(float); -int __fpclassifyl(long double); + int __fpclassify(double); + int __fpclassifyf(float); + int __fpclassifyl(long double); -static __inline unsigned __FLOAT_BITS(float __f) -{ - union {float __f; unsigned __i;} __u; - __u.__f = __f; - return __u.__i; -} -static __inline unsigned long long __DOUBLE_BITS(double __f) -{ - union {double __f; unsigned long long __i;} __u; - __u.__f = __f; - return __u.__i; -} + static __inline unsigned __FLOAT_BITS(float __f) + { + union + { + float __f; + unsigned __i; + } __u; -#define fpclassify(x) ( \ - sizeof(x) == sizeof(float) ? __fpclassifyf(x) : \ - sizeof(x) == sizeof(double) ? __fpclassify(x) : \ - __fpclassifyl(x) ) + __u.__f = __f; + return __u.__i; + } -#define isinf(x) ( \ - sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) == 0x7f800000 : \ - sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) == 0x7ffULL<<52 : \ - __fpclassifyl(x) == FP_INFINITE) + static __inline unsigned long long __DOUBLE_BITS(double __f) + { + union + { + double __f; + unsigned long long __i; + } __u; -#define isnan(x) ( \ - sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) > 0x7f800000 : \ - sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL>>1) > 0x7ffULL<<52 : \ - __fpclassifyl(x) == FP_NAN) + __u.__f = __f; + return __u.__i; + } -double acos(double); +#define fpclassify(x) ( \ + sizeof(x) == sizeof(float) ? __fpclassifyf(x) : sizeof(x) == sizeof(double) ? __fpclassify(x) \ + : __fpclassifyl(x)) -double ceil(double); +#define isinf(x) ( \ + sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) == 0x7f800000 : sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL >> 1) == 0x7ffULL << 52 \ + : __fpclassifyl(x) == FP_INFINITE) -double cos(double); -float cosf(float); +#define isnan(x) ( \ + sizeof(x) == sizeof(float) ? (__FLOAT_BITS(x) & 0x7fffffff) > 0x7f800000 : sizeof(x) == sizeof(double) ? (__DOUBLE_BITS(x) & -1ULL >> 1) > 0x7ffULL << 52 \ + : __fpclassifyl(x) == FP_NAN) -double fabs(double); + double acos(double); -double floor(double); + double ceil(double); -double fmod(double, double); + double cos(double); + float cosf(float); -double pow(double, double); + double fabs(double); -double scalbn(double, int); + double floor(double); -double sin(double); -float sinf(float); + double fmod(double, double); -double sqrt(double); -float sqrtf(float); + double pow(double, double); -#define M_E 2.7182818284590452354 /* e */ -#define M_LOG2E 1.4426950408889634074 /* log_2 e */ -#define M_LOG10E 0.43429448190325182765 /* log_10 e */ -#define M_LN2 0.69314718055994530942 /* log_e 2 */ -#define M_LN10 2.30258509299404568402 /* log_e 10 */ -#define M_PI 3.14159265358979323846 /* pi */ -#define M_PI_2 1.57079632679489661923 /* pi/2 */ -#define M_PI_4 0.78539816339744830962 /* pi/4 */ -#define M_1_PI 0.31830988618379067154 /* 1/pi */ -#define M_2_PI 0.63661977236758134308 /* 2/pi */ -#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */ -#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ -#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ + double scalbn(double, int); + + double sin(double); + float sinf(float); + + double sqrt(double); + float sqrtf(float); + +#define M_E 2.7182818284590452354 /* e */ +#define M_LOG2E 1.4426950408889634074 /* log_2 e */ +#define M_LOG10E 0.43429448190325182765 /* log_10 e */ +#define M_LN2 0.69314718055994530942 /* log_e 2 */ +#define M_LN10 2.30258509299404568402 /* log_e 10 */ +#define M_PI 3.14159265358979323846 /* pi */ +#define M_PI_2 1.57079632679489661923 /* pi/2 */ +#define M_PI_4 0.78539816339744830962 /* pi/4 */ +#define M_1_PI 0.31830988618379067154 /* 1/pi */ +#define M_2_PI 0.63661977236758134308 /* 2/pi */ +#define M_2_SQRTPI 1.12837916709551257390 /* 2/sqrt(pi) */ +#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ +#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ #ifdef __cplusplus } diff --git a/src/libc-shim/include/stdarg.h b/src/libc-shim/include/stdarg.h index cbc5f3e..227d980 100644 --- a/src/libc-shim/include/stdarg.h +++ b/src/libc-shim/include/stdarg.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: stdarg.h * @author: Martin Fouilleul diff --git a/src/libc-shim/include/stdlib.h b/src/libc-shim/include/stdlib.h index eeceafe..24478d4 100644 --- a/src/libc-shim/include/stdlib.h +++ b/src/libc-shim/include/stdlib.h @@ -2,12 +2,13 @@ #define _STDLIB_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #define abort(...) OC_ABORT(__VA_ARGS__) -int abs (int); + int abs(int); #ifdef __cplusplus } diff --git a/src/libc-shim/include/string.h b/src/libc-shim/include/string.h index 76d92be..dc719bb 100644 --- a/src/libc-shim/include/string.h +++ b/src/libc-shim/include/string.h @@ -1,13 +1,13 @@ -#include"stb/stb_sprintf.h" +#include "stb/stb_sprintf.h" void* memset(void* b, int c, size_t n); -void* memcpy(void *restrict dst, const void *restrict src, size_t n); -void* memmove(void *dst, const void *src, size_t n); -int memcmp(const void *s1, const void *s2, size_t n); +void* memcpy(void* restrict dst, const void* restrict src, size_t n); +void* memmove(void* dst, const void* src, size_t n); +int memcmp(const void* s1, const void* s2, size_t n); -size_t strlen(const char *s); -int strcmp(const char *s1, const char *s2); -int strncmp(const char *s1, const char *s2, size_t n); -char* strcpy(char *restrict s1, const char *restrict s2); +size_t strlen(const char* s); +int strcmp(const char* s1, const char* s2); +int strncmp(const char* s1, const char* s2, size_t n); +char* strcpy(char* restrict s1, const char* restrict s2); #define vsnprintf stbsp_vsnprintf diff --git a/src/libc-shim/src/__cos.c b/src/libc-shim/src/__cos.c index 46cefb3..424b34b 100644 --- a/src/libc-shim/src/__cos.c +++ b/src/libc-shim/src/__cos.c @@ -51,21 +51,21 @@ #include "libm.h" static const double -C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */ -C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */ -C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */ -C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */ -C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */ -C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */ + C1 = 4.16666666666666019037e-02, /* 0x3FA55555, 0x5555554C */ + C2 = -1.38888888888741095749e-03, /* 0xBF56C16C, 0x16C15177 */ + C3 = 2.48015872894767294178e-05, /* 0x3EFA01A0, 0x19CB1590 */ + C4 = -2.75573143513906633035e-07, /* 0xBE927E4F, 0x809C52AD */ + C5 = 2.08757232129817482790e-09, /* 0x3E21EE9E, 0xBDB4B1C4 */ + C6 = -1.13596475577881948265e-11; /* 0xBDA8FAE9, 0xBE8838D4 */ double __cos(double x, double y) { - double_t hz,z,r,w; + double_t hz, z, r, w; - z = x*x; - w = z*z; - r = z*(C1+z*(C2+z*C3)) + w*w*(C4+z*(C5+z*C6)); - hz = 0.5*z; - w = 1.0-hz; - return w + (((1.0-w)-hz) + (z*r-x*y)); + z = x * x; + w = z * z; + r = z * (C1 + z * (C2 + z * C3)) + w * w * (C4 + z * (C5 + z * C6)); + hz = 0.5 * z; + w = 1.0 - hz; + return w + (((1.0 - w) - hz) + (z * r - x * y)); } diff --git a/src/libc-shim/src/__cosdf.c b/src/libc-shim/src/__cosdf.c index 2124989..5f19c26 100644 --- a/src/libc-shim/src/__cosdf.c +++ b/src/libc-shim/src/__cosdf.c @@ -18,18 +18,18 @@ /* |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). */ static const double -C0 = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */ -C1 = 0x155553e1053a42.0p-57, /* 0.0416666233237390631894 */ -C2 = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */ -C3 = 0x199342e0ee5069.0p-68; /* 0.0000243904487962774090654 */ + C0 = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */ + C1 = 0x155553e1053a42.0p-57, /* 0.0416666233237390631894 */ + C2 = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */ + C3 = 0x199342e0ee5069.0p-68; /* 0.0000243904487962774090654 */ float __cosdf(double x) { - double_t r, w, z; + double_t r, w, z; - /* Try to optimize for parallel evaluation as in __tandf.c. */ - z = x*x; - w = z*z; - r = C2+z*C3; - return ((1.0+z*C0) + w*C1) + (w*z)*r; + /* Try to optimize for parallel evaluation as in __tandf.c. */ + z = x * x; + w = z * z; + r = C2 + z * C3; + return ((1.0 + z * C0) + w * C1) + (w * z) * r; } diff --git a/src/libc-shim/src/__errno_location.c b/src/libc-shim/src/__errno_location.c index 6d0f1c9..43f203f 100644 --- a/src/libc-shim/src/__errno_location.c +++ b/src/libc-shim/src/__errno_location.c @@ -2,7 +2,7 @@ int errno; -int *__errno_location(void) +int* __errno_location(void) { // NOTE(orca): We might need a better solution if we eventually support wasm threads. return &errno; diff --git a/src/libc-shim/src/__math_invalid.c b/src/libc-shim/src/__math_invalid.c index 1774049..fa42cd9 100644 --- a/src/libc-shim/src/__math_invalid.c +++ b/src/libc-shim/src/__math_invalid.c @@ -2,5 +2,5 @@ double __math_invalid(double x) { - return (x - x) / (x - x); + return (x - x) / (x - x); } diff --git a/src/libc-shim/src/__math_invalidf.c b/src/libc-shim/src/__math_invalidf.c index 357d4b1..7fc9cb5 100644 --- a/src/libc-shim/src/__math_invalidf.c +++ b/src/libc-shim/src/__math_invalidf.c @@ -2,5 +2,5 @@ float __math_invalidf(float x) { - return (x - x) / (x - x); + return (x - x) / (x - x); } diff --git a/src/libc-shim/src/__math_oflow.c b/src/libc-shim/src/__math_oflow.c index c85dbf9..a197e79 100644 --- a/src/libc-shim/src/__math_oflow.c +++ b/src/libc-shim/src/__math_oflow.c @@ -2,5 +2,5 @@ double __math_oflow(uint32_t sign) { - return __math_xflow(sign, 0x1p769); + return __math_xflow(sign, 0x1p769); } diff --git a/src/libc-shim/src/__math_uflow.c b/src/libc-shim/src/__math_uflow.c index b90594a..7e4c0c2 100644 --- a/src/libc-shim/src/__math_uflow.c +++ b/src/libc-shim/src/__math_uflow.c @@ -2,5 +2,5 @@ double __math_uflow(uint32_t sign) { - return __math_xflow(sign, 0x1p-767); + return __math_xflow(sign, 0x1p-767); } diff --git a/src/libc-shim/src/__math_xflow.c b/src/libc-shim/src/__math_xflow.c index 4ef5394..9118f29 100644 --- a/src/libc-shim/src/__math_xflow.c +++ b/src/libc-shim/src/__math_xflow.c @@ -3,6 +3,6 @@ double __math_xflow(uint32_t sign, double y) { // NOTE(orca): no fp barriers - // return eval_as_double(fp_barrier(sign ? -y : y) * y); - return eval_as_double((sign ? -y : y) * y); + // return eval_as_double(fp_barrier(sign ? -y : y) * y); + return eval_as_double((sign ? -y : y) * y); } diff --git a/src/libc-shim/src/__rem_pio2.c b/src/libc-shim/src/__rem_pio2.c index dcf672f..7e33167 100644 --- a/src/libc-shim/src/__rem_pio2.c +++ b/src/libc-shim/src/__rem_pio2.c @@ -19,10 +19,10 @@ #include "libm.h" -#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 -#define EPS DBL_EPSILON -#elif FLT_EVAL_METHOD==2 -#define EPS LDBL_EPSILON +#if FLT_EVAL_METHOD == 0 || FLT_EVAL_METHOD == 1 + #define EPS DBL_EPSILON +#elif FLT_EVAL_METHOD == 2 + #define EPS LDBL_EPSILON #endif /* @@ -35,156 +35,190 @@ * pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3) */ static const double -toint = 1.5/EPS, -pio4 = 0x1.921fb54442d18p-1, -invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ -pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ -pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */ -pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */ -pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */ -pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */ -pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */ + toint = 1.5 / EPS, + pio4 = 0x1.921fb54442d18p-1, + invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ + pio2_1 = 1.57079632673412561417e+00, /* 0x3FF921FB, 0x54400000 */ + pio2_1t = 6.07710050650619224932e-11, /* 0x3DD0B461, 0x1A626331 */ + pio2_2 = 6.07710050630396597660e-11, /* 0x3DD0B461, 0x1A600000 */ + pio2_2t = 2.02226624879595063154e-21, /* 0x3BA3198A, 0x2E037073 */ + pio2_3 = 2.02226624871116645580e-21, /* 0x3BA3198A, 0x2E000000 */ + pio2_3t = 8.47842766036889956997e-32; /* 0x397B839A, 0x252049C1 */ /* caller must handle the case when reduction is not needed: |x| ~<= pi/4 */ -int __rem_pio2(double x, double *y) +int __rem_pio2(double x, double* y) { - union {double f; uint64_t i;} u = {x}; - double_t z,w,t,r,fn; - double tx[3],ty[2]; - uint32_t ix; - int sign, n, ex, ey, i; + union + { + double f; + uint64_t i; + } u = { x }; - sign = u.i>>63; - ix = u.i>>32 & 0x7fffffff; - if (ix <= 0x400f6a7a) { /* |x| ~<= 5pi/4 */ - if ((ix & 0xfffff) == 0x921fb) /* |x| ~= pi/2 or 2pi/2 */ - goto medium; /* cancellation -- use medium case */ - if (ix <= 0x4002d97c) { /* |x| ~<= 3pi/4 */ - if (!sign) { - z = x - pio2_1; /* one round good to 85 bits */ - y[0] = z - pio2_1t; - y[1] = (z-y[0]) - pio2_1t; - return 1; - } else { - z = x + pio2_1; - y[0] = z + pio2_1t; - y[1] = (z-y[0]) + pio2_1t; - return -1; - } - } else { - if (!sign) { - z = x - 2*pio2_1; - y[0] = z - 2*pio2_1t; - y[1] = (z-y[0]) - 2*pio2_1t; - return 2; - } else { - z = x + 2*pio2_1; - y[0] = z + 2*pio2_1t; - y[1] = (z-y[0]) + 2*pio2_1t; - return -2; - } - } - } - if (ix <= 0x401c463b) { /* |x| ~<= 9pi/4 */ - if (ix <= 0x4015fdbc) { /* |x| ~<= 7pi/4 */ - if (ix == 0x4012d97c) /* |x| ~= 3pi/2 */ - goto medium; - if (!sign) { - z = x - 3*pio2_1; - y[0] = z - 3*pio2_1t; - y[1] = (z-y[0]) - 3*pio2_1t; - return 3; - } else { - z = x + 3*pio2_1; - y[0] = z + 3*pio2_1t; - y[1] = (z-y[0]) + 3*pio2_1t; - return -3; - } - } else { - if (ix == 0x401921fb) /* |x| ~= 4pi/2 */ - goto medium; - if (!sign) { - z = x - 4*pio2_1; - y[0] = z - 4*pio2_1t; - y[1] = (z-y[0]) - 4*pio2_1t; - return 4; - } else { - z = x + 4*pio2_1; - y[0] = z + 4*pio2_1t; - y[1] = (z-y[0]) + 4*pio2_1t; - return -4; - } - } - } - if (ix < 0x413921fb) { /* |x| ~< 2^20*(pi/2), medium size */ -medium: - /* rint(x/(pi/2)) */ - fn = (double_t)x*invpio2 + toint - toint; - n = (int32_t)fn; - r = x - fn*pio2_1; - w = fn*pio2_1t; /* 1st round, good to 85 bits */ - /* Matters with directed rounding. */ - if (predict_false(r - w < -pio4)) { - n--; - fn--; - r = x - fn*pio2_1; - w = fn*pio2_1t; - } else if (predict_false(r - w > pio4)) { - n++; - fn++; - r = x - fn*pio2_1; - w = fn*pio2_1t; - } - y[0] = r - w; - u.f = y[0]; - ey = u.i>>52 & 0x7ff; - ex = ix>>20; - if (ex - ey > 16) { /* 2nd round, good to 118 bits */ - t = r; - w = fn*pio2_2; - r = t - w; - w = fn*pio2_2t - ((t-r)-w); - y[0] = r - w; - u.f = y[0]; - ey = u.i>>52 & 0x7ff; - if (ex - ey > 49) { /* 3rd round, good to 151 bits, covers all cases */ - t = r; - w = fn*pio2_3; - r = t - w; - w = fn*pio2_3t - ((t-r)-w); - y[0] = r - w; - } - } - y[1] = (r - y[0]) - w; - return n; - } - /* + double_t z, w, t, r, fn; + double tx[3], ty[2]; + uint32_t ix; + int sign, n, ex, ey, i; + + sign = u.i >> 63; + ix = u.i >> 32 & 0x7fffffff; + if(ix <= 0x400f6a7a) + { /* |x| ~<= 5pi/4 */ + if((ix & 0xfffff) == 0x921fb) /* |x| ~= pi/2 or 2pi/2 */ + goto medium; /* cancellation -- use medium case */ + if(ix <= 0x4002d97c) + { /* |x| ~<= 3pi/4 */ + if(!sign) + { + z = x - pio2_1; /* one round good to 85 bits */ + y[0] = z - pio2_1t; + y[1] = (z - y[0]) - pio2_1t; + return 1; + } + else + { + z = x + pio2_1; + y[0] = z + pio2_1t; + y[1] = (z - y[0]) + pio2_1t; + return -1; + } + } + else + { + if(!sign) + { + z = x - 2 * pio2_1; + y[0] = z - 2 * pio2_1t; + y[1] = (z - y[0]) - 2 * pio2_1t; + return 2; + } + else + { + z = x + 2 * pio2_1; + y[0] = z + 2 * pio2_1t; + y[1] = (z - y[0]) + 2 * pio2_1t; + return -2; + } + } + } + if(ix <= 0x401c463b) + { /* |x| ~<= 9pi/4 */ + if(ix <= 0x4015fdbc) + { /* |x| ~<= 7pi/4 */ + if(ix == 0x4012d97c) /* |x| ~= 3pi/2 */ + goto medium; + if(!sign) + { + z = x - 3 * pio2_1; + y[0] = z - 3 * pio2_1t; + y[1] = (z - y[0]) - 3 * pio2_1t; + return 3; + } + else + { + z = x + 3 * pio2_1; + y[0] = z + 3 * pio2_1t; + y[1] = (z - y[0]) + 3 * pio2_1t; + return -3; + } + } + else + { + if(ix == 0x401921fb) /* |x| ~= 4pi/2 */ + goto medium; + if(!sign) + { + z = x - 4 * pio2_1; + y[0] = z - 4 * pio2_1t; + y[1] = (z - y[0]) - 4 * pio2_1t; + return 4; + } + else + { + z = x + 4 * pio2_1; + y[0] = z + 4 * pio2_1t; + y[1] = (z - y[0]) + 4 * pio2_1t; + return -4; + } + } + } + if(ix < 0x413921fb) + { /* |x| ~< 2^20*(pi/2), medium size */ + medium: + /* rint(x/(pi/2)) */ + fn = (double_t)x * invpio2 + toint - toint; + n = (int32_t)fn; + r = x - fn * pio2_1; + w = fn * pio2_1t; /* 1st round, good to 85 bits */ + /* Matters with directed rounding. */ + if(predict_false(r - w < -pio4)) + { + n--; + fn--; + r = x - fn * pio2_1; + w = fn * pio2_1t; + } + else if(predict_false(r - w > pio4)) + { + n++; + fn++; + r = x - fn * pio2_1; + w = fn * pio2_1t; + } + y[0] = r - w; + u.f = y[0]; + ey = u.i >> 52 & 0x7ff; + ex = ix >> 20; + if(ex - ey > 16) + { /* 2nd round, good to 118 bits */ + t = r; + w = fn * pio2_2; + r = t - w; + w = fn * pio2_2t - ((t - r) - w); + y[0] = r - w; + u.f = y[0]; + ey = u.i >> 52 & 0x7ff; + if(ex - ey > 49) + { /* 3rd round, good to 151 bits, covers all cases */ + t = r; + w = fn * pio2_3; + r = t - w; + w = fn * pio2_3t - ((t - r) - w); + y[0] = r - w; + } + } + y[1] = (r - y[0]) - w; + return n; + } + /* * all other (large) arguments */ - if (ix >= 0x7ff00000) { /* x is inf or NaN */ - y[0] = y[1] = x - x; - return 0; - } - /* set z = scalbn(|x|,-ilogb(x)+23) */ - u.f = x; - u.i &= (uint64_t)-1>>12; - u.i |= (uint64_t)(0x3ff + 23)<<52; - z = u.f; - for (i=0; i < 2; i++) { - tx[i] = (double)(int32_t)z; - z = (z-tx[i])*0x1p24; - } - tx[i] = z; - /* skip zero terms, first term is non-zero */ - while (tx[i] == 0.0) - i--; - n = __rem_pio2_large(tx,ty,(int)(ix>>20)-(0x3ff+23),i+1,1); - if (sign) { - y[0] = -ty[0]; - y[1] = -ty[1]; - return -n; - } - y[0] = ty[0]; - y[1] = ty[1]; - return n; + if(ix >= 0x7ff00000) + { /* x is inf or NaN */ + y[0] = y[1] = x - x; + return 0; + } + /* set z = scalbn(|x|,-ilogb(x)+23) */ + u.f = x; + u.i &= (uint64_t)-1 >> 12; + u.i |= (uint64_t)(0x3ff + 23) << 52; + z = u.f; + for(i = 0; i < 2; i++) + { + tx[i] = (double)(int32_t)z; + z = (z - tx[i]) * 0x1p24; + } + tx[i] = z; + /* skip zero terms, first term is non-zero */ + while(tx[i] == 0.0) + i--; + n = __rem_pio2_large(tx, ty, (int)(ix >> 20) - (0x3ff + 23), i + 1, 1); + if(sign) + { + y[0] = -ty[0]; + y[1] = -ty[1]; + return -n; + } + y[0] = ty[0]; + y[1] = ty[1]; + return n; } diff --git a/src/libc-shim/src/__rem_pio2_large.c b/src/libc-shim/src/__rem_pio2_large.c index 958f28c..bfdfad3 100644 --- a/src/libc-shim/src/__rem_pio2_large.c +++ b/src/libc-shim/src/__rem_pio2_large.c @@ -124,7 +124,7 @@ #include "libm.h" -static const int init_jk[] = {3,4,4,6}; /* initial value for jk */ +static const int init_jk[] = { 3, 4, 4, 6 }; /* initial value for jk */ /* * Table of constants for 2/pi, 396 Hex digits (476 decimal) of 2/pi @@ -139,304 +139,922 @@ static const int init_jk[] = {3,4,4,6}; /* initial value for jk */ * For quad precision (e0 <= 16360, jk = 6), this is 686. */ static const int32_t ipio2[] = { -0xA2F983, 0x6E4E44, 0x1529FC, 0x2757D1, 0xF534DD, 0xC0DB62, -0x95993C, 0x439041, 0xFE5163, 0xABDEBB, 0xC561B7, 0x246E3A, -0x424DD2, 0xE00649, 0x2EEA09, 0xD1921C, 0xFE1DEB, 0x1CB129, -0xA73EE8, 0x8235F5, 0x2EBB44, 0x84E99C, 0x7026B4, 0x5F7E41, -0x3991D6, 0x398353, 0x39F49C, 0x845F8B, 0xBDF928, 0x3B1FF8, -0x97FFDE, 0x05980F, 0xEF2F11, 0x8B5A0A, 0x6D1F6D, 0x367ECF, -0x27CB09, 0xB74F46, 0x3F669E, 0x5FEA2D, 0x7527BA, 0xC7EBE5, -0xF17B3D, 0x0739F7, 0x8A5292, 0xEA6BFB, 0x5FB11F, 0x8D5D08, -0x560330, 0x46FC7B, 0x6BABF0, 0xCFBC20, 0x9AF436, 0x1DA9E3, -0x91615E, 0xE61B08, 0x659985, 0x5F14A0, 0x68408D, 0xFFD880, -0x4D7327, 0x310606, 0x1556CA, 0x73A8C9, 0x60E27B, 0xC08C6B, + 0xA2F983, + 0x6E4E44, + 0x1529FC, + 0x2757D1, + 0xF534DD, + 0xC0DB62, + 0x95993C, + 0x439041, + 0xFE5163, + 0xABDEBB, + 0xC561B7, + 0x246E3A, + 0x424DD2, + 0xE00649, + 0x2EEA09, + 0xD1921C, + 0xFE1DEB, + 0x1CB129, + 0xA73EE8, + 0x8235F5, + 0x2EBB44, + 0x84E99C, + 0x7026B4, + 0x5F7E41, + 0x3991D6, + 0x398353, + 0x39F49C, + 0x845F8B, + 0xBDF928, + 0x3B1FF8, + 0x97FFDE, + 0x05980F, + 0xEF2F11, + 0x8B5A0A, + 0x6D1F6D, + 0x367ECF, + 0x27CB09, + 0xB74F46, + 0x3F669E, + 0x5FEA2D, + 0x7527BA, + 0xC7EBE5, + 0xF17B3D, + 0x0739F7, + 0x8A5292, + 0xEA6BFB, + 0x5FB11F, + 0x8D5D08, + 0x560330, + 0x46FC7B, + 0x6BABF0, + 0xCFBC20, + 0x9AF436, + 0x1DA9E3, + 0x91615E, + 0xE61B08, + 0x659985, + 0x5F14A0, + 0x68408D, + 0xFFD880, + 0x4D7327, + 0x310606, + 0x1556CA, + 0x73A8C9, + 0x60E27B, + 0xC08C6B, #if LDBL_MAX_EXP > 1024 -0x47C419, 0xC367CD, 0xDCE809, 0x2A8359, 0xC4768B, 0x961CA6, -0xDDAF44, 0xD15719, 0x053EA5, 0xFF0705, 0x3F7E33, 0xE832C2, -0xDE4F98, 0x327DBB, 0xC33D26, 0xEF6B1E, 0x5EF89F, 0x3A1F35, -0xCAF27F, 0x1D87F1, 0x21907C, 0x7C246A, 0xFA6ED5, 0x772D30, -0x433B15, 0xC614B5, 0x9D19C3, 0xC2C4AD, 0x414D2C, 0x5D000C, -0x467D86, 0x2D71E3, 0x9AC69B, 0x006233, 0x7CD2B4, 0x97A7B4, -0xD55537, 0xF63ED7, 0x1810A3, 0xFC764D, 0x2A9D64, 0xABD770, -0xF87C63, 0x57B07A, 0xE71517, 0x5649C0, 0xD9D63B, 0x3884A7, -0xCB2324, 0x778AD6, 0x23545A, 0xB91F00, 0x1B0AF1, 0xDFCE19, -0xFF319F, 0x6A1E66, 0x615799, 0x47FBAC, 0xD87F7E, 0xB76522, -0x89E832, 0x60BFE6, 0xCDC4EF, 0x09366C, 0xD43F5D, 0xD7DE16, -0xDE3B58, 0x929BDE, 0x2822D2, 0xE88628, 0x4D58E2, 0x32CAC6, -0x16E308, 0xCB7DE0, 0x50C017, 0xA71DF3, 0x5BE018, 0x34132E, -0x621283, 0x014883, 0x5B8EF5, 0x7FB0AD, 0xF2E91E, 0x434A48, -0xD36710, 0xD8DDAA, 0x425FAE, 0xCE616A, 0xA4280A, 0xB499D3, -0xF2A606, 0x7F775C, 0x83C2A3, 0x883C61, 0x78738A, 0x5A8CAF, -0xBDD76F, 0x63A62D, 0xCBBFF4, 0xEF818D, 0x67C126, 0x45CA55, -0x36D9CA, 0xD2A828, 0x8D61C2, 0x77C912, 0x142604, 0x9B4612, -0xC459C4, 0x44C5C8, 0x91B24D, 0xF31700, 0xAD43D4, 0xE54929, -0x10D5FD, 0xFCBE00, 0xCC941E, 0xEECE70, 0xF53E13, 0x80F1EC, -0xC3E7B3, 0x28F8C7, 0x940593, 0x3E71C1, 0xB3092E, 0xF3450B, -0x9C1288, 0x7B20AB, 0x9FB52E, 0xC29247, 0x2F327B, 0x6D550C, -0x90A772, 0x1FE76B, 0x96CB31, 0x4A1679, 0xE27941, 0x89DFF4, -0x9794E8, 0x84E6E2, 0x973199, 0x6BED88, 0x365F5F, 0x0EFDBB, -0xB49A48, 0x6CA467, 0x427271, 0x325D8D, 0xB8159F, 0x09E5BC, -0x25318D, 0x3974F7, 0x1C0530, 0x010C0D, 0x68084B, 0x58EE2C, -0x90AA47, 0x02E774, 0x24D6BD, 0xA67DF7, 0x72486E, 0xEF169F, -0xA6948E, 0xF691B4, 0x5153D1, 0xF20ACF, 0x339820, 0x7E4BF5, -0x6863B2, 0x5F3EDD, 0x035D40, 0x7F8985, 0x295255, 0xC06437, -0x10D86D, 0x324832, 0x754C5B, 0xD4714E, 0x6E5445, 0xC1090B, -0x69F52A, 0xD56614, 0x9D0727, 0x50045D, 0xDB3BB4, 0xC576EA, -0x17F987, 0x7D6B49, 0xBA271D, 0x296996, 0xACCCC6, 0x5414AD, -0x6AE290, 0x89D988, 0x50722C, 0xBEA404, 0x940777, 0x7030F3, -0x27FC00, 0xA871EA, 0x49C266, 0x3DE064, 0x83DD97, 0x973FA3, -0xFD9443, 0x8C860D, 0xDE4131, 0x9D3992, 0x8C70DD, 0xE7B717, -0x3BDF08, 0x2B3715, 0xA0805C, 0x93805A, 0x921110, 0xD8E80F, -0xAF806C, 0x4BFFDB, 0x0F9038, 0x761859, 0x15A562, 0xBBCB61, -0xB989C7, 0xBD4010, 0x04F2D2, 0x277549, 0xF6B6EB, 0xBB22DB, -0xAA140A, 0x2F2689, 0x768364, 0x333B09, 0x1A940E, 0xAA3A51, -0xC2A31D, 0xAEEDAF, 0x12265C, 0x4DC26D, 0x9C7A2D, 0x9756C0, -0x833F03, 0xF6F009, 0x8C402B, 0x99316D, 0x07B439, 0x15200C, -0x5BC3D8, 0xC492F5, 0x4BADC6, 0xA5CA4E, 0xCD37A7, 0x36A9E6, -0x9492AB, 0x6842DD, 0xDE6319, 0xEF8C76, 0x528B68, 0x37DBFC, -0xABA1AE, 0x3115DF, 0xA1AE00, 0xDAFB0C, 0x664D64, 0xB705ED, -0x306529, 0xBF5657, 0x3AFF47, 0xB9F96A, 0xF3BE75, 0xDF9328, -0x3080AB, 0xF68C66, 0x15CB04, 0x0622FA, 0x1DE4D9, 0xA4B33D, -0x8F1B57, 0x09CD36, 0xE9424E, 0xA4BE13, 0xB52333, 0x1AAAF0, -0xA8654F, 0xA5C1D2, 0x0F3F0B, 0xCD785B, 0x76F923, 0x048B7B, -0x721789, 0x53A6C6, 0xE26E6F, 0x00EBEF, 0x584A9B, 0xB7DAC4, -0xBA66AA, 0xCFCF76, 0x1D02D1, 0x2DF1B1, 0xC1998C, 0x77ADC3, -0xDA4886, 0xA05DF7, 0xF480C6, 0x2FF0AC, 0x9AECDD, 0xBC5C3F, -0x6DDED0, 0x1FC790, 0xB6DB2A, 0x3A25A3, 0x9AAF00, 0x9353AD, -0x0457B6, 0xB42D29, 0x7E804B, 0xA707DA, 0x0EAA76, 0xA1597B, -0x2A1216, 0x2DB7DC, 0xFDE5FA, 0xFEDB89, 0xFDBE89, 0x6C76E4, -0xFCA906, 0x70803E, 0x156E85, 0xFF87FD, 0x073E28, 0x336761, -0x86182A, 0xEABD4D, 0xAFE7B3, 0x6E6D8F, 0x396795, 0x5BBF31, -0x48D784, 0x16DF30, 0x432DC7, 0x356125, 0xCE70C9, 0xB8CB30, -0xFD6CBF, 0xA200A4, 0xE46C05, 0xA0DD5A, 0x476F21, 0xD21262, -0x845CB9, 0x496170, 0xE0566B, 0x015299, 0x375550, 0xB7D51E, -0xC4F133, 0x5F6E13, 0xE4305D, 0xA92E85, 0xC3B21D, 0x3632A1, -0xA4B708, 0xD4B1EA, 0x21F716, 0xE4698F, 0x77FF27, 0x80030C, -0x2D408D, 0xA0CD4F, 0x99A520, 0xD3A2B3, 0x0A5D2F, 0x42F9B4, -0xCBDA11, 0xD0BE7D, 0xC1DB9B, 0xBD17AB, 0x81A2CA, 0x5C6A08, -0x17552E, 0x550027, 0xF0147F, 0x8607E1, 0x640B14, 0x8D4196, -0xDEBE87, 0x2AFDDA, 0xB6256B, 0x34897B, 0xFEF305, 0x9EBFB9, -0x4F6A68, 0xA82A4A, 0x5AC44F, 0xBCF82D, 0x985AD7, 0x95C7F4, -0x8D4D0D, 0xA63A20, 0x5F57A4, 0xB13F14, 0x953880, 0x0120CC, -0x86DD71, 0xB6DEC9, 0xF560BF, 0x11654D, 0x6B0701, 0xACB08C, -0xD0C0B2, 0x485551, 0x0EFB1E, 0xC37295, 0x3B06A3, 0x3540C0, -0x7BDC06, 0xCC45E0, 0xFA294E, 0xC8CAD6, 0x41F3E8, 0xDE647C, -0xD8649B, 0x31BED9, 0xC397A4, 0xD45877, 0xC5E369, 0x13DAF0, -0x3C3ABA, 0x461846, 0x5F7555, 0xF5BDD2, 0xC6926E, 0x5D2EAC, -0xED440E, 0x423E1C, 0x87C461, 0xE9FD29, 0xF3D6E7, 0xCA7C22, -0x35916F, 0xC5E008, 0x8DD7FF, 0xE26A6E, 0xC6FDB0, 0xC10893, -0x745D7C, 0xB2AD6B, 0x9D6ECD, 0x7B723E, 0x6A11C6, 0xA9CFF7, -0xDF7329, 0xBAC9B5, 0x5100B7, 0x0DB2E2, 0x24BA74, 0x607DE5, -0x8AD874, 0x2C150D, 0x0C1881, 0x94667E, 0x162901, 0x767A9F, -0xBEFDFD, 0xEF4556, 0x367ED9, 0x13D9EC, 0xB9BA8B, 0xFC97C4, -0x27A831, 0xC36EF1, 0x36C594, 0x56A8D8, 0xB5A8B4, 0x0ECCCF, -0x2D8912, 0x34576F, 0x89562C, 0xE3CE99, 0xB920D6, 0xAA5E6B, -0x9C2A3E, 0xCC5F11, 0x4A0BFD, 0xFBF4E1, 0x6D3B8E, 0x2C86E2, -0x84D4E9, 0xA9B4FC, 0xD1EEEF, 0xC9352E, 0x61392F, 0x442138, -0xC8D91B, 0x0AFC81, 0x6A4AFB, 0xD81C2F, 0x84B453, 0x8C994E, -0xCC2254, 0xDC552A, 0xD6C6C0, 0x96190B, 0xB8701A, 0x649569, -0x605A26, 0xEE523F, 0x0F117F, 0x11B5F4, 0xF5CBFC, 0x2DBC34, -0xEEBC34, 0xCC5DE8, 0x605EDD, 0x9B8E67, 0xEF3392, 0xB817C9, -0x9B5861, 0xBC57E1, 0xC68351, 0x103ED8, 0x4871DD, 0xDD1C2D, -0xA118AF, 0x462C21, 0xD7F359, 0x987AD9, 0xC0549E, 0xFA864F, -0xFC0656, 0xAE79E5, 0x362289, 0x22AD38, 0xDC9367, 0xAAE855, -0x382682, 0x9BE7CA, 0xA40D51, 0xB13399, 0x0ED7A9, 0x480569, -0xF0B265, 0xA7887F, 0x974C88, 0x36D1F9, 0xB39221, 0x4A827B, -0x21CF98, 0xDC9F40, 0x5547DC, 0x3A74E1, 0x42EB67, 0xDF9DFE, -0x5FD45E, 0xA4677B, 0x7AACBA, 0xA2F655, 0x23882B, 0x55BA41, -0x086E59, 0x862A21, 0x834739, 0xE6E389, 0xD49EE5, 0x40FB49, -0xE956FF, 0xCA0F1C, 0x8A59C5, 0x2BFA94, 0xC5C1D3, 0xCFC50F, -0xAE5ADB, 0x86C547, 0x624385, 0x3B8621, 0x94792C, 0x876110, -0x7B4C2A, 0x1A2C80, 0x12BF43, 0x902688, 0x893C78, 0xE4C4A8, -0x7BDBE5, 0xC23AC4, 0xEAF426, 0x8A67F7, 0xBF920D, 0x2BA365, -0xB1933D, 0x0B7CBD, 0xDC51A4, 0x63DD27, 0xDDE169, 0x19949A, -0x9529A8, 0x28CE68, 0xB4ED09, 0x209F44, 0xCA984E, 0x638270, -0x237C7E, 0x32B90F, 0x8EF5A7, 0xE75614, 0x08F121, 0x2A9DB5, -0x4D7E6F, 0x5119A5, 0xABF9B5, 0xD6DF82, 0x61DD96, 0x023616, -0x9F3AC4, 0xA1A283, 0x6DED72, 0x7A8D39, 0xA9B882, 0x5C326B, -0x5B2746, 0xED3400, 0x7700D2, 0x55F4FC, 0x4D5901, 0x8071E0, + 0x47C419, + 0xC367CD, + 0xDCE809, + 0x2A8359, + 0xC4768B, + 0x961CA6, + 0xDDAF44, + 0xD15719, + 0x053EA5, + 0xFF0705, + 0x3F7E33, + 0xE832C2, + 0xDE4F98, + 0x327DBB, + 0xC33D26, + 0xEF6B1E, + 0x5EF89F, + 0x3A1F35, + 0xCAF27F, + 0x1D87F1, + 0x21907C, + 0x7C246A, + 0xFA6ED5, + 0x772D30, + 0x433B15, + 0xC614B5, + 0x9D19C3, + 0xC2C4AD, + 0x414D2C, + 0x5D000C, + 0x467D86, + 0x2D71E3, + 0x9AC69B, + 0x006233, + 0x7CD2B4, + 0x97A7B4, + 0xD55537, + 0xF63ED7, + 0x1810A3, + 0xFC764D, + 0x2A9D64, + 0xABD770, + 0xF87C63, + 0x57B07A, + 0xE71517, + 0x5649C0, + 0xD9D63B, + 0x3884A7, + 0xCB2324, + 0x778AD6, + 0x23545A, + 0xB91F00, + 0x1B0AF1, + 0xDFCE19, + 0xFF319F, + 0x6A1E66, + 0x615799, + 0x47FBAC, + 0xD87F7E, + 0xB76522, + 0x89E832, + 0x60BFE6, + 0xCDC4EF, + 0x09366C, + 0xD43F5D, + 0xD7DE16, + 0xDE3B58, + 0x929BDE, + 0x2822D2, + 0xE88628, + 0x4D58E2, + 0x32CAC6, + 0x16E308, + 0xCB7DE0, + 0x50C017, + 0xA71DF3, + 0x5BE018, + 0x34132E, + 0x621283, + 0x014883, + 0x5B8EF5, + 0x7FB0AD, + 0xF2E91E, + 0x434A48, + 0xD36710, + 0xD8DDAA, + 0x425FAE, + 0xCE616A, + 0xA4280A, + 0xB499D3, + 0xF2A606, + 0x7F775C, + 0x83C2A3, + 0x883C61, + 0x78738A, + 0x5A8CAF, + 0xBDD76F, + 0x63A62D, + 0xCBBFF4, + 0xEF818D, + 0x67C126, + 0x45CA55, + 0x36D9CA, + 0xD2A828, + 0x8D61C2, + 0x77C912, + 0x142604, + 0x9B4612, + 0xC459C4, + 0x44C5C8, + 0x91B24D, + 0xF31700, + 0xAD43D4, + 0xE54929, + 0x10D5FD, + 0xFCBE00, + 0xCC941E, + 0xEECE70, + 0xF53E13, + 0x80F1EC, + 0xC3E7B3, + 0x28F8C7, + 0x940593, + 0x3E71C1, + 0xB3092E, + 0xF3450B, + 0x9C1288, + 0x7B20AB, + 0x9FB52E, + 0xC29247, + 0x2F327B, + 0x6D550C, + 0x90A772, + 0x1FE76B, + 0x96CB31, + 0x4A1679, + 0xE27941, + 0x89DFF4, + 0x9794E8, + 0x84E6E2, + 0x973199, + 0x6BED88, + 0x365F5F, + 0x0EFDBB, + 0xB49A48, + 0x6CA467, + 0x427271, + 0x325D8D, + 0xB8159F, + 0x09E5BC, + 0x25318D, + 0x3974F7, + 0x1C0530, + 0x010C0D, + 0x68084B, + 0x58EE2C, + 0x90AA47, + 0x02E774, + 0x24D6BD, + 0xA67DF7, + 0x72486E, + 0xEF169F, + 0xA6948E, + 0xF691B4, + 0x5153D1, + 0xF20ACF, + 0x339820, + 0x7E4BF5, + 0x6863B2, + 0x5F3EDD, + 0x035D40, + 0x7F8985, + 0x295255, + 0xC06437, + 0x10D86D, + 0x324832, + 0x754C5B, + 0xD4714E, + 0x6E5445, + 0xC1090B, + 0x69F52A, + 0xD56614, + 0x9D0727, + 0x50045D, + 0xDB3BB4, + 0xC576EA, + 0x17F987, + 0x7D6B49, + 0xBA271D, + 0x296996, + 0xACCCC6, + 0x5414AD, + 0x6AE290, + 0x89D988, + 0x50722C, + 0xBEA404, + 0x940777, + 0x7030F3, + 0x27FC00, + 0xA871EA, + 0x49C266, + 0x3DE064, + 0x83DD97, + 0x973FA3, + 0xFD9443, + 0x8C860D, + 0xDE4131, + 0x9D3992, + 0x8C70DD, + 0xE7B717, + 0x3BDF08, + 0x2B3715, + 0xA0805C, + 0x93805A, + 0x921110, + 0xD8E80F, + 0xAF806C, + 0x4BFFDB, + 0x0F9038, + 0x761859, + 0x15A562, + 0xBBCB61, + 0xB989C7, + 0xBD4010, + 0x04F2D2, + 0x277549, + 0xF6B6EB, + 0xBB22DB, + 0xAA140A, + 0x2F2689, + 0x768364, + 0x333B09, + 0x1A940E, + 0xAA3A51, + 0xC2A31D, + 0xAEEDAF, + 0x12265C, + 0x4DC26D, + 0x9C7A2D, + 0x9756C0, + 0x833F03, + 0xF6F009, + 0x8C402B, + 0x99316D, + 0x07B439, + 0x15200C, + 0x5BC3D8, + 0xC492F5, + 0x4BADC6, + 0xA5CA4E, + 0xCD37A7, + 0x36A9E6, + 0x9492AB, + 0x6842DD, + 0xDE6319, + 0xEF8C76, + 0x528B68, + 0x37DBFC, + 0xABA1AE, + 0x3115DF, + 0xA1AE00, + 0xDAFB0C, + 0x664D64, + 0xB705ED, + 0x306529, + 0xBF5657, + 0x3AFF47, + 0xB9F96A, + 0xF3BE75, + 0xDF9328, + 0x3080AB, + 0xF68C66, + 0x15CB04, + 0x0622FA, + 0x1DE4D9, + 0xA4B33D, + 0x8F1B57, + 0x09CD36, + 0xE9424E, + 0xA4BE13, + 0xB52333, + 0x1AAAF0, + 0xA8654F, + 0xA5C1D2, + 0x0F3F0B, + 0xCD785B, + 0x76F923, + 0x048B7B, + 0x721789, + 0x53A6C6, + 0xE26E6F, + 0x00EBEF, + 0x584A9B, + 0xB7DAC4, + 0xBA66AA, + 0xCFCF76, + 0x1D02D1, + 0x2DF1B1, + 0xC1998C, + 0x77ADC3, + 0xDA4886, + 0xA05DF7, + 0xF480C6, + 0x2FF0AC, + 0x9AECDD, + 0xBC5C3F, + 0x6DDED0, + 0x1FC790, + 0xB6DB2A, + 0x3A25A3, + 0x9AAF00, + 0x9353AD, + 0x0457B6, + 0xB42D29, + 0x7E804B, + 0xA707DA, + 0x0EAA76, + 0xA1597B, + 0x2A1216, + 0x2DB7DC, + 0xFDE5FA, + 0xFEDB89, + 0xFDBE89, + 0x6C76E4, + 0xFCA906, + 0x70803E, + 0x156E85, + 0xFF87FD, + 0x073E28, + 0x336761, + 0x86182A, + 0xEABD4D, + 0xAFE7B3, + 0x6E6D8F, + 0x396795, + 0x5BBF31, + 0x48D784, + 0x16DF30, + 0x432DC7, + 0x356125, + 0xCE70C9, + 0xB8CB30, + 0xFD6CBF, + 0xA200A4, + 0xE46C05, + 0xA0DD5A, + 0x476F21, + 0xD21262, + 0x845CB9, + 0x496170, + 0xE0566B, + 0x015299, + 0x375550, + 0xB7D51E, + 0xC4F133, + 0x5F6E13, + 0xE4305D, + 0xA92E85, + 0xC3B21D, + 0x3632A1, + 0xA4B708, + 0xD4B1EA, + 0x21F716, + 0xE4698F, + 0x77FF27, + 0x80030C, + 0x2D408D, + 0xA0CD4F, + 0x99A520, + 0xD3A2B3, + 0x0A5D2F, + 0x42F9B4, + 0xCBDA11, + 0xD0BE7D, + 0xC1DB9B, + 0xBD17AB, + 0x81A2CA, + 0x5C6A08, + 0x17552E, + 0x550027, + 0xF0147F, + 0x8607E1, + 0x640B14, + 0x8D4196, + 0xDEBE87, + 0x2AFDDA, + 0xB6256B, + 0x34897B, + 0xFEF305, + 0x9EBFB9, + 0x4F6A68, + 0xA82A4A, + 0x5AC44F, + 0xBCF82D, + 0x985AD7, + 0x95C7F4, + 0x8D4D0D, + 0xA63A20, + 0x5F57A4, + 0xB13F14, + 0x953880, + 0x0120CC, + 0x86DD71, + 0xB6DEC9, + 0xF560BF, + 0x11654D, + 0x6B0701, + 0xACB08C, + 0xD0C0B2, + 0x485551, + 0x0EFB1E, + 0xC37295, + 0x3B06A3, + 0x3540C0, + 0x7BDC06, + 0xCC45E0, + 0xFA294E, + 0xC8CAD6, + 0x41F3E8, + 0xDE647C, + 0xD8649B, + 0x31BED9, + 0xC397A4, + 0xD45877, + 0xC5E369, + 0x13DAF0, + 0x3C3ABA, + 0x461846, + 0x5F7555, + 0xF5BDD2, + 0xC6926E, + 0x5D2EAC, + 0xED440E, + 0x423E1C, + 0x87C461, + 0xE9FD29, + 0xF3D6E7, + 0xCA7C22, + 0x35916F, + 0xC5E008, + 0x8DD7FF, + 0xE26A6E, + 0xC6FDB0, + 0xC10893, + 0x745D7C, + 0xB2AD6B, + 0x9D6ECD, + 0x7B723E, + 0x6A11C6, + 0xA9CFF7, + 0xDF7329, + 0xBAC9B5, + 0x5100B7, + 0x0DB2E2, + 0x24BA74, + 0x607DE5, + 0x8AD874, + 0x2C150D, + 0x0C1881, + 0x94667E, + 0x162901, + 0x767A9F, + 0xBEFDFD, + 0xEF4556, + 0x367ED9, + 0x13D9EC, + 0xB9BA8B, + 0xFC97C4, + 0x27A831, + 0xC36EF1, + 0x36C594, + 0x56A8D8, + 0xB5A8B4, + 0x0ECCCF, + 0x2D8912, + 0x34576F, + 0x89562C, + 0xE3CE99, + 0xB920D6, + 0xAA5E6B, + 0x9C2A3E, + 0xCC5F11, + 0x4A0BFD, + 0xFBF4E1, + 0x6D3B8E, + 0x2C86E2, + 0x84D4E9, + 0xA9B4FC, + 0xD1EEEF, + 0xC9352E, + 0x61392F, + 0x442138, + 0xC8D91B, + 0x0AFC81, + 0x6A4AFB, + 0xD81C2F, + 0x84B453, + 0x8C994E, + 0xCC2254, + 0xDC552A, + 0xD6C6C0, + 0x96190B, + 0xB8701A, + 0x649569, + 0x605A26, + 0xEE523F, + 0x0F117F, + 0x11B5F4, + 0xF5CBFC, + 0x2DBC34, + 0xEEBC34, + 0xCC5DE8, + 0x605EDD, + 0x9B8E67, + 0xEF3392, + 0xB817C9, + 0x9B5861, + 0xBC57E1, + 0xC68351, + 0x103ED8, + 0x4871DD, + 0xDD1C2D, + 0xA118AF, + 0x462C21, + 0xD7F359, + 0x987AD9, + 0xC0549E, + 0xFA864F, + 0xFC0656, + 0xAE79E5, + 0x362289, + 0x22AD38, + 0xDC9367, + 0xAAE855, + 0x382682, + 0x9BE7CA, + 0xA40D51, + 0xB13399, + 0x0ED7A9, + 0x480569, + 0xF0B265, + 0xA7887F, + 0x974C88, + 0x36D1F9, + 0xB39221, + 0x4A827B, + 0x21CF98, + 0xDC9F40, + 0x5547DC, + 0x3A74E1, + 0x42EB67, + 0xDF9DFE, + 0x5FD45E, + 0xA4677B, + 0x7AACBA, + 0xA2F655, + 0x23882B, + 0x55BA41, + 0x086E59, + 0x862A21, + 0x834739, + 0xE6E389, + 0xD49EE5, + 0x40FB49, + 0xE956FF, + 0xCA0F1C, + 0x8A59C5, + 0x2BFA94, + 0xC5C1D3, + 0xCFC50F, + 0xAE5ADB, + 0x86C547, + 0x624385, + 0x3B8621, + 0x94792C, + 0x876110, + 0x7B4C2A, + 0x1A2C80, + 0x12BF43, + 0x902688, + 0x893C78, + 0xE4C4A8, + 0x7BDBE5, + 0xC23AC4, + 0xEAF426, + 0x8A67F7, + 0xBF920D, + 0x2BA365, + 0xB1933D, + 0x0B7CBD, + 0xDC51A4, + 0x63DD27, + 0xDDE169, + 0x19949A, + 0x9529A8, + 0x28CE68, + 0xB4ED09, + 0x209F44, + 0xCA984E, + 0x638270, + 0x237C7E, + 0x32B90F, + 0x8EF5A7, + 0xE75614, + 0x08F121, + 0x2A9DB5, + 0x4D7E6F, + 0x5119A5, + 0xABF9B5, + 0xD6DF82, + 0x61DD96, + 0x023616, + 0x9F3AC4, + 0xA1A283, + 0x6DED72, + 0x7A8D39, + 0xA9B882, + 0x5C326B, + 0x5B2746, + 0xED3400, + 0x7700D2, + 0x55F4FC, + 0x4D5901, + 0x8071E0, #endif }; static const double PIo2[] = { - 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */ - 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */ - 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */ - 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */ - 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */ - 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */ - 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */ - 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */ + 1.57079625129699707031e+00, /* 0x3FF921FB, 0x40000000 */ + 7.54978941586159635335e-08, /* 0x3E74442D, 0x00000000 */ + 5.39030252995776476554e-15, /* 0x3CF84698, 0x80000000 */ + 3.28200341580791294123e-22, /* 0x3B78CC51, 0x60000000 */ + 1.27065575308067607349e-29, /* 0x39F01B83, 0x80000000 */ + 1.22933308981111328932e-36, /* 0x387A2520, 0x40000000 */ + 2.73370053816464559624e-44, /* 0x36E38222, 0x80000000 */ + 2.16741683877804819444e-51, /* 0x3569F31D, 0x00000000 */ }; -int __rem_pio2_large(double *x, double *y, int e0, int nx, int prec) +int __rem_pio2_large(double* x, double* y, int e0, int nx, int prec) { - int32_t jz,jx,jv,jp,jk,carry,n,iq[20],i,j,k,m,q0,ih; - double z,fw,f[20],fq[20],q[20]; + int32_t jz, jx, jv, jp, jk, carry, n, iq[20], i, j, k, m, q0, ih; + double z, fw, f[20], fq[20], q[20]; - /* initialize jk*/ - jk = init_jk[prec]; - jp = jk; + /* initialize jk*/ + jk = init_jk[prec]; + jp = jk; - /* determine jx,jv,q0, note that 3>q0 */ - jx = nx-1; - jv = (e0-3)/24; if(jv<0) jv=0; - q0 = e0-24*(jv+1); + /* determine jx,jv,q0, note that 3>q0 */ + jx = nx - 1; + jv = (e0 - 3) / 24; + if(jv < 0) + jv = 0; + q0 = e0 - 24 * (jv + 1); - /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ - j = jv-jx; m = jx+jk; - for (i=0; i<=m; i++,j++) - f[i] = j<0 ? 0.0 : (double)ipio2[j]; + /* set up f[0] to f[jx+jk] where f[jx+jk] = ipio2[jv+jk] */ + j = jv - jx; + m = jx + jk; + for(i = 0; i <= m; i++, j++) + f[i] = j < 0 ? 0.0 : (double)ipio2[j]; - /* compute q[0],q[1],...q[jk] */ - for (i=0; i<=jk; i++) { - for (j=0,fw=0.0; j<=jx; j++) - fw += x[j]*f[jx+i-j]; - q[i] = fw; - } + /* compute q[0],q[1],...q[jk] */ + for(i = 0; i <= jk; i++) + { + for(j = 0, fw = 0.0; j <= jx; j++) + fw += x[j] * f[jx + i - j]; + q[i] = fw; + } - jz = jk; + jz = jk; recompute: - /* distill q[] into iq[] reversingly */ - for (i=0,j=jz,z=q[jz]; j>0; i++,j--) { - fw = (double)(int32_t)(0x1p-24*z); - iq[i] = (int32_t)(z - 0x1p24*fw); - z = q[j-1]+fw; - } + /* distill q[] into iq[] reversingly */ + for(i = 0, j = jz, z = q[jz]; j > 0; i++, j--) + { + fw = (double)(int32_t)(0x1p-24 * z); + iq[i] = (int32_t)(z - 0x1p24 * fw); + z = q[j - 1] + fw; + } - /* compute n */ - z = scalbn(z,q0); /* actual value of z */ - z -= 8.0*floor(z*0.125); /* trim off integer >= 8 */ - n = (int32_t)z; - z -= (double)n; - ih = 0; - if (q0 > 0) { /* need iq[jz-1] to determine n */ - i = iq[jz-1]>>(24-q0); n += i; - iq[jz-1] -= i<<(24-q0); - ih = iq[jz-1]>>(23-q0); - } - else if (q0 == 0) ih = iq[jz-1]>>23; - else if (z >= 0.5) ih = 2; + /* compute n */ + z = scalbn(z, q0); /* actual value of z */ + z -= 8.0 * floor(z * 0.125); /* trim off integer >= 8 */ + n = (int32_t)z; + z -= (double)n; + ih = 0; + if(q0 > 0) + { /* need iq[jz-1] to determine n */ + i = iq[jz - 1] >> (24 - q0); + n += i; + iq[jz - 1] -= i << (24 - q0); + ih = iq[jz - 1] >> (23 - q0); + } + else if(q0 == 0) + ih = iq[jz - 1] >> 23; + else if(z >= 0.5) + ih = 2; - if (ih > 0) { /* q > 0.5 */ - n += 1; carry = 0; - for (i=0; i 0) { /* rare case: chance is 1 in 12 */ - switch(q0) { - case 1: - iq[jz-1] &= 0x7fffff; break; - case 2: - iq[jz-1] &= 0x3fffff; break; - } - } - if (ih == 2) { - z = 1.0 - z; - if (carry != 0) - z -= scalbn(1.0,q0); - } - } + if(ih > 0) + { /* q > 0.5 */ + n += 1; + carry = 0; + for(i = 0; i < jz; i++) + { /* compute 1-q */ + j = iq[i]; + if(carry == 0) + { + if(j != 0) + { + carry = 1; + iq[i] = 0x1000000 - j; + } + } + else + iq[i] = 0xffffff - j; + } + if(q0 > 0) + { /* rare case: chance is 1 in 12 */ + switch(q0) + { + case 1: + iq[jz - 1] &= 0x7fffff; + break; + case 2: + iq[jz - 1] &= 0x3fffff; + break; + } + } + if(ih == 2) + { + z = 1.0 - z; + if(carry != 0) + z -= scalbn(1.0, q0); + } + } - /* check if recomputation is needed */ - if (z == 0.0) { - j = 0; - for (i=jz-1; i>=jk; i--) j |= iq[i]; - if (j == 0) { /* need recomputation */ - for (k=1; iq[jk-k]==0; k++); /* k = no. of terms needed */ + /* check if recomputation is needed */ + if(z == 0.0) + { + j = 0; + for(i = jz - 1; i >= jk; i--) + j |= iq[i]; + if(j == 0) + { /* need recomputation */ + for(k = 1; iq[jk - k] == 0; k++) + ; /* k = no. of terms needed */ - for (i=jz+1; i<=jz+k; i++) { /* add q[jz+1] to q[jz+k] */ - f[jx+i] = (double)ipio2[jv+i]; - for (j=0,fw=0.0; j<=jx; j++) - fw += x[j]*f[jx+i-j]; - q[i] = fw; - } - jz += k; - goto recompute; - } - } + for(i = jz + 1; i <= jz + k; i++) + { /* add q[jz+1] to q[jz+k] */ + f[jx + i] = (double)ipio2[jv + i]; + for(j = 0, fw = 0.0; j <= jx; j++) + fw += x[j] * f[jx + i - j]; + q[i] = fw; + } + jz += k; + goto recompute; + } + } - /* chop off zero terms */ - if (z == 0.0) { - jz -= 1; - q0 -= 24; - while (iq[jz] == 0) { - jz--; - q0 -= 24; - } - } else { /* break z into 24-bit if necessary */ - z = scalbn(z,-q0); - if (z >= 0x1p24) { - fw = (double)(int32_t)(0x1p-24*z); - iq[jz] = (int32_t)(z - 0x1p24*fw); - jz += 1; - q0 += 24; - iq[jz] = (int32_t)fw; - } else - iq[jz] = (int32_t)z; - } + /* chop off zero terms */ + if(z == 0.0) + { + jz -= 1; + q0 -= 24; + while(iq[jz] == 0) + { + jz--; + q0 -= 24; + } + } + else + { /* break z into 24-bit if necessary */ + z = scalbn(z, -q0); + if(z >= 0x1p24) + { + fw = (double)(int32_t)(0x1p-24 * z); + iq[jz] = (int32_t)(z - 0x1p24 * fw); + jz += 1; + q0 += 24; + iq[jz] = (int32_t)fw; + } + else + iq[jz] = (int32_t)z; + } - /* convert integer "bit" chunk to floating-point value */ - fw = scalbn(1.0,q0); - for (i=jz; i>=0; i--) { - q[i] = fw*(double)iq[i]; - fw *= 0x1p-24; - } + /* convert integer "bit" chunk to floating-point value */ + fw = scalbn(1.0, q0); + for(i = jz; i >= 0; i--) + { + q[i] = fw * (double)iq[i]; + fw *= 0x1p-24; + } - /* compute PIo2[0,...,jp]*q[jz,...,0] */ - for(i=jz; i>=0; i--) { - for (fw=0.0,k=0; k<=jp && k<=jz-i; k++) - fw += PIo2[k]*q[i+k]; - fq[jz-i] = fw; - } + /* compute PIo2[0,...,jp]*q[jz,...,0] */ + for(i = jz; i >= 0; i--) + { + for(fw = 0.0, k = 0; k <= jp && k <= jz - i; k++) + fw += PIo2[k] * q[i + k]; + fq[jz - i] = fw; + } - /* compress fq[] into y[] */ - switch(prec) { - case 0: - fw = 0.0; - for (i=jz; i>=0; i--) - fw += fq[i]; - y[0] = ih==0 ? fw : -fw; - break; - case 1: - case 2: - fw = 0.0; - for (i=jz; i>=0; i--) - fw += fq[i]; - // TODO: drop excess precision here once double_t is used - fw = (double)fw; - y[0] = ih==0 ? fw : -fw; - fw = fq[0]-fw; - for (i=1; i<=jz; i++) - fw += fq[i]; - y[1] = ih==0 ? fw : -fw; - break; - case 3: /* painful */ - for (i=jz; i>0; i--) { - fw = fq[i-1]+fq[i]; - fq[i] += fq[i-1]-fw; - fq[i-1] = fw; - } - for (i=jz; i>1; i--) { - fw = fq[i-1]+fq[i]; - fq[i] += fq[i-1]-fw; - fq[i-1] = fw; - } - for (fw=0.0,i=jz; i>=2; i--) - fw += fq[i]; - if (ih==0) { - y[0] = fq[0]; y[1] = fq[1]; y[2] = fw; - } else { - y[0] = -fq[0]; y[1] = -fq[1]; y[2] = -fw; - } - } - return n&7; + /* compress fq[] into y[] */ + switch(prec) + { + case 0: + fw = 0.0; + for(i = jz; i >= 0; i--) + fw += fq[i]; + y[0] = ih == 0 ? fw : -fw; + break; + case 1: + case 2: + fw = 0.0; + for(i = jz; i >= 0; i--) + fw += fq[i]; + // TODO: drop excess precision here once double_t is used + fw = (double)fw; + y[0] = ih == 0 ? fw : -fw; + fw = fq[0] - fw; + for(i = 1; i <= jz; i++) + fw += fq[i]; + y[1] = ih == 0 ? fw : -fw; + break; + case 3: /* painful */ + for(i = jz; i > 0; i--) + { + fw = fq[i - 1] + fq[i]; + fq[i] += fq[i - 1] - fw; + fq[i - 1] = fw; + } + for(i = jz; i > 1; i--) + { + fw = fq[i - 1] + fq[i]; + fq[i] += fq[i - 1] - fw; + fq[i - 1] = fw; + } + for(fw = 0.0, i = jz; i >= 2; i--) + fw += fq[i]; + if(ih == 0) + { + y[0] = fq[0]; + y[1] = fq[1]; + y[2] = fw; + } + else + { + y[0] = -fq[0]; + y[1] = -fq[1]; + y[2] = -fw; + } + } + return n & 7; } diff --git a/src/libc-shim/src/__rem_pio2f.c b/src/libc-shim/src/__rem_pio2f.c index e676564..6917f1d 100644 --- a/src/libc-shim/src/__rem_pio2f.c +++ b/src/libc-shim/src/__rem_pio2f.c @@ -22,10 +22,10 @@ #include "libm.h" -#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 -#define EPS DBL_EPSILON -#elif FLT_EVAL_METHOD==2 -#define EPS LDBL_EPSILON +#if FLT_EVAL_METHOD == 0 || FLT_EVAL_METHOD == 1 + #define EPS DBL_EPSILON +#elif FLT_EVAL_METHOD == 2 + #define EPS LDBL_EPSILON #endif /* @@ -34,53 +34,64 @@ * pio2_1t: pi/2 - pio2_1 */ static const double -toint = 1.5/EPS, -pio4 = 0x1.921fb6p-1, -invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ -pio2_1 = 1.57079631090164184570e+00, /* 0x3FF921FB, 0x50000000 */ -pio2_1t = 1.58932547735281966916e-08; /* 0x3E5110b4, 0x611A6263 */ + toint = 1.5 / EPS, + pio4 = 0x1.921fb6p-1, + invpio2 = 6.36619772367581382433e-01, /* 0x3FE45F30, 0x6DC9C883 */ + pio2_1 = 1.57079631090164184570e+00, /* 0x3FF921FB, 0x50000000 */ + pio2_1t = 1.58932547735281966916e-08; /* 0x3E5110b4, 0x611A6263 */ -int __rem_pio2f(float x, double *y) +int __rem_pio2f(float x, double* y) { - union {float f; uint32_t i;} u = {x}; - double tx[1],ty[1]; - double_t fn; - uint32_t ix; - int n, sign, e0; + union + { + float f; + uint32_t i; + } u = { x }; - ix = u.i & 0x7fffffff; - /* 25+53 bit pi is good enough for medium size */ - if (ix < 0x4dc90fdb) { /* |x| ~< 2^28*(pi/2), medium size */ - /* Use a specialized rint() to get fn. */ - fn = (double_t)x*invpio2 + toint - toint; - n = (int32_t)fn; - *y = x - fn*pio2_1 - fn*pio2_1t; - /* Matters with directed rounding. */ - if (predict_false(*y < -pio4)) { - n--; - fn--; - *y = x - fn*pio2_1 - fn*pio2_1t; - } else if (predict_false(*y > pio4)) { - n++; - fn++; - *y = x - fn*pio2_1 - fn*pio2_1t; - } - return n; - } - if(ix>=0x7f800000) { /* x is inf or NaN */ - *y = x-x; - return 0; - } - /* scale x into [2^23, 2^24-1] */ - sign = u.i>>31; - e0 = (ix>>23) - (0x7f+23); /* e0 = ilogb(|x|)-23, positive */ - u.i = ix - (e0<<23); - tx[0] = u.f; - n = __rem_pio2_large(tx,ty,e0,1,0); - if (sign) { - *y = -ty[0]; - return -n; - } - *y = ty[0]; - return n; + double tx[1], ty[1]; + double_t fn; + uint32_t ix; + int n, sign, e0; + + ix = u.i & 0x7fffffff; + /* 25+53 bit pi is good enough for medium size */ + if(ix < 0x4dc90fdb) + { /* |x| ~< 2^28*(pi/2), medium size */ + /* Use a specialized rint() to get fn. */ + fn = (double_t)x * invpio2 + toint - toint; + n = (int32_t)fn; + *y = x - fn * pio2_1 - fn * pio2_1t; + /* Matters with directed rounding. */ + if(predict_false(*y < -pio4)) + { + n--; + fn--; + *y = x - fn * pio2_1 - fn * pio2_1t; + } + else if(predict_false(*y > pio4)) + { + n++; + fn++; + *y = x - fn * pio2_1 - fn * pio2_1t; + } + return n; + } + if(ix >= 0x7f800000) + { /* x is inf or NaN */ + *y = x - x; + return 0; + } + /* scale x into [2^23, 2^24-1] */ + sign = u.i >> 31; + e0 = (ix >> 23) - (0x7f + 23); /* e0 = ilogb(|x|)-23, positive */ + u.i = ix - (e0 << 23); + tx[0] = u.f; + n = __rem_pio2_large(tx, ty, e0, 1, 0); + if(sign) + { + *y = -ty[0]; + return -n; + } + *y = ty[0]; + return n; } diff --git a/src/libc-shim/src/__sin.c b/src/libc-shim/src/__sin.c index 4030949..c0b24e8 100644 --- a/src/libc-shim/src/__sin.c +++ b/src/libc-shim/src/__sin.c @@ -42,23 +42,23 @@ #include "libm.h" static const double -S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */ -S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */ -S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */ -S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */ -S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */ -S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */ + S1 = -1.66666666666666324348e-01, /* 0xBFC55555, 0x55555549 */ + S2 = 8.33333333332248946124e-03, /* 0x3F811111, 0x1110F8A6 */ + S3 = -1.98412698298579493134e-04, /* 0xBF2A01A0, 0x19C161D5 */ + S4 = 2.75573137070700676789e-06, /* 0x3EC71DE3, 0x57B1FE7D */ + S5 = -2.50507602534068634195e-08, /* 0xBE5AE5E6, 0x8A2B9CEB */ + S6 = 1.58969099521155010221e-10; /* 0x3DE5D93A, 0x5ACFD57C */ double __sin(double x, double y, int iy) { - double_t z,r,v,w; + double_t z, r, v, w; - z = x*x; - w = z*z; - r = S2 + z*(S3 + z*S4) + z*w*(S5 + z*S6); - v = z*x; - if (iy == 0) - return x + v*(S1 + z*r); - else - return x - ((z*(0.5*y - v*r) - y) - v*S1); + z = x * x; + w = z * z; + r = S2 + z * (S3 + z * S4) + z * w * (S5 + z * S6); + v = z * x; + if(iy == 0) + return x + v * (S1 + z * r); + else + return x - ((z * (0.5 * y - v * r) - y) - v * S1); } diff --git a/src/libc-shim/src/__sindf.c b/src/libc-shim/src/__sindf.c index 8fec2a3..95fb7e6 100644 --- a/src/libc-shim/src/__sindf.c +++ b/src/libc-shim/src/__sindf.c @@ -18,19 +18,19 @@ /* |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). */ static const double -S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */ -S2 = 0x111110896efbb2.0p-59, /* 0.0083333293858894631756 */ -S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */ -S4 = 0x16cd878c3b46a7.0p-71; /* 0.0000027183114939898219064 */ + S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */ + S2 = 0x111110896efbb2.0p-59, /* 0.0083333293858894631756 */ + S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */ + S4 = 0x16cd878c3b46a7.0p-71; /* 0.0000027183114939898219064 */ float __sindf(double x) { - double_t r, s, w, z; + double_t r, s, w, z; - /* Try to optimize for parallel evaluation as in __tandf.c. */ - z = x*x; - w = z*z; - r = S3 + z*S4; - s = z*x; - return (x + s*(S1 + z*S2)) + s*w*r; + /* Try to optimize for parallel evaluation as in __tandf.c. */ + z = x * x; + w = z * z; + r = S3 + z * S4; + s = z * x; + return (x + s * (S1 + z * S2)) + s * w * r; } diff --git a/src/libc-shim/src/abs.c b/src/libc-shim/src/abs.c index e721fdc..b6a294f 100644 --- a/src/libc-shim/src/abs.c +++ b/src/libc-shim/src/abs.c @@ -2,5 +2,5 @@ int abs(int a) { - return a>0 ? a : -a; + return a > 0 ? a : -a; } diff --git a/src/libc-shim/src/acos.c b/src/libc-shim/src/acos.c index ea9c87b..9d24899 100644 --- a/src/libc-shim/src/acos.c +++ b/src/libc-shim/src/acos.c @@ -36,66 +36,70 @@ #include "libm.h" static const double -pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ -pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */ -pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */ -pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */ -pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */ -pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */ -pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */ -pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */ -qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */ -qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ -qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ -qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ + pio2_hi = 1.57079632679489655800e+00, /* 0x3FF921FB, 0x54442D18 */ + pio2_lo = 6.12323399573676603587e-17, /* 0x3C91A626, 0x33145C07 */ + pS0 = 1.66666666666666657415e-01, /* 0x3FC55555, 0x55555555 */ + pS1 = -3.25565818622400915405e-01, /* 0xBFD4D612, 0x03EB6F7D */ + pS2 = 2.01212532134862925881e-01, /* 0x3FC9C155, 0x0E884455 */ + pS3 = -4.00555345006794114027e-02, /* 0xBFA48228, 0xB5688F3B */ + pS4 = 7.91534994289814532176e-04, /* 0x3F49EFE0, 0x7501B288 */ + pS5 = 3.47933107596021167570e-05, /* 0x3F023DE1, 0x0DFDF709 */ + qS1 = -2.40339491173441421878e+00, /* 0xC0033A27, 0x1C8A2D4B */ + qS2 = 2.02094576023350569471e+00, /* 0x40002AE5, 0x9C598AC8 */ + qS3 = -6.88283971605453293030e-01, /* 0xBFE6066C, 0x1B8D0159 */ + qS4 = 7.70381505559019352791e-02; /* 0x3FB3B8C5, 0xB12E9282 */ static double R(double z) { - double_t p, q; - p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); - q = 1.0+z*(qS1+z*(qS2+z*(qS3+z*qS4))); - return p/q; + double_t p, q; + p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5))))); + q = 1.0 + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4))); + return p / q; } double acos(double x) { - double z,w,s,c,df; - uint32_t hx,ix; + double z, w, s, c, df; + uint32_t hx, ix; - GET_HIGH_WORD(hx, x); - ix = hx & 0x7fffffff; - /* |x| >= 1 or nan */ - if (ix >= 0x3ff00000) { - uint32_t lx; + GET_HIGH_WORD(hx, x); + ix = hx & 0x7fffffff; + /* |x| >= 1 or nan */ + if(ix >= 0x3ff00000) + { + uint32_t lx; - GET_LOW_WORD(lx,x); - if ((ix-0x3ff00000 | lx) == 0) { - /* acos(1)=0, acos(-1)=pi */ - if (hx >> 31) - return 2*pio2_hi + 0x1p-120f; - return 0; - } - return 0/(x-x); - } - /* |x| < 0.5 */ - if (ix < 0x3fe00000) { - if (ix <= 0x3c600000) /* |x| < 2**-57 */ - return pio2_hi + 0x1p-120f; - return pio2_hi - (x - (pio2_lo-x*R(x*x))); - } - /* x < -0.5 */ - if (hx >> 31) { - z = (1.0+x)*0.5; - s = sqrt(z); - w = R(z)*s-pio2_lo; - return 2*(pio2_hi - (s+w)); - } - /* x > 0.5 */ - z = (1.0-x)*0.5; - s = sqrt(z); - df = s; - SET_LOW_WORD(df,0); - c = (z-df*df)/(s+df); - w = R(z)*s+c; - return 2*(df+w); + GET_LOW_WORD(lx, x); + if((ix - 0x3ff00000 | lx) == 0) + { + /* acos(1)=0, acos(-1)=pi */ + if(hx >> 31) + return 2 * pio2_hi + 0x1p-120f; + return 0; + } + return 0 / (x - x); + } + /* |x| < 0.5 */ + if(ix < 0x3fe00000) + { + if(ix <= 0x3c600000) /* |x| < 2**-57 */ + return pio2_hi + 0x1p-120f; + return pio2_hi - (x - (pio2_lo - x * R(x * x))); + } + /* x < -0.5 */ + if(hx >> 31) + { + z = (1.0 + x) * 0.5; + s = sqrt(z); + w = R(z) * s - pio2_lo; + return 2 * (pio2_hi - (s + w)); + } + /* x > 0.5 */ + z = (1.0 - x) * 0.5; + s = sqrt(z); + df = s; + SET_LOW_WORD(df, 0); + c = (z - df * df) / (s + df); + w = R(z) * s + c; + return 2 * (df + w); } diff --git a/src/libc-shim/src/ceil.c b/src/libc-shim/src/ceil.c index b13e6f2..b33d196 100644 --- a/src/libc-shim/src/ceil.c +++ b/src/libc-shim/src/ceil.c @@ -1,31 +1,37 @@ #include "libm.h" -#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 -#define EPS DBL_EPSILON -#elif FLT_EVAL_METHOD==2 -#define EPS LDBL_EPSILON +#if FLT_EVAL_METHOD == 0 || FLT_EVAL_METHOD == 1 + #define EPS DBL_EPSILON +#elif FLT_EVAL_METHOD == 2 + #define EPS LDBL_EPSILON #endif -static const double_t toint = 1/EPS; +static const double_t toint = 1 / EPS; double ceil(double x) { - union {double f; uint64_t i;} u = {x}; - int e = u.i >> 52 & 0x7ff; - double_t y; + union + { + double f; + uint64_t i; + } u = { x }; - if (e >= 0x3ff+52 || x == 0) - return x; - /* y = int(x) - x, where int(x) is an integer neighbor of x */ - if (u.i >> 63) - y = x - toint + toint - x; - else - y = x + toint - toint - x; - /* special case because of non-nearest rounding modes */ - if (e <= 0x3ff-1) { - FORCE_EVAL(y); - return u.i >> 63 ? -0.0 : 1; - } - if (y < 0) - return x + y + 1; - return x + y; + int e = u.i >> 52 & 0x7ff; + double_t y; + + if(e >= 0x3ff + 52 || x == 0) + return x; + /* y = int(x) - x, where int(x) is an integer neighbor of x */ + if(u.i >> 63) + y = x - toint + toint - x; + else + y = x + toint - toint - x; + /* special case because of non-nearest rounding modes */ + if(e <= 0x3ff - 1) + { + FORCE_EVAL(y); + return u.i >> 63 ? -0.0 : 1; + } + if(y < 0) + return x + y + 1; + return x + y; } diff --git a/src/libc-shim/src/cos.c b/src/libc-shim/src/cos.c index ee97f68..040883c 100644 --- a/src/libc-shim/src/cos.c +++ b/src/libc-shim/src/cos.c @@ -44,34 +44,40 @@ double cos(double x) { - double y[2]; - uint32_t ix; - unsigned n; + double y[2]; + uint32_t ix; + unsigned n; - GET_HIGH_WORD(ix, x); - ix &= 0x7fffffff; + GET_HIGH_WORD(ix, x); + ix &= 0x7fffffff; - /* |x| ~< pi/4 */ - if (ix <= 0x3fe921fb) { - if (ix < 0x3e46a09e) { /* |x| < 2**-27 * sqrt(2) */ - /* raise inexact if x!=0 */ - FORCE_EVAL(x + 0x1p120f); - return 1.0; - } - return __cos(x, 0); - } + /* |x| ~< pi/4 */ + if(ix <= 0x3fe921fb) + { + if(ix < 0x3e46a09e) + { /* |x| < 2**-27 * sqrt(2) */ + /* raise inexact if x!=0 */ + FORCE_EVAL(x + 0x1p120f); + return 1.0; + } + return __cos(x, 0); + } - /* cos(Inf or NaN) is NaN */ - if (ix >= 0x7ff00000) - return x-x; + /* cos(Inf or NaN) is NaN */ + if(ix >= 0x7ff00000) + return x - x; - /* argument reduction */ - n = __rem_pio2(x, y); - switch (n&3) { - case 0: return __cos(y[0], y[1]); - case 1: return -__sin(y[0], y[1], 1); - case 2: return -__cos(y[0], y[1]); - default: - return __sin(y[0], y[1], 1); - } + /* argument reduction */ + n = __rem_pio2(x, y); + switch(n & 3) + { + case 0: + return __cos(y[0], y[1]); + case 1: + return -__sin(y[0], y[1], 1); + case 2: + return -__cos(y[0], y[1]); + default: + return __sin(y[0], y[1], 1); + } } diff --git a/src/libc-shim/src/cosf.c b/src/libc-shim/src/cosf.c index 23f3e5b..e2a0793 100644 --- a/src/libc-shim/src/cosf.c +++ b/src/libc-shim/src/cosf.c @@ -18,61 +18,71 @@ /* Small multiples of pi/2 rounded to double precision. */ static const double -c1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */ -c2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */ -c3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ -c4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */ + c1pio2 = 1 * M_PI_2, /* 0x3FF921FB, 0x54442D18 */ + c2pio2 = 2 * M_PI_2, /* 0x400921FB, 0x54442D18 */ + c3pio2 = 3 * M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ + c4pio2 = 4 * M_PI_2; /* 0x401921FB, 0x54442D18 */ float cosf(float x) { - double y; - uint32_t ix; - unsigned n, sign; + double y; + uint32_t ix; + unsigned n, sign; - GET_FLOAT_WORD(ix, x); - sign = ix >> 31; - ix &= 0x7fffffff; + GET_FLOAT_WORD(ix, x); + sign = ix >> 31; + ix &= 0x7fffffff; - if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */ - if (ix < 0x39800000) { /* |x| < 2**-12 */ - /* raise inexact if x != 0 */ - FORCE_EVAL(x + 0x1p120f); - return 1.0f; - } - return __cosdf(x); - } - if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */ - if (ix > 0x4016cbe3) /* |x| ~> 3*pi/4 */ - return -__cosdf(sign ? x+c2pio2 : x-c2pio2); - else { - if (sign) - return __sindf(x + c1pio2); - else - return __sindf(c1pio2 - x); - } - } - if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */ - if (ix > 0x40afeddf) /* |x| ~> 7*pi/4 */ - return __cosdf(sign ? x+c4pio2 : x-c4pio2); - else { - if (sign) - return __sindf(-x - c3pio2); - else - return __sindf(x - c3pio2); - } - } + if(ix <= 0x3f490fda) + { /* |x| ~<= pi/4 */ + if(ix < 0x39800000) + { /* |x| < 2**-12 */ + /* raise inexact if x != 0 */ + FORCE_EVAL(x + 0x1p120f); + return 1.0f; + } + return __cosdf(x); + } + if(ix <= 0x407b53d1) + { /* |x| ~<= 5*pi/4 */ + if(ix > 0x4016cbe3) /* |x| ~> 3*pi/4 */ + return -__cosdf(sign ? x + c2pio2 : x - c2pio2); + else + { + if(sign) + return __sindf(x + c1pio2); + else + return __sindf(c1pio2 - x); + } + } + if(ix <= 0x40e231d5) + { /* |x| ~<= 9*pi/4 */ + if(ix > 0x40afeddf) /* |x| ~> 7*pi/4 */ + return __cosdf(sign ? x + c4pio2 : x - c4pio2); + else + { + if(sign) + return __sindf(-x - c3pio2); + else + return __sindf(x - c3pio2); + } + } - /* cos(Inf or NaN) is NaN */ - if (ix >= 0x7f800000) - return x-x; + /* cos(Inf or NaN) is NaN */ + if(ix >= 0x7f800000) + return x - x; - /* general argument reduction needed */ - n = __rem_pio2f(x,&y); - switch (n&3) { - case 0: return __cosdf(y); - case 1: return __sindf(-y); - case 2: return -__cosdf(y); - default: - return __sindf(y); - } + /* general argument reduction needed */ + n = __rem_pio2f(x, &y); + switch(n & 3) + { + case 0: + return __cosdf(y); + case 1: + return __sindf(-y); + case 2: + return -__cosdf(y); + default: + return __sindf(y); + } } diff --git a/src/libc-shim/src/exp_data.h b/src/libc-shim/src/exp_data.h index b8df2a2..932a70a 100644 --- a/src/libc-shim/src/exp_data.h +++ b/src/libc-shim/src/exp_data.h @@ -12,15 +12,17 @@ #define EXP_POLY_ORDER 5 #define EXP_USE_TOINT_NARROW 0 #define EXP2_POLY_ORDER 5 -extern const struct exp_data { - double invln2N; - double shift; - double negln2hiN; - double negln2loN; - double poly[4]; /* Last four coefficients. */ - double exp2_shift; - double exp2_poly[EXP2_POLY_ORDER]; - uint64_t tab[2*(1 << EXP_TABLE_BITS)]; + +extern const struct exp_data +{ + double invln2N; + double shift; + double negln2hiN; + double negln2loN; + double poly[4]; /* Last four coefficients. */ + double exp2_shift; + double exp2_poly[EXP2_POLY_ORDER]; + uint64_t tab[2 * (1 << EXP_TABLE_BITS)]; } __exp_data; #endif diff --git a/src/libc-shim/src/fabs.c b/src/libc-shim/src/fabs.c index e8258cf..a051b0a 100644 --- a/src/libc-shim/src/fabs.c +++ b/src/libc-shim/src/fabs.c @@ -3,7 +3,12 @@ double fabs(double x) { - union {double f; uint64_t i;} u = {x}; - u.i &= -1ULL/2; - return u.f; + union + { + double f; + uint64_t i; + } u = { x }; + + u.i &= -1ULL / 2; + return u.f; } diff --git a/src/libc-shim/src/floor.c b/src/libc-shim/src/floor.c index 14a31cd..8a5f727 100644 --- a/src/libc-shim/src/floor.c +++ b/src/libc-shim/src/floor.c @@ -1,31 +1,37 @@ #include "libm.h" -#if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1 -#define EPS DBL_EPSILON -#elif FLT_EVAL_METHOD==2 -#define EPS LDBL_EPSILON +#if FLT_EVAL_METHOD == 0 || FLT_EVAL_METHOD == 1 + #define EPS DBL_EPSILON +#elif FLT_EVAL_METHOD == 2 + #define EPS LDBL_EPSILON #endif -static const double_t toint = 1/EPS; +static const double_t toint = 1 / EPS; double floor(double x) { - union {double f; uint64_t i;} u = {x}; - int e = u.i >> 52 & 0x7ff; - double_t y; + union + { + double f; + uint64_t i; + } u = { x }; - if (e >= 0x3ff+52 || x == 0) - return x; - /* y = int(x) - x, where int(x) is an integer neighbor of x */ - if (u.i >> 63) - y = x - toint + toint - x; - else - y = x + toint - toint - x; - /* special case because of non-nearest rounding modes */ - if (e <= 0x3ff-1) { - FORCE_EVAL(y); - return u.i >> 63 ? -1 : 0; - } - if (y > 0) - return x + y - 1; - return x + y; + int e = u.i >> 52 & 0x7ff; + double_t y; + + if(e >= 0x3ff + 52 || x == 0) + return x; + /* y = int(x) - x, where int(x) is an integer neighbor of x */ + if(u.i >> 63) + y = x - toint + toint - x; + else + y = x + toint - toint - x; + /* special case because of non-nearest rounding modes */ + if(e <= 0x3ff - 1) + { + FORCE_EVAL(y); + return u.i >> 63 ? -1 : 0; + } + if(y > 0) + return x + y - 1; + return x + y; } diff --git a/src/libc-shim/src/fmod.c b/src/libc-shim/src/fmod.c index 6849722..9020406 100644 --- a/src/libc-shim/src/fmod.c +++ b/src/libc-shim/src/fmod.c @@ -3,66 +3,87 @@ double fmod(double x, double y) { - union {double f; uint64_t i;} ux = {x}, uy = {y}; - int ex = ux.i>>52 & 0x7ff; - int ey = uy.i>>52 & 0x7ff; - int sx = ux.i>>63; - uint64_t i; + union + { + double f; + uint64_t i; + } ux = { x }, uy = { y }; - /* in the followings uxi should be ux.i, but then gcc wrongly adds */ - /* float load/store to inner loops ruining performance and code size */ - uint64_t uxi = ux.i; + int ex = ux.i >> 52 & 0x7ff; + int ey = uy.i >> 52 & 0x7ff; + int sx = ux.i >> 63; + uint64_t i; - if (uy.i<<1 == 0 || isnan(y) || ex == 0x7ff) - return (x*y)/(x*y); - if (uxi<<1 <= uy.i<<1) { - if (uxi<<1 == uy.i<<1) - return 0*x; - return x; - } + /* in the followings uxi should be ux.i, but then gcc wrongly adds */ + /* float load/store to inner loops ruining performance and code size */ + uint64_t uxi = ux.i; - /* normalize x and y */ - if (!ex) { - for (i = uxi<<12; i>>63 == 0; ex--, i <<= 1); - uxi <<= -ex + 1; - } else { - uxi &= -1ULL >> 12; - uxi |= 1ULL << 52; - } - if (!ey) { - for (i = uy.i<<12; i>>63 == 0; ey--, i <<= 1); - uy.i <<= -ey + 1; - } else { - uy.i &= -1ULL >> 12; - uy.i |= 1ULL << 52; - } + if(uy.i << 1 == 0 || isnan(y) || ex == 0x7ff) + return (x * y) / (x * y); + if(uxi << 1 <= uy.i << 1) + { + if(uxi << 1 == uy.i << 1) + return 0 * x; + return x; + } - /* x mod y */ - for (; ex > ey; ex--) { - i = uxi - uy.i; - if (i >> 63 == 0) { - if (i == 0) - return 0*x; - uxi = i; - } - uxi <<= 1; - } - i = uxi - uy.i; - if (i >> 63 == 0) { - if (i == 0) - return 0*x; - uxi = i; - } - for (; uxi>>52 == 0; uxi <<= 1, ex--); + /* normalize x and y */ + if(!ex) + { + for(i = uxi << 12; i >> 63 == 0; ex--, i <<= 1) + ; + uxi <<= -ex + 1; + } + else + { + uxi &= -1ULL >> 12; + uxi |= 1ULL << 52; + } + if(!ey) + { + for(i = uy.i << 12; i >> 63 == 0; ey--, i <<= 1) + ; + uy.i <<= -ey + 1; + } + else + { + uy.i &= -1ULL >> 12; + uy.i |= 1ULL << 52; + } - /* scale result */ - if (ex > 0) { - uxi -= 1ULL << 52; - uxi |= (uint64_t)ex << 52; - } else { - uxi >>= -ex + 1; - } - uxi |= (uint64_t)sx << 63; - ux.i = uxi; - return ux.f; + /* x mod y */ + for(; ex > ey; ex--) + { + i = uxi - uy.i; + if(i >> 63 == 0) + { + if(i == 0) + return 0 * x; + uxi = i; + } + uxi <<= 1; + } + i = uxi - uy.i; + if(i >> 63 == 0) + { + if(i == 0) + return 0 * x; + uxi = i; + } + for(; uxi >> 52 == 0; uxi <<= 1, ex--) + ; + + /* scale result */ + if(ex > 0) + { + uxi -= 1ULL << 52; + uxi |= (uint64_t)ex << 52; + } + else + { + uxi >>= -ex + 1; + } + uxi |= (uint64_t)sx << 63; + ux.i = uxi; + return ux.f; } diff --git a/src/libc-shim/src/libm.h b/src/libc-shim/src/libm.h index a310f59..ee69eb6 100644 --- a/src/libc-shim/src/libm.h +++ b/src/libc-shim/src/libm.h @@ -1,35 +1,35 @@ -#include #include #include +#include #define WANT_ROUNDING 1 #if WANT_SNAN -#error SNaN is unsupported + #error SNaN is unsupported #else -#define issignalingf_inline(x) 0 -#define issignaling_inline(x) 0 + #define issignalingf_inline(x) 0 + #define issignaling_inline(x) 0 #endif /* Helps static branch prediction so hot path can be better optimized. */ #ifdef __GNUC__ -#define predict_true(x) __builtin_expect(!!(x), 1) -#define predict_false(x) __builtin_expect(x, 0) + #define predict_true(x) __builtin_expect(!!(x), 1) + #define predict_false(x) __builtin_expect(x, 0) #else -#define predict_true(x) (x) -#define predict_false(x) (x) + #define predict_true(x) (x) + #define predict_false(x) (x) #endif static inline float eval_as_float(float x) { - float y = x; - return y; + float y = x; + return y; } static inline double eval_as_double(double x) { - double y = x; - return y; + double y = x; + return y; } /* fp_force_eval ensures that the input value is computed when that's @@ -39,94 +39,110 @@ static inline double eval_as_double(double x) used to evaluate an expression for its fenv side-effects only. */ #ifndef fp_force_evalf -#define fp_force_evalf fp_force_evalf + #define fp_force_evalf fp_force_evalf + static inline void fp_force_evalf(float x) { - volatile float y; - y = x; + volatile float y; + y = x; } #endif #ifndef fp_force_eval -#define fp_force_eval fp_force_eval + #define fp_force_eval fp_force_eval + static inline void fp_force_eval(double x) { - volatile double y; - y = x; + volatile double y; + y = x; } #endif #ifndef fp_force_evall -#define fp_force_evall fp_force_evall + #define fp_force_evall fp_force_evall + static inline void fp_force_evall(long double x) { - volatile long double y; - y = x; + volatile long double y; + y = x; } #endif -#define FORCE_EVAL(x) do { \ - if (sizeof(x) == sizeof(float)) { \ - fp_force_evalf(x); \ - } else if (sizeof(x) == sizeof(double)) { \ - fp_force_eval(x); \ - } else { \ - fp_force_evall(x); \ - } \ -} while(0) +#define FORCE_EVAL(x) \ + do \ + { \ + if(sizeof(x) == sizeof(float)) \ + { \ + fp_force_evalf(x); \ + } \ + else if(sizeof(x) == sizeof(double)) \ + { \ + fp_force_eval(x); \ + } \ + else \ + { \ + fp_force_evall(x); \ + } \ + } while(0) -#define asuint(f) ((union{float _f; uint32_t _i;}){f})._i -#define asfloat(i) ((union{uint32_t _i; float _f;}){i})._f -#define asuint64(f) ((union{double _f; uint64_t _i;}){f})._i -#define asdouble(i) ((union{uint64_t _i; double _f;}){i})._f +#define asuint(f) ((union {float _f; uint32_t _i; }){ f })._i +#define asfloat(i) ((union {uint32_t _i; float _f; }){ i })._f +#define asuint64(f) ((union {double _f; uint64_t _i; }){ f })._i +#define asdouble(i) ((union {uint64_t _i; double _f; }){ i })._f -#define EXTRACT_WORDS(hi,lo,d) \ -do { \ - uint64_t __u = asuint64(d); \ - (hi) = __u >> 32; \ - (lo) = (uint32_t)__u; \ -} while (0) +#define EXTRACT_WORDS(hi, lo, d) \ + do \ + { \ + uint64_t __u = asuint64(d); \ + (hi) = __u >> 32; \ + (lo) = (uint32_t)__u; \ + } while(0) -#define GET_HIGH_WORD(hi,d) \ -do { \ - (hi) = asuint64(d) >> 32; \ -} while (0) +#define GET_HIGH_WORD(hi, d) \ + do \ + { \ + (hi) = asuint64(d) >> 32; \ + } while(0) -#define GET_LOW_WORD(lo,d) \ -do { \ - (lo) = (uint32_t)asuint64(d); \ -} while (0) +#define GET_LOW_WORD(lo, d) \ + do \ + { \ + (lo) = (uint32_t)asuint64(d); \ + } while(0) -#define INSERT_WORDS(d,hi,lo) \ -do { \ - (d) = asdouble(((uint64_t)(hi)<<32) | (uint32_t)(lo)); \ -} while (0) +#define INSERT_WORDS(d, hi, lo) \ + do \ + { \ + (d) = asdouble(((uint64_t)(hi) << 32) | (uint32_t)(lo)); \ + } while(0) -#define SET_HIGH_WORD(d,hi) \ - INSERT_WORDS(d, hi, (uint32_t)asuint64(d)) +#define SET_HIGH_WORD(d, hi) \ + INSERT_WORDS(d, hi, (uint32_t)asuint64(d)) -#define SET_LOW_WORD(d,lo) \ - INSERT_WORDS(d, asuint64(d)>>32, lo) +#define SET_LOW_WORD(d, lo) \ + INSERT_WORDS(d, asuint64(d) >> 32, lo) -#define GET_FLOAT_WORD(w,d) \ -do { \ - (w) = asuint(d); \ -} while (0) +#define GET_FLOAT_WORD(w, d) \ + do \ + { \ + (w) = asuint(d); \ + } while(0) -#define SET_FLOAT_WORD(d,w) \ -do { \ - (d) = asfloat(w); \ -} while (0) +#define SET_FLOAT_WORD(d, w) \ + do \ + { \ + (d) = asfloat(w); \ + } while(0) -int __rem_pio2_large(double*,double*,int,int,int); +int __rem_pio2_large(double*, double*, int, int, int); -int __rem_pio2(double,double*); -double __sin(double,double,int); -double __cos(double,double); +int __rem_pio2(double, double*); +double __sin(double, double, int); +double __cos(double, double); -int __rem_pio2f(float,double*); -float __sindf(double); -float __cosdf(double); +int __rem_pio2f(float, double*); +float __sindf(double); +float __cosdf(double); float __math_invalidf(float); double __math_xflow(uint32_t, double); diff --git a/src/libc-shim/src/pow.c b/src/libc-shim/src/pow.c index 84dd35e..4e682fc 100644 --- a/src/libc-shim/src/pow.c +++ b/src/libc-shim/src/pow.c @@ -5,11 +5,11 @@ * SPDX-License-Identifier: MIT */ +#include "exp_data.h" +#include "libm.h" +#include "pow_data.h" #include #include -#include "libm.h" -#include "exp_data.h" -#include "pow_data.h" /* Worst-case error: 0.54 ULP (~= ulperr_exp + 1024*Ln2*relerr_log*2^53) @@ -27,77 +27,76 @@ ulperr_exp: 0.509 ULP (ULP error of exp, 0.511 ULP without fma) /* Top 12 bits of a double (sign and exponent bits). */ static inline uint32_t top12(double x) { - return asuint64(x) >> 52; + return asuint64(x) >> 52; } /* Compute y+TAIL = log(x) where the rounded result is y and TAIL has about additional 15 bits precision. IX is the bit representation of x, but normalized in the subnormal range using the sign bit for the exponent. */ -static inline double_t log_inline(uint64_t ix, double_t *tail) +static inline double_t log_inline(uint64_t ix, double_t* tail) { - /* double_t for better performance on targets with FLT_EVAL_METHOD==2. */ - double_t z, r, y, invc, logc, logctail, kd, hi, t1, t2, lo, lo1, lo2, p; - uint64_t iz, tmp; - int k, i; + /* double_t for better performance on targets with FLT_EVAL_METHOD==2. */ + double_t z, r, y, invc, logc, logctail, kd, hi, t1, t2, lo, lo1, lo2, p; + uint64_t iz, tmp; + int k, i; - /* x = 2^k z; where z is in range [OFF,2*OFF) and exact. + /* x = 2^k z; where z is in range [OFF,2*OFF) and exact. The range is split into N subintervals. The ith subinterval contains z and c is near its center. */ - tmp = ix - OFF; - i = (tmp >> (52 - POW_LOG_TABLE_BITS)) % N; - k = (int64_t)tmp >> 52; /* arithmetic shift */ - iz = ix - (tmp & 0xfffULL << 52); - z = asdouble(iz); - kd = (double_t)k; + tmp = ix - OFF; + i = (tmp >> (52 - POW_LOG_TABLE_BITS)) % N; + k = (int64_t)tmp >> 52; /* arithmetic shift */ + iz = ix - (tmp & 0xfffULL << 52); + z = asdouble(iz); + kd = (double_t)k; - /* log(x) = k*Ln2 + log(c) + log1p(z/c-1). */ - invc = T[i].invc; - logc = T[i].logc; - logctail = T[i].logctail; + /* log(x) = k*Ln2 + log(c) + log1p(z/c-1). */ + invc = T[i].invc; + logc = T[i].logc; + logctail = T[i].logctail; - /* Note: 1/c is j/N or j/N/2 where j is an integer in [N,2N) and + /* Note: 1/c is j/N or j/N/2 where j is an integer in [N,2N) and |z/c - 1| < 1/N, so r = z/c - 1 is exactly representible. */ #if __FP_FAST_FMA - r = __builtin_fma(z, invc, -1.0); + r = __builtin_fma(z, invc, -1.0); #else - /* Split z such that rhi, rlo and rhi*rhi are exact and |rlo| <= |r|. */ - double_t zhi = asdouble((iz + (1ULL << 31)) & (-1ULL << 32)); - double_t zlo = z - zhi; - double_t rhi = zhi * invc - 1.0; - double_t rlo = zlo * invc; - r = rhi + rlo; + /* Split z such that rhi, rlo and rhi*rhi are exact and |rlo| <= |r|. */ + double_t zhi = asdouble((iz + (1ULL << 31)) & (-1ULL << 32)); + double_t zlo = z - zhi; + double_t rhi = zhi * invc - 1.0; + double_t rlo = zlo * invc; + r = rhi + rlo; #endif - /* k*Ln2 + log(c) + r. */ - t1 = kd * Ln2hi + logc; - t2 = t1 + r; - lo1 = kd * Ln2lo + logctail; - lo2 = t1 - t2 + r; + /* k*Ln2 + log(c) + r. */ + t1 = kd * Ln2hi + logc; + t2 = t1 + r; + lo1 = kd * Ln2lo + logctail; + lo2 = t1 - t2 + r; - /* Evaluation is optimized assuming superscalar pipelined execution. */ - double_t ar, ar2, ar3, lo3, lo4; - ar = A[0] * r; /* A[0] = -0.5. */ - ar2 = r * ar; - ar3 = r * ar2; - /* k*Ln2 + log(c) + r + A[0]*r*r. */ + /* Evaluation is optimized assuming superscalar pipelined execution. */ + double_t ar, ar2, ar3, lo3, lo4; + ar = A[0] * r; /* A[0] = -0.5. */ + ar2 = r * ar; + ar3 = r * ar2; + /* k*Ln2 + log(c) + r + A[0]*r*r. */ #if __FP_FAST_FMA - hi = t2 + ar2; - lo3 = __builtin_fma(ar, r, -ar2); - lo4 = t2 - hi + ar2; + hi = t2 + ar2; + lo3 = __builtin_fma(ar, r, -ar2); + lo4 = t2 - hi + ar2; #else - double_t arhi = A[0] * rhi; - double_t arhi2 = rhi * arhi; - hi = t2 + arhi2; - lo3 = rlo * (ar + arhi); - lo4 = t2 - hi + arhi2; + double_t arhi = A[0] * rhi; + double_t arhi2 = rhi * arhi; + hi = t2 + arhi2; + lo3 = rlo * (ar + arhi); + lo4 = t2 - hi + arhi2; #endif - /* p = log1p(r) - r - A[0]*r*r. */ - p = (ar3 * (A[1] + r * A[2] + - ar2 * (A[3] + r * A[4] + ar2 * (A[5] + r * A[6])))); - lo = lo1 + lo2 + lo3 + lo4 + p; - y = hi + lo; - *tail = hi - y + lo; - return y; + /* p = log1p(r) - r - A[0]*r*r. */ + p = (ar3 * (A[1] + r * A[2] + ar2 * (A[3] + r * A[4] + ar2 * (A[5] + r * A[6])))); + lo = lo1 + lo2 + lo3 + lo4 + p; + y = hi + lo; + *tail = hi - y + lo; + return y; } #undef N @@ -123,41 +122,43 @@ static inline double_t log_inline(uint64_t ix, double_t *tail) negative k means the result may underflow. */ static inline double specialcase(double_t tmp, uint64_t sbits, uint64_t ki) { - double_t scale, y; + double_t scale, y; - if ((ki & 0x80000000) == 0) { - /* k > 0, the exponent of scale might have overflowed by <= 460. */ - sbits -= 1009ull << 52; - scale = asdouble(sbits); - y = 0x1p1009 * (scale + scale * tmp); - return eval_as_double(y); - } - /* k < 0, need special care in the subnormal range. */ - sbits += 1022ull << 52; - /* Note: sbits is signed scale. */ - scale = asdouble(sbits); - y = scale + scale * tmp; - if (fabs(y) < 1.0) { - /* Round y to the right precision before scaling it into the subnormal + if((ki & 0x80000000) == 0) + { + /* k > 0, the exponent of scale might have overflowed by <= 460. */ + sbits -= 1009ull << 52; + scale = asdouble(sbits); + y = 0x1p1009 * (scale + scale * tmp); + return eval_as_double(y); + } + /* k < 0, need special care in the subnormal range. */ + sbits += 1022ull << 52; + /* Note: sbits is signed scale. */ + scale = asdouble(sbits); + y = scale + scale * tmp; + if(fabs(y) < 1.0) + { + /* Round y to the right precision before scaling it into the subnormal range to avoid double rounding that can cause 0.5+E/2 ulp error where E is the worst-case ulp error outside the subnormal range. So this is only useful if the goal is better than 1 ulp worst-case error. */ - double_t hi, lo, one = 1.0; - if (y < 0.0) - one = -1.0; - lo = scale - y + scale * tmp; - hi = one + y; - lo = one - hi + y + lo; - y = eval_as_double(hi + lo) - one; - /* Fix the sign of 0. */ - if (y == 0.0) - y = asdouble(sbits & 0x8000000000000000); - /* The underflow exception needs to be signaled explicitly. */ - // NOTE(orca): removing special fp functions - // fp_force_eval(fp_barrier(0x1p-1022) * 0x1p-1022); - } - y = 0x1p-1022 * y; - return eval_as_double(y); + double_t hi, lo, one = 1.0; + if(y < 0.0) + one = -1.0; + lo = scale - y + scale * tmp; + hi = one + y; + lo = one - hi + y + lo; + y = eval_as_double(hi + lo) - one; + /* Fix the sign of 0. */ + if(y == 0.0) + y = asdouble(sbits & 0x8000000000000000); + /* The underflow exception needs to be signaled explicitly. */ + // NOTE(orca): removing special fp functions + // fp_force_eval(fp_barrier(0x1p-1022) * 0x1p-1022); + } + y = 0x1p-1022 * y; + return eval_as_double(y); } #define SIGN_BIAS (0x800 << EXP_TABLE_BITS) @@ -166,181 +167,185 @@ static inline double specialcase(double_t tmp, uint64_t sbits, uint64_t ki) The sign_bias argument is SIGN_BIAS or 0 and sets the sign to -1 or 1. */ static inline double exp_inline(double_t x, double_t xtail, uint32_t sign_bias) { - uint32_t abstop; - uint64_t ki, idx, top, sbits; - /* double_t for better performance on targets with FLT_EVAL_METHOD==2. */ - double_t kd, z, r, r2, scale, tail, tmp; + uint32_t abstop; + uint64_t ki, idx, top, sbits; + /* double_t for better performance on targets with FLT_EVAL_METHOD==2. */ + double_t kd, z, r, r2, scale, tail, tmp; - abstop = top12(x) & 0x7ff; - if (predict_false(abstop - top12(0x1p-54) >= - top12(512.0) - top12(0x1p-54))) { - if (abstop - top12(0x1p-54) >= 0x80000000) { - /* Avoid spurious underflow for tiny x. */ - /* Note: 0 is common input. */ - double_t one = WANT_ROUNDING ? 1.0 + x : 1.0; - return sign_bias ? -one : one; - } - if (abstop >= top12(1024.0)) { - /* Note: inf and nan are already handled. */ - if (asuint64(x) >> 63) - return __math_uflow(sign_bias); - else - return __math_oflow(sign_bias); - } - /* Large x is special cased below. */ - abstop = 0; - } + abstop = top12(x) & 0x7ff; + if(predict_false(abstop - top12(0x1p-54) >= top12(512.0) - top12(0x1p-54))) + { + if(abstop - top12(0x1p-54) >= 0x80000000) + { + /* Avoid spurious underflow for tiny x. */ + /* Note: 0 is common input. */ + double_t one = WANT_ROUNDING ? 1.0 + x : 1.0; + return sign_bias ? -one : one; + } + if(abstop >= top12(1024.0)) + { + /* Note: inf and nan are already handled. */ + if(asuint64(x) >> 63) + return __math_uflow(sign_bias); + else + return __math_oflow(sign_bias); + } + /* Large x is special cased below. */ + abstop = 0; + } - /* exp(x) = 2^(k/N) * exp(r), with exp(r) in [2^(-1/2N),2^(1/2N)]. */ - /* x = ln2/N*k + r, with int k and r in [-ln2/2N, ln2/2N]. */ - z = InvLn2N * x; + /* exp(x) = 2^(k/N) * exp(r), with exp(r) in [2^(-1/2N),2^(1/2N)]. */ + /* x = ln2/N*k + r, with int k and r in [-ln2/2N, ln2/2N]. */ + z = InvLn2N * x; #if TOINT_INTRINSICS - kd = roundtoint(z); - ki = converttoint(z); + kd = roundtoint(z); + ki = converttoint(z); #elif EXP_USE_TOINT_NARROW - /* z - kd is in [-0.5-2^-16, 0.5] in all rounding modes. */ - kd = eval_as_double(z + Shift); - ki = asuint64(kd) >> 16; - kd = (double_t)(int32_t)ki; + /* z - kd is in [-0.5-2^-16, 0.5] in all rounding modes. */ + kd = eval_as_double(z + Shift); + ki = asuint64(kd) >> 16; + kd = (double_t)(int32_t)ki; #else - /* z - kd is in [-1, 1] in non-nearest rounding modes. */ - kd = eval_as_double(z + Shift); - ki = asuint64(kd); - kd -= Shift; + /* z - kd is in [-1, 1] in non-nearest rounding modes. */ + kd = eval_as_double(z + Shift); + ki = asuint64(kd); + kd -= Shift; #endif - r = x + kd * NegLn2hiN + kd * NegLn2loN; - /* The code assumes 2^-200 < |xtail| < 2^-8/N. */ - r += xtail; - /* 2^(k/N) ~= scale * (1 + tail). */ - idx = 2 * (ki % N); - top = (ki + sign_bias) << (52 - EXP_TABLE_BITS); - tail = asdouble(T[idx]); - /* This is only a valid scale when -1023*N < k < 1024*N. */ - sbits = T[idx + 1] + top; - /* exp(x) = 2^(k/N) * exp(r) ~= scale + scale * (tail + exp(r) - 1). */ - /* Evaluation is optimized assuming superscalar pipelined execution. */ - r2 = r * r; - /* Without fma the worst case error is 0.25/N ulp larger. */ - /* Worst case error is less than 0.5+1.11/N+(abs poly error * 2^53) ulp. */ - tmp = tail + r + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5); - if (predict_false(abstop == 0)) - return specialcase(tmp, sbits, ki); - scale = asdouble(sbits); - /* Note: tmp == 0 or |tmp| > 2^-200 and scale > 2^-739, so there + r = x + kd * NegLn2hiN + kd * NegLn2loN; + /* The code assumes 2^-200 < |xtail| < 2^-8/N. */ + r += xtail; + /* 2^(k/N) ~= scale * (1 + tail). */ + idx = 2 * (ki % N); + top = (ki + sign_bias) << (52 - EXP_TABLE_BITS); + tail = asdouble(T[idx]); + /* This is only a valid scale when -1023*N < k < 1024*N. */ + sbits = T[idx + 1] + top; + /* exp(x) = 2^(k/N) * exp(r) ~= scale + scale * (tail + exp(r) - 1). */ + /* Evaluation is optimized assuming superscalar pipelined execution. */ + r2 = r * r; + /* Without fma the worst case error is 0.25/N ulp larger. */ + /* Worst case error is less than 0.5+1.11/N+(abs poly error * 2^53) ulp. */ + tmp = tail + r + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5); + if(predict_false(abstop == 0)) + return specialcase(tmp, sbits, ki); + scale = asdouble(sbits); + /* Note: tmp == 0 or |tmp| > 2^-200 and scale > 2^-739, so there is no spurious underflow here even without fma. */ - return eval_as_double(scale + scale * tmp); + return eval_as_double(scale + scale * tmp); } /* Returns 0 if not int, 1 if odd int, 2 if even int. The argument is the bit representation of a non-zero finite floating-point value. */ static inline int checkint(uint64_t iy) { - int e = iy >> 52 & 0x7ff; - if (e < 0x3ff) - return 0; - if (e > 0x3ff + 52) - return 2; - if (iy & ((1ULL << (0x3ff + 52 - e)) - 1)) - return 0; - if (iy & (1ULL << (0x3ff + 52 - e))) - return 1; - return 2; + int e = iy >> 52 & 0x7ff; + if(e < 0x3ff) + return 0; + if(e > 0x3ff + 52) + return 2; + if(iy & ((1ULL << (0x3ff + 52 - e)) - 1)) + return 0; + if(iy & (1ULL << (0x3ff + 52 - e))) + return 1; + return 2; } /* Returns 1 if input is the bit representation of 0, infinity or nan. */ static inline int zeroinfnan(uint64_t i) { - return 2 * i - 1 >= 2 * asuint64(INFINITY) - 1; + return 2 * i - 1 >= 2 * asuint64(INFINITY) - 1; } double pow(double x, double y) { - uint32_t sign_bias = 0; - uint64_t ix, iy; - uint32_t topx, topy; + uint32_t sign_bias = 0; + uint64_t ix, iy; + uint32_t topx, topy; - ix = asuint64(x); - iy = asuint64(y); - topx = top12(x); - topy = top12(y); - if (predict_false(topx - 0x001 >= 0x7ff - 0x001 || - (topy & 0x7ff) - 0x3be >= 0x43e - 0x3be)) { - /* Note: if |y| > 1075 * ln2 * 2^53 ~= 0x1.749p62 then pow(x,y) = inf/0 + ix = asuint64(x); + iy = asuint64(y); + topx = top12(x); + topy = top12(y); + if(predict_false(topx - 0x001 >= 0x7ff - 0x001 || (topy & 0x7ff) - 0x3be >= 0x43e - 0x3be)) + { + /* Note: if |y| > 1075 * ln2 * 2^53 ~= 0x1.749p62 then pow(x,y) = inf/0 and if |y| < 2^-54 / 1075 ~= 0x1.e7b6p-65 then pow(x,y) = +-1. */ - /* Special cases: (x < 0x1p-126 or inf or nan) or + /* Special cases: (x < 0x1p-126 or inf or nan) or (|y| < 0x1p-65 or |y| >= 0x1p63 or nan). */ - if (predict_false(zeroinfnan(iy))) { - if (2 * iy == 0) - return issignaling_inline(x) ? x + y : 1.0; - if (ix == asuint64(1.0)) - return issignaling_inline(y) ? x + y : 1.0; - if (2 * ix > 2 * asuint64(INFINITY) || - 2 * iy > 2 * asuint64(INFINITY)) - return x + y; - if (2 * ix == 2 * asuint64(1.0)) - return 1.0; - if ((2 * ix < 2 * asuint64(1.0)) == !(iy >> 63)) - return 0.0; /* |x|<1 && y==inf or |x|>1 && y==-inf. */ - return y * y; - } - if (predict_false(zeroinfnan(ix))) { - double_t x2 = x * x; - if (ix >> 63 && checkint(iy) == 1) - x2 = -x2; - /* Without the barrier some versions of clang hoist the 1/x2 and + if(predict_false(zeroinfnan(iy))) + { + if(2 * iy == 0) + return issignaling_inline(x) ? x + y : 1.0; + if(ix == asuint64(1.0)) + return issignaling_inline(y) ? x + y : 1.0; + if(2 * ix > 2 * asuint64(INFINITY) || 2 * iy > 2 * asuint64(INFINITY)) + return x + y; + if(2 * ix == 2 * asuint64(1.0)) + return 1.0; + if((2 * ix < 2 * asuint64(1.0)) == !(iy >> 63)) + return 0.0; /* |x|<1 && y==inf or |x|>1 && y==-inf. */ + return y * y; + } + if(predict_false(zeroinfnan(ix))) + { + double_t x2 = x * x; + if(ix >> 63 && checkint(iy) == 1) + x2 = -x2; + /* Without the barrier some versions of clang hoist the 1/x2 and thus division by zero exception can be signaled spuriously. */ - // NOTE(orca): I hope my version of clang is not affected lol - // return iy >> 63 ? fp_barrier(1 / x2) : x2; - return iy >> 63 ? (1 / x2) : x2; - } - /* Here x and y are non-zero finite. */ - if (ix >> 63) { - /* Finite x < 0. */ - int yint = checkint(iy); - if (yint == 0) - return __math_invalid(x); - if (yint == 1) - sign_bias = SIGN_BIAS; - ix &= 0x7fffffffffffffff; - topx &= 0x7ff; - } - if ((topy & 0x7ff) - 0x3be >= 0x43e - 0x3be) { - /* Note: sign_bias == 0 here because y is not odd. */ - if (ix == asuint64(1.0)) - return 1.0; - if ((topy & 0x7ff) < 0x3be) { - /* |y| < 2^-65, x^y ~= 1 + y*log(x). */ - if (WANT_ROUNDING) - return ix > asuint64(1.0) ? 1.0 + y : - 1.0 - y; - else - return 1.0; - } - return (ix > asuint64(1.0)) == (topy < 0x800) ? - __math_oflow(0) : - __math_uflow(0); - } - if (topx == 0) { - /* Normalize subnormal x so exponent becomes negative. */ - ix = asuint64(x * 0x1p52); - ix &= 0x7fffffffffffffff; - ix -= 52ULL << 52; - } - } + // NOTE(orca): I hope my version of clang is not affected lol + // return iy >> 63 ? fp_barrier(1 / x2) : x2; + return iy >> 63 ? (1 / x2) : x2; + } + /* Here x and y are non-zero finite. */ + if(ix >> 63) + { + /* Finite x < 0. */ + int yint = checkint(iy); + if(yint == 0) + return __math_invalid(x); + if(yint == 1) + sign_bias = SIGN_BIAS; + ix &= 0x7fffffffffffffff; + topx &= 0x7ff; + } + if((topy & 0x7ff) - 0x3be >= 0x43e - 0x3be) + { + /* Note: sign_bias == 0 here because y is not odd. */ + if(ix == asuint64(1.0)) + return 1.0; + if((topy & 0x7ff) < 0x3be) + { + /* |y| < 2^-65, x^y ~= 1 + y*log(x). */ + if(WANT_ROUNDING) + return ix > asuint64(1.0) ? 1.0 + y : 1.0 - y; + else + return 1.0; + } + return (ix > asuint64(1.0)) == (topy < 0x800) ? __math_oflow(0) : __math_uflow(0); + } + if(topx == 0) + { + /* Normalize subnormal x so exponent becomes negative. */ + ix = asuint64(x * 0x1p52); + ix &= 0x7fffffffffffffff; + ix -= 52ULL << 52; + } + } - double_t lo; - double_t hi = log_inline(ix, &lo); - double_t ehi, elo; + double_t lo; + double_t hi = log_inline(ix, &lo); + double_t ehi, elo; #if __FP_FAST_FMA - ehi = y * hi; - elo = y * lo + __builtin_fma(y, hi, -ehi); + ehi = y * hi; + elo = y * lo + __builtin_fma(y, hi, -ehi); #else - double_t yhi = asdouble(iy & -1ULL << 27); - double_t ylo = y - yhi; - double_t lhi = asdouble(asuint64(hi) & -1ULL << 27); - double_t llo = hi - lhi + lo; - ehi = yhi * lhi; - elo = ylo * lhi + y * llo; /* |elo| < |ehi| * 2^-25. */ + double_t yhi = asdouble(iy & -1ULL << 27); + double_t ylo = y - yhi; + double_t lhi = asdouble(asuint64(hi) & -1ULL << 27); + double_t llo = hi - lhi + lo; + ehi = yhi * lhi; + elo = ylo * lhi + y * llo; /* |elo| < |ehi| * 2^-25. */ #endif - return exp_inline(ehi, elo, sign_bias); + return exp_inline(ehi, elo, sign_bias); } diff --git a/src/libc-shim/src/pow_data.h b/src/libc-shim/src/pow_data.h index 897d2bc..3c13894 100644 --- a/src/libc-shim/src/pow_data.h +++ b/src/libc-shim/src/pow_data.h @@ -9,14 +9,18 @@ #define POW_LOG_TABLE_BITS 7 #define POW_LOG_POLY_ORDER 8 -extern const struct pow_log_data { - double ln2hi; - double ln2lo; - double poly[POW_LOG_POLY_ORDER - 1]; /* First coefficient is 1. */ - /* Note: the pad field is unused, but allows slightly faster indexing. */ - struct { - double invc, pad, logc, logctail; - } tab[1 << POW_LOG_TABLE_BITS]; + +extern const struct pow_log_data +{ + double ln2hi; + double ln2lo; + double poly[POW_LOG_POLY_ORDER - 1]; /* First coefficient is 1. */ + + /* Note: the pad field is unused, but allows slightly faster indexing. */ + struct + { + double invc, pad, logc, logctail; + } tab[1 << POW_LOG_TABLE_BITS]; } __pow_log_data; #endif diff --git a/src/libc-shim/src/scalbn.c b/src/libc-shim/src/scalbn.c index 182f561..5b7d4d9 100644 --- a/src/libc-shim/src/scalbn.c +++ b/src/libc-shim/src/scalbn.c @@ -3,31 +3,41 @@ double scalbn(double x, int n) { - union {double f; uint64_t i;} u; - double_t y = x; + union + { + double f; + uint64_t i; + } u; - if (n > 1023) { - y *= 0x1p1023; - n -= 1023; - if (n > 1023) { - y *= 0x1p1023; - n -= 1023; - if (n > 1023) - n = 1023; - } - } else if (n < -1022) { - /* make sure final n < -53 to avoid double + double_t y = x; + + if(n > 1023) + { + y *= 0x1p1023; + n -= 1023; + if(n > 1023) + { + y *= 0x1p1023; + n -= 1023; + if(n > 1023) + n = 1023; + } + } + else if(n < -1022) + { + /* make sure final n < -53 to avoid double rounding in the subnormal range */ - y *= 0x1p-1022 * 0x1p53; - n += 1022 - 53; - if (n < -1022) { - y *= 0x1p-1022 * 0x1p53; - n += 1022 - 53; - if (n < -1022) - n = -1022; - } - } - u.i = (uint64_t)(0x3ff+n)<<52; - x = y * u.f; - return x; + y *= 0x1p-1022 * 0x1p53; + n += 1022 - 53; + if(n < -1022) + { + y *= 0x1p-1022 * 0x1p53; + n += 1022 - 53; + if(n < -1022) + n = -1022; + } + } + u.i = (uint64_t)(0x3ff + n) << 52; + x = y * u.f; + return x; } diff --git a/src/libc-shim/src/sin.c b/src/libc-shim/src/sin.c index 055e215..c5b9e39 100644 --- a/src/libc-shim/src/sin.c +++ b/src/libc-shim/src/sin.c @@ -44,35 +44,41 @@ double sin(double x) { - double y[2]; - uint32_t ix; - unsigned n; + double y[2]; + uint32_t ix; + unsigned n; - /* High word of x. */ - GET_HIGH_WORD(ix, x); - ix &= 0x7fffffff; + /* High word of x. */ + GET_HIGH_WORD(ix, x); + ix &= 0x7fffffff; - /* |x| ~< pi/4 */ - if (ix <= 0x3fe921fb) { - if (ix < 0x3e500000) { /* |x| < 2**-26 */ - /* raise inexact if x != 0 and underflow if subnormal*/ - FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f); - return x; - } - return __sin(x, 0.0, 0); - } + /* |x| ~< pi/4 */ + if(ix <= 0x3fe921fb) + { + if(ix < 0x3e500000) + { /* |x| < 2**-26 */ + /* raise inexact if x != 0 and underflow if subnormal*/ + FORCE_EVAL(ix < 0x00100000 ? x / 0x1p120f : x + 0x1p120f); + return x; + } + return __sin(x, 0.0, 0); + } - /* sin(Inf or NaN) is NaN */ - if (ix >= 0x7ff00000) - return x - x; + /* sin(Inf or NaN) is NaN */ + if(ix >= 0x7ff00000) + return x - x; - /* argument reduction needed */ - n = __rem_pio2(x, y); - switch (n&3) { - case 0: return __sin(y[0], y[1], 1); - case 1: return __cos(y[0], y[1]); - case 2: return -__sin(y[0], y[1], 1); - default: - return -__cos(y[0], y[1]); - } + /* argument reduction needed */ + n = __rem_pio2(x, y); + switch(n & 3) + { + case 0: + return __sin(y[0], y[1], 1); + case 1: + return __cos(y[0], y[1]); + case 2: + return -__sin(y[0], y[1], 1); + default: + return -__cos(y[0], y[1]); + } } diff --git a/src/libc-shim/src/sinf.c b/src/libc-shim/src/sinf.c index 64e39f5..83d21cb 100644 --- a/src/libc-shim/src/sinf.c +++ b/src/libc-shim/src/sinf.c @@ -18,59 +18,69 @@ /* Small multiples of pi/2 rounded to double precision. */ static const double -s1pio2 = 1*M_PI_2, /* 0x3FF921FB, 0x54442D18 */ -s2pio2 = 2*M_PI_2, /* 0x400921FB, 0x54442D18 */ -s3pio2 = 3*M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ -s4pio2 = 4*M_PI_2; /* 0x401921FB, 0x54442D18 */ + s1pio2 = 1 * M_PI_2, /* 0x3FF921FB, 0x54442D18 */ + s2pio2 = 2 * M_PI_2, /* 0x400921FB, 0x54442D18 */ + s3pio2 = 3 * M_PI_2, /* 0x4012D97C, 0x7F3321D2 */ + s4pio2 = 4 * M_PI_2; /* 0x401921FB, 0x54442D18 */ float sinf(float x) { - double y; - uint32_t ix; - int n, sign; + double y; + uint32_t ix; + int n, sign; - GET_FLOAT_WORD(ix, x); - sign = ix >> 31; - ix &= 0x7fffffff; + GET_FLOAT_WORD(ix, x); + sign = ix >> 31; + ix &= 0x7fffffff; - if (ix <= 0x3f490fda) { /* |x| ~<= pi/4 */ - if (ix < 0x39800000) { /* |x| < 2**-12 */ - /* raise inexact if x!=0 and underflow if subnormal */ - FORCE_EVAL(ix < 0x00800000 ? x/0x1p120f : x+0x1p120f); - return x; - } - return __sindf(x); - } - if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */ - if (ix <= 0x4016cbe3) { /* |x| ~<= 3pi/4 */ - if (sign) - return -__cosdf(x + s1pio2); - else - return __cosdf(x - s1pio2); - } - return __sindf(sign ? -(x + s2pio2) : -(x - s2pio2)); - } - if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */ - if (ix <= 0x40afeddf) { /* |x| ~<= 7*pi/4 */ - if (sign) - return __cosdf(x + s3pio2); - else - return -__cosdf(x - s3pio2); - } - return __sindf(sign ? x + s4pio2 : x - s4pio2); - } + if(ix <= 0x3f490fda) + { /* |x| ~<= pi/4 */ + if(ix < 0x39800000) + { /* |x| < 2**-12 */ + /* raise inexact if x!=0 and underflow if subnormal */ + FORCE_EVAL(ix < 0x00800000 ? x / 0x1p120f : x + 0x1p120f); + return x; + } + return __sindf(x); + } + if(ix <= 0x407b53d1) + { /* |x| ~<= 5*pi/4 */ + if(ix <= 0x4016cbe3) + { /* |x| ~<= 3pi/4 */ + if(sign) + return -__cosdf(x + s1pio2); + else + return __cosdf(x - s1pio2); + } + return __sindf(sign ? -(x + s2pio2) : -(x - s2pio2)); + } + if(ix <= 0x40e231d5) + { /* |x| ~<= 9*pi/4 */ + if(ix <= 0x40afeddf) + { /* |x| ~<= 7*pi/4 */ + if(sign) + return __cosdf(x + s3pio2); + else + return -__cosdf(x - s3pio2); + } + return __sindf(sign ? x + s4pio2 : x - s4pio2); + } - /* sin(Inf or NaN) is NaN */ - if (ix >= 0x7f800000) - return x - x; + /* sin(Inf or NaN) is NaN */ + if(ix >= 0x7f800000) + return x - x; - /* general argument reduction needed */ - n = __rem_pio2f(x, &y); - switch (n&3) { - case 0: return __sindf(y); - case 1: return __cosdf(y); - case 2: return __sindf(-y); - default: - return -__cosdf(y); - } + /* general argument reduction needed */ + n = __rem_pio2f(x, &y); + switch(n & 3) + { + case 0: + return __sindf(y); + case 1: + return __cosdf(y); + case 2: + return __sindf(-y); + default: + return -__cosdf(y); + } } diff --git a/src/libc-shim/src/sqrt.c b/src/libc-shim/src/sqrt.c index 5ba2655..a17e101 100644 --- a/src/libc-shim/src/sqrt.c +++ b/src/libc-shim/src/sqrt.c @@ -1,57 +1,59 @@ -#include -#include #include "libm.h" #include "sqrt_data.h" +#include +#include #define FENV_SUPPORT 1 /* returns a*b*2^-32 - e, with error 0 <= e < 1. */ static inline uint32_t mul32(uint32_t a, uint32_t b) { - return (uint64_t)a*b >> 32; + return (uint64_t)a * b >> 32; } /* returns a*b*2^-64 - e, with error 0 <= e < 3. */ static inline uint64_t mul64(uint64_t a, uint64_t b) { - uint64_t ahi = a>>32; - uint64_t alo = a&0xffffffff; - uint64_t bhi = b>>32; - uint64_t blo = b&0xffffffff; - return ahi*bhi + (ahi*blo >> 32) + (alo*bhi >> 32); + uint64_t ahi = a >> 32; + uint64_t alo = a & 0xffffffff; + uint64_t bhi = b >> 32; + uint64_t blo = b & 0xffffffff; + return ahi * bhi + (ahi * blo >> 32) + (alo * bhi >> 32); } double sqrt(double x) { - uint64_t ix, top, m; + uint64_t ix, top, m; - /* special case handling. */ - ix = asuint64(x); - top = ix >> 52; - if (predict_false(top - 0x001 >= 0x7ff - 0x001)) { - /* x < 0x1p-1022 or inf or nan. */ - if (ix * 2 == 0) - return x; - if (ix == 0x7ff0000000000000) - return x; - if (ix > 0x7ff0000000000000) - return __math_invalid(x); - /* x is subnormal, normalize it. */ - ix = asuint64(x * 0x1p52); - top = ix >> 52; - top -= 52; - } + /* special case handling. */ + ix = asuint64(x); + top = ix >> 52; + if(predict_false(top - 0x001 >= 0x7ff - 0x001)) + { + /* x < 0x1p-1022 or inf or nan. */ + if(ix * 2 == 0) + return x; + if(ix == 0x7ff0000000000000) + return x; + if(ix > 0x7ff0000000000000) + return __math_invalid(x); + /* x is subnormal, normalize it. */ + ix = asuint64(x * 0x1p52); + top = ix >> 52; + top -= 52; + } - /* argument reduction: + /* argument reduction: x = 4^e m; with integer e, and m in [1, 4) m: fixed point representation [2.62] 2^e is the exponent part of the result. */ - int even = top & 1; - m = (ix << 11) | 0x8000000000000000; - if (even) m >>= 1; - top = (top + 0x3ff) >> 1; + int even = top & 1; + m = (ix << 11) | 0x8000000000000000; + if(even) + m >>= 1; + top = (top + 0x3ff) >> 1; - /* approximate r ~ 1/sqrt(m) and s ~ sqrt(m) when m in [1,4) + /* approximate r ~ 1/sqrt(m) and s ~ sqrt(m) when m in [1,4) initial estimate: 7bit table lookup (1bit exponent and 6bit significand). @@ -105,54 +107,55 @@ double sqrt(double x) and after switching to 64 bit m: 2.62 r: 0.64, s: 2.62, d: 2.62, u: 2.62, three: 2.62 */ - static const uint64_t three = 0xc0000000; - uint64_t r, s, d, u, i; + static const uint64_t three = 0xc0000000; + uint64_t r, s, d, u, i; - i = (ix >> 46) % 128; - r = (uint32_t)__rsqrt_tab[i] << 16; - /* |r sqrt(m) - 1| < 0x1.fdp-9 */ - s = mul32(m>>32, r); - /* |s/sqrt(m) - 1| < 0x1.fdp-9 */ - d = mul32(s, r); - u = three - d; - r = mul32(r, u) << 1; - /* |r sqrt(m) - 1| < 0x1.7bp-16 */ - s = mul32(s, u) << 1; - /* |s/sqrt(m) - 1| < 0x1.7bp-16 */ - d = mul32(s, r); - u = three - d; - r = mul32(r, u) << 1; - /* |r sqrt(m) - 1| < 0x1.3704p-29 (measured worst-case) */ - r = r << 32; - s = mul64(m, r); - d = mul64(s, r); - u = (three<<32) - d; - s = mul64(s, u); /* repr: 3.61 */ - /* -0x1p-57 < s - sqrt(m) < 0x1.8001p-61 */ - s = (s - 2) >> 9; /* repr: 12.52 */ - /* -0x1.09p-52 < s - sqrt(m) < -0x1.fffcp-63 */ + i = (ix >> 46) % 128; + r = (uint32_t)__rsqrt_tab[i] << 16; + /* |r sqrt(m) - 1| < 0x1.fdp-9 */ + s = mul32(m >> 32, r); + /* |s/sqrt(m) - 1| < 0x1.fdp-9 */ + d = mul32(s, r); + u = three - d; + r = mul32(r, u) << 1; + /* |r sqrt(m) - 1| < 0x1.7bp-16 */ + s = mul32(s, u) << 1; + /* |s/sqrt(m) - 1| < 0x1.7bp-16 */ + d = mul32(s, r); + u = three - d; + r = mul32(r, u) << 1; + /* |r sqrt(m) - 1| < 0x1.3704p-29 (measured worst-case) */ + r = r << 32; + s = mul64(m, r); + d = mul64(s, r); + u = (three << 32) - d; + s = mul64(s, u); /* repr: 3.61 */ + /* -0x1p-57 < s - sqrt(m) < 0x1.8001p-61 */ + s = (s - 2) >> 9; /* repr: 12.52 */ + /* -0x1.09p-52 < s - sqrt(m) < -0x1.fffcp-63 */ - /* s < sqrt(m) < s + 0x1.09p-52, + /* s < sqrt(m) < s + 0x1.09p-52, compute nearest rounded result: the nearest result to 52 bits is either s or s+0x1p-52, we can decide by comparing (2^52 s + 0.5)^2 to 2^104 m. */ - uint64_t d0, d1, d2; - double y, t; - d0 = (m << 42) - s*s; - d1 = s - d0; - d2 = d1 + s + 1; - s += d1 >> 63; - s &= 0x000fffffffffffff; - s |= top << 52; - y = asdouble(s); - if (FENV_SUPPORT) { - /* handle rounding modes and inexact exception: + uint64_t d0, d1, d2; + double y, t; + d0 = (m << 42) - s * s; + d1 = s - d0; + d2 = d1 + s + 1; + s += d1 >> 63; + s &= 0x000fffffffffffff; + s |= top << 52; + y = asdouble(s); + if(FENV_SUPPORT) + { + /* handle rounding modes and inexact exception: only (s+1)^2 == 2^42 m case is exact otherwise add a tiny value to cause the fenv effects. */ - uint64_t tiny = predict_false(d2==0) ? 0 : 0x0010000000000000; - tiny |= (d1^d2) & 0x8000000000000000; - t = asdouble(tiny); - y = eval_as_double(y + t); - } - return y; + uint64_t tiny = predict_false(d2 == 0) ? 0 : 0x0010000000000000; + tiny |= (d1 ^ d2) & 0x8000000000000000; + t = asdouble(tiny); + y = eval_as_double(y + t); + } + return y; } diff --git a/src/libc-shim/src/sqrt_data.c b/src/libc-shim/src/sqrt_data.c index 61bc22f..df0a86d 100644 --- a/src/libc-shim/src/sqrt_data.c +++ b/src/libc-shim/src/sqrt_data.c @@ -1,19 +1,131 @@ #include "sqrt_data.h" const uint16_t __rsqrt_tab[128] = { -0xb451,0xb2f0,0xb196,0xb044,0xaef9,0xadb6,0xac79,0xab43, -0xaa14,0xa8eb,0xa7c8,0xa6aa,0xa592,0xa480,0xa373,0xa26b, -0xa168,0xa06a,0x9f70,0x9e7b,0x9d8a,0x9c9d,0x9bb5,0x9ad1, -0x99f0,0x9913,0x983a,0x9765,0x9693,0x95c4,0x94f8,0x9430, -0x936b,0x92a9,0x91ea,0x912e,0x9075,0x8fbe,0x8f0a,0x8e59, -0x8daa,0x8cfe,0x8c54,0x8bac,0x8b07,0x8a64,0x89c4,0x8925, -0x8889,0x87ee,0x8756,0x86c0,0x862b,0x8599,0x8508,0x8479, -0x83ec,0x8361,0x82d8,0x8250,0x81c9,0x8145,0x80c2,0x8040, -0xff02,0xfd0e,0xfb25,0xf947,0xf773,0xf5aa,0xf3ea,0xf234, -0xf087,0xeee3,0xed47,0xebb3,0xea27,0xe8a3,0xe727,0xe5b2, -0xe443,0xe2dc,0xe17a,0xe020,0xdecb,0xdd7d,0xdc34,0xdaf1, -0xd9b3,0xd87b,0xd748,0xd61a,0xd4f1,0xd3cd,0xd2ad,0xd192, -0xd07b,0xcf69,0xce5b,0xcd51,0xcc4a,0xcb48,0xca4a,0xc94f, -0xc858,0xc764,0xc674,0xc587,0xc49d,0xc3b7,0xc2d4,0xc1f4, -0xc116,0xc03c,0xbf65,0xbe90,0xbdbe,0xbcef,0xbc23,0xbb59, -0xba91,0xb9cc,0xb90a,0xb84a,0xb78c,0xb6d0,0xb617,0xb560, + 0xb451, + 0xb2f0, + 0xb196, + 0xb044, + 0xaef9, + 0xadb6, + 0xac79, + 0xab43, + 0xaa14, + 0xa8eb, + 0xa7c8, + 0xa6aa, + 0xa592, + 0xa480, + 0xa373, + 0xa26b, + 0xa168, + 0xa06a, + 0x9f70, + 0x9e7b, + 0x9d8a, + 0x9c9d, + 0x9bb5, + 0x9ad1, + 0x99f0, + 0x9913, + 0x983a, + 0x9765, + 0x9693, + 0x95c4, + 0x94f8, + 0x9430, + 0x936b, + 0x92a9, + 0x91ea, + 0x912e, + 0x9075, + 0x8fbe, + 0x8f0a, + 0x8e59, + 0x8daa, + 0x8cfe, + 0x8c54, + 0x8bac, + 0x8b07, + 0x8a64, + 0x89c4, + 0x8925, + 0x8889, + 0x87ee, + 0x8756, + 0x86c0, + 0x862b, + 0x8599, + 0x8508, + 0x8479, + 0x83ec, + 0x8361, + 0x82d8, + 0x8250, + 0x81c9, + 0x8145, + 0x80c2, + 0x8040, + 0xff02, + 0xfd0e, + 0xfb25, + 0xf947, + 0xf773, + 0xf5aa, + 0xf3ea, + 0xf234, + 0xf087, + 0xeee3, + 0xed47, + 0xebb3, + 0xea27, + 0xe8a3, + 0xe727, + 0xe5b2, + 0xe443, + 0xe2dc, + 0xe17a, + 0xe020, + 0xdecb, + 0xdd7d, + 0xdc34, + 0xdaf1, + 0xd9b3, + 0xd87b, + 0xd748, + 0xd61a, + 0xd4f1, + 0xd3cd, + 0xd2ad, + 0xd192, + 0xd07b, + 0xcf69, + 0xce5b, + 0xcd51, + 0xcc4a, + 0xcb48, + 0xca4a, + 0xc94f, + 0xc858, + 0xc764, + 0xc674, + 0xc587, + 0xc49d, + 0xc3b7, + 0xc2d4, + 0xc1f4, + 0xc116, + 0xc03c, + 0xbf65, + 0xbe90, + 0xbdbe, + 0xbcef, + 0xbc23, + 0xbb59, + 0xba91, + 0xb9cc, + 0xb90a, + 0xb84a, + 0xb78c, + 0xb6d0, + 0xb617, + 0xb560, }; diff --git a/src/libc-shim/src/sqrtf.c b/src/libc-shim/src/sqrtf.c index 740d81c..efa8012 100644 --- a/src/libc-shim/src/sqrtf.c +++ b/src/libc-shim/src/sqrtf.c @@ -1,83 +1,85 @@ -#include -#include #include "libm.h" #include "sqrt_data.h" +#include +#include #define FENV_SUPPORT 1 static inline uint32_t mul32(uint32_t a, uint32_t b) { - return (uint64_t)a*b >> 32; + return (uint64_t)a * b >> 32; } /* see sqrt.c for more detailed comments. */ float sqrtf(float x) { - uint32_t ix, m, m1, m0, even, ey; + uint32_t ix, m, m1, m0, even, ey; - ix = asuint(x); - if (predict_false(ix - 0x00800000 >= 0x7f800000 - 0x00800000)) { - /* x < 0x1p-126 or inf or nan. */ - if (ix * 2 == 0) - return x; - if (ix == 0x7f800000) - return x; - if (ix > 0x7f800000) - return __math_invalidf(x); - /* x is subnormal, normalize it. */ - ix = asuint(x * 0x1p23f); - ix -= 23 << 23; - } + ix = asuint(x); + if(predict_false(ix - 0x00800000 >= 0x7f800000 - 0x00800000)) + { + /* x < 0x1p-126 or inf or nan. */ + if(ix * 2 == 0) + return x; + if(ix == 0x7f800000) + return x; + if(ix > 0x7f800000) + return __math_invalidf(x); + /* x is subnormal, normalize it. */ + ix = asuint(x * 0x1p23f); + ix -= 23 << 23; + } - /* x = 4^e m; with int e and m in [1, 4). */ - even = ix & 0x00800000; - m1 = (ix << 8) | 0x80000000; - m0 = (ix << 7) & 0x7fffffff; - m = even ? m0 : m1; + /* x = 4^e m; with int e and m in [1, 4). */ + even = ix & 0x00800000; + m1 = (ix << 8) | 0x80000000; + m0 = (ix << 7) & 0x7fffffff; + m = even ? m0 : m1; - /* 2^e is the exponent part of the return value. */ - ey = ix >> 1; - ey += 0x3f800000 >> 1; - ey &= 0x7f800000; + /* 2^e is the exponent part of the return value. */ + ey = ix >> 1; + ey += 0x3f800000 >> 1; + ey &= 0x7f800000; - /* compute r ~ 1/sqrt(m), s ~ sqrt(m) with 2 goldschmidt iterations. */ - static const uint32_t three = 0xc0000000; - uint32_t r, s, d, u, i; - i = (ix >> 17) % 128; - r = (uint32_t)__rsqrt_tab[i] << 16; - /* |r*sqrt(m) - 1| < 0x1p-8 */ - s = mul32(m, r); - /* |s/sqrt(m) - 1| < 0x1p-8 */ - d = mul32(s, r); - u = three - d; - r = mul32(r, u) << 1; - /* |r*sqrt(m) - 1| < 0x1.7bp-16 */ - s = mul32(s, u) << 1; - /* |s/sqrt(m) - 1| < 0x1.7bp-16 */ - d = mul32(s, r); - u = three - d; - s = mul32(s, u); - /* -0x1.03p-28 < s/sqrt(m) - 1 < 0x1.fp-31 */ - s = (s - 1)>>6; - /* s < sqrt(m) < s + 0x1.08p-23 */ + /* compute r ~ 1/sqrt(m), s ~ sqrt(m) with 2 goldschmidt iterations. */ + static const uint32_t three = 0xc0000000; + uint32_t r, s, d, u, i; + i = (ix >> 17) % 128; + r = (uint32_t)__rsqrt_tab[i] << 16; + /* |r*sqrt(m) - 1| < 0x1p-8 */ + s = mul32(m, r); + /* |s/sqrt(m) - 1| < 0x1p-8 */ + d = mul32(s, r); + u = three - d; + r = mul32(r, u) << 1; + /* |r*sqrt(m) - 1| < 0x1.7bp-16 */ + s = mul32(s, u) << 1; + /* |s/sqrt(m) - 1| < 0x1.7bp-16 */ + d = mul32(s, r); + u = three - d; + s = mul32(s, u); + /* -0x1.03p-28 < s/sqrt(m) - 1 < 0x1.fp-31 */ + s = (s - 1) >> 6; + /* s < sqrt(m) < s + 0x1.08p-23 */ - /* compute nearest rounded result. */ - uint32_t d0, d1, d2; - float y, t; - d0 = (m << 16) - s*s; - d1 = s - d0; - d2 = d1 + s + 1; - s += d1 >> 31; - s &= 0x007fffff; - s |= ey; - y = asfloat(s); - if (FENV_SUPPORT) { - /* handle rounding and inexact exception. */ - uint32_t tiny = predict_false(d2==0) ? 0 : 0x01000000; - tiny |= (d1^d2) & 0x80000000; - t = asfloat(tiny); - y = eval_as_float(y + t); - } - return y; + /* compute nearest rounded result. */ + uint32_t d0, d1, d2; + float y, t; + d0 = (m << 16) - s * s; + d1 = s - d0; + d2 = d1 + s + 1; + s += d1 >> 31; + s &= 0x007fffff; + s |= ey; + y = asfloat(s); + if(FENV_SUPPORT) + { + /* handle rounding and inexact exception. */ + uint32_t tiny = predict_false(d2 == 0) ? 0 : 0x01000000; + tiny |= (d1 ^ d2) & 0x80000000; + t = asfloat(tiny); + y = eval_as_float(y + t); + } + return y; } diff --git a/src/libc-shim/src/string.c b/src/libc-shim/src/string.c index 8c44f50..00dcc64 100644 --- a/src/libc-shim/src/string.c +++ b/src/libc-shim/src/string.c @@ -1,122 +1,121 @@ -/************************************************************//** +/************************************************************/ /** * * @file: string.c * @author: Martin Fouilleul * @date: 18/04/2023 * *****************************************************************/ -#include +#include void* memset(void* b, int c, size_t n) { - return(__builtin_memset(b, c, n)); + return (__builtin_memset(b, c, n)); } -void* memcpy(void *restrict dst, const void *restrict src, size_t n) +void* memcpy(void* restrict dst, const void* restrict src, size_t n) { - return(__builtin_memcpy(dst, src, n)); + return (__builtin_memcpy(dst, src, n)); } -void* memmove(void *dst, const void *src, size_t n) +void* memmove(void* dst, const void* src, size_t n) { - return(__builtin_memmove(dst, src, n)); + return (__builtin_memmove(dst, src, n)); } -int memcmp(const void *s1, const void *s2, size_t n) +int memcmp(const void* s1, const void* s2, size_t n) { - return(__builtin_memcmp(s1, s2, n)); + return (__builtin_memcmp(s1, s2, n)); } - #define STB_SPRINTF_IMPLEMENTATION -#include"stb/stb_sprintf.h" +#include "stb/stb_sprintf.h" -size_t strlen(const char *s) +size_t strlen(const char* s) { - size_t len = 0; - while(s[len] != '\0') - { - len++; - } - return(len); + size_t len = 0; + while(s[len] != '\0') + { + len++; + } + return (len); } -int strcmp(const char *s1, const char *s2) +int strcmp(const char* s1, const char* s2) { - size_t i = 0; - while(s1[i] != '\0' && s1[i] == s2[i]) - { - i++; - } - int res = 0; - if(s1[i] != s2[i]) - { - if(s1[i] == '\0') - { - res = -1; - } - else if(s2[i] == '\0') - { - res = 1; - } - else - { - res = (unsigned char)s1[i] - (unsigned char)s2[i]; - } - } - return(res); + size_t i = 0; + while(s1[i] != '\0' && s1[i] == s2[i]) + { + i++; + } + int res = 0; + if(s1[i] != s2[i]) + { + if(s1[i] == '\0') + { + res = -1; + } + else if(s2[i] == '\0') + { + res = 1; + } + else + { + res = (unsigned char)s1[i] - (unsigned char)s2[i]; + } + } + return (res); } -int strncmp(const char *s1, const char *s2, size_t n) +int strncmp(const char* s1, const char* s2, size_t n) { - size_t i = 0; - while(i < n && s1[i] != '\0' && s1[i] == s2[i]) - { - i++; - } - int res = 0; - if(s1[i] != s2[i]) - { - if(s1[i] == '\0') - { - res = -1; - } - else if(s2[i] == '\0') - { - res = 1; - } - else - { - res = (unsigned char)s1[i] - (unsigned char)s2[i]; - } - } - return(res); + size_t i = 0; + while(i < n && s1[i] != '\0' && s1[i] == s2[i]) + { + i++; + } + int res = 0; + if(s1[i] != s2[i]) + { + if(s1[i] == '\0') + { + res = -1; + } + else if(s2[i] == '\0') + { + res = 1; + } + else + { + res = (unsigned char)s1[i] - (unsigned char)s2[i]; + } + } + return (res); } -char* strcpy(char *restrict s1, const char *restrict s2) +char* strcpy(char* restrict s1, const char* restrict s2) { - size_t i = 0; - while(s2[i] != '\0') - { - s1[i] = s2[i]; - i++; - } - s1[i] = '\0'; - return(s1); + size_t i = 0; + while(s2[i] != '\0') + { + s1[i] = s2[i]; + i++; + } + s1[i] = '\0'; + return (s1); } -char* strncpy(char *restrict s1, const char *restrict s2, size_t len) +char* strncpy(char* restrict s1, const char* restrict s2, size_t len) { - size_t i = 0; - while(i < len && s2[i] != '\0') - { - s1[i] = s2[i]; - i++; - } - while(i < len) - { - s1[i] = 0; - i++; - } - return(s1); + size_t i = 0; + while(i < len && s2[i] != '\0') + { + s1[i] = s2[i]; + i++; + } + while(i < len) + { + s1[i] = 0; + i++; + } + return (s1); } diff --git a/src/orca.c b/src/orca.c index 3fbde0d..5771dbf 100644 --- a/src/orca.c +++ b/src/orca.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: orca.c * @author: Martin Fouilleul @@ -10,94 +10,94 @@ //--------------------------------------------------------------- // platform implementations //--------------------------------------------------------------- -#include"platform/platform.h" +#include "platform/platform.h" #if OC_PLATFORM_WINDOWS - #include"platform/native_debug.c" - #include"platform/win32_memory.c" - #include"platform/win32_clock.c" - #include"platform/win32_string_helpers.c" - #include"platform/win32_path.c" - #include"platform/win32_io.c" - #include"platform/win32_thread.c" - //TODO + #include "platform/native_debug.c" + #include "platform/win32_memory.c" + #include "platform/win32_clock.c" + #include "platform/win32_string_helpers.c" + #include "platform/win32_path.c" + #include "platform/win32_io.c" + #include "platform/win32_thread.c" +//TODO #elif OC_PLATFORM_MACOS - #include"platform/native_debug.c" - #include"platform/unix_memory.c" - #include"platform/osx_clock.c" - #include"platform/posix_io.c" - #include"platform/posix_thread.c" + #include "platform/native_debug.c" + #include "platform/unix_memory.c" + #include "platform/osx_clock.c" + #include "platform/posix_io.c" + #include "platform/posix_thread.c" - /* +/* #include"platform/unix_rng.c" #include"platform/posix_socket.c" */ #elif PLATFORM_LINUX - #include"platform/native_debug.c" - #include"platform/unix_base_memory.c" - #include"platform/linux_clock.c" - #include"platform/posix_io.c" - #include"platform/posix_thread.c" - /* + #include "platform/native_debug.c" + #include "platform/unix_base_memory.c" + #include "platform/linux_clock.c" + #include "platform/posix_io.c" + #include "platform/posix_thread.c" +/* #include"platform/unix_rng.c" #include"platform/posix_socket.c" */ #elif OC_PLATFORM_ORCA - #include"platform/orca_debug.c" - #include"platform/orca_clock.c" - #include"platform/orca_memory.c" - #include"platform/orca_malloc.c" - #include"platform/platform_io_common.c" - #include"platform/orca_io_stubs.c" + #include "platform/orca_debug.c" + #include "platform/orca_clock.c" + #include "platform/orca_memory.c" + #include "platform/orca_malloc.c" + #include "platform/platform_io_common.c" + #include "platform/orca_io_stubs.c" #else - #error "Unsupported platform" + #error "Unsupported platform" #endif //--------------------------------------------------------------- // utilities implementations //--------------------------------------------------------------- -#include"util/memory.c" -#include"util/strings.c" -#include"util/utf8.c" -#include"util/hash.c" -#include"util/ringbuffer.c" -#include"util/algebra.c" +#include "util/algebra.c" +#include "util/hash.c" +#include "util/memory.c" +#include "util/ringbuffer.c" +#include "util/strings.c" +#include "util/utf8.c" //--------------------------------------------------------------- // app/graphics layer //--------------------------------------------------------------- #if OC_PLATFORM_WINDOWS - #include"app/win32_app.c" - #include"graphics/graphics_common.c" - #include"graphics/graphics_surface.c" + #include "app/win32_app.c" + #include "graphics/graphics_common.c" + #include "graphics/graphics_surface.c" - #if OC_COMPILE_GL || OC_COMPILE_GLES - #include"graphics/gl_loader.c" - #endif + #if OC_COMPILE_GL || OC_COMPILE_GLES + #include "graphics/gl_loader.c" + #endif - #if OC_COMPILE_GL - #include"graphics/wgl_surface.c" - #endif + #if OC_COMPILE_GL + #include "graphics/wgl_surface.c" + #endif - #if OC_COMPILE_CANVAS - #include"graphics/gl_canvas.c" - #endif + #if OC_COMPILE_CANVAS + #include "graphics/gl_canvas.c" + #endif - #if OC_COMPILE_GLES - #include"graphics/egl_surface.c" - #endif + #if OC_COMPILE_GLES + #include "graphics/egl_surface.c" + #endif #elif OC_PLATFORM_MACOS - //NOTE: macos application layer and graphics backends are defined in orca.m +//NOTE: macos application layer and graphics backends are defined in orca.m #elif OC_PLATFORM_ORCA - #include"app/orca_app.c" - #include"graphics/graphics_common.c" - #include"graphics/orca_surface_stubs.c" + #include "app/orca_app.c" + #include "graphics/graphics_common.c" + #include "graphics/orca_surface_stubs.c" #else - #error "Unsupported platform" + #error "Unsupported platform" #endif -#include"ui/input_state.c" -#include"ui/ui.c" +#include "ui/input_state.c" +#include "ui/ui.c" diff --git a/src/orca.h b/src/orca.h index 3b29235..02d4e9c 100644 --- a/src/orca.h +++ b/src/orca.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: orca.h * @author: Martin Fouilleul @@ -9,48 +9,48 @@ #ifndef __ORCA_H_ #define __ORCA_H_ -#include"util/typedefs.h" -#include"util/macros.h" -#include"util/debug.h" -#include"util/lists.h" -#include"util/memory.h" -#include"util/strings.h" -#include"util/utf8.h" -#include"util/hash.h" -#include"util/algebra.h" +#include "util/algebra.h" +#include "util/debug.h" +#include "util/hash.h" +#include "util/lists.h" +#include "util/macros.h" +#include "util/memory.h" +#include "util/strings.h" +#include "util/typedefs.h" +#include "util/utf8.h" -#include"platform/platform.h" -#include"platform/platform_clock.h" -#include"platform/platform_path.h" -#include"platform/platform_io.h" +#include "platform/platform.h" +#include "platform/platform_clock.h" +#include "platform/platform_io.h" +#include "platform/platform_path.h" #if !defined(OC_PLATFORM_ORCA) || !(OC_PLATFORM_ORCA) - #include"platform/platform_thread.h" + #include "platform/platform_thread.h" #endif -#include"app/app.h" +#include "app/app.h" //---------------------------------------------------------------- // graphics //---------------------------------------------------------------- -#include"graphics/graphics.h" +#include "graphics/graphics.h" #if OC_PLATFORM_ORCA - //TODO: maybe make this conditional - #include"graphics/orca_gl31.h" + //TODO: maybe make this conditional + #include "graphics/orca_gl31.h" - oc_surface oc_surface_canvas(); - oc_surface oc_surface_gles(); +oc_surface oc_surface_canvas(); +oc_surface oc_surface_gles(); #else - #ifdef OC_INCLUDE_GL_API - #include"graphics/gl_api.h" - #endif + #ifdef OC_INCLUDE_GL_API + #include "graphics/gl_api.h" + #endif #endif //---------------------------------------------------------------- // UI //---------------------------------------------------------------- -#include"ui/input_state.h" -#include"ui/ui.h" +#include "ui/input_state.h" +#include "ui/ui.h" #endif //__ORCA_H_ diff --git a/src/orca.m b/src/orca.m index 484774f..1979734 100644 --- a/src/orca.m +++ b/src/orca.m @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: milepost.m * @author: Martin Fouilleul @@ -7,20 +7,20 @@ * *****************************************************************/ -#include"platform/osx_path.m" -#include"app/osx_app.m" -#include"graphics/graphics_common.c" -#include"graphics/graphics_surface.c" +#include "app/osx_app.m" +#include "graphics/graphics_common.c" +#include "graphics/graphics_surface.c" +#include "platform/osx_path.m" #if OC_COMPILE_METAL - #include"graphics/mtl_surface.m" + #include "graphics/mtl_surface.m" #endif #if OC_COMPILE_CANVAS - #include"graphics/mtl_renderer.m" + #include "graphics/mtl_renderer.m" #endif #if OC_COMPILE_GLES - #include"graphics/gl_loader.c" - #include"graphics/egl_surface.c" + #include "graphics/gl_loader.c" + #include "graphics/egl_surface.c" #endif diff --git a/src/platform/native_debug.c b/src/platform/native_debug.c index 0782075..fe939e0 100644 --- a/src/platform/native_debug.c +++ b/src/platform/native_debug.c @@ -1,44 +1,46 @@ -/************************************************************//** +/************************************************************/ /** * * @file: native_debug.c * @author: Martin Fouilleul * @date: 13/08/2023 * *****************************************************************/ -#include +#include -#include"app/app.h" -#include"platform_debug.c" +#include "app/app.h" +#include "platform_debug.c" //---------------------------------------------------------------- // Logging //---------------------------------------------------------------- #if OC_PLATFORM_WINDOWS - #include - #define isatty _isatty - #define fileno _fileno + #include + #define isatty _isatty + #define fileno _fileno #elif OC_PLATFORM_MACOS || PLATFORM_LINUX - #include + #include #endif static const char* OC_LOG_HEADINGS[OC_LOG_LEVEL_COUNT] = { - "Error", - "Warning", - "Info"}; + "Error", + "Warning", + "Info" +}; static const char* OC_LOG_FORMATS[OC_LOG_LEVEL_COUNT] = { - "\033[38;5;9m\033[1m", - "\033[38;5;13m\033[1m", - "\033[38;5;10m\033[1m"}; + "\033[38;5;9m\033[1m", + "\033[38;5;13m\033[1m", + "\033[38;5;10m\033[1m" +}; static const char* OC_LOG_FORMAT_STOP = "\033[m"; typedef struct oc_log_output { - FILE* f; + FILE* f; } oc_log_output; -static oc_log_output oc_logDefaultOutput = {0}; +static oc_log_output oc_logDefaultOutput = { 0 }; oc_log_output* OC_LOG_DEFAULT_OUTPUT = &oc_logDefaultOutput; void platform_log_push(oc_log_output* output, @@ -49,33 +51,33 @@ void platform_log_push(oc_log_output* output, const char* fmt, va_list ap) { - if(output == OC_LOG_DEFAULT_OUTPUT && output->f == 0) - { - output->f = stdout; - } + if(output == OC_LOG_DEFAULT_OUTPUT && output->f == 0) + { + output->f = stdout; + } - int fd = fileno(output->f); - if(isatty(fd)) - { - fprintf(output->f, - "%s%s:%s %s() in %s:%i: ", - OC_LOG_FORMATS[level], - OC_LOG_HEADINGS[level], - OC_LOG_FORMAT_STOP, - function, - file, - line); - } - else - { - fprintf(output->f, - "%s: %s() in %s:%i: ", - OC_LOG_HEADINGS[level], - function, - file, - line); - } - vfprintf(output->f, fmt, ap); + int fd = fileno(output->f); + if(isatty(fd)) + { + fprintf(output->f, + "%s%s:%s %s() in %s:%i: ", + OC_LOG_FORMATS[level], + OC_LOG_HEADINGS[level], + OC_LOG_FORMAT_STOP, + function, + file, + line); + } + else + { + fprintf(output->f, + "%s: %s() in %s:%i: ", + OC_LOG_HEADINGS[level], + function, + file, + line); + } + vfprintf(output->f, fmt, ap); } //---------------------------------------------------------------- @@ -84,56 +86,56 @@ void platform_log_push(oc_log_output* output, _Noreturn void oc_abort_ext(const char* file, const char* function, int line, const char* fmt, ...) { - oc_arena* scratch = oc_scratch(); + oc_arena* scratch = oc_scratch(); - va_list ap; - va_start(ap, fmt); - oc_str8 note = oc_str8_pushfv(scratch, fmt, ap); - va_end(ap); + va_list ap; + va_start(ap, fmt); + oc_str8 note = oc_str8_pushfv(scratch, fmt, ap); + va_end(ap); - oc_str8 msg = oc_str8_pushf(scratch, - "Fatal error in function %s() in file \"%s\", line %i:\n%.*s\n", - function, - file, - line, - (int)note.len, - note.ptr); + oc_str8 msg = oc_str8_pushf(scratch, + "Fatal error in function %s() in file \"%s\", line %i:\n%.*s\n", + function, + file, + line, + (int)note.len, + note.ptr); - oc_log_error(msg.ptr); + oc_log_error(msg.ptr); - oc_str8_list options = {0}; - oc_str8_list_push(scratch, &options, OC_STR8("OK")); + oc_str8_list options = { 0 }; + oc_str8_list_push(scratch, &options, OC_STR8("OK")); - oc_alert_popup(OC_STR8("Fatal Error"), msg, options); + oc_alert_popup(OC_STR8("Fatal Error"), msg, options); - //TODO: could terminate more gracefully? - exit(-1); + //TODO: could terminate more gracefully? + exit(-1); } _Noreturn void oc_assert_fail(const char* file, const char* function, int line, const char* src, const char* fmt, ...) { - oc_arena* scratch = oc_scratch(); + oc_arena* scratch = oc_scratch(); - va_list ap; - va_start(ap, fmt); - oc_str8 note = oc_str8_pushfv(scratch, fmt, ap); - va_end(ap); + va_list ap; + va_start(ap, fmt); + oc_str8 note = oc_str8_pushfv(scratch, fmt, ap); + va_end(ap); - oc_str8 msg = oc_str8_pushf(scratch, - "Assertion failed in function %s() in file \"%s\", line %i:\n%s\nNote: %.*s\n", - function, - file, - line, - src, - oc_str8_ip(note)); + oc_str8 msg = oc_str8_pushf(scratch, + "Assertion failed in function %s() in file \"%s\", line %i:\n%s\nNote: %.*s\n", + function, + file, + line, + src, + oc_str8_ip(note)); - oc_log_error(msg.ptr); + oc_log_error(msg.ptr); - oc_str8_list options = {0}; - oc_str8_list_push(scratch, &options, OC_STR8("OK")); + oc_str8_list options = { 0 }; + oc_str8_list_push(scratch, &options, OC_STR8("OK")); - oc_alert_popup(OC_STR8("Assertion Failed"), msg, options); + oc_alert_popup(OC_STR8("Assertion Failed"), msg, options); - //TODO: could terminate more gracefully? - exit(-1); + //TODO: could terminate more gracefully? + exit(-1); } diff --git a/src/platform/orca_clock.c b/src/platform/orca_clock.c index e066ee4..0540a06 100644 --- a/src/platform/orca_clock.c +++ b/src/platform/orca_clock.c @@ -1,4 +1,4 @@ -#include"util/typedefs.h" -#include"platform_clock.h" +#include "platform_clock.h" +#include "util/typedefs.h" f64 ORCA_IMPORT(oc_clock_time)(oc_clock_kind clock); diff --git a/src/platform/orca_debug.c b/src/platform/orca_debug.c index d4a1b56..2ccdc5a 100644 --- a/src/platform/orca_debug.c +++ b/src/platform/orca_debug.c @@ -1,15 +1,14 @@ -/************************************************************//** +/************************************************************/ /** * * @file: orca_debug.c * @author: Martin Fouilleul * @date: 13/08/2023 * *****************************************************************/ -#include - -#include"platform_debug.c" -#include"util/strings.h" +#include +#include "platform_debug.c" +#include "util/strings.h" //---------------------------------------------------------------- // stb sprintf callback and user struct @@ -17,18 +16,18 @@ typedef struct oc_stbsp_context { - oc_arena* arena; - oc_str8_list list; + oc_arena* arena; + oc_str8_list list; } oc_stbsp_context; char* oc_stbsp_callback(char const* buf, void* user, int len) { - oc_stbsp_context* ctx = (oc_stbsp_context*)user; + oc_stbsp_context* ctx = (oc_stbsp_context*)user; - oc_str8 string = oc_str8_push_buffer(ctx->arena, len, (char*)buf); - oc_str8_list_push(ctx->arena, &ctx->list, string); + oc_str8 string = oc_str8_push_buffer(ctx->arena, len, (char*)buf); + oc_str8_list_push(ctx->arena, &ctx->list, string); - return((char*)buf); + return ((char*)buf); } //---------------------------------------------------------------- @@ -37,27 +36,27 @@ char* oc_stbsp_callback(char const* buf, void* user, int len) typedef enum { - ORCA_LOG_OUTPUT_CONSOLE, - ORCA_LOG_OUTPUT_FILE + ORCA_LOG_OUTPUT_CONSOLE, + ORCA_LOG_OUTPUT_FILE } oc_log_output_kind; typedef struct oc_log_output { - oc_log_output_kind kind; - //TODO: file output + oc_log_output_kind kind; + //TODO: file output } oc_log_output; -static oc_log_output oc_logDefaultOutput = {.kind = ORCA_LOG_OUTPUT_CONSOLE}; +static oc_log_output oc_logDefaultOutput = { .kind = ORCA_LOG_OUTPUT_CONSOLE }; oc_log_output* OC_LOG_DEFAULT_OUTPUT = &oc_logDefaultOutput; void ORCA_IMPORT(oc_runtime_log)(oc_log_level level, - int fileLen, - const char* file, - int functionLen, - const char* function, - int line, - int msgLen, - const char* msg); + int fileLen, + const char* file, + int functionLen, + const char* function, + int line, + int msgLen, + const char* msg); void platform_log_push(oc_log_output* output, oc_log_level level, @@ -67,20 +66,20 @@ void platform_log_push(oc_log_output* output, const char* fmt, va_list ap) { - oc_arena* scratch = oc_scratch(); - oc_arena_scope tmp = oc_arena_scope_begin(scratch); + oc_arena* scratch = oc_scratch(); + oc_arena_scope tmp = oc_arena_scope_begin(scratch); - oc_stbsp_context ctx = {.arena = scratch, - .list = {0}}; + oc_stbsp_context ctx = { .arena = scratch, + .list = { 0 } }; - char buf[STB_SPRINTF_MIN]; - stbsp_vsprintfcb(oc_stbsp_callback, &ctx, buf, fmt, ap); + char buf[STB_SPRINTF_MIN]; + stbsp_vsprintfcb(oc_stbsp_callback, &ctx, buf, fmt, ap); - oc_str8 string = oc_str8_list_join(scratch, ctx.list); + oc_str8 string = oc_str8_list_join(scratch, ctx.list); - oc_runtime_log(level, strlen(file), file, strlen(function), function, line, oc_str8_ip(string)); + oc_runtime_log(level, strlen(file), file, strlen(function), function, line, oc_str8_ip(string)); - oc_arena_scope_end(tmp); + oc_arena_scope_end(tmp); } //---------------------------------------------------------------- @@ -92,48 +91,48 @@ _Noreturn void ORCA_IMPORT(oc_runtime_assert_fail)(const char* file, const char* _Noreturn void oc_abort_ext(const char* file, const char* function, int line, const char* fmt, ...) { - oc_arena_scope scratch = oc_scratch_begin(); + oc_arena_scope scratch = oc_scratch_begin(); - oc_stbsp_context ctx = { - .arena = scratch.arena, - .list = {0} - }; + oc_stbsp_context ctx = { + .arena = scratch.arena, + .list = { 0 } + }; - va_list ap; - va_start(ap, fmt); + va_list ap; + va_start(ap, fmt); - char buf[STB_SPRINTF_MIN]; - stbsp_vsprintfcb(oc_stbsp_callback, &ctx, buf, fmt, ap); + char buf[STB_SPRINTF_MIN]; + stbsp_vsprintfcb(oc_stbsp_callback, &ctx, buf, fmt, ap); - va_end(ap); + va_end(ap); - oc_str8 msg = oc_str8_list_join(scratch.arena, ctx.list); + oc_str8 msg = oc_str8_list_join(scratch.arena, ctx.list); - oc_runtime_abort_ext(file, function, line, msg.ptr); + oc_runtime_abort_ext(file, function, line, msg.ptr); - oc_scratch_end(scratch); + oc_scratch_end(scratch); } _Noreturn void oc_assert_fail(const char* file, const char* function, int line, const char* src, const char* fmt, ...) { - oc_arena_scope scratch = oc_scratch_begin(); + oc_arena_scope scratch = oc_scratch_begin(); - oc_stbsp_context ctx = { - .arena = scratch.arena, - .list = {0} - }; + oc_stbsp_context ctx = { + .arena = scratch.arena, + .list = { 0 } + }; - va_list ap; - va_start(ap, fmt); + va_list ap; + va_start(ap, fmt); - char buf[STB_SPRINTF_MIN]; - stbsp_vsprintfcb(oc_stbsp_callback, &ctx, buf, fmt, ap); + char buf[STB_SPRINTF_MIN]; + stbsp_vsprintfcb(oc_stbsp_callback, &ctx, buf, fmt, ap); - va_end(ap); + va_end(ap); - oc_str8 msg = oc_str8_list_join(scratch.arena, ctx.list); + oc_str8 msg = oc_str8_list_join(scratch.arena, ctx.list); - oc_runtime_assert_fail(file, function, line, src, msg.ptr); + oc_runtime_assert_fail(file, function, line, src, msg.ptr); - oc_scratch_end(scratch); + oc_scratch_end(scratch); } diff --git a/src/platform/orca_malloc.c b/src/platform/orca_malloc.c index ded90f6..d27a7da 100644 --- a/src/platform/orca_malloc.c +++ b/src/platform/orca_malloc.c @@ -1,5 +1,5 @@ -#include #include +#include // Orca-specific defines #define HAVE_MMAP 0 @@ -244,46 +244,46 @@ extern void* oc_mem_grow(u64 size); #ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include + #define WIN32_LEAN_AND_MEAN + #include -/* Win32 doesn't supply or need the following headers */ -#define LACKS_UNISTD_H -#define LACKS_SYS_PARAM_H -#define LACKS_SYS_MMAN_H + /* Win32 doesn't supply or need the following headers */ + #define LACKS_UNISTD_H + #define LACKS_SYS_PARAM_H + #define LACKS_SYS_MMAN_H -/* Use the supplied emulation of sbrk */ -#define MORECORE sbrk -#define MORECORE_CONTIGUOUS 1 -#define MORECORE_FAILURE ((void*)(-1)) + /* Use the supplied emulation of sbrk */ + #define MORECORE sbrk + #define MORECORE_CONTIGUOUS 1 + #define MORECORE_FAILURE ((void*)(-1)) -/* Use the supplied emulation of mmap and munmap */ -#define HAVE_MMAP 1 -#define MUNMAP_FAILURE (-1) -#define MMAP_CLEARS 1 + /* Use the supplied emulation of mmap and munmap */ + #define HAVE_MMAP 1 + #define MUNMAP_FAILURE (-1) + #define MMAP_CLEARS 1 -/* These values don't really matter in windows mmap emulation */ -#define MAP_PRIVATE 1 -#define MAP_ANONYMOUS 2 -#define PROT_READ 1 -#define PROT_WRITE 2 + /* These values don't really matter in windows mmap emulation */ + #define MAP_PRIVATE 1 + #define MAP_ANONYMOUS 2 + #define PROT_READ 1 + #define PROT_WRITE 2 -/* Emulation functions defined at the end of this file */ + /* Emulation functions defined at the end of this file */ -/* If USE_MALLOC_LOCK, use supplied critical-section-based lock functions */ -#ifdef USE_MALLOC_LOCK -static int slwait(int *sl); -static int slrelease(int *sl); -#endif + /* If USE_MALLOC_LOCK, use supplied critical-section-based lock functions */ + #ifdef USE_MALLOC_LOCK +static int slwait(int* sl); +static int slrelease(int* sl); + #endif static long getpagesize(void); static long getregionsize(void); -static void *sbrk(long size); -static void *mmap(void *ptr, long size, long prot, long type, long handle, long arg); -static long munmap(void *ptr, long size); +static void* sbrk(long size); +static void* mmap(void* ptr, long size, long prot, long type, long handle, long arg); +static long munmap(void* ptr, long size); -static void vminfo (unsigned long*free, unsigned long*reserved, unsigned long*committed); -static int cpuinfo (int whole, unsigned long*kernel, unsigned long*user); +static void vminfo(unsigned long* free, unsigned long* reserved, unsigned long* committed); +static int cpuinfo(int whole, unsigned long* kernel, unsigned long* user); #endif @@ -294,55 +294,54 @@ static int cpuinfo (int whole, unsigned long*kernel, unsigned long*user); */ #ifndef __STD_C -#if defined(__STDC__) || defined(_cplusplus) -#define __STD_C 1 -#else -#define __STD_C 0 -#endif + #if defined(__STDC__) || defined(_cplusplus) + #define __STD_C 1 + #else + #define __STD_C 0 + #endif #endif /*__STD_C*/ - /* Void_t* is the pointer type that malloc should say it returns */ #ifndef Void_t -#if (__STD_C || defined(WIN32)) -#define Void_t void -#else -#define Void_t char -#endif + #if(__STD_C || defined(WIN32)) + #define Void_t void + #else + #define Void_t char + #endif #endif /*Void_t*/ #if __STD_C -#include /* for size_t */ + #include /* for size_t */ #else -#include + #include #endif #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -/* define LACKS_UNISTD_H if your system does not have a . */ + /* define LACKS_UNISTD_H if your system does not have a . */ -/* #define LACKS_UNISTD_H */ + /* #define LACKS_UNISTD_H */ #ifndef LACKS_UNISTD_H -#include + #include #endif -/* define LACKS_SYS_PARAM_H if your system does not have a . */ + /* define LACKS_SYS_PARAM_H if your system does not have a . */ -/* #define LACKS_SYS_PARAM_H */ + /* #define LACKS_SYS_PARAM_H */ + //NOTE(ORCA): stdio doesn't make sense in orca platform + // #include /* needed for malloc_stats */ -//NOTE(ORCA): stdio doesn't make sense in orca platform -// #include /* needed for malloc_stats */ +#include /* needed for optional MALLOC_FAILURE_ACTION */ -#include /* needed for optional MALLOC_FAILURE_ACTION */ - -/* + /* Debugging: Because freed chunks may be overwritten with bookkeeping fields, this @@ -371,18 +370,18 @@ extern "C" { */ #if DL_DEBUG -#include + #include #else -#define assert(x) ((void)0) + #define assert(x) ((void)0) #endif -/* + /* The unsigned integer type used for comparing any two chunk sizes. This should be at least as wide as size_t, but should not be signed. */ #ifndef CHUNK_SIZE_T -#define CHUNK_SIZE_T unsigned long + #define CHUNK_SIZE_T unsigned long #endif /* @@ -391,11 +390,10 @@ extern "C" { systems, intptr_t would suffice. */ #ifndef PTR_UINT -#define PTR_UINT unsigned long + #define PTR_UINT unsigned long #endif - -/* + /* INTERNAL_SIZE_T is the word-size used for internal bookkeeping of chunk sizes. @@ -427,15 +425,13 @@ extern "C" { */ #ifndef INTERNAL_SIZE_T -#define INTERNAL_SIZE_T size_t + #define INTERNAL_SIZE_T size_t #endif /* The corresponding word size */ -#define SIZE_SZ (sizeof(INTERNAL_SIZE_T)) +#define SIZE_SZ (sizeof(INTERNAL_SIZE_T)) - - -/* + /* MALLOC_ALIGNMENT is the minimum alignment for malloc'ed chunks. It must be a power of two at least 2 * SIZE_SZ, even on machines for which smaller alignments would suffice. It may be defined as @@ -443,26 +439,23 @@ extern "C" { are optimized for the case of 8-byte alignment. */ - #ifndef MALLOC_ALIGNMENT -#define MALLOC_ALIGNMENT (2 * SIZE_SZ) + #define MALLOC_ALIGNMENT (2 * SIZE_SZ) #endif /* The corresponding bit mask value */ -#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1) +#define MALLOC_ALIGN_MASK (MALLOC_ALIGNMENT - 1) - - -/* + /* REALLOC_ZERO_BYTES_FREES should be set if a call to realloc with zero bytes should be the same as a call to free. Some people think it should. Otherwise, since this malloc returns a unique pointer for malloc(0), so does realloc(p, 0). */ -/* #define REALLOC_ZERO_BYTES_FREES */ + /* #define REALLOC_ZERO_BYTES_FREES */ -/* + /* TRIM_FASTBINS controls whether free() of a very small chunk can immediately lead to trimming. Setting to true (1) can reduce memory footprint, but will almost always slow down programs that use a lot @@ -479,31 +472,27 @@ extern "C" { */ #ifndef TRIM_FASTBINS -#define TRIM_FASTBINS 0 + #define TRIM_FASTBINS 0 #endif - -/* + /* USE_DL_PREFIX will prefix all public routines with the string 'dl'. This is necessary when you only want to use this malloc in one part of a program, using your regular system malloc elsewhere. */ -/* #define USE_DL_PREFIX */ + /* #define USE_DL_PREFIX */ - -/* + /* USE_MALLOC_LOCK causes wrapper functions to surround each callable routine with pthread mutex lock/unlock. USE_MALLOC_LOCK forces USE_PUBLIC_MALLOC_WRAPPERS to be defined */ + /* #define USE_MALLOC_LOCK */ -/* #define USE_MALLOC_LOCK */ - - -/* + /* If USE_PUBLIC_MALLOC_WRAPPERS is defined, every public routine is actually a wrapper function that first calls MALLOC_PREACTION, then calls the internal routine, and follows it with @@ -514,13 +503,12 @@ extern "C" { */ #ifdef USE_MALLOC_LOCK -#define USE_PUBLIC_MALLOC_WRAPPERS + #define USE_PUBLIC_MALLOC_WRAPPERS #else /* #define USE_PUBLIC_MALLOC_WRAPPERS */ #endif - -/* + /* Two-phase name translation. All of the actual routines are given mangled names. When wrappers are used, they become the public callable versions. @@ -528,59 +516,58 @@ extern "C" { */ #ifndef USE_PUBLIC_MALLOC_WRAPPERS -#define cALLOc public_cALLOc -#define fREe public_fREe -#define cFREe public_cFREe -#define mALLOc public_mALLOc -#define mEMALIGn public_mEMALIGn -#define rEALLOc public_rEALLOc -#define vALLOc public_vALLOc -#define pVALLOc public_pVALLOc -#define mALLINFo public_mALLINFo -#define mALLOPt public_mALLOPt -#define mTRIm public_mTRIm -#define mSTATs public_mSTATs -#define mUSABLe public_mUSABLe -#define iCALLOc public_iCALLOc -#define iCOMALLOc public_iCOMALLOc + #define cALLOc public_cALLOc + #define fREe public_fREe + #define cFREe public_cFREe + #define mALLOc public_mALLOc + #define mEMALIGn public_mEMALIGn + #define rEALLOc public_rEALLOc + #define vALLOc public_vALLOc + #define pVALLOc public_pVALLOc + #define mALLINFo public_mALLINFo + #define mALLOPt public_mALLOPt + #define mTRIm public_mTRIm + #define mSTATs public_mSTATs + #define mUSABLe public_mUSABLe + #define iCALLOc public_iCALLOc + #define iCOMALLOc public_iCOMALLOc #endif #ifdef USE_DL_PREFIX -#define public_cALLOc dlcalloc -#define public_fREe dlfree -#define public_cFREe dlcfree -#define public_mALLOc dlmalloc -#define public_mEMALIGn dlmemalign -#define public_rEALLOc dlrealloc -#define public_vALLOc dlvalloc -#define public_pVALLOc dlpvalloc -#define public_mALLINFo dlmallinfo -#define public_mALLOPt dlmallopt -#define public_mTRIm dlmalloc_trim -#define public_mSTATs dlmalloc_stats -#define public_mUSABLe dlmalloc_usable_size -#define public_iCALLOc dlindependent_calloc -#define public_iCOMALLOc dlindependent_comalloc + #define public_cALLOc dlcalloc + #define public_fREe dlfree + #define public_cFREe dlcfree + #define public_mALLOc dlmalloc + #define public_mEMALIGn dlmemalign + #define public_rEALLOc dlrealloc + #define public_vALLOc dlvalloc + #define public_pVALLOc dlpvalloc + #define public_mALLINFo dlmallinfo + #define public_mALLOPt dlmallopt + #define public_mTRIm dlmalloc_trim + #define public_mSTATs dlmalloc_stats + #define public_mUSABLe dlmalloc_usable_size + #define public_iCALLOc dlindependent_calloc + #define public_iCOMALLOc dlindependent_comalloc #else /* USE_DL_PREFIX */ -#define public_cALLOc calloc -#define public_fREe free -#define public_cFREe cfree -#define public_mALLOc malloc -#define public_mEMALIGn memalign -#define public_rEALLOc realloc -#define public_vALLOc valloc -#define public_pVALLOc pvalloc -#define public_mALLINFo mallinfo -#define public_mALLOPt mallopt -#define public_mTRIm malloc_trim -#define public_mSTATs malloc_stats -#define public_mUSABLe malloc_usable_size -#define public_iCALLOc independent_calloc -#define public_iCOMALLOc independent_comalloc + #define public_cALLOc calloc + #define public_fREe free + #define public_cFREe cfree + #define public_mALLOc malloc + #define public_mEMALIGn memalign + #define public_rEALLOc realloc + #define public_vALLOc valloc + #define public_pVALLOc pvalloc + #define public_mALLINFo mallinfo + #define public_mALLOPt mallopt + #define public_mTRIm malloc_trim + #define public_mSTATs malloc_stats + #define public_mUSABLe malloc_usable_size + #define public_iCALLOc independent_calloc + #define public_iCOMALLOc independent_comalloc #endif /* USE_DL_PREFIX */ - -/* + /* HAVE_MEMCPY should be defined if you are not otherwise using ANSI STD C, but still have memcpy and memset in your C library and want to use them in calloc and realloc. Otherwise simple @@ -597,30 +584,29 @@ extern "C" { #define HAVE_MEMCPY #ifndef USE_MEMCPY -#ifdef HAVE_MEMCPY -#define USE_MEMCPY 1 -#else -#define USE_MEMCPY 0 -#endif + #ifdef HAVE_MEMCPY + #define USE_MEMCPY 1 + #else + #define USE_MEMCPY 0 + #endif #endif +#if(__STD_C || defined(HAVE_MEMCPY)) -#if (__STD_C || defined(HAVE_MEMCPY)) - -#ifdef WIN32 -/* On Win32 memset and memcpy are already declared in windows.h */ -#else -#if __STD_C -void* memset(void*, int, size_t); -void* memcpy(void*, const void*, size_t); -#else -Void_t* memset(); -Void_t* memcpy(); -#endif -#endif + #ifdef WIN32 + /* On Win32 memset and memcpy are already declared in windows.h */ + #else + #if __STD_C + void* memset(void*, int, size_t); + void* memcpy(void*, const void*, size_t); + #else + Void_t* memset(); + Void_t* memcpy(); + #endif + #endif #endif -/* + /* MALLOC_FAILURE_ACTION is the action to take before "return 0" when malloc fails to be able to return memory, either because memory is exhausted or because of illegal arguments. @@ -629,31 +615,30 @@ Void_t* memcpy(); */ #ifndef MALLOC_FAILURE_ACTION -#if __STD_C -#define MALLOC_FAILURE_ACTION \ - errno = ENOMEM; + #if __STD_C + #define MALLOC_FAILURE_ACTION \ + errno = ENOMEM; -#else -#define MALLOC_FAILURE_ACTION -#endif + #else + #define MALLOC_FAILURE_ACTION + #endif #endif -/* + /* MORECORE-related declarations. By default, rely on sbrk */ - #ifdef LACKS_UNISTD_H -#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) -#if __STD_C -extern Void_t* sbrk(ptrdiff_t); -#else -extern Void_t* sbrk(); -#endif -#endif + #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) + #if __STD_C + extern Void_t* sbrk(ptrdiff_t); + #else + extern Void_t* sbrk(); + #endif + #endif #endif -/* + /* MORECORE is the name of the routine to call to obtain more memory from the system. See below for general guidance on writing alternative MORECORE functions, as well as a version for WIN32 and a @@ -661,10 +646,10 @@ extern Void_t* sbrk(); */ #ifndef MORECORE -#define MORECORE sbrk + #define MORECORE sbrk #endif -/* + /* MORECORE_FAILURE is the value returned upon failure of MORECORE as well as mmap. Since it cannot be an otherwise valid memory address, and must reflect values of standard sys calls, you probably ought not @@ -672,10 +657,10 @@ extern Void_t* sbrk(); */ #ifndef MORECORE_FAILURE -#define MORECORE_FAILURE (-1) + #define MORECORE_FAILURE (-1) #endif -/* + /* If MORECORE_CONTIGUOUS is true, take advantage of fact that consecutive calls to MORECORE with positive arguments always return contiguous increasing addresses. This is true of unix sbrk. Even @@ -686,20 +671,19 @@ extern Void_t* sbrk(); */ #ifndef MORECORE_CONTIGUOUS -#define MORECORE_CONTIGUOUS 1 + #define MORECORE_CONTIGUOUS 1 #endif -/* + /* Define MORECORE_CANNOT_TRIM if your version of MORECORE cannot release space back to the system when given negative arguments. This is generally necessary only if you are using a hand-crafted MORECORE function that cannot handle negative arguments. */ -/* #define MORECORE_CANNOT_TRIM */ + /* #define MORECORE_CANNOT_TRIM */ - -/* + /* Define HAVE_MMAP as true to optionally make malloc() use mmap() to allocate very large blocks. These will be returned to the operating system immediately after a free(). Also, if mmap @@ -712,27 +696,26 @@ extern Void_t* sbrk(); */ #ifndef HAVE_MMAP -#define HAVE_MMAP 1 + #define HAVE_MMAP 1 #endif #if HAVE_MMAP -/* + /* Standard unix mmap using /dev/zero clears memory so calloc doesn't need to. */ -#ifndef MMAP_CLEARS -#define MMAP_CLEARS 1 -#endif + #ifndef MMAP_CLEARS + #define MMAP_CLEARS 1 + #endif #else /* no mmap */ -#ifndef MMAP_CLEARS -#define MMAP_CLEARS 0 -#endif + #ifndef MMAP_CLEARS + #define MMAP_CLEARS 0 + #endif #endif - -/* + /* MMAP_AS_MORECORE_SIZE is the minimum mmap size argument to use if sbrk fails, and mmap is used as a backup (which is done only if HAVE_MMAP). The value must be a multiple of page size. This @@ -747,26 +730,25 @@ extern Void_t* sbrk(); */ #ifndef MMAP_AS_MORECORE_SIZE -#define MMAP_AS_MORECORE_SIZE (1024 * 1024) + #define MMAP_AS_MORECORE_SIZE (1024 * 1024) #endif -/* + /* Define HAVE_MREMAP to make realloc() use mremap() to re-allocate large blocks. This is currently only possible on Linux with kernel versions newer than 1.3.77. */ #ifndef HAVE_MREMAP -#if defined(linux) && defined(__USE_GNU) -#define HAVE_MREMAP 1 -#else -#define HAVE_MREMAP 0 -#endif + #if defined(linux) && defined(__USE_GNU) + #define HAVE_MREMAP 1 + #else + #define HAVE_MREMAP 0 + #endif #endif /* HAVE_MMAP */ - -/* + /* The system page size. To the extent possible, this malloc manages memory from the system in page-size units. Note that this value is cached during initialization into a field of malloc_state. So even @@ -778,59 +760,58 @@ extern Void_t* sbrk(); the actual value probably doesn't impact performance. */ - #ifndef malloc_getpagesize -#ifndef LACKS_UNISTD_H -# include + #ifndef LACKS_UNISTD_H + #include + #endif + + #ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ + #ifndef _SC_PAGE_SIZE + #define _SC_PAGE_SIZE _SC_PAGESIZE + #endif + #endif + + #ifdef _SC_PAGE_SIZE + #define malloc_getpagesize sysconf(_SC_PAGE_SIZE) + #else + #if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) + extern size_t getpagesize(); + #define malloc_getpagesize getpagesize() + #else + #ifdef WIN32 /* use supplied emulation of getpagesize */ + #define malloc_getpagesize getpagesize() + #else + #ifndef LACKS_SYS_PARAM_H + #include + #endif + #ifdef EXEC_PAGESIZE + #define malloc_getpagesize EXEC_PAGESIZE + #else + #ifdef NBPG + #ifndef CLSIZE + #define malloc_getpagesize NBPG + #else + #define malloc_getpagesize (NBPG * CLSIZE) + #endif + #else + #ifdef NBPC + #define malloc_getpagesize NBPC + #else + #ifdef PAGESIZE + #define malloc_getpagesize PAGESIZE + #else /* just guess */ + #define malloc_getpagesize (4096) + #endif + #endif + #endif + #endif + #endif + #endif + #endif #endif -# ifdef _SC_PAGESIZE /* some SVR4 systems omit an underscore */ -# ifndef _SC_PAGE_SIZE -# define _SC_PAGE_SIZE _SC_PAGESIZE -# endif -# endif - -# ifdef _SC_PAGE_SIZE -# define malloc_getpagesize sysconf(_SC_PAGE_SIZE) -# else -# if defined(BSD) || defined(DGUX) || defined(HAVE_GETPAGESIZE) - extern size_t getpagesize(); -# define malloc_getpagesize getpagesize() -# else -# ifdef WIN32 /* use supplied emulation of getpagesize */ -# define malloc_getpagesize getpagesize() -# else -# ifndef LACKS_SYS_PARAM_H -# include -# endif -# ifdef EXEC_PAGESIZE -# define malloc_getpagesize EXEC_PAGESIZE -# else -# ifdef NBPG -# ifndef CLSIZE -# define malloc_getpagesize NBPG -# else -# define malloc_getpagesize (NBPG * CLSIZE) -# endif -# else -# ifdef NBPC -# define malloc_getpagesize NBPC -# else -# ifdef PAGESIZE -# define malloc_getpagesize PAGESIZE -# else /* just guess */ -# define malloc_getpagesize (4096) -# endif -# endif -# endif -# endif -# endif -# endif -# endif -#endif - -/* + /* This version of malloc supports the standard SVID/XPG mallinfo routine that returns a struct containing usage properties and statistics. It should work on any SVID/XPG compliant system that has @@ -857,25 +838,26 @@ extern Void_t* sbrk(); HAVE_USR_INCLUDE_MALLOC_H. */ -/* #define HAVE_USR_INCLUDE_MALLOC_H */ + /* #define HAVE_USR_INCLUDE_MALLOC_H */ #ifdef HAVE_USR_INCLUDE_MALLOC_H -#include "/usr/include/malloc.h" + #include "/usr/include/malloc.h" #else /* SVID2/XPG mallinfo structure */ -struct mallinfo { - int arena; /* non-mmapped space allocated from system */ - int ordblks; /* number of free chunks */ - int smblks; /* number of fastbin blocks */ - int hblks; /* number of mmapped regions */ - int hblkhd; /* space in mmapped regions */ - int usmblks; /* maximum total allocated space */ - int fsmblks; /* space available in freed fastbin blocks */ - int uordblks; /* total allocated space */ - int fordblks; /* total free space */ - int keepcost; /* top-most, releasable (via malloc_trim) space */ +struct mallinfo +{ + int arena; /* non-mmapped space allocated from system */ + int ordblks; /* number of free chunks */ + int smblks; /* number of fastbin blocks */ + int hblks; /* number of mmapped regions */ + int hblkhd; /* space in mmapped regions */ + int usmblks; /* maximum total allocated space */ + int fsmblks; /* space available in freed fastbin blocks */ + int uordblks; /* total allocated space */ + int fordblks; /* total free space */ + int keepcost; /* top-most, releasable (via malloc_trim) space */ }; /* @@ -887,7 +869,6 @@ struct mallinfo { */ #endif - /* ---------- description of public routines ------------ */ /* @@ -905,9 +886,9 @@ struct mallinfo { representable value of a size_t. */ #if __STD_C -Void_t* public_mALLOc(size_t); + Void_t* public_mALLOc(size_t); #else -Void_t* public_mALLOc(); +Void_t* public_mALLOc(); #endif /* @@ -922,9 +903,9 @@ Void_t* public_mALLOc(); back unused memory to the system, thus reducing program footprint. */ #if __STD_C -void public_fREe(Void_t*); + void public_fREe(Void_t*); #else -void public_fREe(); +void public_fREe(); #endif /* @@ -933,9 +914,9 @@ void public_fREe(); set to zero. */ #if __STD_C -Void_t* public_cALLOc(size_t, size_t); + Void_t* public_cALLOc(size_t, size_t); #else -Void_t* public_cALLOc(); +Void_t* public_cALLOc(); #endif /* @@ -966,9 +947,9 @@ Void_t* public_cALLOc(); to be used as an argument to realloc is not supported. */ #if __STD_C -Void_t* public_rEALLOc(Void_t*, size_t); + Void_t* public_rEALLOc(Void_t*, size_t); #else -Void_t* public_rEALLOc(); +Void_t* public_rEALLOc(); #endif /* @@ -984,9 +965,9 @@ Void_t* public_rEALLOc(); Overreliance on memalign is a sure way to fragment space. */ #if __STD_C -Void_t* public_mEMALIGn(size_t, size_t); + Void_t* public_mEMALIGn(size_t, size_t); #else -Void_t* public_mEMALIGn(); +Void_t* public_mEMALIGn(); #endif /* @@ -995,13 +976,11 @@ Void_t* public_mEMALIGn(); size of the system. If the pagesize is unknown, 4096 is used. */ #if __STD_C -Void_t* public_vALLOc(size_t); + Void_t* public_vALLOc(size_t); #else -Void_t* public_vALLOc(); +Void_t* public_vALLOc(); #endif - - /* mallopt(int parameter_number, int parameter_value) Sets tunable parameters The format is to provide a @@ -1024,12 +1003,11 @@ Void_t* public_vALLOc(); M_MMAP_MAX -4 65536 any (0 disables use of mmap) */ #if __STD_C -int public_mALLOPt(int, int); + int public_mALLOPt(int, int); #else -int public_mALLOPt(); +int public_mALLOPt(); #endif - /* mallinfo() Returns (by copy) a struct containing various summary statistics: @@ -1054,7 +1032,7 @@ int public_mALLOPt(); thus be inaccurate. */ #if __STD_C -struct mallinfo public_mALLINFo(void); + struct mallinfo public_mALLINFo(void); #else struct mallinfo public_mALLINFo(); #endif @@ -1112,7 +1090,7 @@ struct mallinfo public_mALLINFo(); } */ #if __STD_C -Void_t** public_iCALLOc(size_t, size_t, Void_t**); + Void_t** public_iCALLOc(size_t, size_t, Void_t**); #else Void_t** public_iCALLOc(); #endif @@ -1177,21 +1155,20 @@ Void_t** public_iCALLOc(); might be available for some of the elements. */ #if __STD_C -Void_t** public_iCOMALLOc(size_t, size_t*, Void_t**); + Void_t** public_iCOMALLOc(size_t, size_t*, Void_t**); #else Void_t** public_iCOMALLOc(); #endif - /* pvalloc(size_t n); Equivalent to valloc(minimum-page-that-holds(n)), that is, round up n to nearest pagesize. */ #if __STD_C -Void_t* public_pVALLOc(size_t); + Void_t* public_pVALLOc(size_t); #else -Void_t* public_pVALLOc(); +Void_t* public_pVALLOc(); #endif /* @@ -1203,9 +1180,9 @@ Void_t* public_pVALLOc(); code in the first edition of K&R). */ #if __STD_C -void public_cFREe(Void_t*); + void public_cFREe(Void_t*); #else -void public_cFREe(); +void public_cFREe(); #endif /* @@ -1233,9 +1210,9 @@ void public_cFREe(); rreturn 0. */ #if __STD_C -int public_mTRIm(size_t); + int public_mTRIm(size_t); #else -int public_mTRIm(); +int public_mTRIm(); #endif /* @@ -1254,9 +1231,9 @@ int public_mTRIm(); */ #if __STD_C -size_t public_mUSABLe(Void_t*); + size_t public_mUSABLe(Void_t*); #else -size_t public_mUSABLe(); +size_t public_mUSABLe(); #endif /* @@ -1280,9 +1257,9 @@ size_t public_mUSABLe(); */ #if __STD_C -void public_mSTATs(void); + void public_mSTATs(void); #else -void public_mSTATs(void); +void public_mSTATs(void); #endif /* mallopt tuning options */ @@ -1312,18 +1289,16 @@ void public_mSTATs(void); slower. */ - /* M_MXFAST is a standard SVID/XPG tuning option, usually listed in malloc.h */ #ifndef M_MXFAST -#define M_MXFAST 1 + #define M_MXFAST 1 #endif #ifndef DEFAULT_MXFAST -#define DEFAULT_MXFAST 64 + #define DEFAULT_MXFAST 64 #endif - -/* + /* M_TRIM_THRESHOLD is the maximum amount of unused top-most memory to keep before releasing via malloc_trim in free(). @@ -1383,13 +1358,13 @@ void public_mSTATs(void); since that memory will immediately be returned to the system. */ -#define M_TRIM_THRESHOLD -1 +#define M_TRIM_THRESHOLD -1 #ifndef DEFAULT_TRIM_THRESHOLD -#define DEFAULT_TRIM_THRESHOLD (256 * 1024) + #define DEFAULT_TRIM_THRESHOLD (256 * 1024) #endif -/* + /* M_TOP_PAD is the amount of extra `padding' space to allocate or retain whenever sbrk is called. It is used in two ways internally: @@ -1416,13 +1391,13 @@ void public_mSTATs(void); the program needs. */ -#define M_TOP_PAD -2 +#define M_TOP_PAD -2 #ifndef DEFAULT_TOP_PAD -#define DEFAULT_TOP_PAD (0) + #define DEFAULT_TOP_PAD (0) #endif -/* + /* M_MMAP_THRESHOLD is the request size threshold for using mmap() to service a request. Requests of at least this size that cannot be allocated using already-existing space will be serviced via mmap. @@ -1463,13 +1438,13 @@ void public_mSTATs(void); systems. */ -#define M_MMAP_THRESHOLD -3 +#define M_MMAP_THRESHOLD -3 #ifndef DEFAULT_MMAP_THRESHOLD -#define DEFAULT_MMAP_THRESHOLD (256 * 1024) + #define DEFAULT_MMAP_THRESHOLD (256 * 1024) #endif -/* + /* M_MMAP_MAX is the maximum number of requests to simultaneously service using mmap. This parameter exists because . Some systems have a limited number of internal tables for @@ -1482,18 +1457,18 @@ void public_mSTATs(void); to non-zero values in mallopt will fail. */ -#define M_MMAP_MAX -4 +#define M_MMAP_MAX -4 #ifndef DEFAULT_MMAP_MAX -#if HAVE_MMAP -#define DEFAULT_MMAP_MAX (65536) -#else -#define DEFAULT_MMAP_MAX (0) -#endif + #if HAVE_MMAP + #define DEFAULT_MMAP_MAX (65536) + #else + #define DEFAULT_MMAP_MAX (0) + #endif #endif #ifdef __cplusplus -}; /* end of extern "C" */ +}; /* end of extern "C" */ #endif /* @@ -1510,40 +1485,40 @@ void public_mSTATs(void); #ifdef USE_PUBLIC_MALLOC_WRAPPERS -/* Declare all routines as internal */ -#if __STD_C -static Void_t* mALLOc(size_t); -static void fREe(Void_t*); -static Void_t* rEALLOc(Void_t*, size_t); -static Void_t* mEMALIGn(size_t, size_t); -static Void_t* vALLOc(size_t); -static Void_t* pVALLOc(size_t); -static Void_t* cALLOc(size_t, size_t); + /* Declare all routines as internal */ + #if __STD_C +static Void_t* mALLOc(size_t); +static void fREe(Void_t*); +static Void_t* rEALLOc(Void_t*, size_t); +static Void_t* mEMALIGn(size_t, size_t); +static Void_t* vALLOc(size_t); +static Void_t* pVALLOc(size_t); +static Void_t* cALLOc(size_t, size_t); static Void_t** iCALLOc(size_t, size_t, Void_t**); static Void_t** iCOMALLOc(size_t, size_t*, Void_t**); -static void cFREe(Void_t*); -static int mTRIm(size_t); -static size_t mUSABLe(Void_t*); -static void mSTATs(); -static int mALLOPt(int, int); +static void cFREe(Void_t*); +static int mTRIm(size_t); +static size_t mUSABLe(Void_t*); +static void mSTATs(); +static int mALLOPt(int, int); static struct mallinfo mALLINFo(void); -#else -static Void_t* mALLOc(); -static void fREe(); -static Void_t* rEALLOc(); -static Void_t* mEMALIGn(); -static Void_t* vALLOc(); -static Void_t* pVALLOc(); -static Void_t* cALLOc(); + #else +static Void_t* mALLOc(); +static void fREe(); +static Void_t* rEALLOc(); +static Void_t* mEMALIGn(); +static Void_t* vALLOc(); +static Void_t* pVALLOc(); +static Void_t* cALLOc(); static Void_t** iCALLOc(); static Void_t** iCOMALLOc(); -static void cFREe(); -static int mTRIm(); -static size_t mUSABLe(); -static void mSTATs(); -static int mALLOPt(); +static void cFREe(); +static int mTRIm(); +static size_t mUSABLe(); +static void mSTATs(); +static int mALLOPt(); static struct mallinfo mALLINFo(); -#endif + #endif /* MALLOC_PREACTION and MALLOC_POSTACTION should be @@ -1553,202 +1528,242 @@ static struct mallinfo mALLINFo(); action to take on failure. */ + #ifdef USE_MALLOC_LOCK -#ifdef USE_MALLOC_LOCK - -#ifdef WIN32 + #ifdef WIN32 static int mALLOC_MUTEx; -#define MALLOC_PREACTION slwait(&mALLOC_MUTEx) -#define MALLOC_POSTACTION slrelease(&mALLOC_MUTEx) + #define MALLOC_PREACTION slwait(&mALLOC_MUTEx) + #define MALLOC_POSTACTION slrelease(&mALLOC_MUTEx) -#else + #else -#include + #include static pthread_mutex_t mALLOC_MUTEx = PTHREAD_MUTEX_INITIALIZER; -#define MALLOC_PREACTION pthread_mutex_lock(&mALLOC_MUTEx) -#define MALLOC_POSTACTION pthread_mutex_unlock(&mALLOC_MUTEx) + #define MALLOC_PREACTION pthread_mutex_lock(&mALLOC_MUTEx) + #define MALLOC_POSTACTION pthread_mutex_unlock(&mALLOC_MUTEx) -#endif /* USE_MALLOC_LOCK */ + #endif /* USE_MALLOC_LOCK */ -#else + #else -/* Substitute anything you like for these */ + /* Substitute anything you like for these */ -#define MALLOC_PREACTION (0) -#define MALLOC_POSTACTION (0) + #define MALLOC_PREACTION (0) + #define MALLOC_POSTACTION (0) -#endif + #endif -Void_t* public_mALLOc(size_t bytes) { - Void_t* m; - if (MALLOC_PREACTION != 0) { - return 0; - } - m = mALLOc(bytes); - if (MALLOC_POSTACTION != 0) { - } - return m; +Void_t* public_mALLOc(size_t bytes) +{ + Void_t* m; + if(MALLOC_PREACTION != 0) + { + return 0; + } + m = mALLOc(bytes); + if(MALLOC_POSTACTION != 0) + { + } + return m; } -void public_fREe(Void_t* m) { - if (MALLOC_PREACTION != 0) { - return; - } - fREe(m); - if (MALLOC_POSTACTION != 0) { - } +void public_fREe(Void_t* m) +{ + if(MALLOC_PREACTION != 0) + { + return; + } + fREe(m); + if(MALLOC_POSTACTION != 0) + { + } } -Void_t* public_rEALLOc(Void_t* m, size_t bytes) { - if (MALLOC_PREACTION != 0) { - return 0; - } - m = rEALLOc(m, bytes); - if (MALLOC_POSTACTION != 0) { - } - return m; +Void_t* public_rEALLOc(Void_t* m, size_t bytes) +{ + if(MALLOC_PREACTION != 0) + { + return 0; + } + m = rEALLOc(m, bytes); + if(MALLOC_POSTACTION != 0) + { + } + return m; } -Void_t* public_mEMALIGn(size_t alignment, size_t bytes) { - Void_t* m; - if (MALLOC_PREACTION != 0) { - return 0; - } - m = mEMALIGn(alignment, bytes); - if (MALLOC_POSTACTION != 0) { - } - return m; +Void_t* public_mEMALIGn(size_t alignment, size_t bytes) +{ + Void_t* m; + if(MALLOC_PREACTION != 0) + { + return 0; + } + m = mEMALIGn(alignment, bytes); + if(MALLOC_POSTACTION != 0) + { + } + return m; } -Void_t* public_vALLOc(size_t bytes) { - Void_t* m; - if (MALLOC_PREACTION != 0) { - return 0; - } - m = vALLOc(bytes); - if (MALLOC_POSTACTION != 0) { - } - return m; +Void_t* public_vALLOc(size_t bytes) +{ + Void_t* m; + if(MALLOC_PREACTION != 0) + { + return 0; + } + m = vALLOc(bytes); + if(MALLOC_POSTACTION != 0) + { + } + return m; } -Void_t* public_pVALLOc(size_t bytes) { - Void_t* m; - if (MALLOC_PREACTION != 0) { - return 0; - } - m = pVALLOc(bytes); - if (MALLOC_POSTACTION != 0) { - } - return m; +Void_t* public_pVALLOc(size_t bytes) +{ + Void_t* m; + if(MALLOC_PREACTION != 0) + { + return 0; + } + m = pVALLOc(bytes); + if(MALLOC_POSTACTION != 0) + { + } + return m; } -Void_t* public_cALLOc(size_t n, size_t elem_size) { - Void_t* m; - if (MALLOC_PREACTION != 0) { - return 0; - } - m = cALLOc(n, elem_size); - if (MALLOC_POSTACTION != 0) { - } - return m; +Void_t* public_cALLOc(size_t n, size_t elem_size) +{ + Void_t* m; + if(MALLOC_PREACTION != 0) + { + return 0; + } + m = cALLOc(n, elem_size); + if(MALLOC_POSTACTION != 0) + { + } + return m; } - -Void_t** public_iCALLOc(size_t n, size_t elem_size, Void_t** chunks) { - Void_t** m; - if (MALLOC_PREACTION != 0) { - return 0; - } - m = iCALLOc(n, elem_size, chunks); - if (MALLOC_POSTACTION != 0) { - } - return m; +Void_t** public_iCALLOc(size_t n, size_t elem_size, Void_t** chunks) +{ + Void_t** m; + if(MALLOC_PREACTION != 0) + { + return 0; + } + m = iCALLOc(n, elem_size, chunks); + if(MALLOC_POSTACTION != 0) + { + } + return m; } -Void_t** public_iCOMALLOc(size_t n, size_t sizes[], Void_t** chunks) { - Void_t** m; - if (MALLOC_PREACTION != 0) { - return 0; - } - m = iCOMALLOc(n, sizes, chunks); - if (MALLOC_POSTACTION != 0) { - } - return m; +Void_t** public_iCOMALLOc(size_t n, size_t sizes[], Void_t** chunks) +{ + Void_t** m; + if(MALLOC_PREACTION != 0) + { + return 0; + } + m = iCOMALLOc(n, sizes, chunks); + if(MALLOC_POSTACTION != 0) + { + } + return m; } -void public_cFREe(Void_t* m) { - if (MALLOC_PREACTION != 0) { - return; - } - cFREe(m); - if (MALLOC_POSTACTION != 0) { - } +void public_cFREe(Void_t* m) +{ + if(MALLOC_PREACTION != 0) + { + return; + } + cFREe(m); + if(MALLOC_POSTACTION != 0) + { + } } -int public_mTRIm(size_t s) { - int result; - if (MALLOC_PREACTION != 0) { - return 0; - } - result = mTRIm(s); - if (MALLOC_POSTACTION != 0) { - } - return result; +int public_mTRIm(size_t s) +{ + int result; + if(MALLOC_PREACTION != 0) + { + return 0; + } + result = mTRIm(s); + if(MALLOC_POSTACTION != 0) + { + } + return result; } -size_t public_mUSABLe(Void_t* m) { - size_t result; - if (MALLOC_PREACTION != 0) { - return 0; - } - result = mUSABLe(m); - if (MALLOC_POSTACTION != 0) { - } - return result; +size_t public_mUSABLe(Void_t* m) +{ + size_t result; + if(MALLOC_PREACTION != 0) + { + return 0; + } + result = mUSABLe(m); + if(MALLOC_POSTACTION != 0) + { + } + return result; } -void public_mSTATs() { - if (MALLOC_PREACTION != 0) { - return; - } - mSTATs(); - if (MALLOC_POSTACTION != 0) { - } +void public_mSTATs() +{ + if(MALLOC_PREACTION != 0) + { + return; + } + mSTATs(); + if(MALLOC_POSTACTION != 0) + { + } } -struct mallinfo public_mALLINFo() { - struct mallinfo m; - if (MALLOC_PREACTION != 0) { - struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - return nm; - } - m = mALLINFo(); - if (MALLOC_POSTACTION != 0) { - } - return m; +struct mallinfo public_mALLINFo() +{ + struct mallinfo m; + if(MALLOC_PREACTION != 0) + { + struct mallinfo nm = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + return nm; + } + m = mALLINFo(); + if(MALLOC_POSTACTION != 0) + { + } + return m; } -int public_mALLOPt(int p, int v) { - int result; - if (MALLOC_PREACTION != 0) { - return 0; - } - result = mALLOPt(p, v); - if (MALLOC_POSTACTION != 0) { - } - return result; +int public_mALLOPt(int p, int v) +{ + int result; + if(MALLOC_PREACTION != 0) + { + return 0; + } + result = mALLOPt(p, v); + if(MALLOC_POSTACTION != 0) + { + } + return result; } #endif - - /* ------------- Optional versions of memcopy ---------------- */ - #if USE_MEMCPY /* @@ -1756,68 +1771,111 @@ int public_mALLOPt(int p, int v) { so the (usually slower) memmove is not needed. */ -#define MALLOC_COPY(dest, src, nbytes) memcpy(dest, src, nbytes) -#define MALLOC_ZERO(dest, nbytes) memset(dest, 0, nbytes) + #define MALLOC_COPY(dest, src, nbytes) memcpy(dest, src, nbytes) + #define MALLOC_ZERO(dest, nbytes) memset(dest, 0, nbytes) #else /* !USE_MEMCPY */ /* Use Duff's device for good zeroing/copying performance. */ -#define MALLOC_ZERO(charp, nbytes) \ -do { \ - INTERNAL_SIZE_T* mzp = (INTERNAL_SIZE_T*)(charp); \ - CHUNK_SIZE_T mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T); \ - long mcn; \ - if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; } \ - switch (mctmp) { \ - case 0: for(;;) { *mzp++ = 0; \ - case 7: *mzp++ = 0; \ - case 6: *mzp++ = 0; \ - case 5: *mzp++ = 0; \ - case 4: *mzp++ = 0; \ - case 3: *mzp++ = 0; \ - case 2: *mzp++ = 0; \ - case 1: *mzp++ = 0; if(mcn <= 0) break; mcn--; } \ - } \ -} while(0) + #define MALLOC_ZERO(charp, nbytes) \ + do \ + { \ + INTERNAL_SIZE_T* mzp = (INTERNAL_SIZE_T*)(charp); \ + CHUNK_SIZE_T mctmp = (nbytes) / sizeof(INTERNAL_SIZE_T); \ + long mcn; \ + if(mctmp < 8) \ + mcn = 0; \ + else \ + { \ + mcn = (mctmp - 1) / 8; \ + mctmp %= 8; \ + } \ + switch(mctmp) \ + { \ + case 0: \ + for(;;) \ + { \ + *mzp++ = 0; \ + case 7: \ + *mzp++ = 0; \ + case 6: \ + *mzp++ = 0; \ + case 5: \ + *mzp++ = 0; \ + case 4: \ + *mzp++ = 0; \ + case 3: \ + *mzp++ = 0; \ + case 2: \ + *mzp++ = 0; \ + case 1: \ + *mzp++ = 0; \ + if(mcn <= 0) \ + break; \ + mcn--; \ + } \ + } \ + } while(0) -#define MALLOC_COPY(dest,src,nbytes) \ -do { \ - INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*) src; \ - INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*) dest; \ - CHUNK_SIZE_T mctmp = (nbytes)/sizeof(INTERNAL_SIZE_T); \ - long mcn; \ - if (mctmp < 8) mcn = 0; else { mcn = (mctmp-1)/8; mctmp %= 8; } \ - switch (mctmp) { \ - case 0: for(;;) { *mcdst++ = *mcsrc++; \ - case 7: *mcdst++ = *mcsrc++; \ - case 6: *mcdst++ = *mcsrc++; \ - case 5: *mcdst++ = *mcsrc++; \ - case 4: *mcdst++ = *mcsrc++; \ - case 3: *mcdst++ = *mcsrc++; \ - case 2: *mcdst++ = *mcsrc++; \ - case 1: *mcdst++ = *mcsrc++; if(mcn <= 0) break; mcn--; } \ - } \ -} while(0) + #define MALLOC_COPY(dest, src, nbytes) \ + do \ + { \ + INTERNAL_SIZE_T* mcsrc = (INTERNAL_SIZE_T*)src; \ + INTERNAL_SIZE_T* mcdst = (INTERNAL_SIZE_T*)dest; \ + CHUNK_SIZE_T mctmp = (nbytes) / sizeof(INTERNAL_SIZE_T); \ + long mcn; \ + if(mctmp < 8) \ + mcn = 0; \ + else \ + { \ + mcn = (mctmp - 1) / 8; \ + mctmp %= 8; \ + } \ + switch(mctmp) \ + { \ + case 0: \ + for(;;) \ + { \ + *mcdst++ = *mcsrc++; \ + case 7: \ + *mcdst++ = *mcsrc++; \ + case 6: \ + *mcdst++ = *mcsrc++; \ + case 5: \ + *mcdst++ = *mcsrc++; \ + case 4: \ + *mcdst++ = *mcsrc++; \ + case 3: \ + *mcdst++ = *mcsrc++; \ + case 2: \ + *mcdst++ = *mcsrc++; \ + case 1: \ + *mcdst++ = *mcsrc++; \ + if(mcn <= 0) \ + break; \ + mcn--; \ + } \ + } \ + } while(0) #endif /* ------------------ MMAP support ------------------ */ - #if HAVE_MMAP -#ifndef LACKS_FCNTL_H -#include -#endif + #ifndef LACKS_FCNTL_H + #include + #endif -#ifndef LACKS_SYS_MMAN_H -#include -#endif + #ifndef LACKS_SYS_MMAN_H + #include + #endif -#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) -#define MAP_ANONYMOUS MAP_ANON -#endif + #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) + #define MAP_ANONYMOUS MAP_ANON + #endif /* Nearly all versions of mmap support MAP_ANONYMOUS, @@ -1825,47 +1883,43 @@ do { \ supplied just in case. */ -#ifndef MAP_ANONYMOUS + #ifndef MAP_ANONYMOUS static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */ -#define MMAP(addr, size, prot, flags) ((dev_zero_fd < 0) ? \ - (dev_zero_fd = open("/dev/zero", O_RDWR), \ - mmap((addr), (size), (prot), (flags), dev_zero_fd, 0)) : \ - mmap((addr), (size), (prot), (flags), dev_zero_fd, 0)) + #define MMAP(addr, size, prot, flags) ((dev_zero_fd < 0) ? (dev_zero_fd = open("/dev/zero", O_RDWR), \ + mmap((addr), (size), (prot), (flags), dev_zero_fd, 0)) \ + : mmap((addr), (size), (prot), (flags), dev_zero_fd, 0)) -#else + #else -#define MMAP(addr, size, prot, flags) \ - (mmap((addr), (size), (prot), (flags)|MAP_ANONYMOUS, -1, 0)) - -#endif + #define MMAP(addr, size, prot, flags) \ + (mmap((addr), (size), (prot), (flags) | MAP_ANONYMOUS, -1, 0)) + #endif #endif /* HAVE_MMAP */ - /* ----------------------- Chunk representations ----------------------- */ - /* This struct declaration is misleading (but accurate and necessary). It declares a "view" into memory allowing access to necessary fields at known offsets from a given base. See explanation below. */ -struct malloc_chunk { +struct malloc_chunk +{ - INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */ - INTERNAL_SIZE_T size; /* Size in bytes, including overhead. */ + INTERNAL_SIZE_T prev_size; /* Size of previous chunk (if free). */ + INTERNAL_SIZE_T size; /* Size in bytes, including overhead. */ - struct malloc_chunk* fd; /* double links -- used only if free. */ - struct malloc_chunk* bk; + struct malloc_chunk* fd; /* double links -- used only if free. */ + struct malloc_chunk* bk; }; - typedef struct malloc_chunk* mchunkptr; /* @@ -1961,21 +2015,20 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ /* conversion from malloc headers to user pointers, and back */ -#define chunk2mem(p) ((Void_t*)((char*)(p) + 2*SIZE_SZ)) -#define mem2chunk(mem) ((mchunkptr)((char*)(mem) - 2*SIZE_SZ)) +#define chunk2mem(p) ((Void_t*)((char*)(p) + 2 * SIZE_SZ)) +#define mem2chunk(mem) ((mchunkptr)((char*)(mem)-2 * SIZE_SZ)) /* The smallest possible chunk */ -#define MIN_CHUNK_SIZE (sizeof(struct malloc_chunk)) +#define MIN_CHUNK_SIZE (sizeof(struct malloc_chunk)) /* The smallest size we can malloc is an aligned minimal chunk */ -#define MINSIZE \ - (CHUNK_SIZE_T)(((MIN_CHUNK_SIZE+MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)) +#define MINSIZE \ + (CHUNK_SIZE_T)(((MIN_CHUNK_SIZE + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)) /* Check if m has acceptable alignment */ -#define aligned_OK(m) (((PTR_UINT)((m)) & (MALLOC_ALIGN_MASK)) == 0) - +#define aligned_OK(m) (((PTR_UINT)((m)) & (MALLOC_ALIGN_MASK)) == 0) /* Check if a request is so large that it would wrap around zero when @@ -1983,37 +2036,33 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ low enough so that adding MINSIZE will also not wrap around sero. */ -#define REQUEST_OUT_OF_RANGE(req) \ - ((CHUNK_SIZE_T)(req) >= \ - (CHUNK_SIZE_T)(INTERNAL_SIZE_T)(-2 * MINSIZE)) +#define REQUEST_OUT_OF_RANGE(req) \ + ((CHUNK_SIZE_T)(req) >= (CHUNK_SIZE_T)(INTERNAL_SIZE_T)(-2 * MINSIZE)) /* pad request bytes into a usable size -- internal version */ -#define request2size(req) \ - (((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE) ? \ - MINSIZE : \ - ((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK) +#define request2size(req) \ + (((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE) ? MINSIZE : ((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK) /* Same, except also perform argument check */ -#define checked_request2size(req, sz) \ - if (REQUEST_OUT_OF_RANGE(req)) { \ - MALLOC_FAILURE_ACTION; \ - return 0; \ - } \ - (sz) = request2size(req); +#define checked_request2size(req, sz) \ + if(REQUEST_OUT_OF_RANGE(req)) \ + { \ + MALLOC_FAILURE_ACTION; \ + return 0; \ + } \ + (sz) = request2size(req); /* --------------- Physical chunk operations --------------- */ - /* size field is or'ed with PREV_INUSE when previous adjacent chunk in use */ #define PREV_INUSE 0x1 /* extract inuse bit of previous chunk */ -#define prev_inuse(p) ((p)->size & PREV_INUSE) - +#define prev_inuse(p) ((p)->size & PREV_INUSE) /* size field is or'ed with IS_MMAPPED if the chunk was obtained with mmap() */ #define IS_MMAPPED 0x2 @@ -2029,53 +2078,49 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ cause helpful core dumps to occur if it is tried by accident by people extending or adapting this malloc. */ -#define SIZE_BITS (PREV_INUSE|IS_MMAPPED) +#define SIZE_BITS (PREV_INUSE | IS_MMAPPED) /* Get size, ignoring use bits */ -#define chunksize(p) ((p)->size & ~(SIZE_BITS)) - +#define chunksize(p) ((p)->size & ~(SIZE_BITS)) /* Ptr to next physical malloc_chunk. */ -#define next_chunk(p) ((mchunkptr)( ((char*)(p)) + ((p)->size & ~PREV_INUSE) )) +#define next_chunk(p) ((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE))) /* Ptr to previous physical malloc_chunk */ -#define prev_chunk(p) ((mchunkptr)( ((char*)(p)) - ((p)->prev_size) )) +#define prev_chunk(p) ((mchunkptr)(((char*)(p)) - ((p)->prev_size))) /* Treat space at ptr + offset as a chunk */ -#define chunk_at_offset(p, s) ((mchunkptr)(((char*)(p)) + (s))) +#define chunk_at_offset(p, s) ((mchunkptr)(((char*)(p)) + (s))) /* extract p's inuse bit */ -#define inuse(p)\ -((((mchunkptr)(((char*)(p))+((p)->size & ~PREV_INUSE)))->size) & PREV_INUSE) +#define inuse(p) \ + ((((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size) & PREV_INUSE) /* set/clear chunk as being inuse without otherwise disturbing */ -#define set_inuse(p)\ -((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size |= PREV_INUSE - -#define clear_inuse(p)\ -((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size &= ~(PREV_INUSE) +#define set_inuse(p) \ + ((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size |= PREV_INUSE +#define clear_inuse(p) \ + ((mchunkptr)(((char*)(p)) + ((p)->size & ~PREV_INUSE)))->size &= ~(PREV_INUSE) /* check/set/clear inuse bits in known places */ -#define inuse_bit_at_offset(p, s)\ - (((mchunkptr)(((char*)(p)) + (s)))->size & PREV_INUSE) +#define inuse_bit_at_offset(p, s) \ + (((mchunkptr)(((char*)(p)) + (s)))->size & PREV_INUSE) -#define set_inuse_bit_at_offset(p, s)\ - (((mchunkptr)(((char*)(p)) + (s)))->size |= PREV_INUSE) - -#define clear_inuse_bit_at_offset(p, s)\ - (((mchunkptr)(((char*)(p)) + (s)))->size &= ~(PREV_INUSE)) +#define set_inuse_bit_at_offset(p, s) \ + (((mchunkptr)(((char*)(p)) + (s)))->size |= PREV_INUSE) +#define clear_inuse_bit_at_offset(p, s) \ + (((mchunkptr)(((char*)(p)) + (s)))->size &= ~(PREV_INUSE)) /* Set size at head, without disturbing its use bit */ -#define set_head_size(p, s) ((p)->size = (((p)->size & PREV_INUSE) | (s))) +#define set_head_size(p, s) ((p)->size = (((p)->size & PREV_INUSE) | (s))) /* Set size/use field */ -#define set_head(p, s) ((p)->size = (s)) +#define set_head(p, s) ((p)->size = (s)) /* Set size at footer (only when chunk is not in use) */ -#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_size = (s)) - +#define set_foot(p, s) (((mchunkptr)((char*)(p) + (s)))->prev_size = (s)) /* -------------------- Internal data structures -------------------- @@ -2131,22 +2176,23 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ typedef struct malloc_chunk* mbinptr; /* addressing -- note that bin_at(0) does not exist */ -#define bin_at(m, i) ((mbinptr)((char*)&((m)->bins[(i)<<1]) - (SIZE_SZ<<1))) +#define bin_at(m, i) ((mbinptr)((char*)&((m)->bins[(i) << 1]) - (SIZE_SZ << 1))) /* analog of ++bin */ -#define next_bin(b) ((mbinptr)((char*)(b) + (sizeof(mchunkptr)<<1))) +#define next_bin(b) ((mbinptr)((char*)(b) + (sizeof(mchunkptr) << 1))) /* Reminders about list directionality within bins */ -#define first(b) ((b)->fd) -#define last(b) ((b)->bk) +#define first(b) ((b)->fd) +#define last(b) ((b)->bk) /* Take a chunk off a bin list */ -#define unlink(P, BK, FD) { \ - FD = P->fd; \ - BK = P->bk; \ - FD->bk = BK; \ - BK->fd = FD; \ -} +#define unlink(P, BK, FD) \ + { \ + FD = P->fd; \ + BK = P->bk; \ + FD->bk = BK; \ + BK->fd = FD; \ + } /* Indexing @@ -2166,58 +2212,60 @@ typedef struct malloc_chunk* mbinptr; requests via mmap. */ -#define NBINS 96 -#define NSMALLBINS 32 -#define SMALLBIN_WIDTH 8 -#define MIN_LARGE_SIZE 256 +#define NBINS 96 +#define NSMALLBINS 32 +#define SMALLBIN_WIDTH 8 +#define MIN_LARGE_SIZE 256 -#define in_smallbin_range(sz) \ - ((CHUNK_SIZE_T)(sz) < (CHUNK_SIZE_T)MIN_LARGE_SIZE) +#define in_smallbin_range(sz) \ + ((CHUNK_SIZE_T)(sz) < (CHUNK_SIZE_T)MIN_LARGE_SIZE) -#define smallbin_index(sz) (((unsigned)(sz)) >> 3) +#define smallbin_index(sz) (((unsigned)(sz)) >> 3) /* Compute index for size. We expect this to be inlined when compiled with optimization, else not, which works out well. */ -static int largebin_index(unsigned int sz) { - unsigned int x = sz >> SMALLBIN_WIDTH; - unsigned int m; /* bit position of highest set bit of m */ +static int largebin_index(unsigned int sz) +{ + unsigned int x = sz >> SMALLBIN_WIDTH; + unsigned int m; /* bit position of highest set bit of m */ - if (x >= 0x10000) return NBINS-1; + if(x >= 0x10000) + return NBINS - 1; - /* On intel, use BSRL instruction to find highest bit */ + /* On intel, use BSRL instruction to find highest bit */ #if defined(__GNUC__) && defined(i386) - __asm__("bsrl %1,%0\n\t" - : "=r" (m) - : "g" (x)); + __asm__("bsrl %1,%0\n\t" + : "=r"(m) + : "g"(x)); #else - { - /* + { + /* Based on branch-free nlz algorithm in chapter 5 of Henry S. Warren Jr's book "Hacker's Delight". */ - unsigned int n = ((x - 0x100) >> 16) & 8; - x <<= n; - m = ((x - 0x1000) >> 16) & 4; - n += m; - x <<= m; - m = ((x - 0x4000) >> 16) & 2; - n += m; - x = (x << m) >> 14; - m = 13 - n + (x & ~(x>>1)); - } + unsigned int n = ((x - 0x100) >> 16) & 8; + x <<= n; + m = ((x - 0x1000) >> 16) & 4; + n += m; + x <<= m; + m = ((x - 0x4000) >> 16) & 2; + n += m; + x = (x << m) >> 14; + m = 13 - n + (x & ~(x >> 1)); + } #endif - /* Use next 2 bits to create finer-granularity bins */ - return NSMALLBINS + (m << 2) + ((sz >> (m + 6)) & 3); + /* Use next 2 bits to create finer-granularity bins */ + return NSMALLBINS + (m << 2) + ((sz >> (m + 6)) & 3); } #define bin_index(sz) \ - ((in_smallbin_range(sz)) ? smallbin_index(sz) : largebin_index(sz)) + ((in_smallbin_range(sz)) ? smallbin_index(sz) : largebin_index(sz)) /* FIRST_SORTED_BIN_SIZE is the chunk size corresponding to the @@ -2253,7 +2301,7 @@ static int largebin_index(unsigned int sz) { */ /* The otherwise unindexable 1-bin is used to hold unsorted chunks. */ -#define unsorted_chunks(M) (bin_at(M, 1)) +#define unsorted_chunks(M) (bin_at(M, 1)) /* Top @@ -2274,7 +2322,7 @@ static int largebin_index(unsigned int sz) { */ /* Conveniently, the unsorted bin can be used as dummy top on first call */ -#define initial_top(M) (unsorted_chunks(M)) +#define initial_top(M) (unsorted_chunks(M)) /* Binmap @@ -2288,16 +2336,16 @@ static int largebin_index(unsigned int sz) { */ /* Conservatively use 32 bits per map word, even if on 64bit system */ -#define BINMAPSHIFT 5 -#define BITSPERMAP (1U << BINMAPSHIFT) -#define BINMAPSIZE (NBINS / BITSPERMAP) +#define BINMAPSHIFT 5 +#define BITSPERMAP (1U << BINMAPSHIFT) +#define BINMAPSIZE (NBINS / BITSPERMAP) -#define idx2block(i) ((i) >> BINMAPSHIFT) -#define idx2bit(i) ((1U << ((i) & ((1U << BINMAPSHIFT)-1)))) +#define idx2block(i) ((i) >> BINMAPSHIFT) +#define idx2bit(i) ((1U << ((i) & ((1U << BINMAPSHIFT) - 1)))) -#define mark_bin(m,i) ((m)->binmap[idx2block(i)] |= idx2bit(i)) -#define unmark_bin(m,i) ((m)->binmap[idx2block(i)] &= ~(idx2bit(i))) -#define get_binmap(m,i) ((m)->binmap[idx2block(i)] & idx2bit(i)) +#define mark_bin(m, i) ((m)->binmap[idx2block(i)] |= idx2bit(i)) +#define unmark_bin(m, i) ((m)->binmap[idx2block(i)] &= ~(idx2bit(i))) +#define get_binmap(m, i) ((m)->binmap[idx2block(i)] & idx2bit(i)) /* Fastbins @@ -2319,12 +2367,12 @@ static int largebin_index(unsigned int sz) { typedef struct malloc_chunk* mfastbinptr; /* offset 2 to use otherwise unindexable first 2 bins */ -#define fastbin_index(sz) ((((unsigned int)(sz)) >> 3) - 2) +#define fastbin_index(sz) ((((unsigned int)(sz)) >> 3) - 2) /* The maximum fastbin request size we support */ -#define MAX_FAST_SIZE 80 +#define MAX_FAST_SIZE 80 -#define NFASTBINS (fastbin_index(request2size(MAX_FAST_SIZE))+1) +#define NFASTBINS (fastbin_index(request2size(MAX_FAST_SIZE)) + 1) /* FASTBIN_CONSOLIDATION_THRESHOLD is the size of a chunk in free() @@ -2337,8 +2385,8 @@ typedef struct malloc_chunk* mfastbinptr; if trimming is not used. */ -#define FASTBIN_CONSOLIDATION_THRESHOLD \ - ((unsigned long)(DEFAULT_TRIM_THRESHOLD) >> 1) +#define FASTBIN_CONSOLIDATION_THRESHOLD \ + ((unsigned long)(DEFAULT_TRIM_THRESHOLD) >> 1) /* Since the lowest 2 bits in max_fast don't matter in size comparisons, @@ -2351,11 +2399,11 @@ typedef struct malloc_chunk* mfastbinptr; bin. */ -#define ANYCHUNKS_BIT (1U) +#define ANYCHUNKS_BIT (1U) -#define have_anychunks(M) (((M)->max_fast & ANYCHUNKS_BIT)) -#define set_anychunks(M) ((M)->max_fast |= ANYCHUNKS_BIT) -#define clear_anychunks(M) ((M)->max_fast &= ~ANYCHUNKS_BIT) +#define have_anychunks(M) (((M)->max_fast & ANYCHUNKS_BIT)) +#define set_anychunks(M) ((M)->max_fast |= ANYCHUNKS_BIT) +#define clear_anychunks(M) ((M)->max_fast &= ~ANYCHUNKS_BIT) /* FASTCHUNKS_BIT held in max_fast indicates that there are probably @@ -2363,11 +2411,11 @@ typedef struct malloc_chunk* mfastbinptr; fastbin, and cleared only in malloc_consolidate. */ -#define FASTCHUNKS_BIT (2U) +#define FASTCHUNKS_BIT (2U) -#define have_fastchunks(M) (((M)->max_fast & FASTCHUNKS_BIT)) -#define set_fastchunks(M) ((M)->max_fast |= (FASTCHUNKS_BIT|ANYCHUNKS_BIT)) -#define clear_fastchunks(M) ((M)->max_fast &= ~(FASTCHUNKS_BIT)) +#define have_fastchunks(M) (((M)->max_fast & FASTCHUNKS_BIT)) +#define set_fastchunks(M) ((M)->max_fast |= (FASTCHUNKS_BIT | ANYCHUNKS_BIT)) +#define clear_fastchunks(M) ((M)->max_fast &= ~(FASTCHUNKS_BIT)) /* Set value of max_fast. @@ -2375,79 +2423,77 @@ typedef struct malloc_chunk* mfastbinptr; */ #define set_max_fast(M, s) \ - (M)->max_fast = (((s) == 0)? SMALLBIN_WIDTH: request2size(s)) | \ - ((M)->max_fast & (FASTCHUNKS_BIT|ANYCHUNKS_BIT)) + (M)->max_fast = (((s) == 0) ? SMALLBIN_WIDTH : request2size(s)) | ((M)->max_fast & (FASTCHUNKS_BIT | ANYCHUNKS_BIT)) #define get_max_fast(M) \ - ((M)->max_fast & ~(FASTCHUNKS_BIT | ANYCHUNKS_BIT)) - + ((M)->max_fast & ~(FASTCHUNKS_BIT | ANYCHUNKS_BIT)) /* morecore_properties is a status word holding dynamically discovered or controlled properties of the morecore function */ -#define MORECORE_CONTIGUOUS_BIT (1U) +#define MORECORE_CONTIGUOUS_BIT (1U) #define contiguous(M) \ - (((M)->morecore_properties & MORECORE_CONTIGUOUS_BIT)) + (((M)->morecore_properties & MORECORE_CONTIGUOUS_BIT)) #define noncontiguous(M) \ - (((M)->morecore_properties & MORECORE_CONTIGUOUS_BIT) == 0) + (((M)->morecore_properties & MORECORE_CONTIGUOUS_BIT) == 0) #define set_contiguous(M) \ - ((M)->morecore_properties |= MORECORE_CONTIGUOUS_BIT) + ((M)->morecore_properties |= MORECORE_CONTIGUOUS_BIT) #define set_noncontiguous(M) \ - ((M)->morecore_properties &= ~MORECORE_CONTIGUOUS_BIT) - + ((M)->morecore_properties &= ~MORECORE_CONTIGUOUS_BIT) /* ----------- Internal state representation and initialization ----------- */ -struct malloc_state { +struct malloc_state +{ - /* The maximum chunk size to be eligible for fastbin */ - INTERNAL_SIZE_T max_fast; /* low 2 bits used as flags */ + /* The maximum chunk size to be eligible for fastbin */ + INTERNAL_SIZE_T max_fast; /* low 2 bits used as flags */ - /* Fastbins */ - mfastbinptr fastbins[NFASTBINS]; + /* Fastbins */ + mfastbinptr fastbins[NFASTBINS]; - /* Base of the topmost chunk -- not otherwise kept in a bin */ - mchunkptr top; + /* Base of the topmost chunk -- not otherwise kept in a bin */ + mchunkptr top; - /* The remainder from the most recent split of a small request */ - mchunkptr last_remainder; + /* The remainder from the most recent split of a small request */ + mchunkptr last_remainder; - /* Normal bins packed as described above */ - mchunkptr bins[NBINS * 2]; + /* Normal bins packed as described above */ + mchunkptr bins[NBINS * 2]; - /* Bitmap of bins. Trailing zero map handles cases of largest binned size */ - unsigned int binmap[BINMAPSIZE+1]; + /* Bitmap of bins. Trailing zero map handles cases of largest binned size */ + unsigned int binmap[BINMAPSIZE + 1]; - /* Tunable parameters */ - CHUNK_SIZE_T trim_threshold; - INTERNAL_SIZE_T top_pad; - INTERNAL_SIZE_T mmap_threshold; + /* Tunable parameters */ + CHUNK_SIZE_T trim_threshold; + INTERNAL_SIZE_T top_pad; + INTERNAL_SIZE_T mmap_threshold; - /* Memory map support */ - int n_mmaps; - int n_mmaps_max; - int max_n_mmaps; + /* Memory map support */ + int n_mmaps; + int n_mmaps_max; + int max_n_mmaps; - /* Cache malloc_getpagesize */ - unsigned int pagesize; + /* Cache malloc_getpagesize */ + unsigned int pagesize; - /* Track properties of MORECORE */ - unsigned int morecore_properties; + /* Track properties of MORECORE */ + unsigned int morecore_properties; - /* Statistics */ - INTERNAL_SIZE_T mmapped_mem; - INTERNAL_SIZE_T sbrked_mem; - INTERNAL_SIZE_T max_sbrked_mem; - INTERNAL_SIZE_T max_mmapped_mem; - INTERNAL_SIZE_T max_total_mem; + /* Statistics */ + INTERNAL_SIZE_T mmapped_mem; + INTERNAL_SIZE_T sbrked_mem; + INTERNAL_SIZE_T max_sbrked_mem; + INTERNAL_SIZE_T max_mmapped_mem; + INTERNAL_SIZE_T max_total_mem; }; -typedef struct malloc_state *mstate; +typedef struct malloc_state* mstate; /* There is exactly one instance of this struct in this malloc. @@ -2457,7 +2503,7 @@ typedef struct malloc_state *mstate; all zeroes (as is true of C statics). */ -static struct malloc_state av_; /* never directly referenced */ +static struct malloc_state av_; /* never directly referenced */ /* All uses of av_ are via get_malloc_state(). @@ -2485,31 +2531,31 @@ static void malloc_init_state(mstate av) static void malloc_init_state(av) mstate av; #endif { - int i; - mbinptr bin; + int i; + mbinptr bin; - /* Establish circular links for normal bins */ - for (i = 1; i < NBINS; ++i) { - bin = bin_at(av,i); - bin->fd = bin->bk = bin; - } + /* Establish circular links for normal bins */ + for(i = 1; i < NBINS; ++i) + { + bin = bin_at(av, i); + bin->fd = bin->bk = bin; + } - av->top_pad = DEFAULT_TOP_PAD; - av->n_mmaps_max = DEFAULT_MMAP_MAX; - av->mmap_threshold = DEFAULT_MMAP_THRESHOLD; - av->trim_threshold = DEFAULT_TRIM_THRESHOLD; + av->top_pad = DEFAULT_TOP_PAD; + av->n_mmaps_max = DEFAULT_MMAP_MAX; + av->mmap_threshold = DEFAULT_MMAP_THRESHOLD; + av->trim_threshold = DEFAULT_TRIM_THRESHOLD; #if MORECORE_CONTIGUOUS - set_contiguous(av); + set_contiguous(av); #else - set_noncontiguous(av); + set_noncontiguous(av); #endif + set_max_fast(av, DEFAULT_MXFAST); - set_max_fast(av, DEFAULT_MXFAST); - - av->top = initial_top(av); - av->pagesize = malloc_getpagesize; + av->top = initial_top(av); + av->pagesize = malloc_getpagesize; } /* @@ -2517,14 +2563,14 @@ static void malloc_init_state(av) mstate av; */ #if __STD_C -static Void_t* sYSMALLOc(INTERNAL_SIZE_T, mstate); -static int sYSTRIm(size_t, mstate); -static void malloc_consolidate(mstate); +static Void_t* sYSMALLOc(INTERNAL_SIZE_T, mstate); +static int sYSTRIm(size_t, mstate); +static void malloc_consolidate(mstate); static Void_t** iALLOc(size_t, size_t*, int, Void_t**); #else -static Void_t* sYSMALLOc(); -static int sYSTRIm(); -static void malloc_consolidate(); +static Void_t* sYSMALLOc(); +static int sYSTRIm(); +static void malloc_consolidate(); static Void_t** iALLOc(); #endif @@ -2538,192 +2584,201 @@ static Void_t** iALLOc(); in malloc. In which case, please report it!) */ -#if ! DL_DEBUG +#if !DL_DEBUG -#define check_chunk(P) -#define check_free_chunk(P) -#define check_inuse_chunk(P) -#define check_remalloced_chunk(P,N) -#define check_malloced_chunk(P,N) -#define check_malloc_state() + #define check_chunk(P) + #define check_free_chunk(P) + #define check_inuse_chunk(P) + #define check_remalloced_chunk(P, N) + #define check_malloced_chunk(P, N) + #define check_malloc_state() #else -#define check_chunk(P) do_check_chunk(P) -#define check_free_chunk(P) do_check_free_chunk(P) -#define check_inuse_chunk(P) do_check_inuse_chunk(P) -#define check_remalloced_chunk(P,N) do_check_remalloced_chunk(P,N) -#define check_malloced_chunk(P,N) do_check_malloced_chunk(P,N) -#define check_malloc_state() do_check_malloc_state() + #define check_chunk(P) do_check_chunk(P) + #define check_free_chunk(P) do_check_free_chunk(P) + #define check_inuse_chunk(P) do_check_inuse_chunk(P) + #define check_remalloced_chunk(P, N) do_check_remalloced_chunk(P, N) + #define check_malloced_chunk(P, N) do_check_malloced_chunk(P, N) + #define check_malloc_state() do_check_malloc_state() /* Properties of all chunks */ -#if __STD_C + #if __STD_C static void do_check_chunk(mchunkptr p) -#else + #else static void do_check_chunk(p) mchunkptr p; -#endif + #endif { - mstate av = get_malloc_state(); - CHUNK_SIZE_T sz = chunksize(p); - /* min and max possible addresses assuming contiguous allocation */ - char* max_address = (char*)(av->top) + chunksize(av->top); - char* min_address = max_address - av->sbrked_mem; + mstate av = get_malloc_state(); + CHUNK_SIZE_T sz = chunksize(p); + /* min and max possible addresses assuming contiguous allocation */ + char* max_address = (char*)(av->top) + chunksize(av->top); + char* min_address = max_address - av->sbrked_mem; - if (!chunk_is_mmapped(p)) { + if(!chunk_is_mmapped(p)) + { - /* Has legal address ... */ - if (p != av->top) { - if (contiguous(av)) { - assert(((char*)p) >= min_address); - assert(((char*)p + sz) <= ((char*)(av->top))); - } + /* Has legal address ... */ + if(p != av->top) + { + if(contiguous(av)) + { + assert(((char*)p) >= min_address); + assert(((char*)p + sz) <= ((char*)(av->top))); + } + } + else + { + /* top size is always at least MINSIZE */ + assert((CHUNK_SIZE_T)(sz) >= MINSIZE); + /* top predecessor always marked inuse */ + assert(prev_inuse(p)); + } } - else { - /* top size is always at least MINSIZE */ - assert((CHUNK_SIZE_T)(sz) >= MINSIZE); - /* top predecessor always marked inuse */ - assert(prev_inuse(p)); + else + { + #if HAVE_MMAP + /* address is outside main heap */ + if(contiguous(av) && av->top != initial_top(av)) + { + assert(((char*)p) < min_address || ((char*)p) > max_address); + } + /* chunk is page-aligned */ + assert(((p->prev_size + sz) & (av->pagesize - 1)) == 0); + /* mem is aligned */ + assert(aligned_OK(chunk2mem(p))); + #else + /* force an appropriate assert violation if debug set */ + assert(!chunk_is_mmapped(p)); + #endif } - - } - else { -#if HAVE_MMAP - /* address is outside main heap */ - if (contiguous(av) && av->top != initial_top(av)) { - assert(((char*)p) < min_address || ((char*)p) > max_address); - } - /* chunk is page-aligned */ - assert(((p->prev_size + sz) & (av->pagesize-1)) == 0); - /* mem is aligned */ - assert(aligned_OK(chunk2mem(p))); -#else - /* force an appropriate assert violation if debug set */ - assert(!chunk_is_mmapped(p)); -#endif - } } /* Properties of free chunks */ -#if __STD_C + #if __STD_C static void do_check_free_chunk(mchunkptr p) -#else + #else static void do_check_free_chunk(p) mchunkptr p; -#endif + #endif { - mstate av = get_malloc_state(); + mstate av = get_malloc_state(); - INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE; - mchunkptr next = chunk_at_offset(p, sz); + INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE; + mchunkptr next = chunk_at_offset(p, sz); - do_check_chunk(p); + do_check_chunk(p); - /* Chunk must claim to be free ... */ - assert(!inuse(p)); - assert (!chunk_is_mmapped(p)); + /* Chunk must claim to be free ... */ + assert(!inuse(p)); + assert(!chunk_is_mmapped(p)); - /* Unless a special marker, must have OK fields */ - if ((CHUNK_SIZE_T)(sz) >= MINSIZE) - { - assert((sz & MALLOC_ALIGN_MASK) == 0); - assert(aligned_OK(chunk2mem(p))); - /* ... matching footer field */ - assert(next->prev_size == sz); - /* ... and is fully consolidated */ - assert(prev_inuse(p)); - assert (next == av->top || inuse(next)); + /* Unless a special marker, must have OK fields */ + if((CHUNK_SIZE_T)(sz) >= MINSIZE) + { + assert((sz & MALLOC_ALIGN_MASK) == 0); + assert(aligned_OK(chunk2mem(p))); + /* ... matching footer field */ + assert(next->prev_size == sz); + /* ... and is fully consolidated */ + assert(prev_inuse(p)); + assert(next == av->top || inuse(next)); - /* ... and has minimally sane links */ - assert(p->fd->bk == p); - assert(p->bk->fd == p); - } - else /* markers are always of size SIZE_SZ */ - assert(sz == SIZE_SZ); + /* ... and has minimally sane links */ + assert(p->fd->bk == p); + assert(p->bk->fd == p); + } + else /* markers are always of size SIZE_SZ */ + assert(sz == SIZE_SZ); } /* Properties of inuse chunks */ -#if __STD_C + #if __STD_C static void do_check_inuse_chunk(mchunkptr p) -#else + #else static void do_check_inuse_chunk(p) mchunkptr p; -#endif + #endif { - mstate av = get_malloc_state(); - mchunkptr next; - do_check_chunk(p); + mstate av = get_malloc_state(); + mchunkptr next; + do_check_chunk(p); - if (chunk_is_mmapped(p)) - return; /* mmapped chunks have no next/prev */ + if(chunk_is_mmapped(p)) + return; /* mmapped chunks have no next/prev */ - /* Check whether it claims to be in use ... */ - assert(inuse(p)); + /* Check whether it claims to be in use ... */ + assert(inuse(p)); - next = next_chunk(p); + next = next_chunk(p); - /* ... and is surrounded by OK chunks. + /* ... and is surrounded by OK chunks. Since more things can be checked with free chunks than inuse ones, if an inuse chunk borders them and debug is on, it's worth doing them. */ - if (!prev_inuse(p)) { - /* Note that we cannot even look at prev unless it is not inuse */ - mchunkptr prv = prev_chunk(p); - assert(next_chunk(prv) == p); - do_check_free_chunk(prv); - } + if(!prev_inuse(p)) + { + /* Note that we cannot even look at prev unless it is not inuse */ + mchunkptr prv = prev_chunk(p); + assert(next_chunk(prv) == p); + do_check_free_chunk(prv); + } - if (next == av->top) { - assert(prev_inuse(next)); - assert(chunksize(next) >= MINSIZE); - } - else if (!inuse(next)) - do_check_free_chunk(next); + if(next == av->top) + { + assert(prev_inuse(next)); + assert(chunksize(next) >= MINSIZE); + } + else if(!inuse(next)) + do_check_free_chunk(next); } /* Properties of chunks recycled from fastbins */ -#if __STD_C + #if __STD_C static void do_check_remalloced_chunk(mchunkptr p, INTERNAL_SIZE_T s) -#else -static void do_check_remalloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s; -#endif + #else +static void do_check_remalloced_chunk(p, s) mchunkptr p; +INTERNAL_SIZE_T s; + #endif { - INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE; + INTERNAL_SIZE_T sz = p->size & ~PREV_INUSE; - do_check_inuse_chunk(p); + do_check_inuse_chunk(p); - /* Legal size ... */ - assert((sz & MALLOC_ALIGN_MASK) == 0); - assert((CHUNK_SIZE_T)(sz) >= MINSIZE); - /* ... and alignment */ - assert(aligned_OK(chunk2mem(p))); - /* chunk is less than MINSIZE more than request */ - assert((long)(sz) - (long)(s) >= 0); - assert((long)(sz) - (long)(s + MINSIZE) < 0); + /* Legal size ... */ + assert((sz & MALLOC_ALIGN_MASK) == 0); + assert((CHUNK_SIZE_T)(sz) >= MINSIZE); + /* ... and alignment */ + assert(aligned_OK(chunk2mem(p))); + /* chunk is less than MINSIZE more than request */ + assert((long)(sz) - (long)(s) >= 0); + assert((long)(sz) - (long)(s + MINSIZE) < 0); } /* Properties of nonrecycled chunks at the point they are malloced */ -#if __STD_C + #if __STD_C static void do_check_malloced_chunk(mchunkptr p, INTERNAL_SIZE_T s) -#else -static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s; -#endif + #else +static void do_check_malloced_chunk(p, s) mchunkptr p; +INTERNAL_SIZE_T s; + #endif { - /* same as recycled case ... */ - do_check_remalloced_chunk(p, s); + /* same as recycled case ... */ + do_check_remalloced_chunk(p, s); - /* + /* ... plus, must obey implementation invariant that prev_inuse is always true of any allocated chunk; i.e., that each allocated chunk borders either a previously allocated and still in-use @@ -2733,10 +2788,9 @@ static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s; recycled via fastbins. */ - assert(prev_inuse(p)); + assert(prev_inuse(p)); } - /* Properties of malloc_state. @@ -2750,120 +2804,120 @@ static void do_check_malloced_chunk(p, s) mchunkptr p; INTERNAL_SIZE_T s; static void do_check_malloc_state(void) { - mstate av = get_malloc_state(); - int i; - mchunkptr p; - mchunkptr q; - mbinptr b; - unsigned int binbit; - int empty; - unsigned int idx; - INTERNAL_SIZE_T size; - CHUNK_SIZE_T total = 0; - int max_fast_bin; + mstate av = get_malloc_state(); + int i; + mchunkptr p; + mchunkptr q; + mbinptr b; + unsigned int binbit; + int empty; + unsigned int idx; + INTERNAL_SIZE_T size; + CHUNK_SIZE_T total = 0; + int max_fast_bin; - /* internal size_t must be no wider than pointer type */ - assert(sizeof(INTERNAL_SIZE_T) <= sizeof(char*)); + /* internal size_t must be no wider than pointer type */ + assert(sizeof(INTERNAL_SIZE_T) <= sizeof(char*)); - /* alignment is a power of 2 */ - assert((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT-1)) == 0); + /* alignment is a power of 2 */ + assert((MALLOC_ALIGNMENT & (MALLOC_ALIGNMENT - 1)) == 0); - /* cannot run remaining checks until fully initialized */ - if (av->top == 0 || av->top == initial_top(av)) - return; + /* cannot run remaining checks until fully initialized */ + if(av->top == 0 || av->top == initial_top(av)) + return; - /* pagesize is a power of 2 */ - assert((av->pagesize & (av->pagesize-1)) == 0); + /* pagesize is a power of 2 */ + assert((av->pagesize & (av->pagesize - 1)) == 0); - /* properties of fastbins */ + /* properties of fastbins */ - /* max_fast is in allowed range */ - assert(get_max_fast(av) <= request2size(MAX_FAST_SIZE)); + /* max_fast is in allowed range */ + assert(get_max_fast(av) <= request2size(MAX_FAST_SIZE)); - max_fast_bin = fastbin_index(av->max_fast); + max_fast_bin = fastbin_index(av->max_fast); - for (i = 0; NFASTBINS-i > 0; ++i) { - p = av->fastbins[i]; + for(i = 0; NFASTBINS - i > 0; ++i) + { + p = av->fastbins[i]; - /* all bins past max_fast are empty */ - if (i > max_fast_bin) - assert(p == 0); + /* all bins past max_fast are empty */ + if(i > max_fast_bin) + assert(p == 0); - while (p != 0) { - /* each chunk claims to be inuse */ - do_check_inuse_chunk(p); - total += chunksize(p); - /* chunk belongs in this bin */ - assert(fastbin_index(chunksize(p)) == i); - p = p->fd; - } - } - - if (total != 0) - assert(have_fastchunks(av)); - else if (!have_fastchunks(av)) - assert(total == 0); - - /* check normal bins */ - for (i = 1; i < NBINS; ++i) { - b = bin_at(av,i); - - /* binmap is accurate (except for bin 1 == unsorted_chunks) */ - if (i >= 2) { - binbit = get_binmap(av,i); - empty = last(b) == b; - if (!binbit) - assert(empty); - else if (!empty) - assert(binbit); - } - - for (p = last(b); p != b; p = p->bk) { - /* each chunk claims to be free */ - do_check_free_chunk(p); - size = chunksize(p); - total += size; - if (i >= 2) { - /* chunk belongs in bin */ - idx = bin_index(size); - assert(idx == i); - /* lists are sorted */ - if ((CHUNK_SIZE_T) size >= (CHUNK_SIZE_T)(FIRST_SORTED_BIN_SIZE)) { - assert(p->bk == b || - (CHUNK_SIZE_T)chunksize(p->bk) >= - (CHUNK_SIZE_T)chunksize(p)); + while(p != 0) + { + /* each chunk claims to be inuse */ + do_check_inuse_chunk(p); + total += chunksize(p); + /* chunk belongs in this bin */ + assert(fastbin_index(chunksize(p)) == i); + p = p->fd; } - } - /* chunk is followed by a legal chain of inuse chunks */ - for (q = next_chunk(p); - (q != av->top && inuse(q) && - (CHUNK_SIZE_T)(chunksize(q)) >= MINSIZE); - q = next_chunk(q)) - do_check_inuse_chunk(q); } - } - /* top chunk is OK */ - check_chunk(av->top); + if(total != 0) + assert(have_fastchunks(av)); + else if(!have_fastchunks(av)) + assert(total == 0); - /* sanity checks for statistics */ + /* check normal bins */ + for(i = 1; i < NBINS; ++i) + { + b = bin_at(av, i); - assert(total <= (CHUNK_SIZE_T)(av->max_total_mem)); - assert(av->n_mmaps >= 0); - assert(av->n_mmaps <= av->max_n_mmaps); + /* binmap is accurate (except for bin 1 == unsorted_chunks) */ + if(i >= 2) + { + binbit = get_binmap(av, i); + empty = last(b) == b; + if(!binbit) + assert(empty); + else if(!empty) + assert(binbit); + } - assert((CHUNK_SIZE_T)(av->sbrked_mem) <= - (CHUNK_SIZE_T)(av->max_sbrked_mem)); + for(p = last(b); p != b; p = p->bk) + { + /* each chunk claims to be free */ + do_check_free_chunk(p); + size = chunksize(p); + total += size; + if(i >= 2) + { + /* chunk belongs in bin */ + idx = bin_index(size); + assert(idx == i); + /* lists are sorted */ + if((CHUNK_SIZE_T)size >= (CHUNK_SIZE_T)(FIRST_SORTED_BIN_SIZE)) + { + assert(p->bk == b || (CHUNK_SIZE_T)chunksize(p->bk) >= (CHUNK_SIZE_T)chunksize(p)); + } + } + /* chunk is followed by a legal chain of inuse chunks */ + for(q = next_chunk(p); + (q != av->top && inuse(q) && (CHUNK_SIZE_T)(chunksize(q)) >= MINSIZE); + q = next_chunk(q)) + do_check_inuse_chunk(q); + } + } - assert((CHUNK_SIZE_T)(av->mmapped_mem) <= - (CHUNK_SIZE_T)(av->max_mmapped_mem)); + /* top chunk is OK */ + check_chunk(av->top); - assert((CHUNK_SIZE_T)(av->max_total_mem) >= - (CHUNK_SIZE_T)(av->mmapped_mem) + (CHUNK_SIZE_T)(av->sbrked_mem)); + /* sanity checks for statistics */ + + assert(total <= (CHUNK_SIZE_T)(av->max_total_mem)); + assert(av->n_mmaps >= 0); + assert(av->n_mmaps <= av->max_n_mmaps); + + assert((CHUNK_SIZE_T)(av->sbrked_mem) <= (CHUNK_SIZE_T)(av->max_sbrked_mem)); + + assert((CHUNK_SIZE_T)(av->mmapped_mem) <= (CHUNK_SIZE_T)(av->max_mmapped_mem)); + + assert((CHUNK_SIZE_T)(av->max_total_mem) >= (CHUNK_SIZE_T)(av->mmapped_mem) + (CHUNK_SIZE_T)(av->sbrked_mem)); } #endif - /* ----------- Routines dealing with system allocation -------------- */ /* @@ -2876,32 +2930,34 @@ static void do_check_malloc_state(void) #if __STD_C static Void_t* sYSMALLOc(INTERNAL_SIZE_T nb, mstate av) #else -static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av; +static Void_t* sYSMALLOc(nb, av) +INTERNAL_SIZE_T nb; +mstate av; #endif { - mchunkptr old_top; /* incoming value of av->top */ - INTERNAL_SIZE_T old_size; /* its size */ - char* old_end; /* its end address */ + mchunkptr old_top; /* incoming value of av->top */ + INTERNAL_SIZE_T old_size; /* its size */ + char* old_end; /* its end address */ - long size; /* arg to first MORECORE or mmap call */ - char* brk; /* return value from MORECORE */ + long size; /* arg to first MORECORE or mmap call */ + char* brk; /* return value from MORECORE */ - long correction; /* arg to 2nd MORECORE call */ - char* snd_brk; /* 2nd return val */ + long correction; /* arg to 2nd MORECORE call */ + char* snd_brk; /* 2nd return val */ - INTERNAL_SIZE_T front_misalign; /* unusable bytes at front of new space */ - INTERNAL_SIZE_T end_misalign; /* partial page left at end of new space */ - char* aligned_brk; /* aligned offset into brk */ + INTERNAL_SIZE_T front_misalign; /* unusable bytes at front of new space */ + INTERNAL_SIZE_T end_misalign; /* partial page left at end of new space */ + char* aligned_brk; /* aligned offset into brk */ - mchunkptr p; /* the allocated/returned chunk */ - mchunkptr remainder; /* remainder from allocation */ - CHUNK_SIZE_T remainder_size; /* its size */ + mchunkptr p; /* the allocated/returned chunk */ + mchunkptr remainder; /* remainder from allocation */ + CHUNK_SIZE_T remainder_size; /* its size */ - CHUNK_SIZE_T sum; /* for updating stats */ + CHUNK_SIZE_T sum; /* for updating stats */ - size_t pagemask = av->pagesize - 1; + size_t pagemask = av->pagesize - 1; - /* + /* If there is space available in fastbins, consolidate and retry malloc from scratch rather than getting memory from system. This can occur only if nb is in smallbin range so we didn't consolidate @@ -2909,42 +2965,44 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av; than in malloc proper. */ - if (have_fastchunks(av)) { - assert(in_smallbin_range(nb)); - malloc_consolidate(av); - return mALLOc(nb - MALLOC_ALIGN_MASK); - } - + if(have_fastchunks(av)) + { + assert(in_smallbin_range(nb)); + malloc_consolidate(av); + return mALLOc(nb - MALLOC_ALIGN_MASK); + } #if HAVE_MMAP - /* + /* If have mmap, and the request size meets the mmap threshold, and the system supports mmap, and there are few enough currently allocated mmapped regions, try to directly map this request rather than expanding top. */ - if ((CHUNK_SIZE_T)(nb) >= (CHUNK_SIZE_T)(av->mmap_threshold) && - (av->n_mmaps < av->n_mmaps_max)) { + if((CHUNK_SIZE_T)(nb) >= (CHUNK_SIZE_T)(av->mmap_threshold) && (av->n_mmaps < av->n_mmaps_max)) + { - char* mm; /* return value from mmap call*/ + char* mm; /* return value from mmap call*/ - /* + /* Round up size to nearest page. For mmapped chunks, the overhead is one SIZE_SZ unit larger than for normal chunks, because there is no following chunk whose prev_size field could be used. */ - size = (nb + SIZE_SZ + MALLOC_ALIGN_MASK + pagemask) & ~pagemask; + size = (nb + SIZE_SZ + MALLOC_ALIGN_MASK + pagemask) & ~pagemask; - /* Don't try if size wraps around 0 */ - if ((CHUNK_SIZE_T)(size) > (CHUNK_SIZE_T)(nb)) { + /* Don't try if size wraps around 0 */ + if((CHUNK_SIZE_T)(size) > (CHUNK_SIZE_T)(nb)) + { - mm = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE)); + mm = (char*)(MMAP(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE)); - if (mm != (char*)(MORECORE_FAILURE)) { + if(mm != (char*)(MORECORE_FAILURE)) + { - /* + /* The offset to the start of the mmapped region is stored in the prev_size field of the chunk. This allows us to adjust returned start address to meet alignment requirements here @@ -2952,77 +3010,76 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av; address argument for later munmap in free() and realloc(). */ - front_misalign = (INTERNAL_SIZE_T)chunk2mem(mm) & MALLOC_ALIGN_MASK; - if (front_misalign > 0) { - correction = MALLOC_ALIGNMENT - front_misalign; - p = (mchunkptr)(mm + correction); - p->prev_size = correction; - set_head(p, (size - correction) |IS_MMAPPED); + front_misalign = (INTERNAL_SIZE_T)chunk2mem(mm) & MALLOC_ALIGN_MASK; + if(front_misalign > 0) + { + correction = MALLOC_ALIGNMENT - front_misalign; + p = (mchunkptr)(mm + correction); + p->prev_size = correction; + set_head(p, (size - correction) | IS_MMAPPED); + } + else + { + p = (mchunkptr)mm; + p->prev_size = 0; + set_head(p, size | IS_MMAPPED); + } + + /* update statistics */ + + if(++av->n_mmaps > av->max_n_mmaps) + av->max_n_mmaps = av->n_mmaps; + + sum = av->mmapped_mem += size; + if(sum > (CHUNK_SIZE_T)(av->max_mmapped_mem)) + av->max_mmapped_mem = sum; + sum += av->sbrked_mem; + if(sum > (CHUNK_SIZE_T)(av->max_total_mem)) + av->max_total_mem = sum; + + check_chunk(p); + + return chunk2mem(p); + } } - else { - p = (mchunkptr)mm; - p->prev_size = 0; - set_head(p, size|IS_MMAPPED); - } - - /* update statistics */ - - if (++av->n_mmaps > av->max_n_mmaps) - av->max_n_mmaps = av->n_mmaps; - - sum = av->mmapped_mem += size; - if (sum > (CHUNK_SIZE_T)(av->max_mmapped_mem)) - av->max_mmapped_mem = sum; - sum += av->sbrked_mem; - if (sum > (CHUNK_SIZE_T)(av->max_total_mem)) - av->max_total_mem = sum; - - check_chunk(p); - - return chunk2mem(p); - } } - } #endif - /* Record incoming configuration of top */ + /* Record incoming configuration of top */ - old_top = av->top; - old_size = chunksize(old_top); - old_end = (char*)(chunk_at_offset(old_top, old_size)); + old_top = av->top; + old_size = chunksize(old_top); + old_end = (char*)(chunk_at_offset(old_top, old_size)); - brk = snd_brk = (char*)(MORECORE_FAILURE); + brk = snd_brk = (char*)(MORECORE_FAILURE); - /* + /* If not the first time through, we require old_size to be at least MINSIZE and to have prev_inuse set. */ - assert((old_top == initial_top(av) && old_size == 0) || - ((CHUNK_SIZE_T) (old_size) >= MINSIZE && - prev_inuse(old_top))); + assert((old_top == initial_top(av) && old_size == 0) || ((CHUNK_SIZE_T)(old_size) >= MINSIZE && prev_inuse(old_top))); - /* Precondition: not enough current space to satisfy nb request */ - assert((CHUNK_SIZE_T)(old_size) < (CHUNK_SIZE_T)(nb + MINSIZE)); + /* Precondition: not enough current space to satisfy nb request */ + assert((CHUNK_SIZE_T)(old_size) < (CHUNK_SIZE_T)(nb + MINSIZE)); - /* Precondition: all fastbins are consolidated */ - assert(!have_fastchunks(av)); + /* Precondition: all fastbins are consolidated */ + assert(!have_fastchunks(av)); + /* Request enough space for nb + pad + overhead */ - /* Request enough space for nb + pad + overhead */ + size = nb + av->top_pad + MINSIZE; - size = nb + av->top_pad + MINSIZE; - - /* + /* If contiguous, we can subtract out existing space that we hope to combine with new space. We add it back later only if we don't actually get contiguous space. */ - if (contiguous(av)) - size -= old_size; + if(contiguous(av)) + size -= old_size; - /* + /* Round to a multiple of page size. If MORECORE is not contiguous, this ensures that we only call it with whole-page arguments. And if MORECORE is contiguous and @@ -3030,18 +3087,18 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av; previous calls. Otherwise, we correct to page-align below. */ - size = (size + pagemask) & ~pagemask; + size = (size + pagemask) & ~pagemask; - /* + /* Don't try to call MORECORE if argument is so big as to appear negative. Note that since mmap takes size_t arg, it may succeed below even if we cannot call MORECORE. */ - if (size > 0) - brk = (char*)(MORECORE(size)); + if(size > 0) + brk = (char*)(MORECORE(size)); - /* + /* If have mmap, try using it as a backup when MORECORE fails or cannot be used. This is worth doing on systems that have "holes" in address space, so sbrk cannot extend to give contiguous space, but @@ -3051,50 +3108,55 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av; */ #if HAVE_MMAP - if (brk == (char*)(MORECORE_FAILURE)) { + if(brk == (char*)(MORECORE_FAILURE)) + { - /* Cannot merge with old top, so add its size back in */ - if (contiguous(av)) - size = (size + old_size + pagemask) & ~pagemask; + /* Cannot merge with old top, so add its size back in */ + if(contiguous(av)) + size = (size + old_size + pagemask) & ~pagemask; - /* If we are relying on mmap as backup, then use larger units */ - if ((CHUNK_SIZE_T)(size) < (CHUNK_SIZE_T)(MMAP_AS_MORECORE_SIZE)) - size = MMAP_AS_MORECORE_SIZE; + /* If we are relying on mmap as backup, then use larger units */ + if((CHUNK_SIZE_T)(size) < (CHUNK_SIZE_T)(MMAP_AS_MORECORE_SIZE)) + size = MMAP_AS_MORECORE_SIZE; - /* Don't try if size wraps around 0 */ - if ((CHUNK_SIZE_T)(size) > (CHUNK_SIZE_T)(nb)) { + /* Don't try if size wraps around 0 */ + if((CHUNK_SIZE_T)(size) > (CHUNK_SIZE_T)(nb)) + { - brk = (char*)(MMAP(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE)); + brk = (char*)(MMAP(0, size, PROT_READ | PROT_WRITE, MAP_PRIVATE)); - if (brk != (char*)(MORECORE_FAILURE)) { + if(brk != (char*)(MORECORE_FAILURE)) + { - /* We do not need, and cannot use, another sbrk call to find end */ - snd_brk = brk + size; + /* We do not need, and cannot use, another sbrk call to find end */ + snd_brk = brk + size; - /* + /* Record that we no longer have a contiguous sbrk region. After the first time mmap is used as backup, we do not ever rely on contiguous space since this could incorrectly bridge regions. */ - set_noncontiguous(av); - } + set_noncontiguous(av); + } + } } - } #endif - if (brk != (char*)(MORECORE_FAILURE)) { - av->sbrked_mem += size; + if(brk != (char*)(MORECORE_FAILURE)) + { + av->sbrked_mem += size; - /* + /* If MORECORE extends previous space, we can likewise extend top size. */ - if (brk == old_end && snd_brk == (char*)(MORECORE_FAILURE)) { - set_head(old_top, (size + old_size) | PREV_INUSE); - } + if(brk == old_end && snd_brk == (char*)(MORECORE_FAILURE)) + { + set_head(old_top, (size + old_size) | PREV_INUSE); + } - /* + /* Otherwise, make adjustments: * If the first time through or noncontiguous, we need to call sbrk @@ -3113,13 +3175,14 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av; which in turn causes future contiguous calls to page-align. */ - else { - front_misalign = 0; - end_misalign = 0; - correction = 0; - aligned_brk = brk; + else + { + front_misalign = 0; + end_misalign = 0; + correction = 0; + aligned_brk = brk; - /* + /* If MORECORE returns an address lower than we have seen before, we know it isn't really contiguous. This and some subsequent checks help cope with non-conforming MORECORE functions and @@ -3127,27 +3190,30 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av; malloc or by other threads. We cannot guarantee to detect these in all cases, but cope with the ones we do detect. */ - if (contiguous(av) && old_size != 0 && brk < old_end) { - set_noncontiguous(av); - } + if(contiguous(av) && old_size != 0 && brk < old_end) + { + set_noncontiguous(av); + } - /* handle contiguous cases */ - if (contiguous(av)) { + /* handle contiguous cases */ + if(contiguous(av)) + { - /* + /* We can tolerate forward non-contiguities here (usually due to foreign calls) but treat them as part of our space for stats reporting. */ - if (old_size != 0) - av->sbrked_mem += brk - old_end; + if(old_size != 0) + av->sbrked_mem += brk - old_end; - /* Guarantee alignment of first new chunk made from this space */ + /* Guarantee alignment of first new chunk made from this space */ - front_misalign = (INTERNAL_SIZE_T)chunk2mem(brk) & MALLOC_ALIGN_MASK; - if (front_misalign > 0) { + front_misalign = (INTERNAL_SIZE_T)chunk2mem(brk) & MALLOC_ALIGN_MASK; + if(front_misalign > 0) + { - /* + /* Skip over some bytes to arrive at an aligned position. We don't need to specially mark these wasted front bytes. They will never be accessed anyway because @@ -3155,34 +3221,36 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av; is always true after initialization. */ - correction = MALLOC_ALIGNMENT - front_misalign; - aligned_brk += correction; - } + correction = MALLOC_ALIGNMENT - front_misalign; + aligned_brk += correction; + } - /* + /* If this isn't adjacent to existing space, then we will not be able to merge with old_top space, so must add to 2nd request. */ - correction += old_size; + correction += old_size; - /* Extend the end address to hit a page boundary */ - end_misalign = (INTERNAL_SIZE_T)(brk + size + correction); - correction += ((end_misalign + pagemask) & ~pagemask) - end_misalign; + /* Extend the end address to hit a page boundary */ + end_misalign = (INTERNAL_SIZE_T)(brk + size + correction); + correction += ((end_misalign + pagemask) & ~pagemask) - end_misalign; - assert(correction >= 0); - snd_brk = (char*)(MORECORE(correction)); + assert(correction >= 0); + snd_brk = (char*)(MORECORE(correction)); - if (snd_brk == (char*)(MORECORE_FAILURE)) { - /* + if(snd_brk == (char*)(MORECORE_FAILURE)) + { + /* If can't allocate correction, try to at least find out current brk. It might be enough to proceed without failing. */ - correction = 0; - snd_brk = (char*)(MORECORE(0)); - } - else if (snd_brk < brk) { - /* + correction = 0; + snd_brk = (char*)(MORECORE(0)); + } + else if(snd_brk < brk) + { + /* If the second call gives noncontiguous space even though it says it won't, the only course of action is to ignore results of second call, and conservatively estimate where @@ -3194,32 +3262,34 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av; there is no reliable way to detect a noncontiguity producing a forward gap for the second call. */ - snd_brk = brk + size; - correction = 0; - set_noncontiguous(av); - } + snd_brk = brk + size; + correction = 0; + set_noncontiguous(av); + } + } - } + /* handle non-contiguous cases */ + else + { + /* MORECORE/mmap must correctly align */ + assert(aligned_OK(chunk2mem(brk))); - /* handle non-contiguous cases */ - else { - /* MORECORE/mmap must correctly align */ - assert(aligned_OK(chunk2mem(brk))); + /* Find out current end of memory */ + if(snd_brk == (char*)(MORECORE_FAILURE)) + { + snd_brk = (char*)(MORECORE(0)); + av->sbrked_mem += snd_brk - brk - size; + } + } - /* Find out current end of memory */ - if (snd_brk == (char*)(MORECORE_FAILURE)) { - snd_brk = (char*)(MORECORE(0)); - av->sbrked_mem += snd_brk - brk - size; - } - } + /* Adjust top based on results of second sbrk */ + if(snd_brk != (char*)(MORECORE_FAILURE)) + { + av->top = (mchunkptr)aligned_brk; + set_head(av->top, (snd_brk - aligned_brk + correction) | PREV_INUSE); + av->sbrked_mem += correction; - /* Adjust top based on results of second sbrk */ - if (snd_brk != (char*)(MORECORE_FAILURE)) { - av->top = (mchunkptr)aligned_brk; - set_head(av->top, (snd_brk - aligned_brk + correction) | PREV_INUSE); - av->sbrked_mem += correction; - - /* + /* If not the first time through, we either have a gap due to foreign sbrk or a non-contiguous region. Insert a double fencepost at old_top to prevent consolidation with space @@ -3228,77 +3298,76 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av; two to make sizes and alignments work out. */ - if (old_size != 0) { - /* + if(old_size != 0) + { + /* Shrink old_top to insert fenceposts, keeping size a multiple of MALLOC_ALIGNMENT. We know there is at least enough space in old_top to do this. */ - old_size = (old_size - 3*SIZE_SZ) & ~MALLOC_ALIGN_MASK; - set_head(old_top, old_size | PREV_INUSE); + old_size = (old_size - 3 * SIZE_SZ) & ~MALLOC_ALIGN_MASK; + set_head(old_top, old_size | PREV_INUSE); - /* + /* Note that the following assignments completely overwrite old_top when old_size was previously MINSIZE. This is intentional. We need the fencepost, even if old_top otherwise gets lost. */ - chunk_at_offset(old_top, old_size )->size = - SIZE_SZ|PREV_INUSE; + chunk_at_offset(old_top, old_size)->size = + SIZE_SZ | PREV_INUSE; - chunk_at_offset(old_top, old_size + SIZE_SZ)->size = - SIZE_SZ|PREV_INUSE; + chunk_at_offset(old_top, old_size + SIZE_SZ)->size = + SIZE_SZ | PREV_INUSE; - /* + /* If possible, release the rest, suppressing trimming. */ - if (old_size >= MINSIZE) { - INTERNAL_SIZE_T tt = av->trim_threshold; - av->trim_threshold = (INTERNAL_SIZE_T)(-1); - fREe(chunk2mem(old_top)); - av->trim_threshold = tt; - } + if(old_size >= MINSIZE) + { + INTERNAL_SIZE_T tt = av->trim_threshold; + av->trim_threshold = (INTERNAL_SIZE_T)(-1); + fREe(chunk2mem(old_top)); + av->trim_threshold = tt; + } + } + } + } + + /* Update statistics */ + sum = av->sbrked_mem; + if(sum > (CHUNK_SIZE_T)(av->max_sbrked_mem)) + av->max_sbrked_mem = sum; + + sum += av->mmapped_mem; + if(sum > (CHUNK_SIZE_T)(av->max_total_mem)) + av->max_total_mem = sum; + + check_malloc_state(); + + /* finally, do the allocation */ + + p = av->top; + size = chunksize(p); + + /* check that one of the above allocation paths succeeded */ + if((CHUNK_SIZE_T)(size) >= (CHUNK_SIZE_T)(nb + MINSIZE)) + { + remainder_size = size - nb; + remainder = chunk_at_offset(p, nb); + av->top = remainder; + set_head(p, nb | PREV_INUSE); + set_head(remainder, remainder_size | PREV_INUSE); + check_malloced_chunk(p, nb); + return chunk2mem(p); } - } } - /* Update statistics */ - sum = av->sbrked_mem; - if (sum > (CHUNK_SIZE_T)(av->max_sbrked_mem)) - av->max_sbrked_mem = sum; - - sum += av->mmapped_mem; - if (sum > (CHUNK_SIZE_T)(av->max_total_mem)) - av->max_total_mem = sum; - - check_malloc_state(); - - /* finally, do the allocation */ - - p = av->top; - size = chunksize(p); - - /* check that one of the above allocation paths succeeded */ - if ((CHUNK_SIZE_T)(size) >= (CHUNK_SIZE_T)(nb + MINSIZE)) { - remainder_size = size - nb; - remainder = chunk_at_offset(p, nb); - av->top = remainder; - set_head(p, nb | PREV_INUSE); - set_head(remainder, remainder_size | PREV_INUSE); - check_malloced_chunk(p, nb); - return chunk2mem(p); - } - - } - - /* catch all failure paths */ - MALLOC_FAILURE_ACTION; - return 0; + /* catch all failure paths */ + MALLOC_FAILURE_ACTION; + return 0; } - - - /* sYSTRIm is an inverse of sorts to sYSMALLOc. It gives memory back to the system (via negative arguments to sbrk) if there is unused @@ -3311,32 +3380,36 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av; #if __STD_C static int sYSTRIm(size_t pad, mstate av) #else -static int sYSTRIm(pad, av) size_t pad; mstate av; +static int sYSTRIm(pad, av) +size_t pad; +mstate av; #endif { - long top_size; /* Amount of top-most memory */ - long extra; /* Amount to release */ - long released; /* Amount actually released */ - char* current_brk; /* address returned by pre-check sbrk call */ - char* new_brk; /* address returned by post-check sbrk call */ - size_t pagesz; + long top_size; /* Amount of top-most memory */ + long extra; /* Amount to release */ + long released; /* Amount actually released */ + char* current_brk; /* address returned by pre-check sbrk call */ + char* new_brk; /* address returned by post-check sbrk call */ + size_t pagesz; - pagesz = av->pagesize; - top_size = chunksize(av->top); + pagesz = av->pagesize; + top_size = chunksize(av->top); - /* Release in pagesize units, keeping at least one page */ - extra = ((top_size - pad - MINSIZE + (pagesz-1)) / pagesz - 1) * pagesz; + /* Release in pagesize units, keeping at least one page */ + extra = ((top_size - pad - MINSIZE + (pagesz - 1)) / pagesz - 1) * pagesz; - if (extra > 0) { + if(extra > 0) + { - /* + /* Only proceed if end of memory is where we last set it. This avoids problems if there were foreign sbrk calls. */ - current_brk = (char*)(MORECORE(0)); - if (current_brk == (char*)(av->top) + top_size) { + current_brk = (char*)(MORECORE(0)); + if(current_brk == (char*)(av->top) + top_size) + { - /* + /* Attempt to release memory. We ignore MORECORE return value, and instead call again to find out where new end of memory is. This avoids problems if first call releases less than we asked, @@ -3346,58 +3419,60 @@ static int sYSTRIm(pad, av) size_t pad; mstate av; some downstream failure.) */ - MORECORE(-extra); - new_brk = (char*)(MORECORE(0)); + MORECORE(-extra); + new_brk = (char*)(MORECORE(0)); - if (new_brk != (char*)MORECORE_FAILURE) { - released = (long)(current_brk - new_brk); + if(new_brk != (char*)MORECORE_FAILURE) + { + released = (long)(current_brk - new_brk); - if (released != 0) { - /* Success. Adjust top. */ - av->sbrked_mem -= released; - set_head(av->top, (top_size - released) | PREV_INUSE); - check_malloc_state(); - return 1; + if(released != 0) + { + /* Success. Adjust top. */ + av->sbrked_mem -= released; + set_head(av->top, (top_size - released) | PREV_INUSE); + check_malloc_state(); + return 1; + } + } } - } } - } - return 0; + return 0; } /* ------------------------------ malloc ------------------------------ */ - #if __STD_C Void_t* mALLOc(size_t bytes) #else - Void_t* mALLOc(bytes) size_t bytes; +Void_t* mALLOc(bytes) +size_t bytes; #endif { - mstate av = get_malloc_state(); + mstate av = get_malloc_state(); - INTERNAL_SIZE_T nb; /* normalized request size */ - unsigned int idx; /* associated bin index */ - mbinptr bin; /* associated bin */ - mfastbinptr* fb; /* associated fastbin */ + INTERNAL_SIZE_T nb; /* normalized request size */ + unsigned int idx; /* associated bin index */ + mbinptr bin; /* associated bin */ + mfastbinptr* fb; /* associated fastbin */ - mchunkptr victim; /* inspected/selected chunk */ - INTERNAL_SIZE_T size; /* its size */ - int victim_index; /* its bin index */ + mchunkptr victim; /* inspected/selected chunk */ + INTERNAL_SIZE_T size; /* its size */ + int victim_index; /* its bin index */ - mchunkptr remainder; /* remainder from a split */ - CHUNK_SIZE_T remainder_size; /* its size */ + mchunkptr remainder; /* remainder from a split */ + CHUNK_SIZE_T remainder_size; /* its size */ - unsigned int block; /* bit map traverser */ - unsigned int bit; /* bit map traverser */ - unsigned int map; /* current word of binmap */ + unsigned int block; /* bit map traverser */ + unsigned int bit; /* bit map traverser */ + unsigned int map; /* current word of binmap */ - mchunkptr fwd; /* misc temp for linking */ - mchunkptr bck; /* misc temp for linking */ + mchunkptr fwd; /* misc temp for linking */ + mchunkptr bck; /* misc temp for linking */ - /* + /* Convert request size to internal form by adding SIZE_SZ bytes overhead plus possibly more to obtain necessary alignment and/or to obtain a size of at least MINSIZE, the smallest allocatable @@ -3406,31 +3481,34 @@ Void_t* mALLOc(size_t bytes) aligned. */ - checked_request2size(bytes, nb); + checked_request2size(bytes, nb); - /* + /* Bypass search if no frees yet */ - if (!have_anychunks(av)) { - if (av->max_fast == 0) /* initialization check */ - malloc_consolidate(av); - goto use_top; - } + if(!have_anychunks(av)) + { + if(av->max_fast == 0) /* initialization check */ + malloc_consolidate(av); + goto use_top; + } - /* + /* If the size qualifies as a fastbin, first check corresponding bin. */ - if ((CHUNK_SIZE_T)(nb) <= (CHUNK_SIZE_T)(av->max_fast)) { - fb = &(av->fastbins[(fastbin_index(nb))]); - if ( (victim = *fb) != 0) { - *fb = victim->fd; - check_remalloced_chunk(victim, nb); - return chunk2mem(victim); + if((CHUNK_SIZE_T)(nb) <= (CHUNK_SIZE_T)(av->max_fast)) + { + fb = &(av->fastbins[(fastbin_index(nb))]); + if((victim = *fb) != 0) + { + *fb = victim->fd; + check_remalloced_chunk(victim, nb); + return chunk2mem(victim); + } } - } - /* + /* If a small request, check regular bin. Since these "smallbins" hold one size each, no searching within bins is necessary. (For a large request, we need to wait until unsorted chunks are @@ -3438,22 +3516,24 @@ Void_t* mALLOc(size_t bytes) anyway, so we can check now, which is faster.) */ - if (in_smallbin_range(nb)) { - idx = smallbin_index(nb); - bin = bin_at(av,idx); + if(in_smallbin_range(nb)) + { + idx = smallbin_index(nb); + bin = bin_at(av, idx); - if ( (victim = last(bin)) != bin) { - bck = victim->bk; - set_inuse_bit_at_offset(victim, nb); - bin->bk = bck; - bck->fd = bin; + if((victim = last(bin)) != bin) + { + bck = victim->bk; + set_inuse_bit_at_offset(victim, nb); + bin->bk = bck; + bck->fd = bin; - check_malloced_chunk(victim, nb); - return chunk2mem(victim); + check_malloced_chunk(victim, nb); + return chunk2mem(victim); + } } - } - /* + /* If this is a large request, consolidate fastbins before continuing. While it might look excessive to kill all fastbins before even seeing if there is space available, this avoids @@ -3464,13 +3544,14 @@ Void_t* mALLOc(size_t bytes) it is called frequently in otherwise tend to fragment. */ - else { - idx = largebin_index(nb); - if (have_fastchunks(av)) - malloc_consolidate(av); - } + else + { + idx = largebin_index(nb); + if(have_fastchunks(av)) + malloc_consolidate(av); + } - /* + /* Process recently freed or remaindered chunks, taking one only if it is exact fit, or, if this a small request, the chunk is remainder from the most recent non-exact fit. Place other traversed chunks in @@ -3478,11 +3559,12 @@ Void_t* mALLOc(size_t bytes) chunks are placed in bins. */ - while ( (victim = unsorted_chunks(av)->bk) != unsorted_chunks(av)) { - bck = victim->bk; - size = chunksize(victim); + while((victim = unsorted_chunks(av)->bk) != unsorted_chunks(av)) + { + bck = victim->bk; + size = chunksize(victim); - /* + /* If a small request, try to use last remainder if it is the only chunk in unsorted bin. This helps promote locality for runs of consecutive small requests. This is the only @@ -3490,76 +3572,79 @@ Void_t* mALLOc(size_t bytes) no exact fit for a small chunk. */ - if (in_smallbin_range(nb) && - bck == unsorted_chunks(av) && - victim == av->last_remainder && - (CHUNK_SIZE_T)(size) > (CHUNK_SIZE_T)(nb + MINSIZE)) { + if(in_smallbin_range(nb) && bck == unsorted_chunks(av) && victim == av->last_remainder && (CHUNK_SIZE_T)(size) > (CHUNK_SIZE_T)(nb + MINSIZE)) + { - /* split and reattach remainder */ - remainder_size = size - nb; - remainder = chunk_at_offset(victim, nb); - unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder; - av->last_remainder = remainder; - remainder->bk = remainder->fd = unsorted_chunks(av); + /* split and reattach remainder */ + remainder_size = size - nb; + remainder = chunk_at_offset(victim, nb); + unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder; + av->last_remainder = remainder; + remainder->bk = remainder->fd = unsorted_chunks(av); - set_head(victim, nb | PREV_INUSE); - set_head(remainder, remainder_size | PREV_INUSE); - set_foot(remainder, remainder_size); + set_head(victim, nb | PREV_INUSE); + set_head(remainder, remainder_size | PREV_INUSE); + set_foot(remainder, remainder_size); - check_malloced_chunk(victim, nb); - return chunk2mem(victim); - } - - /* remove from unsorted list */ - unsorted_chunks(av)->bk = bck; - bck->fd = unsorted_chunks(av); - - /* Take now instead of binning if exact fit */ - - if (size == nb) { - set_inuse_bit_at_offset(victim, size); - check_malloced_chunk(victim, nb); - return chunk2mem(victim); - } - - /* place chunk in bin */ - - if (in_smallbin_range(size)) { - victim_index = smallbin_index(size); - bck = bin_at(av, victim_index); - fwd = bck->fd; - } - else { - victim_index = largebin_index(size); - bck = bin_at(av, victim_index); - fwd = bck->fd; - - if (fwd != bck) { - /* if smaller than smallest, place first */ - if ((CHUNK_SIZE_T)(size) < (CHUNK_SIZE_T)(bck->bk->size)) { - fwd = bck; - bck = bck->bk; + check_malloced_chunk(victim, nb); + return chunk2mem(victim); } - else if ((CHUNK_SIZE_T)(size) >= - (CHUNK_SIZE_T)(FIRST_SORTED_BIN_SIZE)) { - /* maintain large bins in sorted order */ - size |= PREV_INUSE; /* Or with inuse bit to speed comparisons */ - while ((CHUNK_SIZE_T)(size) < (CHUNK_SIZE_T)(fwd->size)) - fwd = fwd->fd; - bck = fwd->bk; + /* remove from unsorted list */ + unsorted_chunks(av)->bk = bck; + bck->fd = unsorted_chunks(av); + + /* Take now instead of binning if exact fit */ + + if(size == nb) + { + set_inuse_bit_at_offset(victim, size); + check_malloced_chunk(victim, nb); + return chunk2mem(victim); } - } + + /* place chunk in bin */ + + if(in_smallbin_range(size)) + { + victim_index = smallbin_index(size); + bck = bin_at(av, victim_index); + fwd = bck->fd; + } + else + { + victim_index = largebin_index(size); + bck = bin_at(av, victim_index); + fwd = bck->fd; + + if(fwd != bck) + { + /* if smaller than smallest, place first */ + if((CHUNK_SIZE_T)(size) < (CHUNK_SIZE_T)(bck->bk->size)) + { + fwd = bck; + bck = bck->bk; + } + else if((CHUNK_SIZE_T)(size) >= (CHUNK_SIZE_T)(FIRST_SORTED_BIN_SIZE)) + { + + /* maintain large bins in sorted order */ + size |= PREV_INUSE; /* Or with inuse bit to speed comparisons */ + while((CHUNK_SIZE_T)(size) < (CHUNK_SIZE_T)(fwd->size)) + fwd = fwd->fd; + bck = fwd->bk; + } + } + } + + mark_bin(av, victim_index); + victim->bk = bck; + victim->fd = fwd; + fwd->bk = victim; + bck->fd = victim; } - mark_bin(av, victim_index); - victim->bk = bck; - victim->fd = fwd; - fwd->bk = victim; - bck->fd = victim; - } - - /* + /* If a large request, scan through the chunks of current bin to find one that fits. (This will be the smallest that fits unless FIRST_SORTED_BIN_SIZE has been changed from default.) This is @@ -3568,38 +3653,43 @@ Void_t* mALLOc(size_t bytes) lists tend to be short. */ - if (!in_smallbin_range(nb)) { - bin = bin_at(av, idx); + if(!in_smallbin_range(nb)) + { + bin = bin_at(av, idx); - for (victim = last(bin); victim != bin; victim = victim->bk) { - size = chunksize(victim); + for(victim = last(bin); victim != bin; victim = victim->bk) + { + size = chunksize(victim); - if ((CHUNK_SIZE_T)(size) >= (CHUNK_SIZE_T)(nb)) { - remainder_size = size - nb; - unlink(victim, bck, fwd); + if((CHUNK_SIZE_T)(size) >= (CHUNK_SIZE_T)(nb)) + { + remainder_size = size - nb; + unlink(victim, bck, fwd); - /* Exhaust */ - if (remainder_size < MINSIZE) { - set_inuse_bit_at_offset(victim, size); - check_malloced_chunk(victim, nb); - return chunk2mem(victim); + /* Exhaust */ + if(remainder_size < MINSIZE) + { + set_inuse_bit_at_offset(victim, size); + check_malloced_chunk(victim, nb); + return chunk2mem(victim); + } + /* Split */ + else + { + remainder = chunk_at_offset(victim, nb); + unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder; + remainder->bk = remainder->fd = unsorted_chunks(av); + set_head(victim, nb | PREV_INUSE); + set_head(remainder, remainder_size | PREV_INUSE); + set_foot(remainder, remainder_size); + check_malloced_chunk(victim, nb); + return chunk2mem(victim); + } + } } - /* Split */ - else { - remainder = chunk_at_offset(victim, nb); - unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder; - remainder->bk = remainder->fd = unsorted_chunks(av); - set_head(victim, nb | PREV_INUSE); - set_head(remainder, remainder_size | PREV_INUSE); - set_foot(remainder, remainder_size); - check_malloced_chunk(victim, nb); - return chunk2mem(victim); - } - } } - } - /* + /* Search for a chunk by scanning bins, starting with next largest bin. This search is strictly by best-fit; i.e., the smallest (with ties going to approximately the least recently used) chunk @@ -3608,83 +3698,91 @@ Void_t* mALLOc(size_t bytes) The bitmap avoids needing to check that most blocks are nonempty. */ - ++idx; - bin = bin_at(av,idx); - block = idx2block(idx); - map = av->binmap[block]; - bit = idx2bit(idx); + ++idx; + bin = bin_at(av, idx); + block = idx2block(idx); + map = av->binmap[block]; + bit = idx2bit(idx); - for (;;) { + for(;;) + { - /* Skip rest of block if there are no more set bits in this block. */ - if (bit > map || bit == 0) { - do { - if (++block >= BINMAPSIZE) /* out of bins */ - goto use_top; - } while ( (map = av->binmap[block]) == 0); + /* Skip rest of block if there are no more set bits in this block. */ + if(bit > map || bit == 0) + { + do + { + if(++block >= BINMAPSIZE) /* out of bins */ + goto use_top; + } while((map = av->binmap[block]) == 0); - bin = bin_at(av, (block << BINMAPSHIFT)); - bit = 1; + bin = bin_at(av, (block << BINMAPSHIFT)); + bit = 1; + } + + /* Advance to bin with set bit. There must be one. */ + while((bit & map) == 0) + { + bin = next_bin(bin); + bit <<= 1; + assert(bit != 0); + } + + /* Inspect the bin. It is likely to be non-empty */ + victim = last(bin); + + /* If a false alarm (empty bin), clear the bit. */ + if(victim == bin) + { + av->binmap[block] = map &= ~bit; /* Write through */ + bin = next_bin(bin); + bit <<= 1; + } + + else + { + size = chunksize(victim); + + /* We know the first chunk in this bin is big enough to use. */ + assert((CHUNK_SIZE_T)(size) >= (CHUNK_SIZE_T)(nb)); + + remainder_size = size - nb; + + /* unlink */ + bck = victim->bk; + bin->bk = bck; + bck->fd = bin; + + /* Exhaust */ + if(remainder_size < MINSIZE) + { + set_inuse_bit_at_offset(victim, size); + check_malloced_chunk(victim, nb); + return chunk2mem(victim); + } + + /* Split */ + else + { + remainder = chunk_at_offset(victim, nb); + + unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder; + remainder->bk = remainder->fd = unsorted_chunks(av); + /* advertise as last remainder */ + if(in_smallbin_range(nb)) + av->last_remainder = remainder; + + set_head(victim, nb | PREV_INUSE); + set_head(remainder, remainder_size | PREV_INUSE); + set_foot(remainder, remainder_size); + check_malloced_chunk(victim, nb); + return chunk2mem(victim); + } + } } - /* Advance to bin with set bit. There must be one. */ - while ((bit & map) == 0) { - bin = next_bin(bin); - bit <<= 1; - assert(bit != 0); - } - - /* Inspect the bin. It is likely to be non-empty */ - victim = last(bin); - - /* If a false alarm (empty bin), clear the bit. */ - if (victim == bin) { - av->binmap[block] = map &= ~bit; /* Write through */ - bin = next_bin(bin); - bit <<= 1; - } - - else { - size = chunksize(victim); - - /* We know the first chunk in this bin is big enough to use. */ - assert((CHUNK_SIZE_T)(size) >= (CHUNK_SIZE_T)(nb)); - - remainder_size = size - nb; - - /* unlink */ - bck = victim->bk; - bin->bk = bck; - bck->fd = bin; - - /* Exhaust */ - if (remainder_size < MINSIZE) { - set_inuse_bit_at_offset(victim, size); - check_malloced_chunk(victim, nb); - return chunk2mem(victim); - } - - /* Split */ - else { - remainder = chunk_at_offset(victim, nb); - - unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder; - remainder->bk = remainder->fd = unsorted_chunks(av); - /* advertise as last remainder */ - if (in_smallbin_range(nb)) - av->last_remainder = remainder; - - set_head(victim, nb | PREV_INUSE); - set_head(remainder, remainder_size | PREV_INUSE); - set_foot(remainder, remainder_size); - check_malloced_chunk(victim, nb); - return chunk2mem(victim); - } - } - } - - use_top: - /* +use_top: + /* If large enough, split off the chunk bordering the end of memory (held in av->top). Note that this is in accord with the best-fit search rule. In effect, av->top is treated as larger (and thus @@ -3699,24 +3797,25 @@ Void_t* mALLOc(size_t bytes) to put in fenceposts in sysmalloc.) */ - victim = av->top; - size = chunksize(victim); + victim = av->top; + size = chunksize(victim); - if ((CHUNK_SIZE_T)(size) >= (CHUNK_SIZE_T)(nb + MINSIZE)) { - remainder_size = size - nb; - remainder = chunk_at_offset(victim, nb); - av->top = remainder; - set_head(victim, nb | PREV_INUSE); - set_head(remainder, remainder_size | PREV_INUSE); + if((CHUNK_SIZE_T)(size) >= (CHUNK_SIZE_T)(nb + MINSIZE)) + { + remainder_size = size - nb; + remainder = chunk_at_offset(victim, nb); + av->top = remainder; + set_head(victim, nb | PREV_INUSE); + set_head(remainder, remainder_size | PREV_INUSE); - check_malloced_chunk(victim, nb); - return chunk2mem(victim); - } + check_malloced_chunk(victim, nb); + return chunk2mem(victim); + } - /* + /* If no space in top, relay to handle system-dependent cases */ - return sYSMALLOc(nb, av); + return sYSMALLOc(nb, av); } /* @@ -3729,108 +3828,115 @@ void fREe(Void_t* mem) void fREe(mem) Void_t* mem; #endif { - mstate av = get_malloc_state(); + mstate av = get_malloc_state(); - mchunkptr p; /* chunk corresponding to mem */ - INTERNAL_SIZE_T size; /* its size */ - mfastbinptr* fb; /* associated fastbin */ - mchunkptr nextchunk; /* next contiguous chunk */ - INTERNAL_SIZE_T nextsize; /* its size */ - int nextinuse; /* true if nextchunk is used */ - INTERNAL_SIZE_T prevsize; /* size of previous contiguous chunk */ - mchunkptr bck; /* misc temp for linking */ - mchunkptr fwd; /* misc temp for linking */ + mchunkptr p; /* chunk corresponding to mem */ + INTERNAL_SIZE_T size; /* its size */ + mfastbinptr* fb; /* associated fastbin */ + mchunkptr nextchunk; /* next contiguous chunk */ + INTERNAL_SIZE_T nextsize; /* its size */ + int nextinuse; /* true if nextchunk is used */ + INTERNAL_SIZE_T prevsize; /* size of previous contiguous chunk */ + mchunkptr bck; /* misc temp for linking */ + mchunkptr fwd; /* misc temp for linking */ - /* free(0) has no effect */ - if (mem != 0) { - p = mem2chunk(mem); - size = chunksize(p); + /* free(0) has no effect */ + if(mem != 0) + { + p = mem2chunk(mem); + size = chunksize(p); - check_inuse_chunk(p); + check_inuse_chunk(p); - /* + /* If eligible, place chunk on a fastbin so it can be found and used quickly in malloc. */ - if ((CHUNK_SIZE_T)(size) <= (CHUNK_SIZE_T)(av->max_fast) + if((CHUNK_SIZE_T)(size) <= (CHUNK_SIZE_T)(av->max_fast) #if TRIM_FASTBINS - /* + /* If TRIM_FASTBINS set, don't place chunks bordering top into fastbins */ - && (chunk_at_offset(p, size) != av->top) + && (chunk_at_offset(p, size) != av->top) #endif - ) { + ) + { - set_fastchunks(av); - fb = &(av->fastbins[fastbin_index(size)]); - p->fd = *fb; - *fb = p; - } - - /* - Consolidate other non-mmapped chunks as they arrive. - */ - - else if (!chunk_is_mmapped(p)) { - set_anychunks(av); - - nextchunk = chunk_at_offset(p, size); - nextsize = chunksize(nextchunk); - - /* consolidate backward */ - if (!prev_inuse(p)) { - prevsize = p->prev_size; - size += prevsize; - p = chunk_at_offset(p, -((long) prevsize)); - unlink(p, bck, fwd); - } - - if (nextchunk != av->top) { - /* get and clear inuse bit */ - nextinuse = inuse_bit_at_offset(nextchunk, nextsize); - set_head(nextchunk, nextsize); - - /* consolidate forward */ - if (!nextinuse) { - unlink(nextchunk, bck, fwd); - size += nextsize; + set_fastchunks(av); + fb = &(av->fastbins[fastbin_index(size)]); + p->fd = *fb; + *fb = p; } /* + Consolidate other non-mmapped chunks as they arrive. + */ + + else if(!chunk_is_mmapped(p)) + { + set_anychunks(av); + + nextchunk = chunk_at_offset(p, size); + nextsize = chunksize(nextchunk); + + /* consolidate backward */ + if(!prev_inuse(p)) + { + prevsize = p->prev_size; + size += prevsize; + p = chunk_at_offset(p, -((long)prevsize)); + unlink(p, bck, fwd); + } + + if(nextchunk != av->top) + { + /* get and clear inuse bit */ + nextinuse = inuse_bit_at_offset(nextchunk, nextsize); + set_head(nextchunk, nextsize); + + /* consolidate forward */ + if(!nextinuse) + { + unlink(nextchunk, bck, fwd); + size += nextsize; + } + + /* Place the chunk in unsorted chunk list. Chunks are not placed into regular bins until after they have been given one chance to be used in malloc. */ - bck = unsorted_chunks(av); - fwd = bck->fd; - p->bk = bck; - p->fd = fwd; - bck->fd = p; - fwd->bk = p; + bck = unsorted_chunks(av); + fwd = bck->fd; + p->bk = bck; + p->fd = fwd; + bck->fd = p; + fwd->bk = p; - set_head(p, size | PREV_INUSE); - set_foot(p, size); + set_head(p, size | PREV_INUSE); + set_foot(p, size); - check_free_chunk(p); - } + check_free_chunk(p); + } - /* + /* If the chunk borders the current high end of memory, consolidate into top */ - else { - size += nextsize; - set_head(p, size | PREV_INUSE); - av->top = p; - check_chunk(p); - } + else + { + size += nextsize; + set_head(p, size | PREV_INUSE); + av->top = p; + check_chunk(p); + } - /* + /* If freeing a large space, consolidate possibly-surrounding chunks. Then, if the total unused topmost memory exceeds trim threshold, ask malloc_trim to reduce top. @@ -3843,19 +3949,18 @@ void fREe(mem) Void_t* mem; is reached. */ - if ((CHUNK_SIZE_T)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) { - if (have_fastchunks(av)) - malloc_consolidate(av); + if((CHUNK_SIZE_T)(size) >= FASTBIN_CONSOLIDATION_THRESHOLD) + { + if(have_fastchunks(av)) + malloc_consolidate(av); #ifndef MORECORE_CANNOT_TRIM - if ((CHUNK_SIZE_T)(chunksize(av->top)) >= - (CHUNK_SIZE_T)(av->trim_threshold)) - sYSTRIm(av->top_pad, av); + if((CHUNK_SIZE_T)(chunksize(av->top)) >= (CHUNK_SIZE_T)(av->trim_threshold)) + sYSTRIm(av->top_pad, av); #endif - } - - } - /* + } + } + /* If the chunk was allocated via mmap, release via munmap() Note that if HAVE_MMAP is false but chunk_is_mmapped is true, then user must have overwritten memory. There's nothing @@ -3863,15 +3968,16 @@ void fREe(mem) Void_t* mem; check_inuse_chunk (above) will have triggered error. */ - else { + else + { #if HAVE_MMAP - INTERNAL_SIZE_T offset = p->prev_size; - av->n_mmaps--; - av->mmapped_mem -= (size + offset); - munmap((char*)p - offset, size + offset); + INTERNAL_SIZE_T offset = p->prev_size; + av->n_mmaps--; + av->mmapped_mem -= (size + offset); + munmap((char*)p - offset, size + offset); #endif + } } - } } /* @@ -3894,33 +4000,34 @@ static void malloc_consolidate(mstate av) static void malloc_consolidate(av) mstate av; #endif { - mfastbinptr* fb; /* current fastbin being consolidated */ - mfastbinptr* maxfb; /* last fastbin (for loop control) */ - mchunkptr p; /* current chunk being consolidated */ - mchunkptr nextp; /* next chunk to consolidate */ - mchunkptr unsorted_bin; /* bin header */ - mchunkptr first_unsorted; /* chunk to link to */ + mfastbinptr* fb; /* current fastbin being consolidated */ + mfastbinptr* maxfb; /* last fastbin (for loop control) */ + mchunkptr p; /* current chunk being consolidated */ + mchunkptr nextp; /* next chunk to consolidate */ + mchunkptr unsorted_bin; /* bin header */ + mchunkptr first_unsorted; /* chunk to link to */ - /* These have same use as in free() */ - mchunkptr nextchunk; - INTERNAL_SIZE_T size; - INTERNAL_SIZE_T nextsize; - INTERNAL_SIZE_T prevsize; - int nextinuse; - mchunkptr bck; - mchunkptr fwd; + /* These have same use as in free() */ + mchunkptr nextchunk; + INTERNAL_SIZE_T size; + INTERNAL_SIZE_T nextsize; + INTERNAL_SIZE_T prevsize; + int nextinuse; + mchunkptr bck; + mchunkptr fwd; - /* + /* If max_fast is 0, we know that av hasn't yet been initialized, in which case do so below */ - if (av->max_fast != 0) { - clear_fastchunks(av); + if(av->max_fast != 0) + { + clear_fastchunks(av); - unsorted_bin = unsorted_chunks(av); + unsorted_bin = unsorted_chunks(av); - /* + /* Remove each chunk from fast bin and consolidate it, placing it then in unsorted bin. Among other reasons for doing this, placing in unsorted bin avoids needing to calculate actual bins @@ -3928,289 +4035,311 @@ static void malloc_consolidate(av) mstate av; reused anyway. */ - maxfb = &(av->fastbins[fastbin_index(av->max_fast)]); - fb = &(av->fastbins[0]); - do { - if ( (p = *fb) != 0) { - *fb = 0; + maxfb = &(av->fastbins[fastbin_index(av->max_fast)]); + fb = &(av->fastbins[0]); + do + { + if((p = *fb) != 0) + { + *fb = 0; - do { - check_inuse_chunk(p); - nextp = p->fd; + do + { + check_inuse_chunk(p); + nextp = p->fd; - /* Slightly streamlined version of consolidation code in free() */ - size = p->size & ~PREV_INUSE; - nextchunk = chunk_at_offset(p, size); - nextsize = chunksize(nextchunk); + /* Slightly streamlined version of consolidation code in free() */ + size = p->size & ~PREV_INUSE; + nextchunk = chunk_at_offset(p, size); + nextsize = chunksize(nextchunk); - if (!prev_inuse(p)) { - prevsize = p->prev_size; - size += prevsize; - p = chunk_at_offset(p, -((long) prevsize)); - unlink(p, bck, fwd); - } + if(!prev_inuse(p)) + { + prevsize = p->prev_size; + size += prevsize; + p = chunk_at_offset(p, -((long)prevsize)); + unlink(p, bck, fwd); + } - if (nextchunk != av->top) { - nextinuse = inuse_bit_at_offset(nextchunk, nextsize); - set_head(nextchunk, nextsize); + if(nextchunk != av->top) + { + nextinuse = inuse_bit_at_offset(nextchunk, nextsize); + set_head(nextchunk, nextsize); - if (!nextinuse) { - size += nextsize; - unlink(nextchunk, bck, fwd); + if(!nextinuse) + { + size += nextsize; + unlink(nextchunk, bck, fwd); + } + + first_unsorted = unsorted_bin->fd; + unsorted_bin->fd = p; + first_unsorted->bk = p; + + set_head(p, size | PREV_INUSE); + p->bk = unsorted_bin; + p->fd = first_unsorted; + set_foot(p, size); + } + + else + { + size += nextsize; + set_head(p, size | PREV_INUSE); + av->top = p; + } + + } while((p = nextp) != 0); } - - first_unsorted = unsorted_bin->fd; - unsorted_bin->fd = p; - first_unsorted->bk = p; - - set_head(p, size | PREV_INUSE); - p->bk = unsorted_bin; - p->fd = first_unsorted; - set_foot(p, size); - } - - else { - size += nextsize; - set_head(p, size | PREV_INUSE); - av->top = p; - } - - } while ( (p = nextp) != 0); - - } - } while (fb++ != maxfb); - } - else { - malloc_init_state(av); - check_malloc_state(); - } + } while(fb++ != maxfb); + } + else + { + malloc_init_state(av); + check_malloc_state(); + } } /* ------------------------------ realloc ------------------------------ */ - #if __STD_C Void_t* rEALLOc(Void_t* oldmem, size_t bytes) #else -Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes; +Void_t* rEALLOc(oldmem, bytes) +Void_t* oldmem; +size_t bytes; #endif { - mstate av = get_malloc_state(); + mstate av = get_malloc_state(); - INTERNAL_SIZE_T nb; /* padded request size */ + INTERNAL_SIZE_T nb; /* padded request size */ - mchunkptr oldp; /* chunk corresponding to oldmem */ - INTERNAL_SIZE_T oldsize; /* its size */ + mchunkptr oldp; /* chunk corresponding to oldmem */ + INTERNAL_SIZE_T oldsize; /* its size */ - mchunkptr newp; /* chunk to return */ - INTERNAL_SIZE_T newsize; /* its size */ - Void_t* newmem; /* corresponding user mem */ + mchunkptr newp; /* chunk to return */ + INTERNAL_SIZE_T newsize; /* its size */ + Void_t* newmem; /* corresponding user mem */ - mchunkptr next; /* next contiguous chunk after oldp */ + mchunkptr next; /* next contiguous chunk after oldp */ - mchunkptr remainder; /* extra space at end of newp */ - CHUNK_SIZE_T remainder_size; /* its size */ + mchunkptr remainder; /* extra space at end of newp */ + CHUNK_SIZE_T remainder_size; /* its size */ - mchunkptr bck; /* misc temp for linking */ - mchunkptr fwd; /* misc temp for linking */ - - CHUNK_SIZE_T copysize; /* bytes to copy */ - unsigned int ncopies; /* INTERNAL_SIZE_T words to copy */ - INTERNAL_SIZE_T* s; /* copy source */ - INTERNAL_SIZE_T* d; /* copy destination */ + mchunkptr bck; /* misc temp for linking */ + mchunkptr fwd; /* misc temp for linking */ + CHUNK_SIZE_T copysize; /* bytes to copy */ + unsigned int ncopies; /* INTERNAL_SIZE_T words to copy */ + INTERNAL_SIZE_T* s; /* copy source */ + INTERNAL_SIZE_T* d; /* copy destination */ #ifdef REALLOC_ZERO_BYTES_FREES - if (bytes == 0) { - fREe(oldmem); - return 0; - } + if(bytes == 0) + { + fREe(oldmem); + return 0; + } #endif - /* realloc of null is supposed to be same as malloc */ - if (oldmem == 0) return mALLOc(bytes); + /* realloc of null is supposed to be same as malloc */ + if(oldmem == 0) + return mALLOc(bytes); - checked_request2size(bytes, nb); + checked_request2size(bytes, nb); - oldp = mem2chunk(oldmem); - oldsize = chunksize(oldp); + oldp = mem2chunk(oldmem); + oldsize = chunksize(oldp); - check_inuse_chunk(oldp); + check_inuse_chunk(oldp); - if (!chunk_is_mmapped(oldp)) { + if(!chunk_is_mmapped(oldp)) + { - if ((CHUNK_SIZE_T)(oldsize) >= (CHUNK_SIZE_T)(nb)) { - /* already big enough; split below */ - newp = oldp; - newsize = oldsize; - } + if((CHUNK_SIZE_T)(oldsize) >= (CHUNK_SIZE_T)(nb)) + { + /* already big enough; split below */ + newp = oldp; + newsize = oldsize; + } - else { - next = chunk_at_offset(oldp, oldsize); + else + { + next = chunk_at_offset(oldp, oldsize); - /* Try to expand forward into top */ - if (next == av->top && - (CHUNK_SIZE_T)(newsize = oldsize + chunksize(next)) >= - (CHUNK_SIZE_T)(nb + MINSIZE)) { - set_head_size(oldp, nb); - av->top = chunk_at_offset(oldp, nb); - set_head(av->top, (newsize - nb) | PREV_INUSE); - return chunk2mem(oldp); - } + /* Try to expand forward into top */ + if(next == av->top && (CHUNK_SIZE_T)(newsize = oldsize + chunksize(next)) >= (CHUNK_SIZE_T)(nb + MINSIZE)) + { + set_head_size(oldp, nb); + av->top = chunk_at_offset(oldp, nb); + set_head(av->top, (newsize - nb) | PREV_INUSE); + return chunk2mem(oldp); + } - /* Try to expand forward into next chunk; split off remainder below */ - else if (next != av->top && - !inuse(next) && - (CHUNK_SIZE_T)(newsize = oldsize + chunksize(next)) >= - (CHUNK_SIZE_T)(nb)) { - newp = oldp; - unlink(next, bck, fwd); - } + /* Try to expand forward into next chunk; split off remainder below */ + else if(next != av->top && !inuse(next) && (CHUNK_SIZE_T)(newsize = oldsize + chunksize(next)) >= (CHUNK_SIZE_T)(nb)) + { + newp = oldp; + unlink(next, bck, fwd); + } - /* allocate, copy, free */ - else { - newmem = mALLOc(nb - MALLOC_ALIGN_MASK); - if (newmem == 0) - return 0; /* propagate failure */ + /* allocate, copy, free */ + else + { + newmem = mALLOc(nb - MALLOC_ALIGN_MASK); + if(newmem == 0) + return 0; /* propagate failure */ - newp = mem2chunk(newmem); - newsize = chunksize(newp); + newp = mem2chunk(newmem); + newsize = chunksize(newp); - /* + /* Avoid copy if newp is next chunk after oldp. */ - if (newp == next) { - newsize += oldsize; - newp = oldp; - } - else { - /* + if(newp == next) + { + newsize += oldsize; + newp = oldp; + } + else + { + /* Unroll copy of <= 36 bytes (72 if 8byte sizes) We know that contents have an odd number of INTERNAL_SIZE_T-sized words; minimally 3. */ - copysize = oldsize - SIZE_SZ; - s = (INTERNAL_SIZE_T*)(oldmem); - d = (INTERNAL_SIZE_T*)(newmem); - ncopies = copysize / sizeof(INTERNAL_SIZE_T); - assert(ncopies >= 3); + copysize = oldsize - SIZE_SZ; + s = (INTERNAL_SIZE_T*)(oldmem); + d = (INTERNAL_SIZE_T*)(newmem); + ncopies = copysize / sizeof(INTERNAL_SIZE_T); + assert(ncopies >= 3); - if (ncopies > 9) - MALLOC_COPY(d, s, copysize); + if(ncopies > 9) + MALLOC_COPY(d, s, copysize); - else { - *(d+0) = *(s+0); - *(d+1) = *(s+1); - *(d+2) = *(s+2); - if (ncopies > 4) { - *(d+3) = *(s+3); - *(d+4) = *(s+4); - if (ncopies > 6) { - *(d+5) = *(s+5); - *(d+6) = *(s+6); - if (ncopies > 8) { - *(d+7) = *(s+7); - *(d+8) = *(s+8); + else + { + *(d + 0) = *(s + 0); + *(d + 1) = *(s + 1); + *(d + 2) = *(s + 2); + if(ncopies > 4) + { + *(d + 3) = *(s + 3); + *(d + 4) = *(s + 4); + if(ncopies > 6) + { + *(d + 5) = *(s + 5); + *(d + 6) = *(s + 6); + if(ncopies > 8) + { + *(d + 7) = *(s + 7); + *(d + 8) = *(s + 8); + } + } + } + } + + fREe(oldmem); + check_inuse_chunk(newp); + return chunk2mem(newp); } - } } - } - - fREe(oldmem); - check_inuse_chunk(newp); - return chunk2mem(newp); } - } + + /* If possible, free extra space in old or extended chunk */ + + assert((CHUNK_SIZE_T)(newsize) >= (CHUNK_SIZE_T)(nb)); + + remainder_size = newsize - nb; + + if(remainder_size < MINSIZE) + { /* not enough extra to split off */ + set_head_size(newp, newsize); + set_inuse_bit_at_offset(newp, newsize); + } + else + { /* split remainder */ + remainder = chunk_at_offset(newp, nb); + set_head_size(newp, nb); + set_head(remainder, remainder_size | PREV_INUSE); + /* Mark remainder as inuse so free() won't complain */ + set_inuse_bit_at_offset(remainder, remainder_size); + fREe(chunk2mem(remainder)); + } + + check_inuse_chunk(newp); + return chunk2mem(newp); } - /* If possible, free extra space in old or extended chunk */ - - assert((CHUNK_SIZE_T)(newsize) >= (CHUNK_SIZE_T)(nb)); - - remainder_size = newsize - nb; - - if (remainder_size < MINSIZE) { /* not enough extra to split off */ - set_head_size(newp, newsize); - set_inuse_bit_at_offset(newp, newsize); - } - else { /* split remainder */ - remainder = chunk_at_offset(newp, nb); - set_head_size(newp, nb); - set_head(remainder, remainder_size | PREV_INUSE); - /* Mark remainder as inuse so free() won't complain */ - set_inuse_bit_at_offset(remainder, remainder_size); - fREe(chunk2mem(remainder)); - } - - check_inuse_chunk(newp); - return chunk2mem(newp); - } - - /* + /* Handle mmap cases */ - else { + else + { #if HAVE_MMAP -#if HAVE_MREMAP - INTERNAL_SIZE_T offset = oldp->prev_size; - size_t pagemask = av->pagesize - 1; - char *cp; - CHUNK_SIZE_T sum; + #if HAVE_MREMAP + INTERNAL_SIZE_T offset = oldp->prev_size; + size_t pagemask = av->pagesize - 1; + char* cp; + CHUNK_SIZE_T sum; - /* Note the extra SIZE_SZ overhead */ - newsize = (nb + offset + SIZE_SZ + pagemask) & ~pagemask; + /* Note the extra SIZE_SZ overhead */ + newsize = (nb + offset + SIZE_SZ + pagemask) & ~pagemask; - /* don't need to remap if still within same page */ - if (oldsize == newsize - offset) - return oldmem; + /* don't need to remap if still within same page */ + if(oldsize == newsize - offset) + return oldmem; - cp = (char*)mremap((char*)oldp - offset, oldsize + offset, newsize, 1); + cp = (char*)mremap((char*)oldp - offset, oldsize + offset, newsize, 1); - if (cp != (char*)MORECORE_FAILURE) { + if(cp != (char*)MORECORE_FAILURE) + { - newp = (mchunkptr)(cp + offset); - set_head(newp, (newsize - offset)|IS_MMAPPED); + newp = (mchunkptr)(cp + offset); + set_head(newp, (newsize - offset) | IS_MMAPPED); - assert(aligned_OK(chunk2mem(newp))); - assert((newp->prev_size == offset)); + assert(aligned_OK(chunk2mem(newp))); + assert((newp->prev_size == offset)); - /* update statistics */ - sum = av->mmapped_mem += newsize - oldsize; - if (sum > (CHUNK_SIZE_T)(av->max_mmapped_mem)) - av->max_mmapped_mem = sum; - sum += av->sbrked_mem; - if (sum > (CHUNK_SIZE_T)(av->max_total_mem)) - av->max_total_mem = sum; + /* update statistics */ + sum = av->mmapped_mem += newsize - oldsize; + if(sum > (CHUNK_SIZE_T)(av->max_mmapped_mem)) + av->max_mmapped_mem = sum; + sum += av->sbrked_mem; + if(sum > (CHUNK_SIZE_T)(av->max_total_mem)) + av->max_total_mem = sum; - return chunk2mem(newp); - } -#endif + return chunk2mem(newp); + } + #endif - /* Note the extra SIZE_SZ overhead. */ - if ((CHUNK_SIZE_T)(oldsize) >= (CHUNK_SIZE_T)(nb + SIZE_SZ)) - newmem = oldmem; /* do nothing */ - else { - /* Must alloc, copy, free. */ - newmem = mALLOc(nb - MALLOC_ALIGN_MASK); - if (newmem != 0) { - MALLOC_COPY(newmem, oldmem, oldsize - 2*SIZE_SZ); - fREe(oldmem); - } - } - return newmem; + /* Note the extra SIZE_SZ overhead. */ + if((CHUNK_SIZE_T)(oldsize) >= (CHUNK_SIZE_T)(nb + SIZE_SZ)) + newmem = oldmem; /* do nothing */ + else + { + /* Must alloc, copy, free. */ + newmem = mALLOc(nb - MALLOC_ALIGN_MASK); + if(newmem != 0) + { + MALLOC_COPY(newmem, oldmem, oldsize - 2 * SIZE_SZ); + fREe(oldmem); + } + } + return newmem; #else - /* If !HAVE_MMAP, but chunk_is_mmapped, user must have overwritten mem */ - check_malloc_state(); - MALLOC_FAILURE_ACTION; - return 0; + /* If !HAVE_MMAP, but chunk_is_mmapped, user must have overwritten mem */ + check_malloc_state(); + MALLOC_FAILURE_ACTION; + return 0; #endif - } + } } /* @@ -4220,54 +4349,61 @@ Void_t* rEALLOc(oldmem, bytes) Void_t* oldmem; size_t bytes; #if __STD_C Void_t* mEMALIGn(size_t alignment, size_t bytes) #else -Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes; +Void_t* mEMALIGn(alignment, bytes) +size_t alignment; +size_t bytes; #endif { - INTERNAL_SIZE_T nb; /* padded request size */ - char* m; /* memory returned by malloc call */ - mchunkptr p; /* corresponding chunk */ - char* brk; /* alignment point within p */ - mchunkptr newp; /* chunk to return */ - INTERNAL_SIZE_T newsize; /* its size */ - INTERNAL_SIZE_T leadsize; /* leading space before alignment point */ - mchunkptr remainder; /* spare room at end to split off */ - CHUNK_SIZE_T remainder_size; /* its size */ - INTERNAL_SIZE_T size; + INTERNAL_SIZE_T nb; /* padded request size */ + char* m; /* memory returned by malloc call */ + mchunkptr p; /* corresponding chunk */ + char* brk; /* alignment point within p */ + mchunkptr newp; /* chunk to return */ + INTERNAL_SIZE_T newsize; /* its size */ + INTERNAL_SIZE_T leadsize; /* leading space before alignment point */ + mchunkptr remainder; /* spare room at end to split off */ + CHUNK_SIZE_T remainder_size; /* its size */ + INTERNAL_SIZE_T size; - /* If need less alignment than we give anyway, just relay to malloc */ + /* If need less alignment than we give anyway, just relay to malloc */ - if (alignment <= MALLOC_ALIGNMENT) return mALLOc(bytes); + if(alignment <= MALLOC_ALIGNMENT) + return mALLOc(bytes); - /* Otherwise, ensure that it is at least a minimum chunk size */ + /* Otherwise, ensure that it is at least a minimum chunk size */ - if (alignment < MINSIZE) alignment = MINSIZE; + if(alignment < MINSIZE) + alignment = MINSIZE; - /* Make sure alignment is power of 2 (in case MINSIZE is not). */ - if ((alignment & (alignment - 1)) != 0) { - size_t a = MALLOC_ALIGNMENT * 2; - while ((CHUNK_SIZE_T)a < (CHUNK_SIZE_T)alignment) a <<= 1; - alignment = a; - } + /* Make sure alignment is power of 2 (in case MINSIZE is not). */ + if((alignment & (alignment - 1)) != 0) + { + size_t a = MALLOC_ALIGNMENT * 2; + while((CHUNK_SIZE_T)a < (CHUNK_SIZE_T)alignment) + a <<= 1; + alignment = a; + } - checked_request2size(bytes, nb); + checked_request2size(bytes, nb); - /* + /* Strategy: find a spot within that chunk that meets the alignment request, and then possibly free the leading and trailing space. */ + /* Call malloc with worst case padding to hit alignment. */ - /* Call malloc with worst case padding to hit alignment. */ + m = (char*)(mALLOc(nb + alignment + MINSIZE)); - m = (char*)(mALLOc(nb + alignment + MINSIZE)); + if(m == 0) + return 0; /* propagate failure */ - if (m == 0) return 0; /* propagate failure */ + p = mem2chunk(m); - p = mem2chunk(m); + if((((PTR_UINT)(m)) % alignment) != 0) + { /* misaligned */ - if ((((PTR_UINT)(m)) % alignment) != 0) { /* misaligned */ - - /* + /* Find an aligned spot inside chunk. Since we need to give back leading space in a chunk of at least MINSIZE, if the first calculation places us at a spot with less than MINSIZE leader, @@ -4275,47 +4411,48 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes; total room so that this is always possible. */ - brk = (char*)mem2chunk((PTR_UINT)(((PTR_UINT)(m + alignment - 1)) & - -((signed long) alignment))); - if ((CHUNK_SIZE_T)(brk - (char*)(p)) < MINSIZE) - brk += alignment; + brk = (char*)mem2chunk((PTR_UINT)(((PTR_UINT)(m + alignment - 1)) & -((signed long)alignment))); + if((CHUNK_SIZE_T)(brk - (char*)(p)) < MINSIZE) + brk += alignment; - newp = (mchunkptr)brk; - leadsize = brk - (char*)(p); - newsize = chunksize(p) - leadsize; + newp = (mchunkptr)brk; + leadsize = brk - (char*)(p); + newsize = chunksize(p) - leadsize; - /* For mmapped chunks, just adjust offset */ - if (chunk_is_mmapped(p)) { - newp->prev_size = p->prev_size + leadsize; - set_head(newp, newsize|IS_MMAPPED); - return chunk2mem(newp); + /* For mmapped chunks, just adjust offset */ + if(chunk_is_mmapped(p)) + { + newp->prev_size = p->prev_size + leadsize; + set_head(newp, newsize | IS_MMAPPED); + return chunk2mem(newp); + } + + /* Otherwise, give back leader, use the rest */ + set_head(newp, newsize | PREV_INUSE); + set_inuse_bit_at_offset(newp, newsize); + set_head_size(p, leadsize); + fREe(chunk2mem(p)); + p = newp; + + assert(newsize >= nb && (((PTR_UINT)(chunk2mem(p))) % alignment) == 0); } - /* Otherwise, give back leader, use the rest */ - set_head(newp, newsize | PREV_INUSE); - set_inuse_bit_at_offset(newp, newsize); - set_head_size(p, leadsize); - fREe(chunk2mem(p)); - p = newp; - - assert (newsize >= nb && - (((PTR_UINT)(chunk2mem(p))) % alignment) == 0); - } - - /* Also give back spare room at the end */ - if (!chunk_is_mmapped(p)) { - size = chunksize(p); - if ((CHUNK_SIZE_T)(size) > (CHUNK_SIZE_T)(nb + MINSIZE)) { - remainder_size = size - nb; - remainder = chunk_at_offset(p, nb); - set_head(remainder, remainder_size | PREV_INUSE); - set_head_size(p, nb); - fREe(chunk2mem(remainder)); + /* Also give back spare room at the end */ + if(!chunk_is_mmapped(p)) + { + size = chunksize(p); + if((CHUNK_SIZE_T)(size) > (CHUNK_SIZE_T)(nb + MINSIZE)) + { + remainder_size = size - nb; + remainder = chunk_at_offset(p, nb); + set_head(remainder, remainder_size | PREV_INUSE); + set_head_size(p, nb); + fREe(chunk2mem(remainder)); + } } - } - check_inuse_chunk(p); - return chunk2mem(p); + check_inuse_chunk(p); + return chunk2mem(p); } /* @@ -4325,66 +4462,73 @@ Void_t* mEMALIGn(alignment, bytes) size_t alignment; size_t bytes; #if __STD_C Void_t* cALLOc(size_t n_elements, size_t elem_size) #else -Void_t* cALLOc(n_elements, elem_size) size_t n_elements; size_t elem_size; +Void_t* cALLOc(n_elements, elem_size) +size_t n_elements; +size_t elem_size; #endif { - mchunkptr p; - CHUNK_SIZE_T clearsize; - CHUNK_SIZE_T nclears; - INTERNAL_SIZE_T* d; + mchunkptr p; + CHUNK_SIZE_T clearsize; + CHUNK_SIZE_T nclears; + INTERNAL_SIZE_T* d; - Void_t* mem = mALLOc(n_elements * elem_size); + Void_t* mem = mALLOc(n_elements * elem_size); - if (mem != 0) { - p = mem2chunk(mem); - - if (!chunk_is_mmapped(p)) + if(mem != 0) { - /* + p = mem2chunk(mem); + + if(!chunk_is_mmapped(p)) + { + /* Unroll clear of <= 36 bytes (72 if 8byte sizes) We know that contents have an odd number of INTERNAL_SIZE_T-sized words; minimally 3. */ - d = (INTERNAL_SIZE_T*)mem; - clearsize = chunksize(p) - SIZE_SZ; - nclears = clearsize / sizeof(INTERNAL_SIZE_T); - assert(nclears >= 3); + d = (INTERNAL_SIZE_T*)mem; + clearsize = chunksize(p) - SIZE_SZ; + nclears = clearsize / sizeof(INTERNAL_SIZE_T); + assert(nclears >= 3); - if (nclears > 9) - MALLOC_ZERO(d, clearsize); + if(nclears > 9) + MALLOC_ZERO(d, clearsize); - else { - *(d+0) = 0; - *(d+1) = 0; - *(d+2) = 0; - if (nclears > 4) { - *(d+3) = 0; - *(d+4) = 0; - if (nclears > 6) { - *(d+5) = 0; - *(d+6) = 0; - if (nclears > 8) { - *(d+7) = 0; - *(d+8) = 0; + else + { + *(d + 0) = 0; + *(d + 1) = 0; + *(d + 2) = 0; + if(nclears > 4) + { + *(d + 3) = 0; + *(d + 4) = 0; + if(nclears > 6) + { + *(d + 5) = 0; + *(d + 6) = 0; + if(nclears > 8) + { + *(d + 7) = 0; + *(d + 8) = 0; + } + } + } } - } } - } - } -#if ! MMAP_CLEARS - else - { - d = (INTERNAL_SIZE_T*)mem; - /* +#if !MMAP_CLEARS + else + { + d = (INTERNAL_SIZE_T*)mem; + /* Note the additional SIZE_SZ */ - clearsize = chunksize(p) - 2*SIZE_SZ; - MALLOC_ZERO(d, clearsize); - } + clearsize = chunksize(p) - 2 * SIZE_SZ; + MALLOC_ZERO(d, clearsize); + } #endif - } - return mem; + } + return mem; } /* @@ -4392,12 +4536,12 @@ Void_t* cALLOc(n_elements, elem_size) size_t n_elements; size_t elem_size; */ #if __STD_C -void cFREe(Void_t *mem) +void cFREe(Void_t* mem) #else -void cFREe(mem) Void_t *mem; +void cFREe(mem) Void_t* mem; #endif { - fREe(mem); + fREe(mem); } /* @@ -4407,12 +4551,15 @@ void cFREe(mem) Void_t *mem; #if __STD_C Void_t** iCALLOc(size_t n_elements, size_t elem_size, Void_t* chunks[]) #else -Void_t** iCALLOc(n_elements, elem_size, chunks) size_t n_elements; size_t elem_size; Void_t* chunks[]; +Void_t** iCALLOc(n_elements, elem_size, chunks) +size_t n_elements; +size_t elem_size; +Void_t* chunks[]; #endif { - size_t sz = elem_size; /* serves as 1-element array */ - /* opts arg of 3 means all elements are same size, and should be cleared */ - return iALLOc(n_elements, &sz, 3, chunks); + size_t sz = elem_size; /* serves as 1-element array */ + /* opts arg of 3 means all elements are same size, and should be cleared */ + return iALLOc(n_elements, &sz, 3, chunks); } /* @@ -4422,13 +4569,15 @@ Void_t** iCALLOc(n_elements, elem_size, chunks) size_t n_elements; size_t elem_s #if __STD_C Void_t** iCOMALLOc(size_t n_elements, size_t sizes[], Void_t* chunks[]) #else -Void_t** iCOMALLOc(n_elements, sizes, chunks) size_t n_elements; size_t sizes[]; Void_t* chunks[]; +Void_t** iCOMALLOc(n_elements, sizes, chunks) +size_t n_elements; +size_t sizes[]; +Void_t* chunks[]; #endif { - return iALLOc(n_elements, sizes, 0, chunks); + return iALLOc(n_elements, sizes, 0, chunks); } - /* ------------------------------ ialloc ------------------------------ ialloc provides common support for independent_X routines, handling all of @@ -4439,127 +4588,140 @@ Void_t** iCOMALLOc(n_elements, sizes, chunks) size_t n_elements; size_t sizes[]; bit 1 set if elements should be zeroed */ - #if __STD_C static Void_t** iALLOc(size_t n_elements, size_t* sizes, int opts, Void_t* chunks[]) #else -static Void_t** iALLOc(n_elements, sizes, opts, chunks) size_t n_elements; size_t* sizes; int opts; Void_t* chunks[]; +static Void_t** iALLOc(n_elements, sizes, opts, chunks) +size_t n_elements; +size_t* sizes; +int opts; +Void_t* chunks[]; #endif { - mstate av = get_malloc_state(); - INTERNAL_SIZE_T element_size; /* chunksize of each element, if all same */ - INTERNAL_SIZE_T contents_size; /* total size of elements */ - INTERNAL_SIZE_T array_size; /* request size of pointer array */ - Void_t* mem; /* malloced aggregate space */ - mchunkptr p; /* corresponding chunk */ - INTERNAL_SIZE_T remainder_size; /* remaining bytes while splitting */ - Void_t** marray; /* either "chunks" or malloced ptr array */ - mchunkptr array_chunk; /* chunk for malloced ptr array */ - int mmx; /* to disable mmap */ - INTERNAL_SIZE_T size; - size_t i; + mstate av = get_malloc_state(); + INTERNAL_SIZE_T element_size; /* chunksize of each element, if all same */ + INTERNAL_SIZE_T contents_size; /* total size of elements */ + INTERNAL_SIZE_T array_size; /* request size of pointer array */ + Void_t* mem; /* malloced aggregate space */ + mchunkptr p; /* corresponding chunk */ + INTERNAL_SIZE_T remainder_size; /* remaining bytes while splitting */ + Void_t** marray; /* either "chunks" or malloced ptr array */ + mchunkptr array_chunk; /* chunk for malloced ptr array */ + int mmx; /* to disable mmap */ + INTERNAL_SIZE_T size; + size_t i; - /* Ensure initialization */ - if (av->max_fast == 0) malloc_consolidate(av); + /* Ensure initialization */ + if(av->max_fast == 0) + malloc_consolidate(av); - /* compute array length, if needed */ - if (chunks != 0) { - if (n_elements == 0) - return chunks; /* nothing to do */ - marray = chunks; - array_size = 0; - } - else { - /* if empty req, must still return chunk representing empty array */ - if (n_elements == 0) - return (Void_t**) mALLOc(0); - marray = 0; - array_size = request2size(n_elements * (sizeof(Void_t*))); - } + /* compute array length, if needed */ + if(chunks != 0) + { + if(n_elements == 0) + return chunks; /* nothing to do */ + marray = chunks; + array_size = 0; + } + else + { + /* if empty req, must still return chunk representing empty array */ + if(n_elements == 0) + return (Void_t**)mALLOc(0); + marray = 0; + array_size = request2size(n_elements * (sizeof(Void_t*))); + } - /* compute total element size */ - if (opts & 0x1) { /* all-same-size */ - element_size = request2size(*sizes); - contents_size = n_elements * element_size; - } - else { /* add up all the sizes */ - element_size = 0; - contents_size = 0; - for (i = 0; i != n_elements; ++i) - contents_size += request2size(sizes[i]); - } + /* compute total element size */ + if(opts & 0x1) + { /* all-same-size */ + element_size = request2size(*sizes); + contents_size = n_elements * element_size; + } + else + { /* add up all the sizes */ + element_size = 0; + contents_size = 0; + for(i = 0; i != n_elements; ++i) + contents_size += request2size(sizes[i]); + } - /* subtract out alignment bytes from total to minimize overallocation */ - size = contents_size + array_size - MALLOC_ALIGN_MASK; + /* subtract out alignment bytes from total to minimize overallocation */ + size = contents_size + array_size - MALLOC_ALIGN_MASK; - /* + /* Allocate the aggregate chunk. But first disable mmap so malloc won't use it, since we would not be able to later free/realloc space internal to a segregated mmap region. */ - mmx = av->n_mmaps_max; /* disable mmap */ - av->n_mmaps_max = 0; - mem = mALLOc(size); - av->n_mmaps_max = mmx; /* reset mmap */ - if (mem == 0) - return 0; + mmx = av->n_mmaps_max; /* disable mmap */ + av->n_mmaps_max = 0; + mem = mALLOc(size); + av->n_mmaps_max = mmx; /* reset mmap */ + if(mem == 0) + return 0; - p = mem2chunk(mem); - assert(!chunk_is_mmapped(p)); - remainder_size = chunksize(p); + p = mem2chunk(mem); + assert(!chunk_is_mmapped(p)); + remainder_size = chunksize(p); - if (opts & 0x2) { /* optionally clear the elements */ - MALLOC_ZERO(mem, remainder_size - SIZE_SZ - array_size); - } - - /* If not provided, allocate the pointer array as final part of chunk */ - if (marray == 0) { - array_chunk = chunk_at_offset(p, contents_size); - marray = (Void_t**) (chunk2mem(array_chunk)); - set_head(array_chunk, (remainder_size - contents_size) | PREV_INUSE); - remainder_size = contents_size; - } - - /* split out elements */ - for (i = 0; ; ++i) { - marray[i] = chunk2mem(p); - if (i != n_elements-1) { - if (element_size != 0) - size = element_size; - else - size = request2size(sizes[i]); - remainder_size -= size; - set_head(p, size | PREV_INUSE); - p = chunk_at_offset(p, size); + if(opts & 0x2) + { /* optionally clear the elements */ + MALLOC_ZERO(mem, remainder_size - SIZE_SZ - array_size); } - else { /* the final element absorbs any overallocation slop */ - set_head(p, remainder_size | PREV_INUSE); - break; + + /* If not provided, allocate the pointer array as final part of chunk */ + if(marray == 0) + { + array_chunk = chunk_at_offset(p, contents_size); + marray = (Void_t**)(chunk2mem(array_chunk)); + set_head(array_chunk, (remainder_size - contents_size) | PREV_INUSE); + remainder_size = contents_size; + } + + /* split out elements */ + for(i = 0;; ++i) + { + marray[i] = chunk2mem(p); + if(i != n_elements - 1) + { + if(element_size != 0) + size = element_size; + else + size = request2size(sizes[i]); + remainder_size -= size; + set_head(p, size | PREV_INUSE); + p = chunk_at_offset(p, size); + } + else + { /* the final element absorbs any overallocation slop */ + set_head(p, remainder_size | PREV_INUSE); + break; + } } - } #if DL_DEBUG - if (marray != chunks) { - /* final element must have exactly exhausted chunk */ - if (element_size != 0) - assert(remainder_size == element_size); - else - assert(remainder_size == request2size(sizes[i])); - check_inuse_chunk(mem2chunk(marray)); - } + if(marray != chunks) + { + /* final element must have exactly exhausted chunk */ + if(element_size != 0) + assert(remainder_size == element_size); + else + assert(remainder_size == request2size(sizes[i])); + check_inuse_chunk(mem2chunk(marray)); + } - for (i = 0; i != n_elements; ++i) - check_inuse_chunk(mem2chunk(marray[i])); + for(i = 0; i != n_elements; ++i) + check_inuse_chunk(mem2chunk(marray[i])); #endif - return marray; + return marray; } - /* ------------------------------ valloc ------------------------------ */ @@ -4567,36 +4729,38 @@ static Void_t** iALLOc(n_elements, sizes, opts, chunks) size_t n_elements; size_ #if __STD_C Void_t* vALLOc(size_t bytes) #else -Void_t* vALLOc(bytes) size_t bytes; +Void_t* vALLOc(bytes) +size_t bytes; #endif { - /* Ensure initialization */ - mstate av = get_malloc_state(); - if (av->max_fast == 0) malloc_consolidate(av); - return mEMALIGn(av->pagesize, bytes); + /* Ensure initialization */ + mstate av = get_malloc_state(); + if(av->max_fast == 0) + malloc_consolidate(av); + return mEMALIGn(av->pagesize, bytes); } /* ------------------------------ pvalloc ------------------------------ */ - #if __STD_C Void_t* pVALLOc(size_t bytes) #else -Void_t* pVALLOc(bytes) size_t bytes; +Void_t* pVALLOc(bytes) +size_t bytes; #endif { - mstate av = get_malloc_state(); - size_t pagesz; + mstate av = get_malloc_state(); + size_t pagesz; - /* Ensure initialization */ - if (av->max_fast == 0) malloc_consolidate(av); - pagesz = av->pagesize; - return mEMALIGn(pagesz, (bytes + pagesz - 1) & ~(pagesz - 1)); + /* Ensure initialization */ + if(av->max_fast == 0) + malloc_consolidate(av); + pagesz = av->pagesize; + return mEMALIGn(pagesz, (bytes + pagesz - 1) & ~(pagesz - 1)); } - /* ------------------------------ malloc_trim ------------------------------ */ @@ -4604,21 +4768,21 @@ Void_t* pVALLOc(bytes) size_t bytes; #if __STD_C int mTRIm(size_t pad) #else -int mTRIm(pad) size_t pad; +int mTRIm(pad) +size_t pad; #endif { - mstate av = get_malloc_state(); - /* Ensure initialization/consolidation */ - malloc_consolidate(av); + mstate av = get_malloc_state(); + /* Ensure initialization/consolidation */ + malloc_consolidate(av); #ifndef MORECORE_CANNOT_TRIM - return sYSTRIm(pad, av); + return sYSTRIm(pad, av); #else - return 0; + return 0; #endif } - /* ------------------------- malloc_usable_size ------------------------- */ @@ -4626,18 +4790,20 @@ int mTRIm(pad) size_t pad; #if __STD_C size_t mUSABLe(Void_t* mem) #else -size_t mUSABLe(mem) Void_t* mem; +size_t mUSABLe(mem) +Void_t* mem; #endif { - mchunkptr p; - if (mem != 0) { - p = mem2chunk(mem); - if (chunk_is_mmapped(p)) - return chunksize(p) - 2*SIZE_SZ; - else if (inuse(p)) - return chunksize(p) - SIZE_SZ; - } - return 0; + mchunkptr p; + if(mem != 0) + { + p = mem2chunk(mem); + if(chunk_is_mmapped(p)) + return chunksize(p) - 2 * SIZE_SZ; + else if(inuse(p)) + return chunksize(p) - SIZE_SZ; + } + return 0; } /* @@ -4646,58 +4812,63 @@ size_t mUSABLe(mem) Void_t* mem; struct mallinfo mALLINFo() { - mstate av = get_malloc_state(); - struct mallinfo mi; - int i; - mbinptr b; - mchunkptr p; - INTERNAL_SIZE_T avail; - INTERNAL_SIZE_T fastavail; - int nblocks; - int nfastblocks; + mstate av = get_malloc_state(); + struct mallinfo mi; + int i; + mbinptr b; + mchunkptr p; + INTERNAL_SIZE_T avail; + INTERNAL_SIZE_T fastavail; + int nblocks; + int nfastblocks; - /* Ensure initialization */ - if (av->top == 0) malloc_consolidate(av); + /* Ensure initialization */ + if(av->top == 0) + malloc_consolidate(av); - check_malloc_state(); + check_malloc_state(); - /* Account for top */ - avail = chunksize(av->top); - nblocks = 1; /* top always exists */ + /* Account for top */ + avail = chunksize(av->top); + nblocks = 1; /* top always exists */ - /* traverse fastbins */ - nfastblocks = 0; - fastavail = 0; + /* traverse fastbins */ + nfastblocks = 0; + fastavail = 0; - for (i = 0; NFASTBINS-i>0; ++i) { - for (p = av->fastbins[i]; p != 0; p = p->fd) { - ++nfastblocks; - fastavail += chunksize(p); + for(i = 0; NFASTBINS - i > 0; ++i) + { + for(p = av->fastbins[i]; p != 0; p = p->fd) + { + ++nfastblocks; + fastavail += chunksize(p); + } } - } - avail += fastavail; + avail += fastavail; - /* traverse regular bins */ - for (i = 1; i < NBINS; ++i) { - b = bin_at(av, i); - for (p = last(b); p != b; p = p->bk) { - ++nblocks; - avail += chunksize(p); + /* traverse regular bins */ + for(i = 1; i < NBINS; ++i) + { + b = bin_at(av, i); + for(p = last(b); p != b; p = p->bk) + { + ++nblocks; + avail += chunksize(p); + } } - } - mi.smblks = nfastblocks; - mi.ordblks = nblocks; - mi.fordblks = avail; - mi.uordblks = av->sbrked_mem - avail; - mi.arena = av->sbrked_mem; - mi.hblks = av->n_mmaps; - mi.hblkhd = av->mmapped_mem; - mi.fsmblks = fastavail; - mi.keepcost = chunksize(av->top); - mi.usmblks = av->max_total_mem; - return mi; + mi.smblks = nfastblocks; + mi.ordblks = nblocks; + mi.fordblks = avail; + mi.uordblks = av->sbrked_mem - avail; + mi.arena = av->sbrked_mem; + mi.hblks = av->n_mmaps; + mi.hblkhd = av->mmapped_mem; + mi.fsmblks = fastavail; + mi.keepcost = chunksize(av->top); + mi.usmblks = av->max_total_mem; + return mi; } /* @@ -4706,7 +4877,7 @@ struct mallinfo mALLINFo() void mSTATs(void) { -/*NOTE(ORCA): stdio doesn't make sense in orca platform + /*NOTE(ORCA): stdio doesn't make sense in orca platform struct mallinfo mi = mALLINFo(); @@ -4745,7 +4916,6 @@ void mSTATs(void) */ } - /* ------------------------------ mallopt ------------------------------ */ @@ -4753,53 +4923,55 @@ void mSTATs(void) #if __STD_C int mALLOPt(int param_number, int value) #else -int mALLOPt(param_number, value) int param_number; int value; +int mALLOPt(param_number, value) +int param_number; +int value; #endif { - mstate av = get_malloc_state(); - /* Ensure initialization/consolidation */ - malloc_consolidate(av); + mstate av = get_malloc_state(); + /* Ensure initialization/consolidation */ + malloc_consolidate(av); - switch(param_number) { - case M_MXFAST: - if (value >= 0 && value <= MAX_FAST_SIZE) { - set_max_fast(av, value); - return 1; - } - else - return 0; + switch(param_number) + { + case M_MXFAST: + if(value >= 0 && value <= MAX_FAST_SIZE) + { + set_max_fast(av, value); + return 1; + } + else + return 0; - case M_TRIM_THRESHOLD: - av->trim_threshold = value; - return 1; + case M_TRIM_THRESHOLD: + av->trim_threshold = value; + return 1; - case M_TOP_PAD: - av->top_pad = value; - return 1; + case M_TOP_PAD: + av->top_pad = value; + return 1; - case M_MMAP_THRESHOLD: - av->mmap_threshold = value; - return 1; + case M_MMAP_THRESHOLD: + av->mmap_threshold = value; + return 1; - case M_MMAP_MAX: + case M_MMAP_MAX: #if !HAVE_MMAP - if (value != 0) - return 0; + if(value != 0) + return 0; #endif - av->n_mmaps_max = value; - return 1; + av->n_mmaps_max = value; + return 1; - default: - return 0; - } + default: + return 0; + } } - /* -------------------- Alternative MORECORE functions -------------------- */ - /* General Requirements for MORECORE. @@ -4939,7 +5111,6 @@ int mALLOPt(param_number, value) int param_number; int value; */ - /* -------------------------------------------------------------- @@ -4949,484 +5120,521 @@ int mALLOPt(param_number, value) int param_number; int value; http://www.genesys-e.de/jwalter/ */ - #ifdef WIN32 -#ifdef _DEBUG -/* #define TRACE */ -#endif + #ifdef _DEBUG + /* #define TRACE */ + #endif -/* Support for USE_MALLOC_LOCK */ -#ifdef USE_MALLOC_LOCK + /* Support for USE_MALLOC_LOCK */ + #ifdef USE_MALLOC_LOCK /* Wait for spin lock */ -static int slwait (int *sl) { - while (InterlockedCompareExchange ((void **) sl, (void *) 1, (void *) 0) != 0) - Sleep (0); +static int slwait(int* sl) +{ + while(InterlockedCompareExchange((void**)sl, (void*)1, (void*)0) != 0) + Sleep(0); return 0; } /* Release spin lock */ -static int slrelease (int *sl) { - InterlockedExchange (sl, 0); +static int slrelease(int* sl) +{ + InterlockedExchange(sl, 0); return 0; } -#ifdef NEEDED + #ifdef NEEDED /* Spin lock for emulation code */ static int g_sl; -#endif + #endif -#endif /* USE_MALLOC_LOCK */ + #endif /* USE_MALLOC_LOCK */ /* getpagesize for windows */ -static long getpagesize (void) { +static long getpagesize(void) +{ static long g_pagesize = 0; - if (! g_pagesize) { + if(!g_pagesize) + { SYSTEM_INFO system_info; - GetSystemInfo (&system_info); + GetSystemInfo(&system_info); g_pagesize = system_info.dwPageSize; } return g_pagesize; } -static long getregionsize (void) { + +static long getregionsize(void) +{ static long g_regionsize = 0; - if (! g_regionsize) { + if(!g_regionsize) + { SYSTEM_INFO system_info; - GetSystemInfo (&system_info); + GetSystemInfo(&system_info); g_regionsize = system_info.dwAllocationGranularity; } return g_regionsize; } /* A region list entry */ -typedef struct _region_list_entry { - void *top_allocated; - void *top_committed; - void *top_reserved; +typedef struct _region_list_entry +{ + void* top_allocated; + void* top_committed; + void* top_reserved; long reserve_size; - struct _region_list_entry *previous; + struct _region_list_entry* previous; } region_list_entry; /* Allocate and link a region entry in the region list */ -static int region_list_append (region_list_entry **last, void *base_reserved, long reserve_size) { - region_list_entry *next = HeapAlloc (GetProcessHeap (), 0, sizeof (region_list_entry)); - if (! next) +static int region_list_append(region_list_entry** last, void* base_reserved, long reserve_size) +{ + region_list_entry* next = HeapAlloc(GetProcessHeap(), 0, sizeof(region_list_entry)); + if(!next) return FALSE; - next->top_allocated = (char *) base_reserved; - next->top_committed = (char *) base_reserved; - next->top_reserved = (char *) base_reserved + reserve_size; + next->top_allocated = (char*)base_reserved; + next->top_committed = (char*)base_reserved; + next->top_reserved = (char*)base_reserved + reserve_size; next->reserve_size = reserve_size; next->previous = *last; *last = next; return TRUE; } + /* Free and unlink the last region entry from the region list */ -static int region_list_remove (region_list_entry **last) { - region_list_entry *previous = (*last)->previous; - if (! HeapFree (GetProcessHeap (), sizeof (region_list_entry), *last)) +static int region_list_remove(region_list_entry** last) +{ + region_list_entry* previous = (*last)->previous; + if(!HeapFree(GetProcessHeap(), sizeof(region_list_entry), *last)) return FALSE; *last = previous; return TRUE; } -#define CEIL(size,to) (((size)+(to)-1)&~((to)-1)) -#define FLOOR(size,to) ((size)&~((to)-1)) + #define CEIL(size, to) (((size) + (to)-1) & ~((to)-1)) + #define FLOOR(size, to) ((size) & ~((to)-1)) + + #define SBRK_SCALE 0 -#define SBRK_SCALE 0 /* #define SBRK_SCALE 1 */ /* #define SBRK_SCALE 2 */ /* #define SBRK_SCALE 4 */ /* sbrk for windows */ -static void *sbrk (long size) { +static void* sbrk(long size) +{ static long g_pagesize, g_my_pagesize; static long g_regionsize, g_my_regionsize; - static region_list_entry *g_last; - void *result = (void *) MORECORE_FAILURE; -#ifdef TRACE - printf ("sbrk %d\n", size); -#endif -#if defined (USE_MALLOC_LOCK) && defined (NEEDED) + static region_list_entry* g_last; + void* result = (void*)MORECORE_FAILURE; + #ifdef TRACE + printf("sbrk %d\n", size); + #endif + #if defined(USE_MALLOC_LOCK) && defined(NEEDED) /* Wait for spin lock */ - slwait (&g_sl); -#endif + slwait(&g_sl); + #endif /* First time initialization */ - if (! g_pagesize) { - g_pagesize = getpagesize (); + if(!g_pagesize) + { + g_pagesize = getpagesize(); g_my_pagesize = g_pagesize << SBRK_SCALE; } - if (! g_regionsize) { - g_regionsize = getregionsize (); + if(!g_regionsize) + { + g_regionsize = getregionsize(); g_my_regionsize = g_regionsize << SBRK_SCALE; } - if (! g_last) { - if (! region_list_append (&g_last, 0, 0)) - goto sbrk_exit; + if(!g_last) + { + if(!region_list_append(&g_last, 0, 0)) + goto sbrk_exit; } /* Assert invariants */ - assert (g_last); - assert ((char *) g_last->top_reserved - g_last->reserve_size <= (char *) g_last->top_allocated && - g_last->top_allocated <= g_last->top_committed); - assert ((char *) g_last->top_reserved - g_last->reserve_size <= (char *) g_last->top_committed && - g_last->top_committed <= g_last->top_reserved && - (unsigned) g_last->top_committed % g_pagesize == 0); - assert ((unsigned) g_last->top_reserved % g_regionsize == 0); - assert ((unsigned) g_last->reserve_size % g_regionsize == 0); + assert(g_last); + assert((char*)g_last->top_reserved - g_last->reserve_size <= (char*)g_last->top_allocated && g_last->top_allocated <= g_last->top_committed); + assert((char*)g_last->top_reserved - g_last->reserve_size <= (char*)g_last->top_committed && g_last->top_committed <= g_last->top_reserved && (unsigned)g_last->top_committed % g_pagesize == 0); + assert((unsigned)g_last->top_reserved % g_regionsize == 0); + assert((unsigned)g_last->reserve_size % g_regionsize == 0); /* Allocation requested? */ - if (size >= 0) { + if(size >= 0) + { /* Allocation size is the requested size */ long allocate_size = size; /* Compute the size to commit */ - long to_commit = (char *) g_last->top_allocated + allocate_size - (char *) g_last->top_committed; + long to_commit = (char*)g_last->top_allocated + allocate_size - (char*)g_last->top_committed; /* Do we reach the commit limit? */ - if (to_commit > 0) { + if(to_commit > 0) + { /* Round size to commit */ - long commit_size = CEIL (to_commit, g_my_pagesize); + long commit_size = CEIL(to_commit, g_my_pagesize); /* Compute the size to reserve */ - long to_reserve = (char *) g_last->top_committed + commit_size - (char *) g_last->top_reserved; + long to_reserve = (char*)g_last->top_committed + commit_size - (char*)g_last->top_reserved; /* Do we reach the reserve limit? */ - if (to_reserve > 0) { + if(to_reserve > 0) + { /* Compute the remaining size to commit in the current region */ - long remaining_commit_size = (char *) g_last->top_reserved - (char *) g_last->top_committed; - if (remaining_commit_size > 0) { + long remaining_commit_size = (char*)g_last->top_reserved - (char*)g_last->top_committed; + if(remaining_commit_size > 0) + { /* Assert preconditions */ - assert ((unsigned) g_last->top_committed % g_pagesize == 0); - assert (0 < remaining_commit_size && remaining_commit_size % g_pagesize == 0); { + assert((unsigned)g_last->top_committed % g_pagesize == 0); + assert(0 < remaining_commit_size && remaining_commit_size % g_pagesize == 0); + { /* Commit this */ - void *base_committed = VirtualAlloc (g_last->top_committed, remaining_commit_size, - MEM_COMMIT, PAGE_READWRITE); + void* base_committed = VirtualAlloc(g_last->top_committed, remaining_commit_size, + MEM_COMMIT, PAGE_READWRITE); /* Check returned pointer for consistency */ - if (base_committed != g_last->top_committed) + if(base_committed != g_last->top_committed) goto sbrk_exit; /* Assert postconditions */ - assert ((unsigned) base_committed % g_pagesize == 0); -#ifdef TRACE - printf ("Commit %p %d\n", base_committed, remaining_commit_size); -#endif + assert((unsigned)base_committed % g_pagesize == 0); + #ifdef TRACE + printf("Commit %p %d\n", base_committed, remaining_commit_size); + #endif /* Adjust the regions commit top */ - g_last->top_committed = (char *) base_committed + remaining_commit_size; + g_last->top_committed = (char*)base_committed + remaining_commit_size; } - } { + } + { /* Now we are going to search and reserve. */ int contiguous = -1; int found = FALSE; MEMORY_BASIC_INFORMATION memory_info; - void *base_reserved; + void* base_reserved; long reserve_size; - do { + do + { /* Assume contiguous memory */ contiguous = TRUE; /* Round size to reserve */ - reserve_size = CEIL (to_reserve, g_my_regionsize); + reserve_size = CEIL(to_reserve, g_my_regionsize); /* Start with the current region's top */ memory_info.BaseAddress = g_last->top_reserved; /* Assert preconditions */ - assert ((unsigned) memory_info.BaseAddress % g_pagesize == 0); - assert (0 < reserve_size && reserve_size % g_regionsize == 0); - while (VirtualQuery (memory_info.BaseAddress, &memory_info, sizeof (memory_info))) { + assert((unsigned)memory_info.BaseAddress % g_pagesize == 0); + assert(0 < reserve_size && reserve_size % g_regionsize == 0); + while(VirtualQuery(memory_info.BaseAddress, &memory_info, sizeof(memory_info))) + { /* Assert postconditions */ - assert ((unsigned) memory_info.BaseAddress % g_pagesize == 0); -#ifdef TRACE - printf ("Query %p %d %s\n", memory_info.BaseAddress, memory_info.RegionSize, - memory_info.State == MEM_FREE ? "FREE": - (memory_info.State == MEM_RESERVE ? "RESERVED": - (memory_info.State == MEM_COMMIT ? "COMMITTED": "?"))); -#endif + assert((unsigned)memory_info.BaseAddress % g_pagesize == 0); + #ifdef TRACE + printf("Query %p %d %s\n", memory_info.BaseAddress, memory_info.RegionSize, + memory_info.State == MEM_FREE ? "FREE" : (memory_info.State == MEM_RESERVE ? "RESERVED" : (memory_info.State == MEM_COMMIT ? "COMMITTED" : "?"))); + #endif /* Region is free, well aligned and big enough: we are done */ - if (memory_info.State == MEM_FREE && - (unsigned) memory_info.BaseAddress % g_regionsize == 0 && - memory_info.RegionSize >= (unsigned) reserve_size) { + if(memory_info.State == MEM_FREE && (unsigned)memory_info.BaseAddress % g_regionsize == 0 && memory_info.RegionSize >= (unsigned)reserve_size) + { found = TRUE; break; } /* From now on we can't get contiguous memory! */ contiguous = FALSE; /* Recompute size to reserve */ - reserve_size = CEIL (allocate_size, g_my_regionsize); - memory_info.BaseAddress = (char *) memory_info.BaseAddress + memory_info.RegionSize; + reserve_size = CEIL(allocate_size, g_my_regionsize); + memory_info.BaseAddress = (char*)memory_info.BaseAddress + memory_info.RegionSize; /* Assert preconditions */ - assert ((unsigned) memory_info.BaseAddress % g_pagesize == 0); - assert (0 < reserve_size && reserve_size % g_regionsize == 0); + assert((unsigned)memory_info.BaseAddress % g_pagesize == 0); + assert(0 < reserve_size && reserve_size % g_regionsize == 0); } /* Search failed? */ - if (! found) + if(!found) goto sbrk_exit; /* Assert preconditions */ - assert ((unsigned) memory_info.BaseAddress % g_regionsize == 0); - assert (0 < reserve_size && reserve_size % g_regionsize == 0); + assert((unsigned)memory_info.BaseAddress % g_regionsize == 0); + assert(0 < reserve_size && reserve_size % g_regionsize == 0); /* Try to reserve this */ - base_reserved = VirtualAlloc (memory_info.BaseAddress, reserve_size, - MEM_RESERVE, PAGE_NOACCESS); - if (! base_reserved) { - int rc = GetLastError (); - if (rc != ERROR_INVALID_ADDRESS) + base_reserved = VirtualAlloc(memory_info.BaseAddress, reserve_size, + MEM_RESERVE, PAGE_NOACCESS); + if(!base_reserved) + { + int rc = GetLastError(); + if(rc != ERROR_INVALID_ADDRESS) goto sbrk_exit; } /* A null pointer signals (hopefully) a race condition with another thread. */ /* In this case, we try again. */ - } while (! base_reserved); + } while(!base_reserved); /* Check returned pointer for consistency */ - if (memory_info.BaseAddress && base_reserved != memory_info.BaseAddress) + if(memory_info.BaseAddress && base_reserved != memory_info.BaseAddress) goto sbrk_exit; /* Assert postconditions */ - assert ((unsigned) base_reserved % g_regionsize == 0); -#ifdef TRACE - printf ("Reserve %p %d\n", base_reserved, reserve_size); -#endif + assert((unsigned)base_reserved % g_regionsize == 0); + #ifdef TRACE + printf("Reserve %p %d\n", base_reserved, reserve_size); + #endif /* Did we get contiguous memory? */ - if (contiguous) { - long start_size = (char *) g_last->top_committed - (char *) g_last->top_allocated; + if(contiguous) + { + long start_size = (char*)g_last->top_committed - (char*)g_last->top_allocated; /* Adjust allocation size */ allocate_size -= start_size; /* Adjust the regions allocation top */ g_last->top_allocated = g_last->top_committed; /* Recompute the size to commit */ - to_commit = (char *) g_last->top_allocated + allocate_size - (char *) g_last->top_committed; + to_commit = (char*)g_last->top_allocated + allocate_size - (char*)g_last->top_committed; /* Round size to commit */ - commit_size = CEIL (to_commit, g_my_pagesize); + commit_size = CEIL(to_commit, g_my_pagesize); } /* Append the new region to the list */ - if (! region_list_append (&g_last, base_reserved, reserve_size)) + if(!region_list_append(&g_last, base_reserved, reserve_size)) goto sbrk_exit; /* Didn't we get contiguous memory? */ - if (! contiguous) { + if(!contiguous) + { /* Recompute the size to commit */ - to_commit = (char *) g_last->top_allocated + allocate_size - (char *) g_last->top_committed; + to_commit = (char*)g_last->top_allocated + allocate_size - (char*)g_last->top_committed; /* Round size to commit */ - commit_size = CEIL (to_commit, g_my_pagesize); + commit_size = CEIL(to_commit, g_my_pagesize); } } } /* Assert preconditions */ - assert ((unsigned) g_last->top_committed % g_pagesize == 0); - assert (0 < commit_size && commit_size % g_pagesize == 0); { + assert((unsigned)g_last->top_committed % g_pagesize == 0); + assert(0 < commit_size && commit_size % g_pagesize == 0); + { /* Commit this */ - void *base_committed = VirtualAlloc (g_last->top_committed, commit_size, - MEM_COMMIT, PAGE_READWRITE); + void* base_committed = VirtualAlloc(g_last->top_committed, commit_size, + MEM_COMMIT, PAGE_READWRITE); /* Check returned pointer for consistency */ - if (base_committed != g_last->top_committed) + if(base_committed != g_last->top_committed) goto sbrk_exit; /* Assert postconditions */ - assert ((unsigned) base_committed % g_pagesize == 0); -#ifdef TRACE - printf ("Commit %p %d\n", base_committed, commit_size); -#endif + assert((unsigned)base_committed % g_pagesize == 0); + #ifdef TRACE + printf("Commit %p %d\n", base_committed, commit_size); + #endif /* Adjust the regions commit top */ - g_last->top_committed = (char *) base_committed + commit_size; + g_last->top_committed = (char*)base_committed + commit_size; } } /* Adjust the regions allocation top */ - g_last->top_allocated = (char *) g_last->top_allocated + allocate_size; - result = (char *) g_last->top_allocated - size; - /* Deallocation requested? */ - } else if (size < 0) { - long deallocate_size = - size; + g_last->top_allocated = (char*)g_last->top_allocated + allocate_size; + result = (char*)g_last->top_allocated - size; + /* Deallocation requested? */ + } + else if(size < 0) + { + long deallocate_size = -size; /* As long as we have a region to release */ - while ((char *) g_last->top_allocated - deallocate_size < (char *) g_last->top_reserved - g_last->reserve_size) { + while((char*)g_last->top_allocated - deallocate_size < (char*)g_last->top_reserved - g_last->reserve_size) + { /* Get the size to release */ long release_size = g_last->reserve_size; /* Get the base address */ - void *base_reserved = (char *) g_last->top_reserved - release_size; + void* base_reserved = (char*)g_last->top_reserved - release_size; /* Assert preconditions */ - assert ((unsigned) base_reserved % g_regionsize == 0); - assert (0 < release_size && release_size % g_regionsize == 0); { + assert((unsigned)base_reserved % g_regionsize == 0); + assert(0 < release_size && release_size % g_regionsize == 0); + { /* Release this */ - int rc = VirtualFree (base_reserved, 0, - MEM_RELEASE); + int rc = VirtualFree(base_reserved, 0, + MEM_RELEASE); /* Check returned code for consistency */ - if (! rc) + if(!rc) goto sbrk_exit; -#ifdef TRACE - printf ("Release %p %d\n", base_reserved, release_size); -#endif + #ifdef TRACE + printf("Release %p %d\n", base_reserved, release_size); + #endif } /* Adjust deallocation size */ - deallocate_size -= (char *) g_last->top_allocated - (char *) base_reserved; + deallocate_size -= (char*)g_last->top_allocated - (char*)base_reserved; /* Remove the old region from the list */ - if (! region_list_remove (&g_last)) + if(!region_list_remove(&g_last)) goto sbrk_exit; - } { + } + { /* Compute the size to decommit */ - long to_decommit = (char *) g_last->top_committed - ((char *) g_last->top_allocated - deallocate_size); - if (to_decommit >= g_my_pagesize) { + long to_decommit = (char*)g_last->top_committed - ((char*)g_last->top_allocated - deallocate_size); + if(to_decommit >= g_my_pagesize) + { /* Compute the size to decommit */ - long decommit_size = FLOOR (to_decommit, g_my_pagesize); + long decommit_size = FLOOR(to_decommit, g_my_pagesize); /* Compute the base address */ - void *base_committed = (char *) g_last->top_committed - decommit_size; + void* base_committed = (char*)g_last->top_committed - decommit_size; /* Assert preconditions */ - assert ((unsigned) base_committed % g_pagesize == 0); - assert (0 < decommit_size && decommit_size % g_pagesize == 0); { + assert((unsigned)base_committed % g_pagesize == 0); + assert(0 < decommit_size && decommit_size % g_pagesize == 0); + { /* Decommit this */ - int rc = VirtualFree ((char *) base_committed, decommit_size, - MEM_DECOMMIT); + int rc = VirtualFree((char*)base_committed, decommit_size, + MEM_DECOMMIT); /* Check returned code for consistency */ - if (! rc) + if(!rc) goto sbrk_exit; -#ifdef TRACE - printf ("Decommit %p %d\n", base_committed, decommit_size); -#endif + #ifdef TRACE + printf("Decommit %p %d\n", base_committed, decommit_size); + #endif } /* Adjust deallocation size and regions commit and allocate top */ - deallocate_size -= (char *) g_last->top_allocated - (char *) base_committed; + deallocate_size -= (char*)g_last->top_allocated - (char*)base_committed; g_last->top_committed = base_committed; g_last->top_allocated = base_committed; } } /* Adjust regions allocate top */ - g_last->top_allocated = (char *) g_last->top_allocated - deallocate_size; + g_last->top_allocated = (char*)g_last->top_allocated - deallocate_size; /* Check for underflow */ - if ((char *) g_last->top_reserved - g_last->reserve_size > (char *) g_last->top_allocated || - g_last->top_allocated > g_last->top_committed) { + if((char*)g_last->top_reserved - g_last->reserve_size > (char*)g_last->top_allocated || g_last->top_allocated > g_last->top_committed) + { /* Adjust regions allocate top */ - g_last->top_allocated = (char *) g_last->top_reserved - g_last->reserve_size; + g_last->top_allocated = (char*)g_last->top_reserved - g_last->reserve_size; goto sbrk_exit; } result = g_last->top_allocated; } /* Assert invariants */ - assert (g_last); - assert ((char *) g_last->top_reserved - g_last->reserve_size <= (char *) g_last->top_allocated && - g_last->top_allocated <= g_last->top_committed); - assert ((char *) g_last->top_reserved - g_last->reserve_size <= (char *) g_last->top_committed && - g_last->top_committed <= g_last->top_reserved && - (unsigned) g_last->top_committed % g_pagesize == 0); - assert ((unsigned) g_last->top_reserved % g_regionsize == 0); - assert ((unsigned) g_last->reserve_size % g_regionsize == 0); + assert(g_last); + assert((char*)g_last->top_reserved - g_last->reserve_size <= (char*)g_last->top_allocated && g_last->top_allocated <= g_last->top_committed); + assert((char*)g_last->top_reserved - g_last->reserve_size <= (char*)g_last->top_committed && g_last->top_committed <= g_last->top_reserved && (unsigned)g_last->top_committed % g_pagesize == 0); + assert((unsigned)g_last->top_reserved % g_regionsize == 0); + assert((unsigned)g_last->reserve_size % g_regionsize == 0); sbrk_exit: -#if defined (USE_MALLOC_LOCK) && defined (NEEDED) + #if defined(USE_MALLOC_LOCK) && defined(NEEDED) /* Release spin lock */ - slrelease (&g_sl); -#endif + slrelease(&g_sl); + #endif return result; } /* mmap for windows */ -static void *mmap (void *ptr, long size, long prot, long type, long handle, long arg) { +static void* mmap(void* ptr, long size, long prot, long type, long handle, long arg) +{ static long g_pagesize; static long g_regionsize; -#ifdef TRACE - printf ("mmap %d\n", size); -#endif -#if defined (USE_MALLOC_LOCK) && defined (NEEDED) + #ifdef TRACE + printf("mmap %d\n", size); + #endif + #if defined(USE_MALLOC_LOCK) && defined(NEEDED) /* Wait for spin lock */ - slwait (&g_sl); -#endif + slwait(&g_sl); + #endif /* First time initialization */ - if (! g_pagesize) - g_pagesize = getpagesize (); - if (! g_regionsize) - g_regionsize = getregionsize (); + if(!g_pagesize) + g_pagesize = getpagesize(); + if(!g_regionsize) + g_regionsize = getregionsize(); /* Assert preconditions */ - assert ((unsigned) ptr % g_regionsize == 0); - assert (size % g_pagesize == 0); + assert((unsigned)ptr % g_regionsize == 0); + assert(size % g_pagesize == 0); /* Allocate this */ - ptr = VirtualAlloc (ptr, size, - MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE); - if (! ptr) { - ptr = (void *) MORECORE_FAILURE; + ptr = VirtualAlloc(ptr, size, + MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE); + if(!ptr) + { + ptr = (void*)MORECORE_FAILURE; goto mmap_exit; } /* Assert postconditions */ - assert ((unsigned) ptr % g_regionsize == 0); -#ifdef TRACE - printf ("Commit %p %d\n", ptr, size); -#endif + assert((unsigned)ptr % g_regionsize == 0); + #ifdef TRACE + printf("Commit %p %d\n", ptr, size); + #endif mmap_exit: -#if defined (USE_MALLOC_LOCK) && defined (NEEDED) + #if defined(USE_MALLOC_LOCK) && defined(NEEDED) /* Release spin lock */ - slrelease (&g_sl); -#endif + slrelease(&g_sl); + #endif return ptr; } /* munmap for windows */ -static long munmap (void *ptr, long size) { +static long munmap(void* ptr, long size) +{ static long g_pagesize; static long g_regionsize; int rc = MUNMAP_FAILURE; -#ifdef TRACE - printf ("munmap %p %d\n", ptr, size); -#endif -#if defined (USE_MALLOC_LOCK) && defined (NEEDED) + #ifdef TRACE + printf("munmap %p %d\n", ptr, size); + #endif + #if defined(USE_MALLOC_LOCK) && defined(NEEDED) /* Wait for spin lock */ - slwait (&g_sl); -#endif + slwait(&g_sl); + #endif /* First time initialization */ - if (! g_pagesize) - g_pagesize = getpagesize (); - if (! g_regionsize) - g_regionsize = getregionsize (); + if(!g_pagesize) + g_pagesize = getpagesize(); + if(!g_regionsize) + g_regionsize = getregionsize(); /* Assert preconditions */ - assert ((unsigned) ptr % g_regionsize == 0); - assert (size % g_pagesize == 0); + assert((unsigned)ptr % g_regionsize == 0); + assert(size % g_pagesize == 0); /* Free this */ - if (! VirtualFree (ptr, 0, - MEM_RELEASE)) + if(!VirtualFree(ptr, 0, + MEM_RELEASE)) goto munmap_exit; rc = 0; -#ifdef TRACE - printf ("Release %p %d\n", ptr, size); -#endif + #ifdef TRACE + printf("Release %p %d\n", ptr, size); + #endif munmap_exit: -#if defined (USE_MALLOC_LOCK) && defined (NEEDED) + #if defined(USE_MALLOC_LOCK) && defined(NEEDED) /* Release spin lock */ - slrelease (&g_sl); -#endif + slrelease(&g_sl); + #endif return rc; } -static void vminfo (CHUNK_SIZE_T *free, CHUNK_SIZE_T *reserved, CHUNK_SIZE_T *committed) { +static void vminfo(CHUNK_SIZE_T* free, CHUNK_SIZE_T* reserved, CHUNK_SIZE_T* committed) +{ MEMORY_BASIC_INFORMATION memory_info; memory_info.BaseAddress = 0; *free = *reserved = *committed = 0; - while (VirtualQuery (memory_info.BaseAddress, &memory_info, sizeof (memory_info))) { - switch (memory_info.State) { - case MEM_FREE: - *free += memory_info.RegionSize; - break; - case MEM_RESERVE: - *reserved += memory_info.RegionSize; - break; - case MEM_COMMIT: - *committed += memory_info.RegionSize; - break; + while(VirtualQuery(memory_info.BaseAddress, &memory_info, sizeof(memory_info))) + { + switch(memory_info.State) + { + case MEM_FREE: + *free += memory_info.RegionSize; + break; + case MEM_RESERVE: + *reserved += memory_info.RegionSize; + break; + case MEM_COMMIT: + *committed += memory_info.RegionSize; + break; } - memory_info.BaseAddress = (char *) memory_info.BaseAddress + memory_info.RegionSize; + memory_info.BaseAddress = (char*)memory_info.BaseAddress + memory_info.RegionSize; } } -static int cpuinfo (int whole, CHUNK_SIZE_T *kernel, CHUNK_SIZE_T *user) { - if (whole) { +static int cpuinfo(int whole, CHUNK_SIZE_T* kernel, CHUNK_SIZE_T* user) +{ + if(whole) + { __int64 creation64, exit64, kernel64, user64; - int rc = GetProcessTimes (GetCurrentProcess (), - (FILETIME *) &creation64, - (FILETIME *) &exit64, - (FILETIME *) &kernel64, - (FILETIME *) &user64); - if (! rc) { + int rc = GetProcessTimes(GetCurrentProcess(), + (FILETIME*)&creation64, + (FILETIME*)&exit64, + (FILETIME*)&kernel64, + (FILETIME*)&user64); + if(!rc) + { *kernel = 0; *user = 0; return FALSE; } - *kernel = (CHUNK_SIZE_T) (kernel64 / 10000); - *user = (CHUNK_SIZE_T) (user64 / 10000); + *kernel = (CHUNK_SIZE_T)(kernel64 / 10000); + *user = (CHUNK_SIZE_T)(user64 / 10000); return TRUE; - } else { + } + else + { __int64 creation64, exit64, kernel64, user64; - int rc = GetThreadTimes (GetCurrentThread (), - (FILETIME *) &creation64, - (FILETIME *) &exit64, - (FILETIME *) &kernel64, - (FILETIME *) &user64); - if (! rc) { + int rc = GetThreadTimes(GetCurrentThread(), + (FILETIME*)&creation64, + (FILETIME*)&exit64, + (FILETIME*)&kernel64, + (FILETIME*)&user64); + if(!rc) + { *kernel = 0; *user = 0; return FALSE; } - *kernel = (CHUNK_SIZE_T) (kernel64 / 10000); - *user = (CHUNK_SIZE_T) (user64 / 10000); + *kernel = (CHUNK_SIZE_T)(kernel64 / 10000); + *user = (CHUNK_SIZE_T)(user64 / 10000); return TRUE; } } diff --git a/src/platform/orca_memory.c b/src/platform/orca_memory.c index 0ef9dbd..bb98ed6 100644 --- a/src/platform/orca_memory.c +++ b/src/platform/orca_memory.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: orca_memory.c * @author: Martin Fouilleul @@ -6,26 +6,26 @@ * *****************************************************************/ -#include"platform_memory.h" +#include "platform_memory.h" void* ORCA_IMPORT(oc_mem_grow)(u64 size); void* orca_oc_base_reserve(oc_base_allocator* context, u64 size) { - return(oc_mem_grow(size)); + return (oc_mem_grow(size)); } void orca_oc_base_nop(oc_base_allocator* context, void* ptr, u64 size) {} oc_base_allocator* oc_base_allocator_default() { - static oc_base_allocator base = {0}; - if(base.reserve == 0) - { - base.reserve = orca_oc_base_reserve; - base.commit = orca_oc_base_nop; - base.decommit = orca_oc_base_nop; - base.release = orca_oc_base_nop; - } - return(&base); + static oc_base_allocator base = { 0 }; + if(base.reserve == 0) + { + base.reserve = orca_oc_base_reserve; + base.commit = orca_oc_base_nop; + base.decommit = orca_oc_base_nop; + base.release = orca_oc_base_nop; + } + return (&base); } diff --git a/src/platform/osx_clock.c b/src/platform/osx_clock.c index b29f89d..7b98026 100644 --- a/src/platform/osx_clock.c +++ b/src/platform/osx_clock.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: osx_clock.cpp * @author: Martin Fouilleul @@ -7,118 +7,120 @@ * *****************************************************************/ -#include //fabs() -#include -#include // gettimeofday() -#include -#include -#include -#include // availability macros +#include // availability macros +#include +#include +#include +#include //fabs() +#include // gettimeofday() +#include -#include -#include - -#include"platform_clock.h" +#include +#include +#include "platform_clock.h" typedef struct timeval timeval; typedef struct timespec timespec; //TODO(martin): measure the actual values of these constants -const f64 OC_CLOCK_FUZZ = 25e-9, // minimum time to read the clock (s) - OC_CLOCK_TICK = 25e-9; // minimum step between two clock readings (s) +const f64 OC_CLOCK_FUZZ = 25e-9, // minimum time to read the clock (s) + OC_CLOCK_TICK = 25e-9; // minimum step between two clock readings (s) -static mach_timebase_info_data_t __machTimeBase__ = {1,1}; +static mach_timebase_info_data_t __machTimeBase__ = { 1, 1 }; static u64 __initialTimestamp__ = 0; static inline u64 OSXGetUptimeNanoseconds() { - //NOTE(martin): according to the documentation, mach_absolute_time() does not - // increment when the system is asleep - u64 now = mach_absolute_time(); - now *= __machTimeBase__.numer; - now /= __machTimeBase__.denom; - return(now); + //NOTE(martin): according to the documentation, mach_absolute_time() does not + // increment when the system is asleep + u64 now = mach_absolute_time(); + now *= __machTimeBase__.numer; + now /= __machTimeBase__.denom; + return (now); } static inline u64 OSXGetMonotonicNanoseconds() { - //NOTE(martin): according to the documentation, OC_CLOCK_MONOTONIC increment monotonically - // on systems where OC_CLOCK_MONOTONIC_RAW is present, we may want to use that instead, - // because OC_CLOCK_MONOTONIC seems to be subject to frequency changes ? + //NOTE(martin): according to the documentation, OC_CLOCK_MONOTONIC increment monotonically + // on systems where OC_CLOCK_MONOTONIC_RAW is present, we may want to use that instead, + // because OC_CLOCK_MONOTONIC seems to be subject to frequency changes ? - #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200 - #ifndef CLOCK_MONOTONIC_RAW - #error "CLOCK_MONOTONIC_RAW not found. Please verify that is included from the MacOSX SDK rather than /usr/local/include" - #else - return(clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW)); - #endif - #else - //TODO(martin): quick and dirty hack is to fallback to uptime, - // but we should either only support macos version >= 10.12, or find a proper solution - return(OSXGetUptimeNanoseconds()); - #endif +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200 + #ifndef CLOCK_MONOTONIC_RAW + #error "CLOCK_MONOTONIC_RAW not found. Please verify that is included from the MacOSX SDK rather than /usr/local/include" + #else + return (clock_gettime_nsec_np(CLOCK_MONOTONIC_RAW)); + #endif +#else + //TODO(martin): quick and dirty hack is to fallback to uptime, + // but we should either only support macos version >= 10.12, or find a proper solution + return (OSXGetUptimeNanoseconds()); +#endif } -static const f64 CLK_TIMESTAMPS_PER_SECOND = 4294967296.; // 2^32 as a double -static const u64 CLK_JAN_1970 = 2208988800ULL; // seconds from january 1900 to january 1970 +static const f64 CLK_TIMESTAMPS_PER_SECOND = 4294967296.; // 2^32 as a double +static const u64 CLK_JAN_1970 = 2208988800ULL; // seconds from january 1900 to january 1970 void oc_clock_init() { - mach_timebase_info(&__machTimeBase__); + mach_timebase_info(&__machTimeBase__); - //NOTE(martin): get the date of system boot time - timeval tv = {0, 0}; + //NOTE(martin): get the date of system boot time + timeval tv = { 0, 0 }; - int mib[2] = {CTL_KERN, - KERN_BOOTTIME}; - size_t size = sizeof(tv); + int mib[2] = { CTL_KERN, + KERN_BOOTTIME }; + size_t size = sizeof(tv); - if(sysctl(mib, 2, &tv, &size, 0, 0) == -1) - { - oc_log_error("can't read boot time\n"); - } - //NOTE(martin): convert boot date to timestamp - __initialTimestamp__ = (((u64)tv.tv_sec + CLK_JAN_1970) << 32) - + (u64)(tv.tv_usec * 1e-6 * CLK_TIMESTAMPS_PER_SECOND); + if(sysctl(mib, 2, &tv, &size, 0, 0) == -1) + { + oc_log_error("can't read boot time\n"); + } + //NOTE(martin): convert boot date to timestamp + __initialTimestamp__ = (((u64)tv.tv_sec + CLK_JAN_1970) << 32) + + (u64)(tv.tv_usec * 1e-6 * CLK_TIMESTAMPS_PER_SECOND); - //TODO(martin): maybe get a state vector for exclusive clock usage ? - //RandomSeedFromDevice(); + //TODO(martin): maybe get a state vector for exclusive clock usage ? + //RandomSeedFromDevice(); } u64 oc_clock_timestamp(oc_clock_kind clock) { - u64 ts = 0; - switch(clock) - { - case OC_CLOCK_MONOTONIC: - { - //NOTE(martin): compute monotonic offset and add it to bootup timestamp - u64 noff = OSXGetMonotonicNanoseconds() ; - u64 foff = (u64)(noff * 1e-9 * CLK_TIMESTAMPS_PER_SECOND); - ts = __initialTimestamp__ + foff; - } break; + u64 ts = 0; + switch(clock) + { + case OC_CLOCK_MONOTONIC: + { + //NOTE(martin): compute monotonic offset and add it to bootup timestamp + u64 noff = OSXGetMonotonicNanoseconds(); + u64 foff = (u64)(noff * 1e-9 * CLK_TIMESTAMPS_PER_SECOND); + ts = __initialTimestamp__ + foff; + } + break; - case OC_CLOCK_UPTIME: - { - //TODO(martin): maybe we should warn that this date is inconsistent after a sleep ? - //NOTE(martin): compute uptime offset and add it to bootup timestamp - u64 noff = OSXGetUptimeNanoseconds() ; - u64 foff = (u64)(noff * 1e-9 * CLK_TIMESTAMPS_PER_SECOND); - ts = __initialTimestamp__ + foff; - } break; + case OC_CLOCK_UPTIME: + { + //TODO(martin): maybe we should warn that this date is inconsistent after a sleep ? + //NOTE(martin): compute uptime offset and add it to bootup timestamp + u64 noff = OSXGetUptimeNanoseconds(); + u64 foff = (u64)(noff * 1e-9 * CLK_TIMESTAMPS_PER_SECOND); + ts = __initialTimestamp__ + foff; + } + break; - case OC_CLOCK_DATE: - { - //NOTE(martin): get system date and convert it to a fixed-point timestamp - timeval tv; - gettimeofday(&tv, 0); - ts = (((u64)tv.tv_sec + CLK_JAN_1970) << 32) - + (u64)(tv.tv_usec * 1e-6 * CLK_TIMESTAMPS_PER_SECOND); - } break; - } + case OC_CLOCK_DATE: + { + //NOTE(martin): get system date and convert it to a fixed-point timestamp + timeval tv; + gettimeofday(&tv, 0); + ts = (((u64)tv.tv_sec + CLK_JAN_1970) << 32) + + (u64)(tv.tv_usec * 1e-6 * CLK_TIMESTAMPS_PER_SECOND); + } + break; + } - /* + /* //NOTE(martin): add a random fuzz between 0 and 1 times the system fuzz //TODO(martin): ensure that we always return a value greater than the last value f64 fuzz = RandomU32()/(f64)(~(0UL)) * OC_CLOCK_FUZZ; @@ -126,37 +128,39 @@ u64 oc_clock_timestamp(oc_clock_kind clock) ts = TimestampAdd(ts, tdfuzz); */ - return(ts); + return (ts); } - f64 oc_clock_time(oc_clock_kind clock) { - switch(clock) - { - case OC_CLOCK_MONOTONIC: - { - //NOTE(martin): compute monotonic offset and add it to bootup timestamp - u64 noff = OSXGetMonotonicNanoseconds(); - return((f64)noff * 1e-9); - } break; + switch(clock) + { + case OC_CLOCK_MONOTONIC: + { + //NOTE(martin): compute monotonic offset and add it to bootup timestamp + u64 noff = OSXGetMonotonicNanoseconds(); + return ((f64)noff * 1e-9); + } + break; - case OC_CLOCK_UPTIME: - { - //TODO(martin): maybe we should warn that this date is inconsistent after a sleep ? - //NOTE(martin): compute uptime offset and add it to bootup timestamp - u64 noff = OSXGetUptimeNanoseconds(); - return((f64)noff * 1e-9); - } break; + case OC_CLOCK_UPTIME: + { + //TODO(martin): maybe we should warn that this date is inconsistent after a sleep ? + //NOTE(martin): compute uptime offset and add it to bootup timestamp + u64 noff = OSXGetUptimeNanoseconds(); + return ((f64)noff * 1e-9); + } + break; - case OC_CLOCK_DATE: - { - //TODO(martin): maybe warn about precision loss ? - // could also change the epoch since we only promise to return a relative time - //NOTE(martin): get system date and convert it to seconds - timeval tv; - gettimeofday(&tv, 0); - return(((f64)tv.tv_sec + CLK_JAN_1970) + ((f64)tv.tv_usec * 1e-6)); - } break; - } + case OC_CLOCK_DATE: + { + //TODO(martin): maybe warn about precision loss ? + // could also change the epoch since we only promise to return a relative time + //NOTE(martin): get system date and convert it to seconds + timeval tv; + gettimeofday(&tv, 0); + return (((f64)tv.tv_sec + CLK_JAN_1970) + ((f64)tv.tv_usec * 1e-6)); + } + break; + } } diff --git a/src/platform/osx_path.m b/src/platform/osx_path.m index ad5740c..855d035 100644 --- a/src/platform/osx_path.m +++ b/src/platform/osx_path.m @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: osx_path.m * @author: Martin Fouilleul @@ -6,39 +6,42 @@ * *****************************************************************/ -#import -#include -#include +#import +#include +#include -#include"platform_path.c" +#include "platform_path.c" bool oc_path_is_absolute(oc_str8 path) { - return(path.len && (path.ptr[0] == '/')); + return (path.len && (path.ptr[0] == '/')); } oc_str8 oc_path_executable(oc_arena* arena) -{@autoreleasepool{ - oc_str8 result = {}; - u32 size = 0; - _NSGetExecutablePath(0, &size); - result.len = size; - result.ptr = oc_arena_push_array(arena, char, result.len+1); - _NSGetExecutablePath(result.ptr, &size); - result.ptr[result.len] = '\0'; - return(result); -}} +{ + @autoreleasepool + { + oc_str8 result = {}; + u32 size = 0; + _NSGetExecutablePath(0, &size); + result.len = size; + result.ptr = oc_arena_push_array(arena, char, result.len + 1); + _NSGetExecutablePath(result.ptr, &size); + result.ptr[result.len] = '\0'; + return (result); + } +} oc_str8 oc_path_canonical(oc_arena* arena, oc_str8 path) { - oc_arena_scope scratch = oc_scratch_begin_next(arena); - char* pathCString = oc_str8_to_cstring(scratch.arena, path); + oc_arena_scope scratch = oc_scratch_begin_next(arena); + char* pathCString = oc_str8_to_cstring(scratch.arena, path); - char* real = realpath(pathCString, 0); - oc_str8 result = oc_str8_push_cstring(arena, real); + char* real = realpath(pathCString, 0); + oc_str8 result = oc_str8_push_cstring(arena, real); - free(real); - oc_scratch_end(scratch); + free(real); + oc_scratch_end(scratch); - return(result); + return (result); } diff --git a/src/platform/platform.h b/src/platform/platform.h index 3fce607..ecbb347 100644 --- a/src/platform/platform.h +++ b/src/platform/platform.h @@ -14,98 +14,98 @@ // Compiler identification //----------------------------------------------------------------- #if defined(__clang__) - #define OC_COMPILER_CLANG 1 - #if defined(__apple_build_version__) - #define OC_COMPILER_CLANG_APPLE 1 - #elif defined(_MSC_VER) - #define OC_COMPILER_CLANG_CL 1 - #endif + #define OC_COMPILER_CLANG 1 + #if defined(__apple_build_version__) + #define OC_COMPILER_CLANG_APPLE 1 + #elif defined(_MSC_VER) + #define OC_COMPILER_CLANG_CL 1 + #endif #elif defined(_MSC_VER) - #define OC_COMPILER_CL 1 + #define OC_COMPILER_CL 1 #elif defined(__GNUC__) - #define OC_COMPILER_GCC 1 + #define OC_COMPILER_GCC 1 #else - #error "Can't identify compiler" + #error "Can't identify compiler" #endif //----------------------------------------------------------------- // OS identification //----------------------------------------------------------------- #if defined(_WIN64) - #define OC_PLATFORM_WINDOWS 1 + #define OC_PLATFORM_WINDOWS 1 #elif defined(_WIN32) - #error "Unsupported OS (32bit only version of Windows)" + #error "Unsupported OS (32bit only version of Windows)" #elif defined(__APPLE__) && defined(__MACH__) - #define OC_PLATFORM_MACOS 1 + #define OC_PLATFORM_MACOS 1 #elif defined(__gnu_linux__) - #define PLATFORM_LINUX 1 + #define PLATFORM_LINUX 1 #elif defined(__ORCA__) - #define OC_PLATFORM_ORCA 1 + #define OC_PLATFORM_ORCA 1 #else - #error "Can't identify platform" + #error "Can't identify platform" #endif //----------------------------------------------------------------- // Architecture identification //----------------------------------------------------------------- #if defined(OC_COMPILER_CL) - #if defined(_M_AMD64) - #define OC_ARCH_X64 1 - #elif defined(_M_I86) - #define OC_ARCH_X86 1 - #elif defined(_M_ARM64) - #define OC_ARCH_ARM64 1 - #elif defined(_M_ARM) - #define OC_ARCH_ARM32 1 - #else - #error "Can't identify architecture" - #endif + #if defined(_M_AMD64) + #define OC_ARCH_X64 1 + #elif defined(_M_I86) + #define OC_ARCH_X86 1 + #elif defined(_M_ARM64) + #define OC_ARCH_ARM64 1 + #elif defined(_M_ARM) + #define OC_ARCH_ARM32 1 + #else + #error "Can't identify architecture" + #endif #else - #if defined(__x86_64__) - #define OC_ARCH_X64 1 - #elif defined(__i386__) - #define OC_ARCH_X86 1 - #elif defined(__arm__) - #define OC_ARCH_ARM32 1 - #elif defined(__aarch64__) - #define OC_ARCH_ARM64 1 - #elif defined(__ORCA__) - #define OC_ARCH_WASM32 1 - #else - #error "Can't identify architecture" - #endif + #if defined(__x86_64__) + #define OC_ARCH_X64 1 + #elif defined(__i386__) + #define OC_ARCH_X86 1 + #elif defined(__arm__) + #define OC_ARCH_ARM32 1 + #elif defined(__aarch64__) + #define OC_ARCH_ARM64 1 + #elif defined(__ORCA__) + #define OC_ARCH_WASM32 1 + #else + #error "Can't identify architecture" + #endif #endif //----------------------------------------------------------------- // platform helper macros //----------------------------------------------------------------- #if defined(OC_COMPILER_CL) - #if defined(OC_BUILD_DLL) - #define ORCA_API __declspec(dllexport) - #else - #define ORCA_API __declspec(dllimport) - #endif + #if defined(OC_BUILD_DLL) + #define ORCA_API __declspec(dllexport) + #else + #define ORCA_API __declspec(dllimport) + #endif #elif defined(OC_COMPILER_GCC) || defined(OC_COMPILER_CLANG) - #define ORCA_API + #define ORCA_API #endif #if OC_PLATFORM_ORCA - #define oc_thread_local // no tls (or threads) for now on wasm orca + #define oc_thread_local // no tls (or threads) for now on wasm orca #elif defined(OC_COMPILER_CL) - #define oc_thread_local __declspec(thread) + #define oc_thread_local __declspec(thread) #elif defined(OC_COMPILER_GCC) || defined(OC_COMPILER_CLANG) - #define oc_thread_local __thread + #define oc_thread_local __thread #endif #if OC_PLATFORM_ORCA - #define ORCA_IMPORT(f) __attribute__((import_name(#f))) f + #define ORCA_IMPORT(f) __attribute__((import_name(#f))) f - #if OC_COMPILER_CLANG - #define ORCA_EXPORT __attribute__((visibility("default"))) - #else - #error "Orca apps can only be compiled with clang for now" - #endif + #if OC_COMPILER_CLANG + #define ORCA_EXPORT __attribute__((visibility("default"))) + #else + #error "Orca apps can only be compiled with clang for now" + #endif #endif #endif // __PLATFORM_H_ diff --git a/src/platform/platform_clock.h b/src/platform/platform_clock.h index 0ef8b9b..f5942e9 100644 --- a/src/platform/platform_clock.h +++ b/src/platform/platform_clock.h @@ -1,34 +1,35 @@ -/************************************************************//** +/************************************************************/ /** * * @file: platform_clock.h * @author: Martin Fouilleul * @date: 07/03/2019 * @revision: * -*****************************************************************/ -#ifndef __PLATFORM_CLOCK_H_ -#define __PLATFORM_CLOCK_H_ - -#include"util/typedefs.h" -#include"platform.h" - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -typedef enum { - OC_CLOCK_MONOTONIC, // clock that increment monotonically - OC_CLOCK_UPTIME, // clock that increment monotonically during uptime - OC_CLOCK_DATE // clock that is driven by the platform time -} oc_clock_kind; - -ORCA_API void oc_clock_init(); // initialize the clock subsystem -ORCA_API u64 oc_clock_timestamp(oc_clock_kind clock); -ORCA_API f64 oc_clock_time(oc_clock_kind clock); - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus - - -#endif //__PLATFORM_CLOCK_H_ +*****************************************************************/ +#ifndef __PLATFORM_CLOCK_H_ +#define __PLATFORM_CLOCK_H_ + +#include "platform.h" +#include "util/typedefs.h" + +#ifdef __cplusplus +extern "C" +{ +#endif // __cplusplus + + typedef enum + { + OC_CLOCK_MONOTONIC, // clock that increment monotonically + OC_CLOCK_UPTIME, // clock that increment monotonically during uptime + OC_CLOCK_DATE // clock that is driven by the platform time + } oc_clock_kind; + + ORCA_API void oc_clock_init(); // initialize the clock subsystem + ORCA_API u64 oc_clock_timestamp(oc_clock_kind clock); + ORCA_API f64 oc_clock_time(oc_clock_kind clock); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +#endif //__PLATFORM_CLOCK_H_ diff --git a/src/platform/platform_debug.c b/src/platform/platform_debug.c index 99dda95..b8c019d 100644 --- a/src/platform/platform_debug.c +++ b/src/platform/platform_debug.c @@ -1,29 +1,29 @@ -/************************************************************//** +/************************************************************/ /** * * @file: platform_log.c * @author: Martin Fouilleul * @date: 18/04/2023 * *****************************************************************/ -#include"platform_debug.h" +#include "platform_debug.h" typedef struct oc_log_config { - oc_log_output* output; - oc_log_level level; + oc_log_output* output; + oc_log_level level; } oc_log_config; //TODO: make default output a compile-time constant to avoid check in oc_log_ext()? -static oc_log_config __logConfig = {0, OC_LOG_LEVEL_INFO}; +static oc_log_config __logConfig = { 0, OC_LOG_LEVEL_INFO }; void oc_log_set_output(oc_log_output* output) { - __logConfig.output = output; + __logConfig.output = output; } void oc_log_set_level(oc_log_level level) { - __logConfig.level = level; + __logConfig.level = level; } void platform_log_push(oc_log_output* output, @@ -35,22 +35,22 @@ void platform_log_push(oc_log_output* output, va_list ap); void oc_log_ext(oc_log_level level, - const char* function, - const char* file, - int line, - const char* fmt, - ...) + const char* function, + const char* file, + int line, + const char* fmt, + ...) { - if(!__logConfig.output) - { - __logConfig.output = OC_LOG_DEFAULT_OUTPUT; - } + if(!__logConfig.output) + { + __logConfig.output = OC_LOG_DEFAULT_OUTPUT; + } - if(level <= __logConfig.level) - { - va_list ap; - va_start(ap, fmt); - platform_log_push(__logConfig.output, level, file, function, line, fmt, ap); - va_end(ap); - } + if(level <= __logConfig.level) + { + va_list ap; + va_start(ap, fmt); + platform_log_push(__logConfig.output, level, file, function, line, fmt, ap); + va_end(ap); + } } diff --git a/src/platform/platform_debug.h b/src/platform/platform_debug.h index 1b81fd0..8e63158 100644 --- a/src/platform/platform_debug.h +++ b/src/platform/platform_debug.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: platform_debug.h * @author: Martin Fouilleul @@ -8,7 +8,7 @@ #ifndef __PLATFORM_DEBUG_H_ #define __PLATFORM_DEBUG_H_ -#include"platform.h" +#include "platform.h" //---------------------------------------------------------------- // Assert / Abort @@ -21,10 +21,13 @@ ORCA_API _Noreturn void oc_assert_fail(const char* file, const char* function, i // Logging //---------------------------------------------------------------- -typedef enum { OC_LOG_LEVEL_ERROR, - OC_LOG_LEVEL_WARNING, - OC_LOG_LEVEL_INFO, - OC_LOG_LEVEL_COUNT } oc_log_level; +typedef enum +{ + OC_LOG_LEVEL_ERROR, + OC_LOG_LEVEL_WARNING, + OC_LOG_LEVEL_INFO, + OC_LOG_LEVEL_COUNT +} oc_log_level; typedef struct oc_log_output oc_log_output; @@ -33,11 +36,10 @@ extern oc_log_output* OC_LOG_DEFAULT_OUTPUT; ORCA_API void oc_log_set_level(oc_log_level level); ORCA_API void oc_log_set_output(oc_log_output* output); ORCA_API void oc_log_ext(oc_log_level level, - const char* function, - const char* file, - int line, - const char* fmt, - ...); - + const char* function, + const char* file, + int line, + const char* fmt, + ...); #endif //__PLATFORM_DEBUG_H_ diff --git a/src/platform/platform_io.h b/src/platform/platform_io.h index e92ac5e..b5403a5 100644 --- a/src/platform/platform_io.h +++ b/src/platform/platform_io.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: platform_io.h * @author: Martin Fouilleul @@ -8,127 +8,140 @@ #ifndef __PLATFORM_IO_H_ #define __PLATFORM_IO_H_ -#include"util/typedefs.h" -#include"util/strings.h" +#include "util/strings.h" +#include "util/typedefs.h" //---------------------------------------------------------------- // IO API //---------------------------------------------------------------- -typedef struct { u64 h; } oc_file; +typedef struct +{ + u64 h; +} oc_file; typedef u16 oc_file_open_flags; + enum oc_file_open_flags_enum { - OC_FILE_OPEN_NONE = 0, - OC_FILE_OPEN_APPEND = 1<<1, - OC_FILE_OPEN_TRUNCATE = 1<<2, - OC_FILE_OPEN_CREATE = 1<<3, + OC_FILE_OPEN_NONE = 0, + OC_FILE_OPEN_APPEND = 1 << 1, + OC_FILE_OPEN_TRUNCATE = 1 << 2, + OC_FILE_OPEN_CREATE = 1 << 3, - OC_FILE_OPEN_SYMLINK = 1<<4, - OC_FILE_OPEN_NO_FOLLOW = 1<<5, - OC_FILE_OPEN_RESTRICT = 1<<6, - //... + OC_FILE_OPEN_SYMLINK = 1 << 4, + OC_FILE_OPEN_NO_FOLLOW = 1 << 5, + OC_FILE_OPEN_RESTRICT = 1 << 6, + //... }; typedef u16 oc_file_access; + enum oc_file_access_enum { - OC_FILE_ACCESS_NONE = 0, - OC_FILE_ACCESS_READ = 1<<1, - OC_FILE_ACCESS_WRITE = 1<<2, + OC_FILE_ACCESS_NONE = 0, + OC_FILE_ACCESS_READ = 1 << 1, + OC_FILE_ACCESS_WRITE = 1 << 2, }; - -typedef enum { OC_FILE_SEEK_SET, OC_FILE_SEEK_END, OC_FILE_SEEK_CURRENT } oc_file_whence; +typedef enum +{ + OC_FILE_SEEK_SET, + OC_FILE_SEEK_END, + OC_FILE_SEEK_CURRENT +} oc_file_whence; typedef u64 oc_io_req_id; typedef u32 oc_io_op; + enum oc_io_op_enum { - OC_IO_OPEN_AT = 0, - OC_IO_CLOSE, + OC_IO_OPEN_AT = 0, + OC_IO_CLOSE, - OC_IO_FSTAT, + OC_IO_FSTAT, - OC_IO_SEEK, - OC_IO_READ, - OC_IO_WRITE, + OC_IO_SEEK, + OC_IO_READ, + OC_IO_WRITE, - OC_OC_IO_ERROR, - //... + OC_OC_IO_ERROR, + //... }; typedef struct oc_io_req { - oc_io_req_id id; - oc_io_op op; - oc_file handle; + oc_io_req_id id; + oc_io_op op; + oc_file handle; - i64 offset; - u64 size; - union - { - char* buffer; - u64 unused; // This is a horrible hack to get the same layout on wasm and on host - }; + i64 offset; + u64 size; - union - { - struct - { - oc_file_access rights; - oc_file_open_flags flags; - } open; + union + { + char* buffer; + u64 unused; // This is a horrible hack to get the same layout on wasm and on host + }; - oc_file_whence whence; - }; + union + { + struct + { + oc_file_access rights; + oc_file_open_flags flags; + } open; + + oc_file_whence whence; + }; } oc_io_req; typedef i32 oc_io_error; -enum oc_io_error_enum { - OC_IO_OK = 0, - OC_IO_ERR_UNKNOWN, - OC_IO_ERR_OP, // unsupported operation - OC_IO_ERR_HANDLE, // invalid handle - OC_IO_ERR_PREV, // previously had a fatal error (last error stored on handle) - OC_IO_ERR_ARG, // invalid argument or argument combination - OC_IO_ERR_PERM, // access denied - OC_IO_ERR_SPACE, // no space left - OC_IO_ERR_NO_ENTRY, // file or directory does not exist - OC_IO_ERR_EXISTS, // file already exists - OC_IO_ERR_NOT_DIR, // path element is not a directory - OC_IO_ERR_DIR, // attempted to write directory - OC_IO_ERR_MAX_FILES, // max open files reached - OC_IO_ERR_MAX_LINKS, // too many symbolic links in path - OC_IO_ERR_PATH_LENGTH, // path too long - OC_IO_ERR_FILE_SIZE, // file too big - OC_IO_ERR_OVERFLOW, // offset too big - OC_IO_ERR_NOT_READY, // no data ready to be read/written - OC_IO_ERR_MEM, // failed to allocate memory - OC_IO_ERR_INTERRUPT, // operation interrupted by a signal - OC_IO_ERR_PHYSICAL, // physical IO error - OC_IO_ERR_NO_DEVICE, // device not found - OC_IO_ERR_WALKOUT, // attempted to walk out of root directory - //... +enum oc_io_error_enum +{ + OC_IO_OK = 0, + OC_IO_ERR_UNKNOWN, + OC_IO_ERR_OP, // unsupported operation + OC_IO_ERR_HANDLE, // invalid handle + OC_IO_ERR_PREV, // previously had a fatal error (last error stored on handle) + OC_IO_ERR_ARG, // invalid argument or argument combination + OC_IO_ERR_PERM, // access denied + OC_IO_ERR_SPACE, // no space left + OC_IO_ERR_NO_ENTRY, // file or directory does not exist + OC_IO_ERR_EXISTS, // file already exists + OC_IO_ERR_NOT_DIR, // path element is not a directory + OC_IO_ERR_DIR, // attempted to write directory + OC_IO_ERR_MAX_FILES, // max open files reached + OC_IO_ERR_MAX_LINKS, // too many symbolic links in path + OC_IO_ERR_PATH_LENGTH, // path too long + OC_IO_ERR_FILE_SIZE, // file too big + OC_IO_ERR_OVERFLOW, // offset too big + OC_IO_ERR_NOT_READY, // no data ready to be read/written + OC_IO_ERR_MEM, // failed to allocate memory + OC_IO_ERR_INTERRUPT, // operation interrupted by a signal + OC_IO_ERR_PHYSICAL, // physical IO error + OC_IO_ERR_NO_DEVICE, // device not found + OC_IO_ERR_WALKOUT, // attempted to walk out of root directory + + //... }; typedef struct oc_io_cmp { - oc_io_req_id id; - oc_io_error error; + oc_io_req_id id; + oc_io_error error; - union - { - i64 result; - u64 size; - i64 offset; - oc_file handle; - //... - }; + union + { + i64 result; + u64 size; + i64 offset; + oc_file handle; + //... + }; } oc_io_cmp; //---------------------------------------------------------------- @@ -161,45 +174,46 @@ ORCA_API oc_io_error oc_file_last_error(oc_file handle); typedef enum oc_file_type { - OC_FILE_UNKNOWN, - OC_FILE_REGULAR, - OC_FILE_DIRECTORY, - OC_FILE_SYMLINK, - OC_FILE_BLOCK, - OC_FILE_CHARACTER, - OC_FILE_FIFO, - OC_FILE_SOCKET, + OC_FILE_UNKNOWN, + OC_FILE_REGULAR, + OC_FILE_DIRECTORY, + OC_FILE_SYMLINK, + OC_FILE_BLOCK, + OC_FILE_CHARACTER, + OC_FILE_FIFO, + OC_FILE_SOCKET, } oc_file_type; typedef u16 oc_file_perm; + enum oc_file_perm { - OC_FILE_OTHER_EXEC = 1<<0, - OC_FILE_OTHER_WRITE = 1<<1, - OC_FILE_OTHER_READ = 1<<2, + OC_FILE_OTHER_EXEC = 1 << 0, + OC_FILE_OTHER_WRITE = 1 << 1, + OC_FILE_OTHER_READ = 1 << 2, - OC_FILE_GROUP_EXEC = 1<<3, - OC_FILE_GROUP_WRITE = 1<<4, - OC_FILE_GROUP_READ = 1<<5, + OC_FILE_GROUP_EXEC = 1 << 3, + OC_FILE_GROUP_WRITE = 1 << 4, + OC_FILE_GROUP_READ = 1 << 5, - OC_FILE_OWNER_EXEC = 1<<6, - OC_FILE_OWNER_WRITE = 1<<7, - OC_FILE_OWNER_READ = 1<<8, + OC_FILE_OWNER_EXEC = 1 << 6, + OC_FILE_OWNER_WRITE = 1 << 7, + OC_FILE_OWNER_READ = 1 << 8, - OC_FILE_STICKY_BIT = 1<<9, - OC_FILE_SET_GID = 1<<10, - OC_FILE_SET_UID = 1<<11, + OC_FILE_STICKY_BIT = 1 << 9, + OC_FILE_SET_GID = 1 << 10, + OC_FILE_SET_UID = 1 << 11, }; typedef struct oc_file_status { - u64 uid; - oc_file_type type; - oc_file_perm perm; - u64 size; + u64 uid; + oc_file_type type; + oc_file_perm perm; + u64 size; - //TODO times + //TODO times } oc_file_status; @@ -208,5 +222,4 @@ ORCA_API u64 oc_file_size(oc_file file); //TODO: Complete as needed... - #endif //__PLATFORM_IO_H_ diff --git a/src/platform/platform_io_common.c b/src/platform/platform_io_common.c index 7d2e1d0..4d1141b 100644 --- a/src/platform/platform_io_common.c +++ b/src/platform/platform_io_common.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: platform_io_common.c * @author: Martin Fouilleul @@ -6,117 +6,120 @@ * *****************************************************************/ -#include"platform_io.h" +#include "platform_io.h" + //------------------------------------------------------------------------------ // File stream read/write API //------------------------------------------------------------------------------ oc_file oc_file_nil() { - return((oc_file){0}); + return ((oc_file){ 0 }); } bool oc_file_is_nil(oc_file handle) { - return(handle.h == 0); + return (handle.h == 0); } oc_file oc_file_open(oc_str8 path, oc_file_access rights, oc_file_open_flags flags) { - oc_io_req req = {.op = OC_IO_OPEN_AT, - .size = path.len, - .buffer = path.ptr, - .open.rights = rights, - .open.flags = flags }; + oc_io_req req = { .op = OC_IO_OPEN_AT, + .size = path.len, + .buffer = path.ptr, + .open.rights = rights, + .open.flags = flags }; - oc_io_cmp cmp = oc_io_wait_single_req(&req); + oc_io_cmp cmp = oc_io_wait_single_req(&req); - //WARN: we always return a handle that can be queried for errors. Handles must be closed - // even if there was an error when opening - return(cmp.handle); + //WARN: we always return a handle that can be queried for errors. Handles must be closed + // even if there was an error when opening + return (cmp.handle); } oc_file oc_file_open_at(oc_file dir, oc_str8 path, oc_file_access rights, oc_file_open_flags flags) { - oc_io_req req = {.op = OC_IO_OPEN_AT, - .handle = dir, - .size = path.len, - .buffer = path.ptr, - .open.rights = rights, - .open.flags = flags,}; + oc_io_req req = { + .op = OC_IO_OPEN_AT, + .handle = dir, + .size = path.len, + .buffer = path.ptr, + .open.rights = rights, + .open.flags = flags, + }; - oc_io_cmp cmp = oc_io_wait_single_req(&req); - return(cmp.handle); + oc_io_cmp cmp = oc_io_wait_single_req(&req); + return (cmp.handle); } void oc_file_close(oc_file file) { - oc_io_req req = {.op = OC_IO_CLOSE, - .handle = file}; - oc_io_wait_single_req(&req); + oc_io_req req = { .op = OC_IO_CLOSE, + .handle = file }; + oc_io_wait_single_req(&req); } i64 oc_file_seek(oc_file file, i64 offset, oc_file_whence whence) { - oc_io_req req = {.op = OC_IO_SEEK, - .handle = file, - .offset = offset, - .whence = whence}; + oc_io_req req = { .op = OC_IO_SEEK, + .handle = file, + .offset = offset, + .whence = whence }; - oc_io_cmp cmp = oc_io_wait_single_req(&req); - return(cmp.offset); + oc_io_cmp cmp = oc_io_wait_single_req(&req); + return (cmp.offset); } i64 oc_file_pos(oc_file file) { - return(oc_file_seek(file, 0, OC_FILE_SEEK_CURRENT)); + return (oc_file_seek(file, 0, OC_FILE_SEEK_CURRENT)); } u64 oc_file_write(oc_file file, u64 size, char* buffer) { - oc_io_req req = {.op = OC_IO_WRITE, - .handle = file, - .size = size, - .buffer = buffer}; + oc_io_req req = { .op = OC_IO_WRITE, + .handle = file, + .size = size, + .buffer = buffer }; - oc_io_cmp cmp = oc_io_wait_single_req(&req); - return(cmp.size); + oc_io_cmp cmp = oc_io_wait_single_req(&req); + return (cmp.size); } u64 oc_file_read(oc_file file, u64 size, char* buffer) { - oc_io_req req = {.op = OC_IO_READ, - .handle = file, - .size = size, - .buffer = buffer}; + oc_io_req req = { .op = OC_IO_READ, + .handle = file, + .size = size, + .buffer = buffer }; - oc_io_cmp cmp = oc_io_wait_single_req(&req); - return(cmp.size); + oc_io_cmp cmp = oc_io_wait_single_req(&req); + return (cmp.size); } oc_io_error oc_file_last_error(oc_file file) { - oc_io_req req = {.op = OC_OC_IO_ERROR, - .handle = file}; + oc_io_req req = { .op = OC_OC_IO_ERROR, + .handle = file }; - oc_io_cmp cmp = oc_io_wait_single_req(&req); - return((oc_io_error)cmp.result); + oc_io_cmp cmp = oc_io_wait_single_req(&req); + return ((oc_io_error)cmp.result); } oc_file_status oc_file_get_status(oc_file file) { - oc_file_status status = {0}; - oc_io_req req = {.op = OC_IO_FSTAT, - .handle = file, - .size = sizeof(oc_file_status), - .buffer = (char*)&status}; + oc_file_status status = { 0 }; + oc_io_req req = { .op = OC_IO_FSTAT, + .handle = file, + .size = sizeof(oc_file_status), + .buffer = (char*)&status }; - oc_io_cmp cmp = oc_io_wait_single_req(&req); - return(status); + oc_io_cmp cmp = oc_io_wait_single_req(&req); + return (status); } u64 oc_file_size(oc_file file) { - oc_file_status status = oc_file_get_status(file); - return(status.size); + oc_file_status status = oc_file_get_status(file); + return (status.size); } diff --git a/src/platform/platform_io_internal.c b/src/platform/platform_io_internal.c index 1450e15..9f922c0 100644 --- a/src/platform/platform_io_internal.c +++ b/src/platform/platform_io_internal.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: platform_io_internal.c * @author: Martin Fouilleul @@ -6,63 +6,63 @@ * *****************************************************************/ -#include"platform_io_internal.h" -#include"platform_path.h" +#include "platform_io_internal.h" +#include "platform_path.h" -oc_file_table oc_globalFileTable = {0}; +oc_file_table oc_globalFileTable = { 0 }; oc_file_slot* oc_file_slot_alloc(oc_file_table* table) { - oc_file_slot* slot = oc_list_pop_entry(&table->freeList, oc_file_slot, freeListElt); - if(!slot && table->nextSlot < OC_IO_MAX_FILE_SLOTS) - { - slot = &table->slots[table->nextSlot]; - slot->generation = 1; - table->nextSlot++; - } + oc_file_slot* slot = oc_list_pop_entry(&table->freeList, oc_file_slot, freeListElt); + if(!slot && table->nextSlot < OC_IO_MAX_FILE_SLOTS) + { + slot = &table->slots[table->nextSlot]; + slot->generation = 1; + table->nextSlot++; + } - u32 tmpGeneration = slot->generation; - memset(slot, 0, sizeof(oc_file_slot)); - slot->generation = tmpGeneration; + u32 tmpGeneration = slot->generation; + memset(slot, 0, sizeof(oc_file_slot)); + slot->generation = tmpGeneration; - return(slot); + return (slot); } void oc_file_slot_recycle(oc_file_table* table, oc_file_slot* slot) { - slot->generation++; - oc_list_push(&table->freeList, &slot->freeListElt); + slot->generation++; + oc_list_push(&table->freeList, &slot->freeListElt); } oc_file oc_file_from_slot(oc_file_table* table, oc_file_slot* slot) { - u64 index = slot - table->slots; - u64 generation = slot->generation; - oc_file handle = {.h = (generation<<32) | index }; - return(handle); + u64 index = slot - table->slots; + u64 generation = slot->generation; + oc_file handle = { .h = (generation << 32) | index }; + return (handle); } oc_file_slot* oc_file_slot_from_handle(oc_file_table* table, oc_file handle) { - oc_file_slot* slot = 0; + oc_file_slot* slot = 0; - u64 index = handle.h & 0xffffffff; - u64 generation = handle.h>>32; + u64 index = handle.h & 0xffffffff; + u64 generation = handle.h >> 32; - if(index < table->nextSlot) - { - oc_file_slot* candidate = &table->slots[index]; - if(candidate->generation == generation) - { - slot = candidate; - } - } - return(slot); + if(index < table->nextSlot) + { + oc_file_slot* candidate = &table->slots[index]; + if(candidate->generation == generation) + { + slot = candidate; + } + } + return (slot); } oc_io_cmp oc_io_wait_single_req(oc_io_req* req) { - return(oc_io_wait_single_req_with_table(req, &oc_globalFileTable)); + return (oc_io_wait_single_req_with_table(req, &oc_globalFileTable)); } //----------------------------------------------------------------------- @@ -71,275 +71,273 @@ oc_io_cmp oc_io_wait_single_req(oc_io_req* req) typedef struct oc_io_open_restrict_context { - oc_io_error error; - u64 rootUID; - oc_file_desc rootFd; - oc_file_desc fd; + oc_io_error error; + u64 rootUID; + oc_file_desc rootFd; + oc_file_desc fd; } oc_io_open_restrict_context; oc_io_error oc_io_open_restrict_enter(oc_io_open_restrict_context* context, oc_str8 name, oc_file_access accessRights, oc_file_open_flags openFlags) { - oc_file_desc nextFd = oc_io_raw_open_at(context->fd, name, accessRights, openFlags); - if(oc_file_desc_is_nil(nextFd)) - { - context->error = oc_io_raw_last_error(); - } - else - { - if(context->fd != context->rootFd) - { - oc_io_raw_close(context->fd); - } - context->fd = nextFd; - } - return(context->error); + oc_file_desc nextFd = oc_io_raw_open_at(context->fd, name, accessRights, openFlags); + if(oc_file_desc_is_nil(nextFd)) + { + context->error = oc_io_raw_last_error(); + } + else + { + if(context->fd != context->rootFd) + { + oc_io_raw_close(context->fd); + } + context->fd = nextFd; + } + return (context->error); } typedef struct oc_io_open_restrict_result { - oc_io_error error; - oc_file_desc fd; + oc_io_error error; + oc_file_desc fd; } oc_io_open_restrict_result; - oc_io_open_restrict_result oc_io_open_restrict(oc_file_desc dirFd, oc_str8 path, oc_file_access accessRights, oc_file_open_flags openFlags) { - oc_arena_scope scratch = oc_scratch_begin(); + oc_arena_scope scratch = oc_scratch_begin(); - oc_str8_list sep = {0}; - oc_str8_list_push(scratch.arena, &sep, OC_STR8("/")); - oc_str8_list_push(scratch.arena, &sep, OC_STR8("\\")); - oc_str8_list pathElements = oc_str8_split(scratch.arena, path, sep); + oc_str8_list sep = { 0 }; + oc_str8_list_push(scratch.arena, &sep, OC_STR8("/")); + oc_str8_list_push(scratch.arena, &sep, OC_STR8("\\")); + oc_str8_list pathElements = oc_str8_split(scratch.arena, path, sep); - oc_io_open_restrict_context context = { - .error = OC_IO_OK, - .rootFd = dirFd, - .fd = dirFd, - }; + oc_io_open_restrict_context context = { + .error = OC_IO_OK, + .rootFd = dirFd, + .fd = dirFd, + }; - if(oc_file_desc_is_nil(dirFd)) - { - context.error = OC_IO_ERR_HANDLE; - } - else - { - oc_file_status status; - context.error = oc_io_raw_fstat(dirFd, &status); - context.rootUID = status.uid; - } + if(oc_file_desc_is_nil(dirFd)) + { + context.error = OC_IO_ERR_HANDLE; + } + else + { + oc_file_status status; + context.error = oc_io_raw_fstat(dirFd, &status); + context.rootUID = status.uid; + } - if(context.error == OC_IO_OK) - { - oc_list_for(&pathElements.list, elt, oc_str8_elt, listElt) - { - oc_str8 name = elt->string; - oc_file_access eltAccessRights = OC_FILE_ACCESS_READ; - oc_file_open_flags eltOpenFlags = 0; + if(context.error == OC_IO_OK) + { + oc_list_for(&pathElements.list, elt, oc_str8_elt, listElt) + { + oc_str8 name = elt->string; + oc_file_access eltAccessRights = OC_FILE_ACCESS_READ; + oc_file_open_flags eltOpenFlags = 0; - bool atLastElement = (&elt->listElt == oc_list_last(&pathElements.list)); - if(atLastElement) - { - eltAccessRights = accessRights; - eltOpenFlags = openFlags; - } + bool atLastElement = (&elt->listElt == oc_list_last(&pathElements.list)); + if(atLastElement) + { + eltAccessRights = accessRights; + eltOpenFlags = openFlags; + } - if( !oc_str8_cmp(name, OC_STR8(".")) - && !atLastElement) - { - //NOTE: if we're not at the last element we can just skip '.' elements - continue; - } - else if(!oc_str8_cmp(name, OC_STR8(".."))) - { - //NOTE: check that we don't escape root dir - oc_file_status status; - context.error = oc_io_raw_fstat(context.fd, &status); - if(context.error) - { - break; - } - else if(status.uid == context.rootUID) - { - context.error = OC_IO_ERR_WALKOUT; - break; - } - } - else if(!oc_io_raw_file_exists_at(context.fd, name, OC_FILE_OPEN_SYMLINK)) - { - //NOTE: if the file doesn't exists, but we're at the last element and OC_FILE_OPEN_CREATE - // is set, we create the file. Otherwise it is a OC_IO_ERROR_NO_ENTRY error. - if( !atLastElement - || !(openFlags & OC_FILE_OPEN_CREATE)) - { - context.error = OC_IO_ERR_NO_ENTRY; - break; - } - } - else - { - //NOTE: if the file exists, we check the type of file - oc_file_status status = {0}; - context.error = oc_io_raw_fstat_at(context.fd, name, OC_FILE_OPEN_SYMLINK, &status); - if(context.error) - { - break; - } + if(!oc_str8_cmp(name, OC_STR8(".")) + && !atLastElement) + { + //NOTE: if we're not at the last element we can just skip '.' elements + continue; + } + else if(!oc_str8_cmp(name, OC_STR8(".."))) + { + //NOTE: check that we don't escape root dir + oc_file_status status; + context.error = oc_io_raw_fstat(context.fd, &status); + if(context.error) + { + break; + } + else if(status.uid == context.rootUID) + { + context.error = OC_IO_ERR_WALKOUT; + break; + } + } + else if(!oc_io_raw_file_exists_at(context.fd, name, OC_FILE_OPEN_SYMLINK)) + { + //NOTE: if the file doesn't exists, but we're at the last element and OC_FILE_OPEN_CREATE + // is set, we create the file. Otherwise it is a OC_IO_ERROR_NO_ENTRY error. + if(!atLastElement + || !(openFlags & OC_FILE_OPEN_CREATE)) + { + context.error = OC_IO_ERR_NO_ENTRY; + break; + } + } + else + { + //NOTE: if the file exists, we check the type of file + oc_file_status status = { 0 }; + context.error = oc_io_raw_fstat_at(context.fd, name, OC_FILE_OPEN_SYMLINK, &status); + if(context.error) + { + break; + } - if(status.type == OC_FILE_REGULAR) - { - if(!atLastElement) - { - context.error = OC_IO_ERR_NOT_DIR; - break; - } - } - else if(status.type == OC_FILE_SYMLINK) - { - //TODO - do we need a OC_FILE_OPEN_NO_FOLLOW that fails if last element is a symlink? - // - do we need a OC_FILE_OPEN_NO_SYMLINKS that fails if _any_ element is a symlink? + if(status.type == OC_FILE_REGULAR) + { + if(!atLastElement) + { + context.error = OC_IO_ERR_NOT_DIR; + break; + } + } + else if(status.type == OC_FILE_SYMLINK) + { + //TODO - do we need a OC_FILE_OPEN_NO_FOLLOW that fails if last element is a symlink? + // - do we need a OC_FILE_OPEN_NO_SYMLINKS that fails if _any_ element is a symlink? - if( !atLastElement - || !(openFlags & OC_FILE_OPEN_SYMLINK)) - { - oc_io_raw_read_link_result link = oc_io_raw_read_link_at(scratch.arena, context.fd, name); - if(link.error) - { - context.error = link.error; - break; - } - if(link.target.len == 0) - { - //NOTE: treat an empty target as a '.' - link.target = OC_STR8("."); - } - else if(oc_path_is_absolute(link.target)) - { - context.error = OC_IO_ERR_WALKOUT; - break; - } + if(!atLastElement + || !(openFlags & OC_FILE_OPEN_SYMLINK)) + { + oc_io_raw_read_link_result link = oc_io_raw_read_link_at(scratch.arena, context.fd, name); + if(link.error) + { + context.error = link.error; + break; + } + if(link.target.len == 0) + { + //NOTE: treat an empty target as a '.' + link.target = OC_STR8("."); + } + else if(oc_path_is_absolute(link.target)) + { + context.error = OC_IO_ERR_WALKOUT; + break; + } - oc_str8_list linkElements = oc_str8_split(scratch.arena, link.target, sep); - if(!oc_list_empty(&linkElements.list)) - { - //NOTE: insert linkElements into pathElements after elt - oc_list_elt* tmp = elt->listElt.next; - elt->listElt.next = linkElements.list.first; - linkElements.list.last->next = tmp; - if(!tmp) - { - pathElements.list.last = linkElements.list.last; - } - } - continue; - } - } - else if(status.type != OC_FILE_DIRECTORY) - { - context.error = OC_IO_ERR_NOT_DIR; - break; - } - } + oc_str8_list linkElements = oc_str8_split(scratch.arena, link.target, sep); + if(!oc_list_empty(&linkElements.list)) + { + //NOTE: insert linkElements into pathElements after elt + oc_list_elt* tmp = elt->listElt.next; + elt->listElt.next = linkElements.list.first; + linkElements.list.last->next = tmp; + if(!tmp) + { + pathElements.list.last = linkElements.list.last; + } + } + continue; + } + } + else if(status.type != OC_FILE_DIRECTORY) + { + context.error = OC_IO_ERR_NOT_DIR; + break; + } + } - //NOTE: if we arrive here, we have no errors and the correct flags are set, - // so we can enter the element - OC_DEBUG_ASSERT(context.error == OC_IO_OK); - oc_io_open_restrict_enter(&context, name, eltAccessRights, eltOpenFlags); - } - } + //NOTE: if we arrive here, we have no errors and the correct flags are set, + // so we can enter the element + OC_DEBUG_ASSERT(context.error == OC_IO_OK); + oc_io_open_restrict_enter(&context, name, eltAccessRights, eltOpenFlags); + } + } - if(context.error && !oc_file_desc_is_nil(context.fd)) - { - if(context.fd != context.rootFd) - { - oc_io_raw_close(context.fd); - } - context.fd = oc_file_desc_nil(); - } + if(context.error && !oc_file_desc_is_nil(context.fd)) + { + if(context.fd != context.rootFd) + { + oc_io_raw_close(context.fd); + } + context.fd = oc_file_desc_nil(); + } - oc_io_open_restrict_result result = { - .error = context.error, - .fd = context.fd - }; + oc_io_open_restrict_result result = { + .error = context.error, + .fd = context.fd + }; - oc_scratch_end(scratch); - return(result); + oc_scratch_end(scratch); + return (result); } oc_io_cmp oc_io_open_at(oc_file_slot* atSlot, oc_io_req* req, oc_file_table* table) { - oc_io_cmp cmp = {0}; + oc_io_cmp cmp = { 0 }; - oc_file_slot* slot = oc_file_slot_alloc(table); - if(!slot) - { - cmp.error = OC_IO_ERR_MAX_FILES; - cmp.result = 0; - } - else - { - slot->fd = oc_file_desc_nil(); - cmp.handle = oc_file_from_slot(table, slot); + oc_file_slot* slot = oc_file_slot_alloc(table); + if(!slot) + { + cmp.error = OC_IO_ERR_MAX_FILES; + cmp.result = 0; + } + else + { + slot->fd = oc_file_desc_nil(); + cmp.handle = oc_file_from_slot(table, slot); + oc_str8 path = oc_str8_from_buffer(req->size, req->buffer); - oc_str8 path = oc_str8_from_buffer(req->size, req->buffer); + if(!path.len) + { + slot->error = OC_IO_ERR_ARG; + } + else if(!atSlot && !oc_file_is_nil(req->handle)) + { + slot->error = OC_IO_ERR_HANDLE; + } + else + { + slot->rights = req->open.rights; + if(atSlot) + { + slot->rights &= atSlot->rights; + } - if(!path.len) - { - slot->error = OC_IO_ERR_ARG; - } - else if(!atSlot && !oc_file_is_nil(req->handle)) - { - slot->error = OC_IO_ERR_HANDLE; - } - else - { - slot->rights = req->open.rights; - if(atSlot) - { - slot->rights &= atSlot->rights; - } + if(slot->rights != req->open.rights) + { + slot->error = OC_IO_ERR_PERM; + } + else + { + oc_file_desc dirFd = atSlot ? atSlot->fd : oc_file_desc_nil(); - if(slot->rights != req->open.rights) - { - slot->error = OC_IO_ERR_PERM; - } - else - { - oc_file_desc dirFd = atSlot ? atSlot->fd : oc_file_desc_nil(); + if(req->open.flags & OC_FILE_OPEN_RESTRICT) + { + oc_io_open_restrict_result res = oc_io_open_restrict(dirFd, path, slot->rights, req->open.flags); + slot->error = res.error; + slot->fd = res.fd; + } + else + { + slot->fd = oc_io_raw_open_at(dirFd, path, slot->rights, req->open.flags); + if(oc_file_desc_is_nil(slot->fd)) + { + slot->error = oc_io_raw_last_error(); + } + } + } + } - if(req->open.flags & OC_FILE_OPEN_RESTRICT) - { - oc_io_open_restrict_result res = oc_io_open_restrict(dirFd, path, slot->rights, req->open.flags); - slot->error = res.error; - slot->fd = res.fd; - } - else - { - slot->fd = oc_io_raw_open_at(dirFd, path, slot->rights, req->open.flags); - if(oc_file_desc_is_nil(slot->fd)) - { - slot->error = oc_io_raw_last_error(); - } - } - } - } + if(slot->error == OC_IO_OK) + { + oc_file_status status; + slot->error = oc_io_raw_fstat(slot->fd, &status); + if(slot->error == OC_IO_OK) + { + slot->type = status.type; + } + } - if(slot->error == OC_IO_OK) - { - oc_file_status status; - slot->error = oc_io_raw_fstat(slot->fd, &status); - if(slot->error == OC_IO_OK) - { - slot->type = status.type; - } - } - - if(slot->error) - { - slot->fatal = true; - cmp.error = slot->error; - } - } - return(cmp); + if(slot->error) + { + slot->fatal = true; + cmp.error = slot->error; + } + } + return (cmp); } diff --git a/src/platform/platform_io_internal.h b/src/platform/platform_io_internal.h index b5e81a9..de20b52 100644 --- a/src/platform/platform_io_internal.h +++ b/src/platform/platform_io_internal.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: platform_io_internal.h * @author: Martin Fouilleul @@ -8,42 +8,42 @@ #ifndef __PLATFORM_IO_INTERNAL_H_ #define __PLATFORM_IO_INTERNAL_H_ -#include"platform_io.h" -#include"platform.h" +#include "platform.h" +#include "platform_io.h" #if OC_PLATFORM_MACOS || PLATFORM_LINUX - typedef int oc_file_desc; +typedef int oc_file_desc; #elif OC_PLATFORM_WINDOWS - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN - #endif - #include - typedef HANDLE oc_file_desc; + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #endif + #include +typedef HANDLE oc_file_desc; #endif typedef struct oc_file_slot { - u32 generation; - oc_io_error error; - bool fatal; - oc_list_elt freeListElt; + u32 generation; + oc_io_error error; + bool fatal; + oc_list_elt freeListElt; - oc_file_type type; - oc_file_access rights; - oc_file_desc fd; + oc_file_type type; + oc_file_access rights; + oc_file_desc fd; } oc_file_slot; enum { - OC_IO_MAX_FILE_SLOTS = 256, + OC_IO_MAX_FILE_SLOTS = 256, }; typedef struct oc_file_table { - oc_file_slot slots[OC_IO_MAX_FILE_SLOTS]; - u32 nextSlot; - oc_list freeList; + oc_file_slot slots[OC_IO_MAX_FILE_SLOTS]; + u32 nextSlot; + oc_list freeList; } oc_file_table; oc_file_slot* oc_file_slot_alloc(oc_file_table* table); @@ -53,7 +53,6 @@ oc_file_slot* oc_file_slot_from_handle(oc_file_table* table, oc_file handle); ORCA_API oc_io_cmp oc_io_wait_single_req_with_table(oc_io_req* req, oc_file_table* table); - //----------------------------------------------------------------------- // raw io primitives //----------------------------------------------------------------------- @@ -81,8 +80,8 @@ oc_io_error oc_io_raw_fstat_at(oc_file_desc dirFd, oc_str8 path, oc_file_open_fl typedef struct oc_io_raw_read_link_result { - oc_io_error error; - oc_str8 target; + oc_io_error error; + oc_str8 target; } oc_io_raw_read_link_result; oc_io_raw_read_link_result oc_io_raw_read_link_at(oc_arena* arena, oc_file_desc dirFd, oc_str8 path); diff --git a/src/platform/platform_memory.h b/src/platform/platform_memory.h index 7c28cfe..1f79883 100644 --- a/src/platform/platform_memory.h +++ b/src/platform/platform_memory.h @@ -1,61 +1,62 @@ -/************************************************************//** +/************************************************************/ /** * * @file: platform_memory.h * @author: Martin Fouilleul * @date: 10/09/2021 * @revision: * -*****************************************************************/ -#ifndef __PLATFORM_MEMORY_H_ -#define __PLATFORM_MEMORY_H_ - -#include"util/typedefs.h" -#include"platform.h" - -#ifdef __cplusplus -extern "C" { -#endif - -//-------------------------------------------------------------------------------- -//NOTE(martin): base allocator -//-------------------------------------------------------------------------------- -typedef struct oc_base_allocator oc_base_allocator; - -typedef void*(*oc_mem_reserve_function)(oc_base_allocator* context, u64 size); -typedef void(*oc_mem_modify_function)(oc_base_allocator* context, void* ptr, u64 size); - -typedef struct oc_base_allocator -{ - oc_mem_reserve_function reserve; - oc_mem_modify_function commit; - oc_mem_modify_function decommit; - oc_mem_modify_function release; - -} oc_base_allocator; - -ORCA_API oc_base_allocator* oc_base_allocator_default(); - -#define oc_base_reserve(base, size) base->reserve(base, size) -#define oc_base_commit(base, ptr, size) base->commit(base, ptr, size) -#define oc_base_decommit(base, ptr, size) base->decommit(base, ptr, size) -#define oc_base_release(base, ptr, size) base->release(base, ptr, size) - -//-------------------------------------------------------------------------------- -//NOTE(martin): malloc/free -//-------------------------------------------------------------------------------- -#include - -#define oc_malloc_type(type) ((type*)malloc(sizeof(type))) -#define oc_malloc_array(type, count) ((type*)malloc(sizeof(type)*count)) - -//-------------------------------------------------------------------------------- -//NOTE(martin): memset / memcpy -//-------------------------------------------------------------------------------- - -#include - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif //__PLATFORM_MEMORY_H_ +*****************************************************************/ +#ifndef __PLATFORM_MEMORY_H_ +#define __PLATFORM_MEMORY_H_ + +#include "platform.h" +#include "util/typedefs.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + //-------------------------------------------------------------------------------- + //NOTE(martin): base allocator + //-------------------------------------------------------------------------------- + typedef struct oc_base_allocator oc_base_allocator; + + typedef void* (*oc_mem_reserve_function)(oc_base_allocator* context, u64 size); + typedef void (*oc_mem_modify_function)(oc_base_allocator* context, void* ptr, u64 size); + + typedef struct oc_base_allocator + { + oc_mem_reserve_function reserve; + oc_mem_modify_function commit; + oc_mem_modify_function decommit; + oc_mem_modify_function release; + + } oc_base_allocator; + + ORCA_API oc_base_allocator* oc_base_allocator_default(); + +#define oc_base_reserve(base, size) base->reserve(base, size) +#define oc_base_commit(base, ptr, size) base->commit(base, ptr, size) +#define oc_base_decommit(base, ptr, size) base->decommit(base, ptr, size) +#define oc_base_release(base, ptr, size) base->release(base, ptr, size) + +//-------------------------------------------------------------------------------- +//NOTE(martin): malloc/free +//-------------------------------------------------------------------------------- +#include + +#define oc_malloc_type(type) ((type*)malloc(sizeof(type))) +#define oc_malloc_array(type, count) ((type*)malloc(sizeof(type) * count)) + + //-------------------------------------------------------------------------------- + //NOTE(martin): memset / memcpy + //-------------------------------------------------------------------------------- + +#include + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif //__PLATFORM_MEMORY_H_ diff --git a/src/platform/platform_path.c b/src/platform/platform_path.c index fdb83d8..ca5643e 100644 --- a/src/platform/platform_path.c +++ b/src/platform/platform_path.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: platform_path.c * @author: Martin Fouilleul @@ -6,100 +6,100 @@ * *****************************************************************/ -#include"platform_path.h" +#include "platform_path.h" oc_str8 oc_path_slice_directory(oc_str8 fullPath) { - i64 lastSlashIndex = -1; + i64 lastSlashIndex = -1; - for(i64 i = fullPath.len-1; i >= 0; i--) - { - if(fullPath.ptr[i] == '/') - { - lastSlashIndex = i; - break; - } - } - oc_str8 directory = oc_str8_slice(fullPath, 0, lastSlashIndex+1); - return(directory); + for(i64 i = fullPath.len - 1; i >= 0; i--) + { + if(fullPath.ptr[i] == '/') + { + lastSlashIndex = i; + break; + } + } + oc_str8 directory = oc_str8_slice(fullPath, 0, lastSlashIndex + 1); + return (directory); } oc_str8 oc_path_slice_filename(oc_str8 fullPath) { - i64 lastSlashIndex = -1; + i64 lastSlashIndex = -1; - for(i64 i = fullPath.len-1; i >= 0; i--) - { - if(fullPath.ptr[i] == '/') - { - lastSlashIndex = i; - break; - } - } + for(i64 i = fullPath.len - 1; i >= 0; i--) + { + if(fullPath.ptr[i] == '/') + { + lastSlashIndex = i; + break; + } + } - oc_str8 basename = oc_str8_slice(fullPath, lastSlashIndex+1, fullPath.len); - return(basename); + oc_str8 basename = oc_str8_slice(fullPath, lastSlashIndex + 1, fullPath.len); + return (basename); } oc_str8_list oc_path_split(oc_arena* arena, oc_str8 path) { - oc_arena_scope tmp = oc_scratch_begin_next(arena); - oc_str8_list split = {0}; - oc_str8_list_push(tmp.arena, &split, OC_STR8("/")); - oc_str8_list res = oc_str8_split(arena, path, split); - oc_scratch_end(tmp); - return(res); + oc_arena_scope tmp = oc_scratch_begin_next(arena); + oc_str8_list split = { 0 }; + oc_str8_list_push(tmp.arena, &split, OC_STR8("/")); + oc_str8_list res = oc_str8_split(arena, path, split); + oc_scratch_end(tmp); + return (res); } oc_str8 oc_path_join(oc_arena* arena, oc_str8_list elements) { - //TODO: check if elements have ending/begining '/' ? - oc_str8 res = oc_str8_list_collate(arena, elements, OC_STR8("/"), OC_STR8("/"), (oc_str8){0}); - return(res); + //TODO: check if elements have ending/begining '/' ? + oc_str8 res = oc_str8_list_collate(arena, elements, OC_STR8("/"), OC_STR8("/"), (oc_str8){ 0 }); + return (res); } oc_str8 oc_path_append(oc_arena* arena, oc_str8 parent, oc_str8 relPath) { - oc_str8 result = {0}; + oc_str8 result = { 0 }; - if(parent.len == 0) - { - result = oc_str8_push_copy(arena, relPath); - } - else if(relPath.len == 0) - { - result = oc_str8_push_copy(arena, parent); - } - else - { - oc_arena_scope tmp = oc_scratch_begin_next(arena); + if(parent.len == 0) + { + result = oc_str8_push_copy(arena, relPath); + } + else if(relPath.len == 0) + { + result = oc_str8_push_copy(arena, parent); + } + else + { + oc_arena_scope tmp = oc_scratch_begin_next(arena); - oc_str8_list list = {0}; - oc_str8_list_push(tmp.arena, &list, parent); - if( (parent.ptr[parent.len-1] != '/') - &&(relPath.ptr[relPath.len-1] != '/')) - { - oc_str8_list_push(tmp.arena, &list, OC_STR8("/")); - } - oc_str8_list_push(tmp.arena, &list, relPath); + oc_str8_list list = { 0 }; + oc_str8_list_push(tmp.arena, &list, parent); + if((parent.ptr[parent.len - 1] != '/') + && (relPath.ptr[relPath.len - 1] != '/')) + { + oc_str8_list_push(tmp.arena, &list, OC_STR8("/")); + } + oc_str8_list_push(tmp.arena, &list, relPath); - result = oc_str8_list_join(arena, list); + result = oc_str8_list_join(arena, list); - oc_scratch_end(tmp); - } - return(result); + oc_scratch_end(tmp); + } + return (result); } oc_str8 oc_path_executable_relative(oc_arena* arena, oc_str8 relPath) { - oc_str8_list list = {0}; - oc_arena_scope scratch = oc_scratch_begin_next(arena); + oc_str8_list list = { 0 }; + oc_arena_scope scratch = oc_scratch_begin_next(arena); - oc_str8 executablePath = oc_path_executable(scratch.arena); - oc_str8 dirPath = oc_path_slice_directory(executablePath); + oc_str8 executablePath = oc_path_executable(scratch.arena); + oc_str8 dirPath = oc_path_slice_directory(executablePath); - oc_str8 path = oc_path_append(arena, dirPath, relPath); + oc_str8 path = oc_path_append(arena, dirPath, relPath); - oc_scratch_end(scratch); - return(path); + oc_scratch_end(scratch); + return (path); } diff --git a/src/platform/platform_path.h b/src/platform/platform_path.h index 6fd8f19..892a775 100644 --- a/src/platform/platform_path.h +++ b/src/platform/platform_path.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: platform_path.h * @author: Martin Fouilleul @@ -8,7 +8,7 @@ #ifndef __PLATFORM_PATH_H_ #define __PLATFORM_PATH_H_ -#include"util/strings.h" +#include "util/strings.h" /*NOTE: by convention, functions that take an arena and return a path diff --git a/src/platform/platform_thread.h b/src/platform/platform_thread.h index 3abaab5..cbabe5e 100644 --- a/src/platform/platform_thread.h +++ b/src/platform/platform_thread.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: platform_thread.h * @author: Martin Fouilleul @@ -9,83 +9,84 @@ #ifndef __PLATFORM_THREAD_H_ #define __PLATFORM_THREAD_H_ -#include"util/strings.h" +#include "util/strings.h" #ifdef __cplusplus - #include - #define _Atomic(T) std::atomic + #include + #define _Atomic(T) std::atomic #else - #include + #include #endif #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif // __cplusplus -//--------------------------------------------------------------- -// Platform Thread API -//--------------------------------------------------------------- + //--------------------------------------------------------------- + // Platform Thread API + //--------------------------------------------------------------- -enum -{ - OC_THREAD_NAME_MAX_SIZE = 64, // including null terminator -}; + enum + { + OC_THREAD_NAME_MAX_SIZE = 64, // including null terminator + }; -typedef struct oc_thread oc_thread; + typedef struct oc_thread oc_thread; -typedef i32 (*oc_thread_start_function)(void* userPointer); + typedef i32 (*oc_thread_start_function)(void* userPointer); -ORCA_API oc_thread* oc_thread_create(oc_thread_start_function start, void* userPointer); -ORCA_API oc_thread* oc_thread_create_with_name(oc_thread_start_function start, void* userPointer, oc_str8 name); -ORCA_API oc_str8 oc_thread_get_name(oc_thread* thread); -ORCA_API u64 oc_thread_unique_id(oc_thread* thread); -ORCA_API u64 oc_thread_self_id(); -ORCA_API int oc_thread_signal(oc_thread* thread, int sig); -ORCA_API int oc_thread_join(oc_thread* thread, i64* exitCode); -ORCA_API int oc_thread_detach(oc_thread* thread); + ORCA_API oc_thread* oc_thread_create(oc_thread_start_function start, void* userPointer); + ORCA_API oc_thread* oc_thread_create_with_name(oc_thread_start_function start, void* userPointer, oc_str8 name); + ORCA_API oc_str8 oc_thread_get_name(oc_thread* thread); + ORCA_API u64 oc_thread_unique_id(oc_thread* thread); + ORCA_API u64 oc_thread_self_id(); + ORCA_API int oc_thread_signal(oc_thread* thread, int sig); + ORCA_API int oc_thread_join(oc_thread* thread, i64* exitCode); + ORCA_API int oc_thread_detach(oc_thread* thread); -//--------------------------------------------------------------- -// Platform Mutex API -//--------------------------------------------------------------- + //--------------------------------------------------------------- + // Platform Mutex API + //--------------------------------------------------------------- -typedef struct oc_mutex oc_mutex; + typedef struct oc_mutex oc_mutex; -ORCA_API oc_mutex* oc_mutex_create(); -ORCA_API int oc_mutex_destroy(oc_mutex* mutex); -ORCA_API int oc_mutex_lock(oc_mutex* mutex); -ORCA_API int oc_mutex_unlock(oc_mutex* mutex); + ORCA_API oc_mutex* oc_mutex_create(); + ORCA_API int oc_mutex_destroy(oc_mutex* mutex); + ORCA_API int oc_mutex_lock(oc_mutex* mutex); + ORCA_API int oc_mutex_unlock(oc_mutex* mutex); -//--------------------------------------------------------------- -// Lightweight ticket mutex API -//--------------------------------------------------------------- + //--------------------------------------------------------------- + // Lightweight ticket mutex API + //--------------------------------------------------------------- -typedef struct oc_ticket -{ - volatile _Atomic(u64) nextTicket; - volatile _Atomic(u64) serving; -} oc_ticket; + typedef struct oc_ticket + { + volatile _Atomic(u64) nextTicket; + volatile _Atomic(u64) serving; + } oc_ticket; -ORCA_API void oc_ticket_init(oc_ticket* mutex); -ORCA_API void oc_ticket_lock(oc_ticket* mutex); -ORCA_API void oc_ticket_unlock(oc_ticket* mutex); + ORCA_API void oc_ticket_init(oc_ticket* mutex); + ORCA_API void oc_ticket_lock(oc_ticket* mutex); + ORCA_API void oc_ticket_unlock(oc_ticket* mutex); -//--------------------------------------------------------------- -// Platform condition variable API -//--------------------------------------------------------------- + //--------------------------------------------------------------- + // Platform condition variable API + //--------------------------------------------------------------- -typedef struct oc_condition oc_condition; + typedef struct oc_condition oc_condition; -ORCA_API oc_condition* oc_condition_create(); -ORCA_API int oc_condition_destroy(oc_condition* cond); -ORCA_API int oc_condition_wait(oc_condition* cond, oc_mutex* mutex); -ORCA_API int oc_condition_timedwait(oc_condition* cond, oc_mutex* mutex, f64 seconds); -ORCA_API int oc_condition_signal(oc_condition* cond); -ORCA_API int oc_condition_broadcast(oc_condition* cond); + ORCA_API oc_condition* oc_condition_create(); + ORCA_API int oc_condition_destroy(oc_condition* cond); + ORCA_API int oc_condition_wait(oc_condition* cond, oc_mutex* mutex); + ORCA_API int oc_condition_timedwait(oc_condition* cond, oc_mutex* mutex, f64 seconds); + ORCA_API int oc_condition_signal(oc_condition* cond); + ORCA_API int oc_condition_broadcast(oc_condition* cond); -//--------------------------------------------------------------- -// Putting threads to sleep -//--------------------------------------------------------------- -ORCA_API void oc_sleep_nano(u64 nanoseconds); // sleep for a given number of nanoseconds + //--------------------------------------------------------------- + // Putting threads to sleep + //--------------------------------------------------------------- + ORCA_API void oc_sleep_nano(u64 nanoseconds); // sleep for a given number of nanoseconds #ifdef __cplusplus } // extern "C" diff --git a/src/platform/posix_io.c b/src/platform/posix_io.c index ef36510..0360bc1 100644 --- a/src/platform/posix_io.c +++ b/src/platform/posix_io.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: posix_io.c * @author: Martin Fouilleul @@ -6,573 +6,573 @@ * *****************************************************************/ -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include -#include"platform_io_common.c" -#include"platform_io_internal.c" +#include "platform_io_common.c" +#include "platform_io_internal.c" oc_file_desc oc_file_desc_nil() { - return(-1); + return (-1); } bool oc_file_desc_is_nil(oc_file_desc fd) { - return(fd < 0); + return (fd < 0); } oc_io_error oc_io_raw_last_error() { - oc_io_error error = OC_IO_OK; - switch(errno) - { - case EPERM: - case EACCES: - case EROFS: - error = OC_IO_ERR_PERM; - break; + oc_io_error error = OC_IO_OK; + switch(errno) + { + case EPERM: + case EACCES: + case EROFS: + error = OC_IO_ERR_PERM; + break; - case ENOENT: - error = OC_IO_ERR_NO_ENTRY; - break; + case ENOENT: + error = OC_IO_ERR_NO_ENTRY; + break; - case EINTR: - error = OC_IO_ERR_INTERRUPT; - break; + case EINTR: + error = OC_IO_ERR_INTERRUPT; + break; - case EIO: - error = OC_IO_ERR_PHYSICAL; - break; + case EIO: + error = OC_IO_ERR_PHYSICAL; + break; - case ENXIO: - error = OC_IO_ERR_NO_DEVICE; - break; + case ENXIO: + error = OC_IO_ERR_NO_DEVICE; + break; - case EBADF: - // this should only happen when user tries to write/read to a file handle - // opened with readonly/writeonly access - error = OC_IO_ERR_PERM; - break; + case EBADF: + // this should only happen when user tries to write/read to a file handle + // opened with readonly/writeonly access + error = OC_IO_ERR_PERM; + break; - case ENOMEM: - error = OC_IO_ERR_MEM; - break; + case ENOMEM: + error = OC_IO_ERR_MEM; + break; - case EFAULT: - case EINVAL: - case EDOM: - error = OC_IO_ERR_ARG; - break; + case EFAULT: + case EINVAL: + case EDOM: + error = OC_IO_ERR_ARG; + break; - case EBUSY: - case EAGAIN: - error = OC_IO_ERR_NOT_READY; - break; + case EBUSY: + case EAGAIN: + error = OC_IO_ERR_NOT_READY; + break; - case EEXIST: - error = OC_IO_ERR_EXISTS; - break; + case EEXIST: + error = OC_IO_ERR_EXISTS; + break; - case ENOTDIR: - error = OC_IO_ERR_NOT_DIR; - break; + case ENOTDIR: + error = OC_IO_ERR_NOT_DIR; + break; - case EISDIR: - error = OC_IO_ERR_DIR; - break; + case EISDIR: + error = OC_IO_ERR_DIR; + break; - case ENFILE: - case EMFILE: - error = OC_IO_ERR_MAX_FILES; - break; + case ENFILE: + case EMFILE: + error = OC_IO_ERR_MAX_FILES; + break; - case EFBIG: - error = OC_IO_ERR_FILE_SIZE; - break; + case EFBIG: + error = OC_IO_ERR_FILE_SIZE; + break; - case ENOSPC: - case EDQUOT: - error = OC_IO_ERR_SPACE; - break; + case ENOSPC: + case EDQUOT: + error = OC_IO_ERR_SPACE; + break; - case ELOOP: - error = OC_IO_ERR_MAX_LINKS; - break; + case ELOOP: + error = OC_IO_ERR_MAX_LINKS; + break; - case ENAMETOOLONG: - error = OC_IO_ERR_PATH_LENGTH; - break; + case ENAMETOOLONG: + error = OC_IO_ERR_PATH_LENGTH; + break; - case EOVERFLOW: - error = OC_IO_ERR_OVERFLOW; - break; + case EOVERFLOW: + error = OC_IO_ERR_OVERFLOW; + break; - default: - error = OC_IO_ERR_UNKNOWN; - break; - } - return(error); + default: + error = OC_IO_ERR_UNKNOWN; + break; + } + return (error); } static int oc_io_convert_access_rights(oc_file_access rights) { - int oflags = 0; + int oflags = 0; - if(rights & OC_FILE_ACCESS_READ) - { - if(rights & OC_FILE_ACCESS_WRITE) - { - oflags = O_RDWR; - } - else - { - oflags = O_RDONLY; - } - } - else if(rights & OC_FILE_ACCESS_WRITE) - { - oflags = O_WRONLY; - } - return(oflags); + if(rights & OC_FILE_ACCESS_READ) + { + if(rights & OC_FILE_ACCESS_WRITE) + { + oflags = O_RDWR; + } + else + { + oflags = O_RDONLY; + } + } + else if(rights & OC_FILE_ACCESS_WRITE) + { + oflags = O_WRONLY; + } + return (oflags); } static int oc_io_convert_open_flags(oc_file_open_flags flags) { - int oflags = 0; + int oflags = 0; - if(flags & OC_FILE_OPEN_TRUNCATE) - { - oflags |= O_TRUNC; - } - if(flags & OC_FILE_OPEN_APPEND) - { - oflags |= O_APPEND; - } - if(flags & OC_FILE_OPEN_CREATE) - { - oflags |= O_CREAT; - } - if(flags & OC_FILE_OPEN_NO_FOLLOW) - { - oflags |= O_NOFOLLOW; - } - if(flags & OC_FILE_OPEN_SYMLINK) - { - oflags |= O_SYMLINK; - } - return(oflags); + if(flags & OC_FILE_OPEN_TRUNCATE) + { + oflags |= O_TRUNC; + } + if(flags & OC_FILE_OPEN_APPEND) + { + oflags |= O_APPEND; + } + if(flags & OC_FILE_OPEN_CREATE) + { + oflags |= O_CREAT; + } + if(flags & OC_FILE_OPEN_NO_FOLLOW) + { + oflags |= O_NOFOLLOW; + } + if(flags & OC_FILE_OPEN_SYMLINK) + { + oflags |= O_SYMLINK; + } + return (oflags); } static int oc_io_update_dir_flags_at(int dirFd, char* path, int flags) { - struct stat s; - if(!fstatat(dirFd, path, &s, AT_SYMLINK_NOFOLLOW)) - { - if((s.st_mode & S_IFMT) == S_IFDIR) - { - if(flags & O_WRONLY) - { - flags &= ~O_WRONLY; - } - else if(flags & O_RDWR) - { - flags &= ~O_RDWR; - flags |= O_RDONLY; - } - } - } - return(flags); + struct stat s; + if(!fstatat(dirFd, path, &s, AT_SYMLINK_NOFOLLOW)) + { + if((s.st_mode & S_IFMT) == S_IFDIR) + { + if(flags & O_WRONLY) + { + flags &= ~O_WRONLY; + } + else if(flags & O_RDWR) + { + flags &= ~O_RDWR; + flags |= O_RDONLY; + } + } + } + return (flags); } oc_file_desc oc_io_raw_open_at(oc_file_desc dirFd, oc_str8 path, oc_file_access accessRights, oc_file_open_flags openFlags) { - int flags = oc_io_convert_access_rights(accessRights); - flags |= oc_io_convert_open_flags(openFlags); + int flags = oc_io_convert_access_rights(accessRights); + flags |= oc_io_convert_open_flags(openFlags); - mode_t mode = S_IRUSR - | S_IWUSR - | S_IRGRP - | S_IWGRP - | S_IROTH - | S_IWOTH; + mode_t mode = S_IRUSR + | S_IWUSR + | S_IRGRP + | S_IWGRP + | S_IROTH + | S_IWOTH; - oc_arena_scope scratch = oc_scratch_begin(); + oc_arena_scope scratch = oc_scratch_begin(); - oc_file_desc fd = -1; - if(dirFd >= 0) - { - if(path.len && path.ptr[0] == '/') - { - //NOTE: if path is absolute, change for a relative one, otherwise openat ignores fd. - oc_str8_list list = {0}; - oc_str8_list_push(scratch.arena, &list, OC_STR8(".")); - oc_str8_list_push(scratch.arena, &list, path); - path = oc_str8_list_join(scratch.arena, list); - } - } - else - { - dirFd = AT_FDCWD; - } + oc_file_desc fd = -1; + if(dirFd >= 0) + { + if(path.len && path.ptr[0] == '/') + { + //NOTE: if path is absolute, change for a relative one, otherwise openat ignores fd. + oc_str8_list list = { 0 }; + oc_str8_list_push(scratch.arena, &list, OC_STR8(".")); + oc_str8_list_push(scratch.arena, &list, path); + path = oc_str8_list_join(scratch.arena, list); + } + } + else + { + dirFd = AT_FDCWD; + } - char* pathCStr = oc_str8_to_cstring(scratch.arena, path); + char* pathCStr = oc_str8_to_cstring(scratch.arena, path); - flags = oc_io_update_dir_flags_at(dirFd, pathCStr, flags); + flags = oc_io_update_dir_flags_at(dirFd, pathCStr, flags); - fd = openat(dirFd, pathCStr, flags, mode); - oc_scratch_end(scratch); + fd = openat(dirFd, pathCStr, flags, mode); + oc_scratch_end(scratch); - return(fd); + return (fd); } void oc_io_raw_close(oc_file_desc fd) { - close(fd); + close(fd); } static oc_file_perm oc_io_convert_perm_from_stat(u16 mode) { - oc_file_perm perm = mode & 07777; - return(perm); + oc_file_perm perm = mode & 07777; + return (perm); } static oc_file_type oc_io_convert_type_from_stat(u16 mode) { - oc_file_type type; - switch(mode & S_IFMT) - { - case S_IFIFO: - type = OC_FILE_FIFO; - break; + oc_file_type type; + switch(mode & S_IFMT) + { + case S_IFIFO: + type = OC_FILE_FIFO; + break; - case S_IFCHR: - type = OC_FILE_CHARACTER; - break; + case S_IFCHR: + type = OC_FILE_CHARACTER; + break; - case S_IFDIR: - type = OC_FILE_DIRECTORY; - break; + case S_IFDIR: + type = OC_FILE_DIRECTORY; + break; - case S_IFBLK: - type = OC_FILE_BLOCK; - break; + case S_IFBLK: + type = OC_FILE_BLOCK; + break; - case S_IFREG: - type = OC_FILE_REGULAR; - break; + case S_IFREG: + type = OC_FILE_REGULAR; + break; - case S_IFLNK: - type = OC_FILE_SYMLINK; - break; + case S_IFLNK: + type = OC_FILE_SYMLINK; + break; - case S_IFSOCK: - type = OC_FILE_SOCKET; - break; + case S_IFSOCK: + type = OC_FILE_SOCKET; + break; - default: - type = OC_FILE_UNKNOWN; - break; - } - return(type); + default: + type = OC_FILE_UNKNOWN; + break; + } + return (type); } oc_io_error oc_io_raw_fstat(oc_file_desc fd, oc_file_status* status) { - oc_io_error error = OC_IO_OK; - struct stat s; - if(fstat(fd, &s)) - { - error = oc_io_raw_last_error(); - } - else - { - status->uid = s.st_ino; - status->perm = oc_io_convert_perm_from_stat(s.st_mode); - status->type = oc_io_convert_type_from_stat(s.st_mode); - status->size = s.st_size; - //TODO: times - } - return(error); + oc_io_error error = OC_IO_OK; + struct stat s; + if(fstat(fd, &s)) + { + error = oc_io_raw_last_error(); + } + else + { + status->uid = s.st_ino; + status->perm = oc_io_convert_perm_from_stat(s.st_mode); + status->type = oc_io_convert_type_from_stat(s.st_mode); + status->size = s.st_size; + //TODO: times + } + return (error); } oc_io_error oc_io_raw_fstat_at(oc_file_desc dirFd, oc_str8 path, oc_file_open_flags flags, oc_file_status* status) { - oc_arena_scope scratch = oc_scratch_begin(); + oc_arena_scope scratch = oc_scratch_begin(); - if(dirFd >= 0) - { - if(path.len && path.ptr[0] == '/') - { - oc_str8_list list = {0}; - oc_str8_list_push(scratch.arena, &list, OC_STR8(".")); - oc_str8_list_push(scratch.arena, &list, path); - path = oc_str8_list_join(scratch.arena, list); - } - } - else - { - dirFd = AT_FDCWD; - } + if(dirFd >= 0) + { + if(path.len && path.ptr[0] == '/') + { + oc_str8_list list = { 0 }; + oc_str8_list_push(scratch.arena, &list, OC_STR8(".")); + oc_str8_list_push(scratch.arena, &list, path); + path = oc_str8_list_join(scratch.arena, list); + } + } + else + { + dirFd = AT_FDCWD; + } - char* pathCStr = oc_str8_to_cstring(scratch.arena, path); + char* pathCStr = oc_str8_to_cstring(scratch.arena, path); - int statFlag = (flags & OC_FILE_OPEN_SYMLINK)? AT_SYMLINK_NOFOLLOW : 0; - oc_io_error error = OC_IO_OK; - struct stat s; - if(fstatat(dirFd, pathCStr, &s, statFlag)) - { - error = oc_io_raw_last_error(); - } - else - { - status->uid = s.st_ino; - status->perm = oc_io_convert_perm_from_stat(s.st_mode); - status->type = oc_io_convert_type_from_stat(s.st_mode); - status->size = s.st_size; - //TODO: times - } + int statFlag = (flags & OC_FILE_OPEN_SYMLINK) ? AT_SYMLINK_NOFOLLOW : 0; + oc_io_error error = OC_IO_OK; + struct stat s; + if(fstatat(dirFd, pathCStr, &s, statFlag)) + { + error = oc_io_raw_last_error(); + } + else + { + status->uid = s.st_ino; + status->perm = oc_io_convert_perm_from_stat(s.st_mode); + status->type = oc_io_convert_type_from_stat(s.st_mode); + status->size = s.st_size; + //TODO: times + } - oc_scratch_end(scratch); - return(error); + oc_scratch_end(scratch); + return (error); } oc_io_raw_read_link_result oc_io_raw_read_link_at(oc_arena* arena, oc_file_desc dirFd, oc_str8 path) { - oc_arena_scope scratch = oc_scratch_begin_next(arena); + oc_arena_scope scratch = oc_scratch_begin_next(arena); - if(dirFd >= 0) - { - if(path.len && path.ptr[0] == '/') - { - oc_str8_list list = {0}; - oc_str8_list_push(scratch.arena, &list, OC_STR8(".")); - oc_str8_list_push(scratch.arena, &list, path); - path = oc_str8_list_join(scratch.arena, list); - } - } - else - { - dirFd = AT_FDCWD; - } + if(dirFd >= 0) + { + if(path.len && path.ptr[0] == '/') + { + oc_str8_list list = { 0 }; + oc_str8_list_push(scratch.arena, &list, OC_STR8(".")); + oc_str8_list_push(scratch.arena, &list, path); + path = oc_str8_list_join(scratch.arena, list); + } + } + else + { + dirFd = AT_FDCWD; + } - char* pathCStr = oc_str8_to_cstring(scratch.arena, path); + char* pathCStr = oc_str8_to_cstring(scratch.arena, path); - oc_io_raw_read_link_result result = {0}; + oc_io_raw_read_link_result result = { 0 }; - char buffer[PATH_MAX]; - u64 bufferSize = PATH_MAX; - i64 r = readlinkat(dirFd, pathCStr, buffer, bufferSize); + char buffer[PATH_MAX]; + u64 bufferSize = PATH_MAX; + i64 r = readlinkat(dirFd, pathCStr, buffer, bufferSize); - if(r<0) - { - result.error = oc_io_raw_last_error(); - } - else - { - result.target.len = r; - result.target.ptr = oc_arena_push_array(arena, char, result.target.len); - memcpy(result.target.ptr, buffer, result.target.len); - } + if(r < 0) + { + result.error = oc_io_raw_last_error(); + } + else + { + result.target.len = r; + result.target.ptr = oc_arena_push_array(arena, char, result.target.len); + memcpy(result.target.ptr, buffer, result.target.len); + } - oc_scratch_end(scratch); - return(result); + oc_scratch_end(scratch); + return (result); } bool oc_io_raw_file_exists_at(oc_file_desc dirFd, oc_str8 path, oc_file_open_flags openFlags) { - oc_arena_scope scratch = oc_scratch_begin(); + oc_arena_scope scratch = oc_scratch_begin(); - if(dirFd >= 0) - { - if(path.len && path.ptr[0] == '/') - { - oc_str8_list list = {0}; - oc_str8_list_push(scratch.arena, &list, OC_STR8(".")); - oc_str8_list_push(scratch.arena, &list, path); - path = oc_str8_list_join(scratch.arena, list); - } - } - else - { - dirFd = AT_FDCWD; - } + if(dirFd >= 0) + { + if(path.len && path.ptr[0] == '/') + { + oc_str8_list list = { 0 }; + oc_str8_list_push(scratch.arena, &list, OC_STR8(".")); + oc_str8_list_push(scratch.arena, &list, path); + path = oc_str8_list_join(scratch.arena, list); + } + } + else + { + dirFd = AT_FDCWD; + } - char* pathCStr = oc_str8_to_cstring(scratch.arena, path); + char* pathCStr = oc_str8_to_cstring(scratch.arena, path); - int flags = (openFlags & OC_FILE_OPEN_SYMLINK)? AT_SYMLINK_NOFOLLOW : 0; - int r = faccessat(dirFd, pathCStr, F_OK, flags); - bool result = (r == 0); + int flags = (openFlags & OC_FILE_OPEN_SYMLINK) ? AT_SYMLINK_NOFOLLOW : 0; + int r = faccessat(dirFd, pathCStr, F_OK, flags); + bool result = (r == 0); - oc_scratch_end(scratch); - return(result); + oc_scratch_end(scratch); + return (result); } oc_io_cmp oc_io_close(oc_file_slot* slot, oc_io_req* req, oc_file_table* table) { - oc_io_cmp cmp = {0}; - if(slot->fd >= 0) - { - close(slot->fd); - } - oc_file_slot_recycle(table, slot); - return(cmp); + oc_io_cmp cmp = { 0 }; + if(slot->fd >= 0) + { + close(slot->fd); + } + oc_file_slot_recycle(table, slot); + return (cmp); } oc_io_cmp oc_io_fstat(oc_file_slot* slot, oc_io_req* req) { - oc_io_cmp cmp = {0}; + oc_io_cmp cmp = { 0 }; - if(req->size < sizeof(oc_file_status)) - { - cmp.error = OC_IO_ERR_ARG; - } - else - { - struct stat s; - if(fstat(slot->fd, &s)) - { - slot->error = oc_io_raw_last_error(); - cmp.error = slot->error; - } - else - { - oc_file_status* status = (oc_file_status*)req->buffer; - status->perm = oc_io_convert_perm_from_stat(s.st_mode); - status->type = oc_io_convert_type_from_stat(s.st_mode); - status->size = s.st_size; - //TODO: times - } - } - return(cmp); + if(req->size < sizeof(oc_file_status)) + { + cmp.error = OC_IO_ERR_ARG; + } + else + { + struct stat s; + if(fstat(slot->fd, &s)) + { + slot->error = oc_io_raw_last_error(); + cmp.error = slot->error; + } + else + { + oc_file_status* status = (oc_file_status*)req->buffer; + status->perm = oc_io_convert_perm_from_stat(s.st_mode); + status->type = oc_io_convert_type_from_stat(s.st_mode); + status->size = s.st_size; + //TODO: times + } + } + return (cmp); } oc_io_cmp oc_io_seek(oc_file_slot* slot, oc_io_req* req) { - oc_io_cmp cmp = {0}; + oc_io_cmp cmp = { 0 }; - int whence; - switch(req->whence) - { - case OC_FILE_SEEK_CURRENT: - whence = SEEK_CUR; - break; + int whence; + switch(req->whence) + { + case OC_FILE_SEEK_CURRENT: + whence = SEEK_CUR; + break; - case OC_FILE_SEEK_SET: - whence = SEEK_SET; - break; + case OC_FILE_SEEK_SET: + whence = SEEK_SET; + break; - case OC_FILE_SEEK_END: - whence = SEEK_END; - } - cmp.result = lseek(slot->fd, req->offset, whence); + case OC_FILE_SEEK_END: + whence = SEEK_END; + } + cmp.result = lseek(slot->fd, req->offset, whence); - if(cmp.result < 0) - { - slot->error = oc_io_raw_last_error(); - cmp.error = slot->error; - } + if(cmp.result < 0) + { + slot->error = oc_io_raw_last_error(); + cmp.error = slot->error; + } - return(cmp); + return (cmp); } oc_io_cmp oc_io_read(oc_file_slot* slot, oc_io_req* req) { - oc_io_cmp cmp = {0}; + oc_io_cmp cmp = { 0 }; - cmp.result = read(slot->fd, req->buffer, req->size); + cmp.result = read(slot->fd, req->buffer, req->size); - if(cmp.result < 0) - { - slot->error = oc_io_raw_last_error(); - cmp.result = 0; - cmp.error = slot->error; - } + if(cmp.result < 0) + { + slot->error = oc_io_raw_last_error(); + cmp.result = 0; + cmp.error = slot->error; + } - return(cmp); + return (cmp); } oc_io_cmp oc_io_write(oc_file_slot* slot, oc_io_req* req) { - oc_io_cmp cmp = {0}; + oc_io_cmp cmp = { 0 }; - cmp.result = write(slot->fd, req->buffer, req->size); + cmp.result = write(slot->fd, req->buffer, req->size); - if(cmp.result < 0) - { - slot->error = oc_io_raw_last_error(); - cmp.result = 0; - cmp.error = slot->error; - } + if(cmp.result < 0) + { + slot->error = oc_io_raw_last_error(); + cmp.result = 0; + cmp.error = slot->error; + } - return(cmp); + return (cmp); } oc_io_cmp oc_io_get_error(oc_file_slot* slot, oc_io_req* req) { - oc_io_cmp cmp = {0}; - cmp.result = slot->error; - return(cmp); + oc_io_cmp cmp = { 0 }; + cmp.result = slot->error; + return (cmp); } oc_io_cmp oc_io_wait_single_req_with_table(oc_io_req* req, oc_file_table* table) { - oc_io_cmp cmp = {0}; + oc_io_cmp cmp = { 0 }; - oc_file_slot* slot = oc_file_slot_from_handle(table, req->handle); - if(!slot) - { - if(req->op != OC_IO_OPEN_AT) - { - cmp.error = OC_IO_ERR_HANDLE; - } - } - else if( slot->fatal - && req->op != OC_IO_CLOSE - && req->op != OC_OC_IO_ERROR) - { - cmp.error = OC_IO_ERR_PREV; - } + oc_file_slot* slot = oc_file_slot_from_handle(table, req->handle); + if(!slot) + { + if(req->op != OC_IO_OPEN_AT) + { + cmp.error = OC_IO_ERR_HANDLE; + } + } + else if(slot->fatal + && req->op != OC_IO_CLOSE + && req->op != OC_OC_IO_ERROR) + { + cmp.error = OC_IO_ERR_PREV; + } - if(cmp.error == OC_IO_OK) - { - switch(req->op) - { - case OC_IO_OPEN_AT: - cmp = oc_io_open_at(slot, req, table); - break; + if(cmp.error == OC_IO_OK) + { + switch(req->op) + { + case OC_IO_OPEN_AT: + cmp = oc_io_open_at(slot, req, table); + break; - case OC_IO_FSTAT: - cmp = oc_io_fstat(slot, req); - break; + case OC_IO_FSTAT: + cmp = oc_io_fstat(slot, req); + break; - case OC_IO_CLOSE: - cmp = oc_io_close(slot, req, table); - break; + case OC_IO_CLOSE: + cmp = oc_io_close(slot, req, table); + break; - case OC_IO_READ: - cmp = oc_io_read(slot, req); - break; + case OC_IO_READ: + cmp = oc_io_read(slot, req); + break; - case OC_IO_WRITE: - cmp = oc_io_write(slot, req); - break; + case OC_IO_WRITE: + cmp = oc_io_write(slot, req); + break; - case OC_IO_SEEK: - cmp = oc_io_seek(slot, req); - break; + case OC_IO_SEEK: + cmp = oc_io_seek(slot, req); + break; - case OC_OC_IO_ERROR: - cmp = oc_io_get_error(slot, req); - break; + case OC_OC_IO_ERROR: + cmp = oc_io_get_error(slot, req); + break; - default: - cmp.error = OC_IO_ERR_OP; - break; - } - } - return(cmp); + default: + cmp.error = OC_IO_ERR_OP; + break; + } + } + return (cmp); } diff --git a/src/platform/posix_thread.c b/src/platform/posix_thread.c index a1925a2..15dad19 100644 --- a/src/platform/posix_thread.c +++ b/src/platform/posix_thread.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: posix_thread.c * @author: Martin Fouilleul @@ -6,254 +6,252 @@ * @revision: * *****************************************************************/ -#include -#include -#include //needed for pthread_kill() on linux -#include -#include -#include // nanosleep() +#include +#include //needed for pthread_kill() on linux +#include +#include +#include +#include // nanosleep() -#include"platform_thread.h" +#include "platform_thread.h" struct oc_thread { - bool valid; - pthread_t pthread; - oc_thread_start_function start; - void* userPointer; - oc_str8 name; - char nameBuffer[OC_THREAD_NAME_MAX_SIZE]; + bool valid; + pthread_t pthread; + oc_thread_start_function start; + void* userPointer; + oc_str8 name; + char nameBuffer[OC_THREAD_NAME_MAX_SIZE]; }; static void* oc_thread_bootstrap(void* data) { - oc_thread* thread = (oc_thread*)data; - if(thread->name.len) - { - pthread_setname_np(thread->nameBuffer); - } - i32 exitCode = thread->start(thread->userPointer); - return((void*)(ptrdiff_t)exitCode); + oc_thread* thread = (oc_thread*)data; + if(thread->name.len) + { + pthread_setname_np(thread->nameBuffer); + } + i32 exitCode = thread->start(thread->userPointer); + return ((void*)(ptrdiff_t)exitCode); } oc_thread* oc_thread_create_with_name(oc_thread_start_function start, void* userPointer, oc_str8 name) { - oc_thread* thread = (oc_thread*)malloc(sizeof(oc_thread)); - if(!thread) - { - return(0); - } + oc_thread* thread = (oc_thread*)malloc(sizeof(oc_thread)); + if(!thread) + { + return (0); + } - if(name.len && name.ptr) - { - char* end = stpncpy(thread->nameBuffer, name.ptr, oc_min(name.len, OC_THREAD_NAME_MAX_SIZE-1)); - *end = '\0'; - thread->name = oc_str8_from_buffer(end - thread->nameBuffer, thread->nameBuffer); - } - else - { - thread->nameBuffer[0] = '\0'; - thread->name = oc_str8_from_buffer(0, thread->nameBuffer); - } - thread->start = start; - thread->userPointer = userPointer; + if(name.len && name.ptr) + { + char* end = stpncpy(thread->nameBuffer, name.ptr, oc_min(name.len, OC_THREAD_NAME_MAX_SIZE - 1)); + *end = '\0'; + thread->name = oc_str8_from_buffer(end - thread->nameBuffer, thread->nameBuffer); + } + else + { + thread->nameBuffer[0] = '\0'; + thread->name = oc_str8_from_buffer(0, thread->nameBuffer); + } + thread->start = start; + thread->userPointer = userPointer; - if(pthread_create(&thread->pthread, 0, oc_thread_bootstrap, thread) != 0) - { - free(thread); - return(0); - } - else - { - thread->valid = true; - return(thread); - } + if(pthread_create(&thread->pthread, 0, oc_thread_bootstrap, thread) != 0) + { + free(thread); + return (0); + } + else + { + thread->valid = true; + return (thread); + } } oc_thread* oc_thread_create(oc_thread_start_function start, void* userPointer) { - return(oc_thread_create_with_name(start, userPointer, (oc_str8){0})); + return (oc_thread_create_with_name(start, userPointer, (oc_str8){ 0 })); } oc_str8 oc_thread_get_name(oc_thread* thread) { - return(thread->name); + return (thread->name); } u64 oc_thread_unique_id(oc_thread* thread) { - u64 id; - pthread_threadid_np(thread->pthread, &id); - return(id); + u64 id; + pthread_threadid_np(thread->pthread, &id); + return (id); } u64 oc_thread_self_id() { - pthread_t thread = pthread_self(); - u64 id; - pthread_threadid_np(thread, &id); - return(id); + pthread_t thread = pthread_self(); + u64 id; + pthread_threadid_np(thread, &id); + return (id); } int oc_thread_signal(oc_thread* thread, int sig) { - return(pthread_kill(thread->pthread, sig)); + return (pthread_kill(thread->pthread, sig)); } int oc_thread_join(oc_thread* thread, i64* exitCode) { - void* ret; - if(pthread_join(thread->pthread, &ret)) - { - return(-1); - } - free(thread); + void* ret; + if(pthread_join(thread->pthread, &ret)) + { + return (-1); + } + free(thread); - if (exitCode) - { - *exitCode = (off_t)ret; - } - return(0); + if(exitCode) + { + *exitCode = (off_t)ret; + } + return (0); } int oc_thread_detach(oc_thread* thread) { - if(pthread_detach(thread->pthread)) - { - return(-1); - } - free(thread); - return(0); + if(pthread_detach(thread->pthread)) + { + return (-1); + } + free(thread); + return (0); } - struct oc_mutex { - pthread_mutex_t pmutex; + pthread_mutex_t pmutex; }; oc_mutex* oc_mutex_create() { - oc_mutex* mutex = (oc_mutex*)malloc(sizeof(oc_mutex)); - if(!mutex) - { - return(0); - } - if(pthread_mutex_init(&mutex->pmutex, 0) != 0) - { - free(mutex); - return(0); - } - return(mutex); + oc_mutex* mutex = (oc_mutex*)malloc(sizeof(oc_mutex)); + if(!mutex) + { + return (0); + } + if(pthread_mutex_init(&mutex->pmutex, 0) != 0) + { + free(mutex); + return (0); + } + return (mutex); } int oc_mutex_destroy(oc_mutex* mutex) { - if(pthread_mutex_destroy(&mutex->pmutex) != 0) - { - return(-1); - } - free(mutex); - return(0); + if(pthread_mutex_destroy(&mutex->pmutex) != 0) + { + return (-1); + } + free(mutex); + return (0); } int oc_mutex_lock(oc_mutex* mutex) { - return(pthread_mutex_lock(&mutex->pmutex)); + return (pthread_mutex_lock(&mutex->pmutex)); } int oc_mutex_unlock(oc_mutex* mutex) { - return(pthread_mutex_unlock(&mutex->pmutex)); + return (pthread_mutex_unlock(&mutex->pmutex)); } // oc_ticket has a mirrored implementation in win32_thread.c void oc_ticket_init(oc_ticket* mutex) { - mutex->nextTicket = 0; - mutex->serving = 0; + mutex->nextTicket = 0; + mutex->serving = 0; } void oc_ticket_lock(oc_ticket* mutex) { - u64 ticket = atomic_fetch_add(&mutex->nextTicket, 1ULL); - while(ticket != mutex->serving); //spin + u64 ticket = atomic_fetch_add(&mutex->nextTicket, 1ULL); + while(ticket != mutex->serving) + ; //spin } void oc_ticket_unlock(oc_ticket* mutex) { - atomic_fetch_add(&mutex->serving, 1ULL); + atomic_fetch_add(&mutex->serving, 1ULL); } - struct oc_condition { - pthread_cond_t pcond; + pthread_cond_t pcond; }; oc_condition* oc_condition_create() { - oc_condition* cond = (oc_condition*)malloc(sizeof(oc_condition)); - if(!cond) - { - return(0); - } - if(pthread_cond_init(&cond->pcond, 0) != 0) - { - free(cond); - return(0); - } - return(cond); + oc_condition* cond = (oc_condition*)malloc(sizeof(oc_condition)); + if(!cond) + { + return (0); + } + if(pthread_cond_init(&cond->pcond, 0) != 0) + { + free(cond); + return (0); + } + return (cond); } int oc_condition_destroy(oc_condition* cond) { - if(pthread_cond_destroy(&cond->pcond) != 0) - { - return(-1); - } - free(cond); - return(0); + if(pthread_cond_destroy(&cond->pcond) != 0) + { + return (-1); + } + free(cond); + return (0); } int oc_condition_wait(oc_condition* cond, oc_mutex* mutex) { - return(pthread_cond_wait(&cond->pcond, &mutex->pmutex)); + return (pthread_cond_wait(&cond->pcond, &mutex->pmutex)); } int oc_condition_timedwait(oc_condition* cond, oc_mutex* mutex, f64 seconds) { - struct timeval tv; - gettimeofday(&tv, 0); + struct timeval tv; + gettimeofday(&tv, 0); - i64 iSeconds = (i64)seconds; - f64 fracSeconds = seconds - (f64)iSeconds; + i64 iSeconds = (i64)seconds; + f64 fracSeconds = seconds - (f64)iSeconds; - struct timespec ts; - ts.tv_sec = tv.tv_sec + iSeconds; - ts.tv_nsec = tv.tv_usec * 1000 + (i32)(fracSeconds*1e9); - ts.tv_sec += ts.tv_nsec / 1000000000; - ts.tv_nsec = ts.tv_nsec % 1000000000; + struct timespec ts; + ts.tv_sec = tv.tv_sec + iSeconds; + ts.tv_nsec = tv.tv_usec * 1000 + (i32)(fracSeconds * 1e9); + ts.tv_sec += ts.tv_nsec / 1000000000; + ts.tv_nsec = ts.tv_nsec % 1000000000; - return(pthread_cond_timedwait(&cond->pcond, &mutex->pmutex, &ts)); + return (pthread_cond_timedwait(&cond->pcond, &mutex->pmutex, &ts)); } int oc_condition_signal(oc_condition* cond) { - return(pthread_cond_signal(&cond->pcond)); + return (pthread_cond_signal(&cond->pcond)); } int oc_condition_broadcast(oc_condition* cond) { - return(pthread_cond_broadcast(&cond->pcond)); + return (pthread_cond_broadcast(&cond->pcond)); } - void oc_sleep_nano(u64 nanoseconds) { - timespec rqtp; - rqtp.tv_sec = nanoseconds / 1000000000; - rqtp.tv_nsec = nanoseconds - rqtp.tv_sec * 1000000000; - nanosleep(&rqtp, 0); + timespec rqtp; + rqtp.tv_sec = nanoseconds / 1000000000; + rqtp.tv_nsec = nanoseconds - rqtp.tv_sec * 1000000000; + nanosleep(&rqtp, 0); } diff --git a/src/platform/unix_memory.c b/src/platform/unix_memory.c index 24f4c89..a407228 100644 --- a/src/platform/unix_memory.c +++ b/src/platform/unix_memory.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: unix_memory.c * @author: Martin Fouilleul @@ -6,8 +6,8 @@ * @revision: * *****************************************************************/ -#include -#include"platform_memory.h" +#include "platform_memory.h" +#include /*NOTE(martin): Linux and MacOS don't make a distinction between reserved and committed memory, contrary to Windows @@ -16,23 +16,23 @@ void oc_base_nop(oc_base_allocator* context, void* ptr, u64 size) {} void* oc_base_reserve_mmap(oc_base_allocator* context, u64 size) { - return(mmap(0, size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, 0, 0)); + return (mmap(0, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, 0, 0)); } void oc_base_release_mmap(oc_base_allocator* context, void* ptr, u64 size) { - munmap(ptr, size); + munmap(ptr, size); } oc_base_allocator* oc_base_allocator_default() { - static oc_base_allocator base = {}; - if(base.reserve == 0) - { - base.reserve = oc_base_reserve_mmap; - base.commit = oc_base_nop; - base.decommit = oc_base_nop; - base.release = oc_base_release_mmap; - } - return(&base); + static oc_base_allocator base = {}; + if(base.reserve == 0) + { + base.reserve = oc_base_reserve_mmap; + base.commit = oc_base_nop; + base.decommit = oc_base_nop; + base.release = oc_base_release_mmap; + } + return (&base); } diff --git a/src/platform/win32_clock.c b/src/platform/win32_clock.c index d54d38e..46a1767 100644 --- a/src/platform/win32_clock.c +++ b/src/platform/win32_clock.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: win32_clock.c * @author: Martin Fouilleul @@ -6,32 +6,33 @@ * @revision: * *****************************************************************/ -#include +#include -#include"util/typedefs.h" -#include"platform_clock.h" +#include "platform_clock.h" +#include "util/typedefs.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -static u64 __performanceCounterFreq = 0; + static u64 __performanceCounterFreq = 0; -void oc_clock_init() -{ - LARGE_INTEGER freq; - QueryPerformanceFrequency(&freq); - __performanceCounterFreq = freq.QuadPart; -} + void oc_clock_init() + { + LARGE_INTEGER freq; + QueryPerformanceFrequency(&freq); + __performanceCounterFreq = freq.QuadPart; + } -f64 oc_clock_time(oc_clock_kind clock) -{ - LARGE_INTEGER counter; - QueryPerformanceCounter(&counter); + f64 oc_clock_time(oc_clock_kind clock) + { + LARGE_INTEGER counter; + QueryPerformanceCounter(&counter); - f64 time = __performanceCounterFreq ? (counter.QuadPart / (f64)__performanceCounterFreq) : 0; - return(time); -} + f64 time = __performanceCounterFreq ? (counter.QuadPart / (f64)__performanceCounterFreq) : 0; + return (time); + } #ifdef __cplusplus } // extern "C" diff --git a/src/platform/win32_io.c b/src/platform/win32_io.c index 001c12a..0c49050 100644 --- a/src/platform/win32_io.c +++ b/src/platform/win32_io.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: win32_io.c * @author: Martin Fouilleul @@ -6,561 +6,562 @@ * *****************************************************************/ -#include -#include -#include -#include +#include +#include +#include +#include -#include"win32_string_helpers.h" -#include"platform_io_internal.c" -#include"platform_io_common.c" +#include "platform_io_common.c" +#include "platform_io_internal.c" +#include "win32_string_helpers.h" oc_io_error oc_io_raw_last_error() { - oc_io_error error = 0; + oc_io_error error = 0; - int winError = GetLastError(); - switch(winError) - { - case ERROR_SUCCESS: - error = OC_IO_OK; - break; + int winError = GetLastError(); + switch(winError) + { + case ERROR_SUCCESS: + error = OC_IO_OK; + break; - case ERROR_ACCESS_DENIED: - error = OC_IO_ERR_PERM; - break; + case ERROR_ACCESS_DENIED: + error = OC_IO_ERR_PERM; + break; - case ERROR_FILE_NOT_FOUND: - case ERROR_PATH_NOT_FOUND: - case ERROR_INVALID_DRIVE: - case ERROR_DIRECTORY: - error = OC_IO_ERR_NO_ENTRY; - break; + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + case ERROR_INVALID_DRIVE: + case ERROR_DIRECTORY: + error = OC_IO_ERR_NO_ENTRY; + break; - case ERROR_TOO_MANY_OPEN_FILES: - error = OC_IO_ERR_MAX_FILES; - break; + case ERROR_TOO_MANY_OPEN_FILES: + error = OC_IO_ERR_MAX_FILES; + break; - case ERROR_NOT_ENOUGH_MEMORY: - case ERROR_OUTOFMEMORY: - error = OC_IO_ERR_MEM; - break; + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_OUTOFMEMORY: + error = OC_IO_ERR_MEM; + break; - case ERROR_DEV_NOT_EXIST: - error = OC_IO_ERR_NO_DEVICE; - break; + case ERROR_DEV_NOT_EXIST: + error = OC_IO_ERR_NO_DEVICE; + break; - case ERROR_FILE_EXISTS: - case ERROR_ALREADY_EXISTS: - error = OC_IO_ERR_EXISTS; - break; + case ERROR_FILE_EXISTS: + case ERROR_ALREADY_EXISTS: + error = OC_IO_ERR_EXISTS; + break; - case ERROR_BUFFER_OVERFLOW: - case ERROR_FILENAME_EXCED_RANGE: - error = OC_IO_ERR_PATH_LENGTH; - break; + case ERROR_BUFFER_OVERFLOW: + case ERROR_FILENAME_EXCED_RANGE: + error = OC_IO_ERR_PATH_LENGTH; + break; - case ERROR_FILE_TOO_LARGE: - error = OC_IO_ERR_FILE_SIZE; - break; + case ERROR_FILE_TOO_LARGE: + error = OC_IO_ERR_FILE_SIZE; + break; - //TODO: complete + //TODO: complete - default: - error = OC_IO_ERR_UNKNOWN; - break; - } - return(error); + default: + error = OC_IO_ERR_UNKNOWN; + break; + } + return (error); } static oc_str16 win32_path_from_handle_null_terminated(oc_arena* arena, HANDLE handle) { - oc_str16 res = {0}; + oc_str16 res = { 0 }; - res.len = GetFinalPathNameByHandleW(handle, NULL, 0, FILE_NAME_NORMALIZED); - if(res.len) - { - res.ptr = oc_arena_push_array(arena, u16, res.len); - if(!GetFinalPathNameByHandleW(handle, res.ptr, res.len, FILE_NAME_NORMALIZED)) - { - res.len = 0; - res.ptr = 0; - } - } - return(res); + res.len = GetFinalPathNameByHandleW(handle, NULL, 0, FILE_NAME_NORMALIZED); + if(res.len) + { + res.ptr = oc_arena_push_array(arena, u16, res.len); + if(!GetFinalPathNameByHandleW(handle, res.ptr, res.len, FILE_NAME_NORMALIZED)) + { + res.len = 0; + res.ptr = 0; + } + } + return (res); } typedef HANDLE oc_file_desc; oc_file_desc oc_file_desc_nil() { - return(INVALID_HANDLE_VALUE); + return (INVALID_HANDLE_VALUE); } bool oc_file_desc_is_nil(oc_file_desc fd) { - return(fd == NULL || fd == INVALID_HANDLE_VALUE); + return (fd == NULL || fd == INVALID_HANDLE_VALUE); } static oc_str16 win32_get_path_at_null_terminated(oc_arena* arena, oc_file_desc dirFd, oc_str8 path) { - oc_str16 result = {0}; - oc_arena_scope scratch = oc_scratch_begin_next(arena); + oc_str16 result = { 0 }; + oc_arena_scope scratch = oc_scratch_begin_next(arena); - oc_str16 dirPathW = win32_path_from_handle_null_terminated(scratch.arena, dirFd); - oc_str16 pathW = oc_win32_utf8_to_wide_null_terminated(scratch.arena, path); + oc_str16 dirPathW = win32_path_from_handle_null_terminated(scratch.arena, dirFd); + oc_str16 pathW = oc_win32_utf8_to_wide_null_terminated(scratch.arena, path); - if(dirPathW.len && pathW.len) - { - u64 fullPathWSize = dirPathW.len + pathW.len; - LPWSTR fullPathW = oc_arena_push_array(scratch.arena, u16, fullPathWSize); - memcpy(fullPathW, dirPathW.ptr, (dirPathW.len-1)*sizeof(u16)); - fullPathW[dirPathW.len-1] = '\\'; - memcpy(fullPathW + dirPathW.len, pathW.ptr, pathW.len*sizeof(u16)); + if(dirPathW.len && pathW.len) + { + u64 fullPathWSize = dirPathW.len + pathW.len; + LPWSTR fullPathW = oc_arena_push_array(scratch.arena, u16, fullPathWSize); + memcpy(fullPathW, dirPathW.ptr, (dirPathW.len - 1) * sizeof(u16)); + fullPathW[dirPathW.len - 1] = '\\'; + memcpy(fullPathW + dirPathW.len, pathW.ptr, pathW.len * sizeof(u16)); - result.len = fullPathWSize; - result.ptr = oc_arena_push_array(arena, wchar_t, result.len); + result.len = fullPathWSize; + result.ptr = oc_arena_push_array(arena, wchar_t, result.len); - if(PathCanonicalizeW(result.ptr, fullPathW)) - { - result.len = lstrlenW(result.ptr); - } - else - { - result.ptr = 0; - result.len = 0; - } - } - oc_scratch_end(scratch); + if(PathCanonicalizeW(result.ptr, fullPathW)) + { + result.len = lstrlenW(result.ptr); + } + else + { + result.ptr = 0; + result.len = 0; + } + } + oc_scratch_end(scratch); - return(result); + return (result); } oc_file_desc oc_io_raw_open_at(oc_file_desc dirFd, oc_str8 path, oc_file_access accessRights, oc_file_open_flags openFlags) { - HANDLE handle = INVALID_HANDLE_VALUE; + HANDLE handle = INVALID_HANDLE_VALUE; - // convert flags - DWORD win32AccessFlags = 0; - DWORD win32ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE; - DWORD win32CreateFlags = 0; - DWORD win32AttributeFlags = FILE_ATTRIBUTE_NORMAL - | FILE_FLAG_BACKUP_SEMANTICS; + // convert flags + DWORD win32AccessFlags = 0; + DWORD win32ShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; + DWORD win32CreateFlags = 0; + DWORD win32AttributeFlags = FILE_ATTRIBUTE_NORMAL + | FILE_FLAG_BACKUP_SEMANTICS; - if(accessRights & OC_FILE_ACCESS_READ) - { - win32AccessFlags |= GENERIC_READ; - } - if(accessRights & OC_FILE_ACCESS_WRITE) - { - if(accessRights & OC_FILE_OPEN_APPEND) - { - win32AccessFlags |= FILE_APPEND_DATA; - } - else - { - win32AccessFlags |= GENERIC_WRITE; - } - } + if(accessRights & OC_FILE_ACCESS_READ) + { + win32AccessFlags |= GENERIC_READ; + } + if(accessRights & OC_FILE_ACCESS_WRITE) + { + if(accessRights & OC_FILE_OPEN_APPEND) + { + win32AccessFlags |= FILE_APPEND_DATA; + } + else + { + win32AccessFlags |= GENERIC_WRITE; + } + } - if(openFlags & OC_FILE_OPEN_TRUNCATE) - { - if(openFlags & OC_FILE_OPEN_CREATE) - { - win32CreateFlags |= CREATE_ALWAYS; - } - else - { - win32CreateFlags |= TRUNCATE_EXISTING; - } - } - if(openFlags & OC_FILE_OPEN_CREATE) - { - if(!(win32CreateFlags & CREATE_ALWAYS)) - { - win32CreateFlags |= OPEN_ALWAYS; - } - } - if( !(win32CreateFlags & OPEN_ALWAYS) - && !(win32CreateFlags & CREATE_ALWAYS) - && !(win32CreateFlags & TRUNCATE_EXISTING)) - { - win32CreateFlags |= OPEN_EXISTING; - } + if(openFlags & OC_FILE_OPEN_TRUNCATE) + { + if(openFlags & OC_FILE_OPEN_CREATE) + { + win32CreateFlags |= CREATE_ALWAYS; + } + else + { + win32CreateFlags |= TRUNCATE_EXISTING; + } + } + if(openFlags & OC_FILE_OPEN_CREATE) + { + if(!(win32CreateFlags & CREATE_ALWAYS)) + { + win32CreateFlags |= OPEN_ALWAYS; + } + } + if(!(win32CreateFlags & OPEN_ALWAYS) + && !(win32CreateFlags & CREATE_ALWAYS) + && !(win32CreateFlags & TRUNCATE_EXISTING)) + { + win32CreateFlags |= OPEN_EXISTING; + } - if(openFlags & OC_FILE_OPEN_SYMLINK) - { - win32AttributeFlags |= FILE_FLAG_OPEN_REPARSE_POINT; - } + if(openFlags & OC_FILE_OPEN_SYMLINK) + { + win32AttributeFlags |= FILE_FLAG_OPEN_REPARSE_POINT; + } - oc_arena_scope scratch = oc_scratch_begin(); - oc_str16 pathW = oc_win32_utf8_to_wide_null_terminated(scratch.arena, path); + oc_arena_scope scratch = oc_scratch_begin(); + oc_str16 pathW = oc_win32_utf8_to_wide_null_terminated(scratch.arena, path); - if(dirFd == NULL || dirFd == INVALID_HANDLE_VALUE) - { - handle = CreateFileW(pathW.ptr, win32AccessFlags, win32ShareMode, NULL, win32CreateFlags, win32AttributeFlags, NULL); - } - else - { - oc_str16 fullPathW = win32_get_path_at_null_terminated(scratch.arena, dirFd, path); - if(fullPathW.len) - { - handle = CreateFileW(fullPathW.ptr, win32AccessFlags, win32ShareMode, NULL, win32CreateFlags, win32AttributeFlags, NULL); - } - } - oc_scratch_end(scratch); - return(handle); + if(dirFd == NULL || dirFd == INVALID_HANDLE_VALUE) + { + handle = CreateFileW(pathW.ptr, win32AccessFlags, win32ShareMode, NULL, win32CreateFlags, win32AttributeFlags, NULL); + } + else + { + oc_str16 fullPathW = win32_get_path_at_null_terminated(scratch.arena, dirFd, path); + if(fullPathW.len) + { + handle = CreateFileW(fullPathW.ptr, win32AccessFlags, win32ShareMode, NULL, win32CreateFlags, win32AttributeFlags, NULL); + } + } + oc_scratch_end(scratch); + return (handle); } void oc_io_raw_close(oc_file_desc fd) { - CloseHandle(fd); + CloseHandle(fd); } bool oc_io_raw_file_exists_at(oc_file_desc dirFd, oc_str8 path, oc_file_open_flags openFlags) { - bool result = false; - oc_file_desc fd = oc_io_raw_open_at(dirFd, path, OC_FILE_ACCESS_NONE, (openFlags & OC_FILE_OPEN_SYMLINK)); - if(!oc_file_desc_is_nil(fd)) - { - result = true; - oc_io_raw_close(fd); - } - return(result); + bool result = false; + oc_file_desc fd = oc_io_raw_open_at(dirFd, path, OC_FILE_ACCESS_NONE, (openFlags & OC_FILE_OPEN_SYMLINK)); + if(!oc_file_desc_is_nil(fd)) + { + result = true; + oc_io_raw_close(fd); + } + return (result); } oc_io_error oc_io_raw_fstat(oc_file_desc fd, oc_file_status* status) { - oc_io_error error = OC_IO_OK; + oc_io_error error = OC_IO_OK; - BY_HANDLE_FILE_INFORMATION info; - if(!GetFileInformationByHandle(fd, &info)) - { - error = oc_io_raw_last_error(); - } - else - { - status->size = (((u64)info.nFileSizeHigh)<<32) | ((u64)info.nFileSizeLow); - status->uid = ((u64)info.nFileIndexHigh<<32) | ((u64)info.nFileIndexLow); + BY_HANDLE_FILE_INFORMATION info; + if(!GetFileInformationByHandle(fd, &info)) + { + error = oc_io_raw_last_error(); + } + else + { + status->size = (((u64)info.nFileSizeHigh) << 32) | ((u64)info.nFileSizeLow); + status->uid = ((u64)info.nFileIndexHigh << 32) | ((u64)info.nFileIndexLow); - DWORD attrRegularSet = FILE_ATTRIBUTE_ARCHIVE - | FILE_ATTRIBUTE_COMPRESSED - | FILE_ATTRIBUTE_ENCRYPTED - | FILE_ATTRIBUTE_HIDDEN - | FILE_ATTRIBUTE_NORMAL - | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED - | FILE_ATTRIBUTE_OFFLINE - | FILE_ATTRIBUTE_READONLY - | FILE_ATTRIBUTE_SPARSE_FILE - | FILE_ATTRIBUTE_SYSTEM - | FILE_ATTRIBUTE_TEMPORARY; + DWORD attrRegularSet = FILE_ATTRIBUTE_ARCHIVE + | FILE_ATTRIBUTE_COMPRESSED + | FILE_ATTRIBUTE_ENCRYPTED + | FILE_ATTRIBUTE_HIDDEN + | FILE_ATTRIBUTE_NORMAL + | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED + | FILE_ATTRIBUTE_OFFLINE + | FILE_ATTRIBUTE_READONLY + | FILE_ATTRIBUTE_SPARSE_FILE + | FILE_ATTRIBUTE_SYSTEM + | FILE_ATTRIBUTE_TEMPORARY; - if((info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) - { - FILE_ATTRIBUTE_TAG_INFO tagInfo; - if(!GetFileInformationByHandleEx(fd, FileAttributeTagInfo, &tagInfo, sizeof(tagInfo))) - { - error = oc_io_raw_last_error(); - } - else if(tagInfo.ReparseTag == IO_REPARSE_TAG_SYMLINK) - { - status->type = OC_FILE_SYMLINK; - } - else - { - status->type = OC_FILE_UNKNOWN; - } - } - else if(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - status->type = OC_FILE_DIRECTORY; - } - else if(info.dwFileAttributes & attrRegularSet) - { - status->type = OC_FILE_REGULAR; - } - else - { - //TODO: might want to check for socket/block/character devices? (otoh MS STL impl. doesn't seem to do it) - status->type = OC_FILE_UNKNOWN; - } + if((info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) + { + FILE_ATTRIBUTE_TAG_INFO tagInfo; + if(!GetFileInformationByHandleEx(fd, FileAttributeTagInfo, &tagInfo, sizeof(tagInfo))) + { + error = oc_io_raw_last_error(); + } + else if(tagInfo.ReparseTag == IO_REPARSE_TAG_SYMLINK) + { + status->type = OC_FILE_SYMLINK; + } + else + { + status->type = OC_FILE_UNKNOWN; + } + } + else if(info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + status->type = OC_FILE_DIRECTORY; + } + else if(info.dwFileAttributes & attrRegularSet) + { + status->type = OC_FILE_REGULAR; + } + else + { + //TODO: might want to check for socket/block/character devices? (otoh MS STL impl. doesn't seem to do it) + status->type = OC_FILE_UNKNOWN; + } - status->perm = OC_FILE_OWNER_READ | OC_FILE_GROUP_READ | OC_FILE_OTHER_READ; - if(!(info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) - { - status->perm = OC_FILE_OWNER_WRITE | OC_FILE_GROUP_WRITE | OC_FILE_OTHER_WRITE; - } - //TODO: times - } - return(error); + status->perm = OC_FILE_OWNER_READ | OC_FILE_GROUP_READ | OC_FILE_OTHER_READ; + if(!(info.dwFileAttributes & FILE_ATTRIBUTE_READONLY)) + { + status->perm = OC_FILE_OWNER_WRITE | OC_FILE_GROUP_WRITE | OC_FILE_OTHER_WRITE; + } + //TODO: times + } + return (error); } oc_io_error oc_io_raw_fstat_at(oc_file_desc dirFd, oc_str8 name, oc_file_open_flags openFlags, oc_file_status* status) { - oc_io_error error = OC_IO_OK; - oc_file_desc fd = oc_io_raw_open_at(dirFd, name, OC_FILE_ACCESS_NONE, OC_FILE_OPEN_SYMLINK); - if(oc_file_desc_is_nil(fd)) - { - error = oc_io_raw_last_error(); - } - else - { - error = oc_io_raw_fstat(fd, status); - oc_io_raw_close(fd); - } - return(error); + oc_io_error error = OC_IO_OK; + oc_file_desc fd = oc_io_raw_open_at(dirFd, name, OC_FILE_ACCESS_NONE, OC_FILE_OPEN_SYMLINK); + if(oc_file_desc_is_nil(fd)) + { + error = oc_io_raw_last_error(); + } + else + { + error = oc_io_raw_fstat(fd, status); + oc_io_raw_close(fd); + } + return (error); } typedef struct { - ULONG ReparseTag; - USHORT ReparseDataLength; - USHORT Reserved; - union - { - struct - { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - ULONG Flags; - WCHAR PathBuffer[1]; - } SymbolicLinkReparseBuffer; + ULONG ReparseTag; + USHORT ReparseDataLength; + USHORT Reserved; - struct - { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - WCHAR PathBuffer[1]; - } MountPointReparseBuffer; + union + { + struct + { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + ULONG Flags; + WCHAR PathBuffer[1]; + } SymbolicLinkReparseBuffer; - struct - { - UCHAR DataBuffer[1]; - } GenericReparseBuffer; - }; + struct + { + USHORT SubstituteNameOffset; + USHORT SubstituteNameLength; + USHORT PrintNameOffset; + USHORT PrintNameLength; + WCHAR PathBuffer[1]; + } MountPointReparseBuffer; + + struct + { + UCHAR DataBuffer[1]; + } GenericReparseBuffer; + }; } oc_win32_reparse_data_buffer; oc_io_raw_read_link_result oc_io_raw_read_link(oc_arena* arena, oc_file_desc fd) { - oc_io_raw_read_link_result result = {0}; + oc_io_raw_read_link_result result = { 0 }; - char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; - DWORD bytesReturned; + char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; + DWORD bytesReturned; - if(!DeviceIoControl(fd, FSCTL_GET_REPARSE_POINT, NULL, 0, buffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bytesReturned, 0)) - { - result.error = oc_io_raw_last_error(); - } - else - { - oc_win32_reparse_data_buffer* reparse = (oc_win32_reparse_data_buffer*)buffer; - if(reparse->ReparseTag == IO_REPARSE_TAG_SYMLINK) - { - oc_str16 nameW = {0}; - nameW.len = reparse->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t); - nameW.ptr = (u16*)((char*)reparse->SymbolicLinkReparseBuffer.PathBuffer + reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset); - result.target = oc_win32_wide_to_utf8(arena, nameW); - } - else - { - result.error = OC_IO_ERR_UNKNOWN; - } - } - return(result); + if(!DeviceIoControl(fd, FSCTL_GET_REPARSE_POINT, NULL, 0, buffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bytesReturned, 0)) + { + result.error = oc_io_raw_last_error(); + } + else + { + oc_win32_reparse_data_buffer* reparse = (oc_win32_reparse_data_buffer*)buffer; + if(reparse->ReparseTag == IO_REPARSE_TAG_SYMLINK) + { + oc_str16 nameW = { 0 }; + nameW.len = reparse->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar_t); + nameW.ptr = (u16*)((char*)reparse->SymbolicLinkReparseBuffer.PathBuffer + reparse->SymbolicLinkReparseBuffer.SubstituteNameOffset); + result.target = oc_win32_wide_to_utf8(arena, nameW); + } + else + { + result.error = OC_IO_ERR_UNKNOWN; + } + } + return (result); } oc_io_raw_read_link_result oc_io_raw_read_link_at(oc_arena* arena, oc_file_desc dirFd, oc_str8 name) { - oc_file_desc fd = oc_io_raw_open_at(dirFd, name, OC_FILE_ACCESS_READ, OC_FILE_OPEN_SYMLINK); - oc_io_raw_read_link_result result = oc_io_raw_read_link(arena, fd); - oc_io_raw_close(fd); - return(result); + oc_file_desc fd = oc_io_raw_open_at(dirFd, name, OC_FILE_ACCESS_READ, OC_FILE_OPEN_SYMLINK); + oc_io_raw_read_link_result result = oc_io_raw_read_link(arena, fd); + oc_io_raw_close(fd); + return (result); } static oc_io_cmp oc_io_close(oc_file_slot* slot, oc_io_req* req, oc_file_table* table) { - oc_io_cmp cmp = {0}; - if(slot->fd) - { - CloseHandle(slot->fd); - } - oc_file_slot_recycle(table, slot); - return(cmp); + oc_io_cmp cmp = { 0 }; + if(slot->fd) + { + CloseHandle(slot->fd); + } + oc_file_slot_recycle(table, slot); + return (cmp); } static oc_io_cmp oc_io_fstat(oc_file_slot* slot, oc_io_req* req) { - oc_io_cmp cmp = {0}; + oc_io_cmp cmp = { 0 }; - if(req->size < sizeof(oc_file_status)) - { - cmp.error = OC_IO_ERR_ARG; - } - else - { - slot->error = oc_io_raw_fstat(slot->fd, (oc_file_status*)req->buffer); - cmp.error = slot->error; - } - return(cmp); + if(req->size < sizeof(oc_file_status)) + { + cmp.error = OC_IO_ERR_ARG; + } + else + { + slot->error = oc_io_raw_fstat(slot->fd, (oc_file_status*)req->buffer); + cmp.error = slot->error; + } + return (cmp); } static oc_io_cmp oc_io_seek(oc_file_slot* slot, oc_io_req* req) { - oc_io_cmp cmp = {0}; + oc_io_cmp cmp = { 0 }; - DWORD whence; - switch(req->whence) - { - case OC_FILE_SEEK_CURRENT: - whence = FILE_CURRENT; - break; + DWORD whence; + switch(req->whence) + { + case OC_FILE_SEEK_CURRENT: + whence = FILE_CURRENT; + break; - case OC_FILE_SEEK_SET: - whence = FILE_BEGIN; - break; + case OC_FILE_SEEK_SET: + whence = FILE_BEGIN; + break; - case OC_FILE_SEEK_END: - whence = FILE_END; - } + case OC_FILE_SEEK_END: + whence = FILE_END; + } - LARGE_INTEGER off = {.QuadPart = req->offset}; - LARGE_INTEGER newPos = {0}; + LARGE_INTEGER off = { .QuadPart = req->offset }; + LARGE_INTEGER newPos = { 0 }; - if(!SetFilePointerEx(slot->fd, off, &newPos, whence)) - { - slot->error = oc_io_raw_last_error(); - cmp.error = slot->error; - } - else - { - cmp.result = newPos.QuadPart; - } + if(!SetFilePointerEx(slot->fd, off, &newPos, whence)) + { + slot->error = oc_io_raw_last_error(); + cmp.error = slot->error; + } + else + { + cmp.result = newPos.QuadPart; + } - return(cmp); + return (cmp); } static oc_io_cmp oc_io_read(oc_file_slot* slot, oc_io_req* req) { - oc_io_cmp cmp = {0}; + oc_io_cmp cmp = { 0 }; - if(slot->type != OC_FILE_REGULAR) - { - slot->error = OC_IO_ERR_PERM; - cmp.error = slot->error; - } - else - { - DWORD bytesRead = 0; + if(slot->type != OC_FILE_REGULAR) + { + slot->error = OC_IO_ERR_PERM; + cmp.error = slot->error; + } + else + { + DWORD bytesRead = 0; - if(!ReadFile(slot->fd, req->buffer, req->size, &bytesRead, NULL)) - { - slot->error = oc_io_raw_last_error(); - cmp.result = 0; - cmp.error = slot->error; - } - else - { - cmp.result = bytesRead; - } - } - return(cmp); + if(!ReadFile(slot->fd, req->buffer, req->size, &bytesRead, NULL)) + { + slot->error = oc_io_raw_last_error(); + cmp.result = 0; + cmp.error = slot->error; + } + else + { + cmp.result = bytesRead; + } + } + return (cmp); } static oc_io_cmp oc_io_write(oc_file_slot* slot, oc_io_req* req) { - oc_io_cmp cmp = {0}; + oc_io_cmp cmp = { 0 }; - if(slot->type != OC_FILE_REGULAR) - { - slot->error = OC_IO_ERR_PERM; - cmp.error = slot->error; - } - else - { - DWORD bytesWritten = 0; + if(slot->type != OC_FILE_REGULAR) + { + slot->error = OC_IO_ERR_PERM; + cmp.error = slot->error; + } + else + { + DWORD bytesWritten = 0; - if(!WriteFile(slot->fd, req->buffer, req->size, &bytesWritten, NULL)) - { - slot->error = oc_io_raw_last_error(); - cmp.result = 0; - cmp.error = slot->error; - } - else - { - cmp.result = bytesWritten; - } - } - return(cmp); + if(!WriteFile(slot->fd, req->buffer, req->size, &bytesWritten, NULL)) + { + slot->error = oc_io_raw_last_error(); + cmp.result = 0; + cmp.error = slot->error; + } + else + { + cmp.result = bytesWritten; + } + } + return (cmp); } static oc_io_cmp oc_io_get_error(oc_file_slot* slot, oc_io_req* req) { - oc_io_cmp cmp = {0}; - cmp.result = slot->error; - return(cmp); + oc_io_cmp cmp = { 0 }; + cmp.result = slot->error; + return (cmp); } oc_io_cmp oc_io_wait_single_req_with_table(oc_io_req* req, oc_file_table* table) { - oc_io_cmp cmp = {0}; + oc_io_cmp cmp = { 0 }; - oc_file_slot* slot = oc_file_slot_from_handle(table, req->handle); - if(!slot) - { - if(req->op != OC_IO_OPEN_AT) - { - cmp.error = OC_IO_ERR_HANDLE; - } - } - else if(slot->fatal && req->op != OC_IO_CLOSE && req->op != OC_OC_IO_ERROR) - { - cmp.error = OC_IO_ERR_PREV; - } + oc_file_slot* slot = oc_file_slot_from_handle(table, req->handle); + if(!slot) + { + if(req->op != OC_IO_OPEN_AT) + { + cmp.error = OC_IO_ERR_HANDLE; + } + } + else if(slot->fatal && req->op != OC_IO_CLOSE && req->op != OC_OC_IO_ERROR) + { + cmp.error = OC_IO_ERR_PREV; + } - if(cmp.error == OC_IO_OK) - { - switch(req->op) - { - case OC_IO_OPEN_AT: - cmp = oc_io_open_at(slot, req, table); - break; + if(cmp.error == OC_IO_OK) + { + switch(req->op) + { + case OC_IO_OPEN_AT: + cmp = oc_io_open_at(slot, req, table); + break; - case OC_IO_FSTAT: - cmp = oc_io_fstat(slot, req); - break; + case OC_IO_FSTAT: + cmp = oc_io_fstat(slot, req); + break; - case OC_IO_CLOSE: - cmp = oc_io_close(slot, req, table); - break; + case OC_IO_CLOSE: + cmp = oc_io_close(slot, req, table); + break; - case OC_IO_READ: - cmp = oc_io_read(slot, req); - break; + case OC_IO_READ: + cmp = oc_io_read(slot, req); + break; - case OC_IO_WRITE: - cmp = oc_io_write(slot, req); - break; + case OC_IO_WRITE: + cmp = oc_io_write(slot, req); + break; - case OC_IO_SEEK: - cmp = oc_io_seek(slot, req); - break; + case OC_IO_SEEK: + cmp = oc_io_seek(slot, req); + break; - case OC_OC_IO_ERROR: - cmp = oc_io_get_error(slot, req); - break; + case OC_OC_IO_ERROR: + cmp = oc_io_get_error(slot, req); + break; - default: - cmp.error = OC_IO_ERR_OP; - if(slot) - { - slot->error = cmp.error; - } - break; - } - } - return(cmp); + default: + cmp.error = OC_IO_ERR_OP; + if(slot) + { + slot->error = cmp.error; + } + break; + } + } + return (cmp); } diff --git a/src/platform/win32_memory.c b/src/platform/win32_memory.c index 0d758a3..53431b4 100644 --- a/src/platform/win32_memory.c +++ b/src/platform/win32_memory.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: win32_memory.c * @author: Martin Fouilleul @@ -7,39 +7,39 @@ * *****************************************************************/ #define WIN32_LEAN_AND_MEAN -#include -#include"platform_memory.h" +#include "platform_memory.h" +#include void* oc_base_reserve_win32(oc_base_allocator* context, u64 size) { - void* result = VirtualAlloc(0, size, MEM_RESERVE, PAGE_READWRITE); - return(result); + void* result = VirtualAlloc(0, size, MEM_RESERVE, PAGE_READWRITE); + return (result); } void oc_base_commit_win32(oc_base_allocator* context, void* ptr, u64 size) { - VirtualAlloc(ptr, size, MEM_COMMIT, PAGE_READWRITE); + VirtualAlloc(ptr, size, MEM_COMMIT, PAGE_READWRITE); } void oc_base_release_win32(oc_base_allocator* context, void* ptr, u64 size) { - VirtualFree(ptr, size, MEM_RELEASE); + VirtualFree(ptr, size, MEM_RELEASE); } void oc_base_decommit_win32(oc_base_allocator* context, void* ptr, u64 size) { - VirtualFree(ptr, size, MEM_DECOMMIT); + VirtualFree(ptr, size, MEM_DECOMMIT); } oc_base_allocator* oc_base_allocator_default() { - static oc_base_allocator base = {0}; - if(base.reserve == 0) - { - base.reserve = oc_base_reserve_win32; - base.commit = oc_base_commit_win32; - base.decommit = oc_base_decommit_win32; - base.release = oc_base_release_win32; - } - return(&base); + static oc_base_allocator base = { 0 }; + if(base.reserve == 0) + { + base.reserve = oc_base_reserve_win32; + base.commit = oc_base_commit_win32; + base.decommit = oc_base_decommit_win32; + base.release = oc_base_release_win32; + } + return (&base); } diff --git a/src/platform/win32_path.c b/src/platform/win32_path.c index c25f2f0..de04e19 100644 --- a/src/platform/win32_path.c +++ b/src/platform/win32_path.c @@ -1,42 +1,42 @@ -/************************************************************//** +/************************************************************/ /** * * @file: win32_path.c * @author: Martin Fouilleul * @date: 24/05/2023 * *****************************************************************/ -#include // PathIsRelative() +#include // PathIsRelative() -#include"win32_string_helpers.h" -#include"platform_path.c" +#include "platform_path.c" +#include "win32_string_helpers.h" bool oc_path_is_absolute(oc_str8 path) { - oc_arena_scope scratch = oc_scratch_begin(); - oc_str16 pathW = oc_win32_utf8_to_wide_null_terminated(scratch.arena, path); - bool result = !PathIsRelativeW(pathW.ptr); + oc_arena_scope scratch = oc_scratch_begin(); + oc_str16 pathW = oc_win32_utf8_to_wide_null_terminated(scratch.arena, path); + bool result = !PathIsRelativeW(pathW.ptr); - oc_scratch_end(scratch); - return(result); + oc_scratch_end(scratch); + return (result); } oc_str8 oc_path_executable(oc_arena* arena) { - /////////////////////////////////////////////////////////////////// - //TODO use wide chars - /////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////// + //TODO use wide chars + /////////////////////////////////////////////////////////////////// - char* buffer = oc_arena_push_array(arena, char, MAX_PATH+2); - int size = GetModuleFileName(NULL, buffer, MAX_PATH+1); - //TODO: check for errors... - for(int i=0; i +#include -#include"win32_string_helpers.h" +#include "win32_string_helpers.h" oc_str16 oc_win32_utf8_to_wide_null_terminated(oc_arena* arena, oc_str8 s) { - oc_str16 res = {0}; - res.len = 1 + MultiByteToWideChar(CP_UTF8, 0, s.ptr, s.len, NULL, 0); - res.ptr = oc_arena_push_array(arena, u16, res.len); - MultiByteToWideChar(CP_UTF8, 0, s.ptr, s.len, res.ptr, res.len); - res.ptr[res.len-1] = '\0'; - return(res); + oc_str16 res = { 0 }; + res.len = 1 + MultiByteToWideChar(CP_UTF8, 0, s.ptr, s.len, NULL, 0); + res.ptr = oc_arena_push_array(arena, u16, res.len); + MultiByteToWideChar(CP_UTF8, 0, s.ptr, s.len, res.ptr, res.len); + res.ptr[res.len - 1] = '\0'; + return (res); } oc_str8 oc_win32_wide_to_utf8(oc_arena* arena, oc_str16 s) { - oc_str8 res = {0}; - res.len = WideCharToMultiByte(CP_UTF8, 0, s.ptr, s.len, NULL, 0, NULL, NULL); - res.ptr = oc_arena_push_array(arena, u8, res.len); - WideCharToMultiByte(CP_UTF8, 0, s.ptr, s.len, res.ptr, res.len, NULL, NULL); - return(res); + oc_str8 res = { 0 }; + res.len = WideCharToMultiByte(CP_UTF8, 0, s.ptr, s.len, NULL, 0, NULL, NULL); + res.ptr = oc_arena_push_array(arena, u8, res.len); + WideCharToMultiByte(CP_UTF8, 0, s.ptr, s.len, res.ptr, res.len, NULL, NULL); + return (res); } diff --git a/src/platform/win32_string_helpers.h b/src/platform/win32_string_helpers.h index 4b76a53..7e00490 100644 --- a/src/platform/win32_string_helpers.h +++ b/src/platform/win32_string_helpers.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: win32_string_helpers.h * @author: Martin Fouilleul @@ -8,10 +8,9 @@ #ifndef __WIN32_STRING_HELPERS_H_ #define __WIN32_STRING_HELPERS_H_ -#include"util/strings.h" +#include "util/strings.h" oc_str16 oc_win32_utf8_to_wide_null_terminated(oc_arena* arena, oc_str8 s); oc_str8 oc_win32_wide_to_utf8(oc_arena* arena, oc_str16 s); - #endif // __WIN32_STRING_HELPERS_H_ diff --git a/src/platform/win32_thread.c b/src/platform/win32_thread.c index d6c4e0c..b9658b3 100644 --- a/src/platform/win32_thread.c +++ b/src/platform/win32_thread.c @@ -1,232 +1,234 @@ -/************************************************************//** +/************************************************************/ /** * * @file: win32_thread.c * @author: Reuben Dunnington * @date: 7/30/2023 * *****************************************************************/ -#include -#include -#include //INFINITY -#include // PostMessage +#include //INFINITY +#include +#include +#include // PostMessage -#include"platform_thread.h" +#include "platform_thread.h" struct oc_thread { - oc_thread_start_function start; - HANDLE handle; - DWORD threadId; - void* userPointer; - oc_str8 name; - char nameBuffer[OC_THREAD_NAME_MAX_SIZE]; + oc_thread_start_function start; + HANDLE handle; + DWORD threadId; + void* userPointer; + oc_str8 name; + char nameBuffer[OC_THREAD_NAME_MAX_SIZE]; }; static DWORD WINAPI oc_thread_bootstrap(LPVOID lpParameter) { - oc_thread* thread = (oc_thread*)lpParameter; - i32 exitCode = thread->start(thread->userPointer); - return(exitCode); + oc_thread* thread = (oc_thread*)lpParameter; + i32 exitCode = thread->start(thread->userPointer); + return (exitCode); } oc_thread* oc_thread_create_with_name(oc_thread_start_function start, void* userPointer, oc_str8 name) { - oc_thread* thread = (oc_thread*)malloc(sizeof(oc_thread)); - thread->start = start; - thread->handle = INVALID_HANDLE_VALUE; - thread->userPointer = userPointer; - if(name.len && name.ptr) - { - strncpy(thread->nameBuffer, name.ptr, oc_min(name.len, OC_THREAD_NAME_MAX_SIZE-1)); - thread->nameBuffer[OC_THREAD_NAME_MAX_SIZE-1] = '\0'; - thread->name = OC_STR8(thread->nameBuffer); - } - else - { - thread->nameBuffer[0] = '\0'; - thread->name = oc_str8_from_buffer(0, thread->nameBuffer); - } + oc_thread* thread = (oc_thread*)malloc(sizeof(oc_thread)); + thread->start = start; + thread->handle = INVALID_HANDLE_VALUE; + thread->userPointer = userPointer; + if(name.len && name.ptr) + { + strncpy(thread->nameBuffer, name.ptr, oc_min(name.len, OC_THREAD_NAME_MAX_SIZE - 1)); + thread->nameBuffer[OC_THREAD_NAME_MAX_SIZE - 1] = '\0'; + thread->name = OC_STR8(thread->nameBuffer); + } + else + { + thread->nameBuffer[0] = '\0'; + thread->name = oc_str8_from_buffer(0, thread->nameBuffer); + } - SECURITY_ATTRIBUTES childProcessSecurity = { - .nLength = sizeof(SECURITY_ATTRIBUTES), - .bInheritHandle = false, - }; - SIZE_T stackSize = 0; // uses process default - DWORD flags = 0; - DWORD threadId = 0; - thread->handle = CreateThread(&childProcessSecurity, stackSize, oc_thread_bootstrap, thread, flags, &threadId); - if (thread->handle == NULL) { - free(thread); - return(NULL); - } + SECURITY_ATTRIBUTES childProcessSecurity = { + .nLength = sizeof(SECURITY_ATTRIBUTES), + .bInheritHandle = false, + }; + SIZE_T stackSize = 0; // uses process default + DWORD flags = 0; + DWORD threadId = 0; + thread->handle = CreateThread(&childProcessSecurity, stackSize, oc_thread_bootstrap, thread, flags, &threadId); + if(thread->handle == NULL) + { + free(thread); + return (NULL); + } - thread->threadId = threadId; + thread->threadId = threadId; - if (thread->name.len) { - wchar_t widename[OC_THREAD_NAME_MAX_SIZE]; - size_t length = mbstowcs(widename, thread->nameBuffer, OC_THREAD_NAME_MAX_SIZE - 1); - widename[length] = '\0'; + if(thread->name.len) + { + wchar_t widename[OC_THREAD_NAME_MAX_SIZE]; + size_t length = mbstowcs(widename, thread->nameBuffer, OC_THREAD_NAME_MAX_SIZE - 1); + widename[length] = '\0'; - SetThreadDescription(thread->handle, widename); - } + SetThreadDescription(thread->handle, widename); + } - return(thread); + return (thread); } oc_thread* oc_thread_create(oc_thread_start_function start, void* userPointer) { - return(oc_thread_create_with_name(start, userPointer, (oc_str8){0})); + return (oc_thread_create_with_name(start, userPointer, (oc_str8){ 0 })); } oc_str8 oc_thread_get_name(oc_thread* thread) { - return(thread->name); + return (thread->name); } u64 oc_thread_unique_id(oc_thread* thread) { - return(thread->threadId); + return (thread->threadId); } u64 oc_thread_self_id() { - return(GetCurrentThreadId()); + return (GetCurrentThreadId()); } int oc_thread_signal(oc_thread* thread, int sig) { - BOOL success = TerminateThread(thread->handle, (DWORD)sig); - return(success ? 0 : -1); + BOOL success = TerminateThread(thread->handle, (DWORD)sig); + return (success ? 0 : -1); } int oc_thread_join(oc_thread* thread, i64* exitCode) { - DWORD result = WaitForSingleObject(thread->handle, INFINITE); - if (result == WAIT_FAILED) { - return(-1); - } + DWORD result = WaitForSingleObject(thread->handle, INFINITE); + if(result == WAIT_FAILED) + { + return (-1); + } - if (exitCode) - { - DWORD exitCodeWin32 = 0; - if (GetExitCodeThread(thread->handle, &exitCodeWin32)) - { - *exitCode = exitCodeWin32; - } - } + if(exitCode) + { + DWORD exitCodeWin32 = 0; + if(GetExitCodeThread(thread->handle, &exitCodeWin32)) + { + *exitCode = exitCodeWin32; + } + } - free(thread); - return(0); + free(thread); + return (0); } int oc_thread_detach(oc_thread* thread) { - if (CloseHandle(thread->handle)) - { - free(thread); - return(0); - } - return(-1); + if(CloseHandle(thread->handle)) + { + free(thread); + return (0); + } + return (-1); } - struct oc_mutex { - u64 owningThreadId; - SRWLOCK lock; + u64 owningThreadId; + SRWLOCK lock; }; oc_mutex* oc_mutex_create() { - oc_mutex* mutex = (oc_mutex*)malloc(sizeof(oc_mutex)); - mutex->owningThreadId = 0; - InitializeSRWLock(&mutex->lock); - return mutex; + oc_mutex* mutex = (oc_mutex*)malloc(sizeof(oc_mutex)); + mutex->owningThreadId = 0; + InitializeSRWLock(&mutex->lock); + return mutex; } int oc_mutex_destroy(oc_mutex* mutex) { - OC_DEBUG_ASSERT(mutex->owningThreadId == 0); - free(mutex); - return(0); + OC_DEBUG_ASSERT(mutex->owningThreadId == 0); + free(mutex); + return (0); } int oc_mutex_lock(oc_mutex* mutex) { - OC_DEBUG_ASSERT(mutex->owningThreadId == 0); - AcquireSRWLockExclusive(&mutex->lock); - return(0); + OC_DEBUG_ASSERT(mutex->owningThreadId == 0); + AcquireSRWLockExclusive(&mutex->lock); + return (0); } int oc_mutex_unlock(oc_mutex* mutex) { - OC_DEBUG_ASSERT(oc_thread_self_id() == mutex->owningThreadId); - ReleaseSRWLockExclusive(&mutex->lock); - mutex->owningThreadId = 0; - return(0); + OC_DEBUG_ASSERT(oc_thread_self_id() == mutex->owningThreadId); + ReleaseSRWLockExclusive(&mutex->lock); + mutex->owningThreadId = 0; + return (0); } // oc_ticket has a mirrored implementation in posix_thread.c void oc_ticket_init(oc_ticket* mutex) { - mutex->nextTicket = 0; - mutex->serving = 0; + mutex->nextTicket = 0; + mutex->serving = 0; } void oc_ticket_lock(oc_ticket* mutex) { - u64 ticket = atomic_fetch_add(&mutex->nextTicket, 1ULL); - while(ticket != mutex->serving); //spin + u64 ticket = atomic_fetch_add(&mutex->nextTicket, 1ULL); + while(ticket != mutex->serving) + ; //spin } void oc_ticket_unlock(oc_ticket* mutex) { - atomic_fetch_add(&mutex->serving, 1ULL); + atomic_fetch_add(&mutex->serving, 1ULL); } - struct oc_condition { - CONDITION_VARIABLE cond; + CONDITION_VARIABLE cond; }; oc_condition* oc_condition_create() { - oc_condition* cond = (oc_condition*)malloc(sizeof(oc_condition)); - InitializeConditionVariable(&cond->cond); - return cond; + oc_condition* cond = (oc_condition*)malloc(sizeof(oc_condition)); + InitializeConditionVariable(&cond->cond); + return cond; } int oc_condition_destroy(oc_condition* cond) { - free(cond); - return(0); + free(cond); + return (0); } int oc_condition_wait(oc_condition* cond, oc_mutex* mutex) { - return oc_condition_timedwait(cond, mutex, INFINITY); + return oc_condition_timedwait(cond, mutex, INFINITY); } int oc_condition_timedwait(oc_condition* cond, oc_mutex* mutex, f64 seconds) { - const f32 ms = (seconds == INFINITY) ? INFINITE : seconds * 1000; - if (!SleepConditionVariableSRW(&cond->cond, &mutex->lock, ms, 0)) - { - return(GetLastError()); - } - return(0); + const f32 ms = (seconds == INFINITY) ? INFINITE : seconds * 1000; + if(!SleepConditionVariableSRW(&cond->cond, &mutex->lock, ms, 0)) + { + return (GetLastError()); + } + return (0); } int oc_condition_signal(oc_condition* cond) { - WakeConditionVariable(&cond->cond); - return(0); + WakeConditionVariable(&cond->cond); + return (0); } int oc_condition_broadcast(oc_condition* cond) { - WakeAllConditionVariable(&cond->cond); - return(0); + WakeAllConditionVariable(&cond->cond); + return (0); } diff --git a/src/runtime.c b/src/runtime.c index 2e2e3fd..8c112c9 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -1,194 +1,193 @@ -/************************************************************//** +/************************************************************/ /** * * @file: runtime.c * @author: Martin Fouilleul * @date: 11/04/2023 * *****************************************************************/ -#include -#include -#include +#include +#include +#include #define OC_INCLUDE_GL_API -#include"orca.h" -#include"graphics/graphics_common.h" +#include "graphics/graphics_common.h" +#include "orca.h" -#include"runtime.h" -#include"runtime_memory.c" -#include"runtime_io.c" +#include "runtime.h" +#include "runtime_io.c" +#include "runtime_memory.c" oc_font orca_font_create(const char* resourcePath) { - //NOTE(martin): create default font - oc_str8 fontPath = oc_path_executable_relative(oc_scratch(), OC_STR8(resourcePath)); + //NOTE(martin): create default font + oc_str8 fontPath = oc_path_executable_relative(oc_scratch(), OC_STR8(resourcePath)); - FILE* fontFile = fopen(fontPath.ptr, "r"); - if(!fontFile) - { - oc_log_error("Could not load font file '%s': %s\n", fontPath.ptr, strerror(errno)); - return(oc_font_nil()); - } - char* fontData = 0; - fseek(fontFile, 0, SEEK_END); - u32 fontDataSize = ftell(fontFile); - rewind(fontFile); - fontData = malloc(fontDataSize); - fread(fontData, 1, fontDataSize, fontFile); - fclose(fontFile); + FILE* fontFile = fopen(fontPath.ptr, "r"); + if(!fontFile) + { + oc_log_error("Could not load font file '%s': %s\n", fontPath.ptr, strerror(errno)); + return (oc_font_nil()); + } + char* fontData = 0; + fseek(fontFile, 0, SEEK_END); + u32 fontDataSize = ftell(fontFile); + rewind(fontFile); + fontData = malloc(fontDataSize); + fread(fontData, 1, fontDataSize, fontFile); + fclose(fontFile); - oc_unicode_range ranges[5] = {OC_UNICODE_BASIC_LATIN, - OC_UNICODE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT, - OC_UNICODE_LATIN_EXTENDED_A, - OC_UNICODE_LATIN_EXTENDED_B, - OC_UNICODE_SPECIALS}; + oc_unicode_range ranges[5] = { OC_UNICODE_BASIC_LATIN, + OC_UNICODE_C1_CONTROLS_AND_LATIN_1_SUPPLEMENT, + OC_UNICODE_LATIN_EXTENDED_A, + OC_UNICODE_LATIN_EXTENDED_B, + OC_UNICODE_SPECIALS }; - oc_font font = oc_font_create_from_memory(oc_str8_from_buffer(fontDataSize, fontData), 5, ranges); + oc_font font = oc_font_create_from_memory(oc_str8_from_buffer(fontDataSize, fontData), 5, ranges); - free(fontData); + free(fontData); - return(font); + return (font); } oc_font oc_font_create_default() { - return(orca_font_create("../resources/OpenSansLatinSubset.ttf")); + return (orca_font_create("../resources/OpenSansLatinSubset.ttf")); } - -oc_runtime __orcaApp = {0}; +oc_runtime __orcaApp = { 0 }; oc_runtime* oc_runtime_get() { - return(&__orcaApp); + return (&__orcaApp); } oc_runtime_env* oc_runtime_env_get() { - return(&__orcaApp.runtime); + return (&__orcaApp.runtime); } void oc_runtime_log(oc_log_level level, - int fileLen, - char* file, - int functionLen, - char* function, - int line, - int msgLen, - char* msg) + int fileLen, + char* file, + int functionLen, + char* function, + int line, + int msgLen, + char* msg) { - oc_debug_overlay* debug = &__orcaApp.debugOverlay; + oc_debug_overlay* debug = &__orcaApp.debugOverlay; - //NOTE: recycle first entry if we exceeded the max entry count - debug->entryCount++; - if(debug->entryCount > debug->maxEntries) - { - log_entry* e = oc_list_pop_entry(&debug->logEntries, log_entry, listElt); - if(e) - { - oc_list_push(&debug->logFreeList, &e->listElt); - debug->entryCount--; - } - } + //NOTE: recycle first entry if we exceeded the max entry count + debug->entryCount++; + if(debug->entryCount > debug->maxEntries) + { + log_entry* e = oc_list_pop_entry(&debug->logEntries, log_entry, listElt); + if(e) + { + oc_list_push(&debug->logFreeList, &e->listElt); + debug->entryCount--; + } + } - u64 cap = sizeof(log_entry)+fileLen+functionLen+msgLen; + u64 cap = sizeof(log_entry) + fileLen + functionLen + msgLen; - //NOTE: allocate a new entry - //TODO: should probably use a buddy allocator over the arena or something - log_entry* entry = 0; - oc_list_for(&debug->logFreeList, elt, log_entry, listElt) - { - if(elt->cap >= cap) - { - oc_list_remove(&debug->logFreeList, &elt->listElt); - entry = elt; - break; - } - } + //NOTE: allocate a new entry + //TODO: should probably use a buddy allocator over the arena or something + log_entry* entry = 0; + oc_list_for(&debug->logFreeList, elt, log_entry, listElt) + { + if(elt->cap >= cap) + { + oc_list_remove(&debug->logFreeList, &elt->listElt); + entry = elt; + break; + } + } - if(!entry) - { - char* mem = oc_arena_push(&debug->logArena, cap); - entry = (log_entry*)mem; - entry->cap = cap; - } - char* payload = (char*)entry + sizeof(log_entry); + if(!entry) + { + char* mem = oc_arena_push(&debug->logArena, cap); + entry = (log_entry*)mem; + entry->cap = cap; + } + char* payload = (char*)entry + sizeof(log_entry); - entry->file.len = fileLen; - entry->file.ptr = payload; - payload += entry->file.len; + entry->file.len = fileLen; + entry->file.ptr = payload; + payload += entry->file.len; - entry->function.len = functionLen; - entry->function.ptr = payload; - payload += entry->function.len; + entry->function.len = functionLen; + entry->function.ptr = payload; + payload += entry->function.len; - entry->msg.len = msgLen; - entry->msg.ptr = payload; - payload += entry->msg.len; + entry->msg.len = msgLen; + entry->msg.ptr = payload; + payload += entry->msg.len; - memcpy(entry->file.ptr, file, fileLen); - memcpy(entry->function.ptr, function, functionLen); - memcpy(entry->msg.ptr, msg, msgLen); + memcpy(entry->file.ptr, file, fileLen); + memcpy(entry->function.ptr, function, functionLen); + memcpy(entry->msg.ptr, msg, msgLen); - entry->level = level; - entry->line = line; - entry->recordIndex = debug->logEntryTotalCount; - debug->logEntryTotalCount++; + entry->level = level; + entry->line = line; + entry->recordIndex = debug->logEntryTotalCount; + debug->logEntryTotalCount++; - oc_list_push_back(&debug->logEntries, &entry->listElt); + oc_list_push_back(&debug->logEntries, &entry->listElt); - oc_log_ext(level, - file, - function, - line, - "%.*s\n", - msgLen, - msg); + oc_log_ext(level, + file, + function, + line, + "%.*s\n", + msgLen, + msg); } typedef struct orca_surface_create_data { - oc_window window; - oc_surface_api api; - oc_surface surface; + oc_window window; + oc_surface_api api; + oc_surface surface; } orca_surface_create_data; i32 orca_surface_callback(void* user) { - orca_surface_create_data* data = (orca_surface_create_data*)user; - data->surface = oc_surface_create_for_window(data->window, data->api); + orca_surface_create_data* data = (orca_surface_create_data*)user; + data->surface = oc_surface_create_for_window(data->window, data->api); - //NOTE: this will be called on main thread, so we need to deselect the surface here, - // and reselect it on the orca thread - oc_surface_deselect(); + //NOTE: this will be called on main thread, so we need to deselect the surface here, + // and reselect it on the orca thread + oc_surface_deselect(); - return(0); + return (0); } oc_surface orca_surface_canvas(void) { - orca_surface_create_data data = { - .surface = oc_surface_nil(), - .window = __orcaApp.window, - .api = OC_CANVAS - }; + orca_surface_create_data data = { + .surface = oc_surface_nil(), + .window = __orcaApp.window, + .api = OC_CANVAS + }; - oc_dispatch_on_main_thread_sync(__orcaApp.window, orca_surface_callback, (void*)&data); - oc_surface_select(data.surface); - return(data.surface); + oc_dispatch_on_main_thread_sync(__orcaApp.window, orca_surface_callback, (void*)&data); + oc_surface_select(data.surface); + return (data.surface); } oc_surface orca_surface_gles(void) { - orca_surface_create_data data = { - .surface = oc_surface_nil(), - .window = __orcaApp.window, - .api = OC_GLES - }; + orca_surface_create_data data = { + .surface = oc_surface_nil(), + .window = __orcaApp.window, + .api = OC_GLES + }; - oc_dispatch_on_main_thread_sync(__orcaApp.window, orca_surface_callback, (void*)&data); - oc_surface_select(data.surface); - return(data.surface); + oc_dispatch_on_main_thread_sync(__orcaApp.window, orca_surface_callback, (void*)&data); + oc_surface_select(data.surface); + return (data.surface); } void orca_surface_render_commands(oc_surface surface, @@ -198,664 +197,667 @@ void orca_surface_render_commands(oc_surface surface, u32 eltCount, oc_path_elt* elements) { - oc_runtime* app = &__orcaApp; + oc_runtime* app = &__orcaApp; - char* memBase = app->runtime.wasmMemory.ptr; - u32 memSize = app->runtime.wasmMemory.committed; - if( ((char*)primitives > memBase) - &&((char*)primitives + primitiveCount*sizeof(oc_primitive) - memBase <= memSize) - &&((char*)elements > memBase) - &&((char*)elements + eltCount*sizeof(oc_path_elt) - memBase <= memSize)) - { - oc_surface_render_commands(surface, - clearColor, - primitiveCount, - primitives, - eltCount, - elements); - } + char* memBase = app->runtime.wasmMemory.ptr; + u32 memSize = app->runtime.wasmMemory.committed; + if(((char*)primitives > memBase) + && ((char*)primitives + primitiveCount * sizeof(oc_primitive) - memBase <= memSize) + && ((char*)elements > memBase) + && ((char*)elements + eltCount * sizeof(oc_path_elt) - memBase <= memSize)) + { + oc_surface_render_commands(surface, + clearColor, + primitiveCount, + primitives, + eltCount, + elements); + } } void debug_overlay_toggle(oc_debug_overlay* overlay) { - overlay->show = !overlay->show; - oc_surface_set_hidden(overlay->surface, !overlay->show); + overlay->show = !overlay->show; + oc_surface_set_hidden(overlay->surface, !overlay->show); - if(overlay->show) - { - overlay->logScrollToLast = true; - } + if(overlay->show) + { + overlay->logScrollToLast = true; + } } - void log_entry_ui(oc_debug_overlay* overlay, log_entry* entry) { - static const char* levelNames[] = {"Error: ", "Warning: ", "Info: "}; - static const oc_color levelColors[] = {{0.8, 0, 0, 1}, - {1, 0.5, 0, 1}, - {0, 0.8, 0, 1}}; + static const char* levelNames[] = { "Error: ", "Warning: ", "Info: " }; + static const oc_color levelColors[] = { { 0.8, 0, 0, 1 }, + { 1, 0.5, 0, 1 }, + { 0, 0.8, 0, 1 } }; - static const oc_color bgColors[3][2] = {//errors - {{0.6, 0, 0, 0.5}, {0.8, 0, 0, 0.5}}, - //warning - {{0.4, 0.4, 0.4, 0.5}, {0.5, 0.5, 0.5, 0.5}}, - //info - {{0.4, 0.4, 0.4, 0.5}, {0.5, 0.5, 0.5, 0.5}}}; + static const oc_color bgColors[3][2] = { //errors + { { 0.6, 0, 0, 0.5 }, { 0.8, 0, 0, 0.5 } }, + //warning + { { 0.4, 0.4, 0.4, 0.5 }, { 0.5, 0.5, 0.5, 0.5 } }, + //info + { { 0.4, 0.4, 0.4, 0.5 }, { 0.5, 0.5, 0.5, 0.5 } } + }; - oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1}, - .size.height = {OC_UI_SIZE_CHILDREN}, - .layout.axis = OC_UI_AXIS_Y, - .layout.margin.x = 10, - .layout.margin.y = 5, - .bgColor = bgColors[entry->level][entry->recordIndex & 1]}, - OC_UI_STYLE_SIZE - |OC_UI_STYLE_LAYOUT_AXIS - |OC_UI_STYLE_LAYOUT_MARGINS - |OC_UI_STYLE_BG_COLOR); + oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 }, + .size.height = { OC_UI_SIZE_CHILDREN }, + .layout.axis = OC_UI_AXIS_Y, + .layout.margin.x = 10, + .layout.margin.y = 5, + .bgColor = bgColors[entry->level][entry->recordIndex & 1] }, + OC_UI_STYLE_SIZE + | OC_UI_STYLE_LAYOUT_AXIS + | OC_UI_STYLE_LAYOUT_MARGINS + | OC_UI_STYLE_BG_COLOR); - oc_str8 key = oc_str8_pushf(oc_scratch(), "%ull", entry->recordIndex); + oc_str8 key = oc_str8_pushf(oc_scratch(), "%ull", entry->recordIndex); - oc_ui_container_str8(key, OC_UI_FLAG_DRAW_BACKGROUND) - { - oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1}, - .size.height = {OC_UI_SIZE_CHILDREN}, - .layout.axis = OC_UI_AXIS_X}, - OC_UI_STYLE_SIZE - |OC_UI_STYLE_LAYOUT_AXIS); + oc_ui_container_str8(key, OC_UI_FLAG_DRAW_BACKGROUND) + { + oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 }, + .size.height = { OC_UI_SIZE_CHILDREN }, + .layout.axis = OC_UI_AXIS_X }, + OC_UI_STYLE_SIZE + | OC_UI_STYLE_LAYOUT_AXIS); - oc_ui_container("header", 0) - { - oc_ui_style_next(&(oc_ui_style){.color = levelColors[entry->level], - .font = overlay->fontBold}, - OC_UI_STYLE_COLOR - |OC_UI_STYLE_FONT); - oc_ui_label(levelNames[entry->level]); + oc_ui_container("header", 0) + { + oc_ui_style_next(&(oc_ui_style){ .color = levelColors[entry->level], + .font = overlay->fontBold }, + OC_UI_STYLE_COLOR + | OC_UI_STYLE_FONT); + oc_ui_label(levelNames[entry->level]); - oc_str8 loc = oc_str8_pushf(oc_scratch(), - "%.*s() in %.*s:%i:", - oc_str8_ip(entry->file), - oc_str8_ip(entry->function), - entry->line); - oc_ui_label_str8(loc); - } - oc_ui_label_str8(entry->msg); - } + oc_str8 loc = oc_str8_pushf(oc_scratch(), + "%.*s() in %.*s:%i:", + oc_str8_ip(entry->file), + oc_str8_ip(entry->function), + entry->line); + oc_ui_label_str8(loc); + } + oc_ui_label_str8(entry->msg); + } } - char m3_type_to_tag(M3ValueType type) { - switch(type) - { - case c_m3Type_none: - return('v'); - case c_m3Type_i32: - return('i'); - case c_m3Type_i64: - return('I'); - case c_m3Type_f32: - return('f'); - case c_m3Type_f64: - return('d'); + switch(type) + { + case c_m3Type_none: + return ('v'); + case c_m3Type_i32: + return ('i'); + case c_m3Type_i64: + return ('I'); + case c_m3Type_f32: + return ('f'); + case c_m3Type_f64: + return ('d'); - case c_m3Type_unknown: - default: - return('!'); - } + case c_m3Type_unknown: + default: + return ('!'); + } } void oc_runtime_env_init(oc_runtime_env* runtime) { - memset(runtime, 0, sizeof(oc_runtime_env)); - oc_base_allocator* allocator = oc_base_allocator_default(); - runtime->wasmMemory.committed = 0; - runtime->wasmMemory.reserved = 4ULL<<30; - runtime->wasmMemory.ptr = oc_base_reserve(allocator, runtime->wasmMemory.reserved); + memset(runtime, 0, sizeof(oc_runtime_env)); + oc_base_allocator* allocator = oc_base_allocator_default(); + runtime->wasmMemory.committed = 0; + runtime->wasmMemory.reserved = 4ULL << 30; + runtime->wasmMemory.ptr = oc_base_reserve(allocator, runtime->wasmMemory.reserved); } -#include"wasmbind/core_api_bind_gen.c" -#include"wasmbind/surface_api_bind_gen.c" -#include"wasmbind/clock_api_bind_gen.c" -#include"wasmbind/io_api_bind_gen.c" -#include"wasmbind/gles_api_bind_manual.c" -#include"wasmbind/gles_api_bind_gen.c" - +#include "wasmbind/clock_api_bind_gen.c" +#include "wasmbind/core_api_bind_gen.c" +#include "wasmbind/gles_api_bind_gen.c" +#include "wasmbind/gles_api_bind_manual.c" +#include "wasmbind/io_api_bind_gen.c" +#include "wasmbind/surface_api_bind_gen.c" void orca_wasm3_abort(IM3Runtime runtime, M3Result res, const char* file, const char* function, int line, const char* msg) { - M3ErrorInfo errInfo = {0}; - m3_GetErrorInfo(runtime, &errInfo); - if(errInfo.message && res == errInfo.result) - { - oc_abort_ext(file, function, line, "%s: %s (%s)", msg, res, errInfo.message); - } - else - { - oc_abort_ext(file, function, line, "%s: %s", msg, res); - } + M3ErrorInfo errInfo = { 0 }; + m3_GetErrorInfo(runtime, &errInfo); + if(errInfo.message && res == errInfo.result) + { + oc_abort_ext(file, function, line, "%s: %s (%s)", msg, res, errInfo.message); + } + else + { + oc_abort_ext(file, function, line, "%s: %s", msg, res); + } } #define ORCA_WASM3_ABORT(runtime, err, msg) orca_wasm3_abort(runtime, err, __FILE__, __FUNCTION__, __LINE__, msg) i32 orca_runloop(void* user) { - oc_runtime* app = &__orcaApp; + oc_runtime* app = &__orcaApp; - oc_runtime_env_init(&app->runtime); + oc_runtime_env_init(&app->runtime); - //NOTE: loads wasm module - const char* bundleNameCString = "module"; - oc_str8 modulePath = oc_path_executable_relative(oc_scratch(), OC_STR8("../app/wasm/module.wasm")); + //NOTE: loads wasm module + const char* bundleNameCString = "module"; + oc_str8 modulePath = oc_path_executable_relative(oc_scratch(), OC_STR8("../app/wasm/module.wasm")); - FILE* file = fopen(modulePath.ptr, "rb"); - if(!file) - { - OC_ABORT("The application couldn't load: web assembly module not found"); - } + FILE* file = fopen(modulePath.ptr, "rb"); + if(!file) + { + OC_ABORT("The application couldn't load: web assembly module not found"); + } - fseek(file, 0, SEEK_END); - u64 wasmSize = ftell(file); - rewind(file); + fseek(file, 0, SEEK_END); + u64 wasmSize = ftell(file); + rewind(file); - app->runtime.wasmBytecode.len = wasmSize; - app->runtime.wasmBytecode.ptr = oc_malloc_array(char, wasmSize); - fread(app->runtime.wasmBytecode.ptr, 1, app->runtime.wasmBytecode.len, file); - fclose(file); + app->runtime.wasmBytecode.len = wasmSize; + app->runtime.wasmBytecode.ptr = oc_malloc_array(char, wasmSize); + fread(app->runtime.wasmBytecode.ptr, 1, app->runtime.wasmBytecode.len, file); + fclose(file); - u32 stackSize = 65536; - app->runtime.m3Env = m3_NewEnvironment(); + u32 stackSize = 65536; + app->runtime.m3Env = m3_NewEnvironment(); - app->runtime.m3Runtime = m3_NewRuntime(app->runtime.m3Env, stackSize, NULL); - //NOTE: host memory will be freed when runtime is freed. - m3_RuntimeSetMemoryCallbacks(app->runtime.m3Runtime, wasm_memory_resize_callback, wasm_memory_free_callback, &app->runtime.wasmMemory); + app->runtime.m3Runtime = m3_NewRuntime(app->runtime.m3Env, stackSize, NULL); + //NOTE: host memory will be freed when runtime is freed. + m3_RuntimeSetMemoryCallbacks(app->runtime.m3Runtime, wasm_memory_resize_callback, wasm_memory_free_callback, &app->runtime.wasmMemory); - M3Result res = m3_ParseModule(app->runtime.m3Env, &app->runtime.m3Module, (u8*)app->runtime.wasmBytecode.ptr, app->runtime.wasmBytecode.len); - if(res) - { - ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "The application couldn't parse its web assembly module"); - } + M3Result res = m3_ParseModule(app->runtime.m3Env, &app->runtime.m3Module, (u8*)app->runtime.wasmBytecode.ptr, app->runtime.wasmBytecode.len); + if(res) + { + ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "The application couldn't parse its web assembly module"); + } - res = m3_LoadModule(app->runtime.m3Runtime, app->runtime.m3Module); - if(res) - { - ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "The application couldn't load its web assembly module into the runtime"); - } - m3_SetModuleName(app->runtime.m3Module, bundleNameCString); + res = m3_LoadModule(app->runtime.m3Runtime, app->runtime.m3Module); + if(res) + { + ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "The application couldn't load its web assembly module into the runtime"); + } + m3_SetModuleName(app->runtime.m3Module, bundleNameCString); - oc_arena_clear(oc_scratch()); + oc_arena_clear(oc_scratch()); - //NOTE: bind orca APIs - { - int err = 0; - err |= bindgen_link_core_api(app->runtime.m3Module); - err |= bindgen_link_surface_api(app->runtime.m3Module); - err |= bindgen_link_clock_api(app->runtime.m3Module); - err |= bindgen_link_io_api(app->runtime.m3Module); - err |= bindgen_link_gles_api(app->runtime.m3Module); - err |= manual_link_gles_api(app->runtime.m3Module); + //NOTE: bind orca APIs + { + int err = 0; + err |= bindgen_link_core_api(app->runtime.m3Module); + err |= bindgen_link_surface_api(app->runtime.m3Module); + err |= bindgen_link_clock_api(app->runtime.m3Module); + err |= bindgen_link_io_api(app->runtime.m3Module); + err |= bindgen_link_gles_api(app->runtime.m3Module); + err |= manual_link_gles_api(app->runtime.m3Module); - if(err) - { - OC_ABORT("The application couldn't link one or more functions to its web assembly module (see console log for more information)"); - } - } - //NOTE: compile - res = m3_CompileModule(app->runtime.m3Module); - if(res) - { - ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "The application couldn't compile its web assembly module"); - } + if(err) + { + OC_ABORT("The application couldn't link one or more functions to its web assembly module (see console log for more information)"); + } + } + //NOTE: compile + res = m3_CompileModule(app->runtime.m3Module); + if(res) + { + ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "The application couldn't compile its web assembly module"); + } - //NOTE: Find and type check event handlers. - for(int i=0; iruntime.m3Runtime, desc->name.ptr); + //NOTE: Find and type check event handlers. + for(int i = 0; i < OC_EXPORT_COUNT; i++) + { + const oc_export_desc* desc = &OC_EXPORT_DESC[i]; + IM3Function handler = 0; + m3_FindFunction(&handler, app->runtime.m3Runtime, desc->name.ptr); - if(handler) - { - bool checked = false; + if(handler) + { + bool checked = false; - //NOTE: check function signature - int retCount = m3_GetRetCount(handler); - int argCount = m3_GetArgCount(handler); - if(retCount == desc->retTags.len && argCount == desc->argTags.len) - { - checked = true; - for(int retIndex = 0; retIndex < retCount; retIndex++) - { - M3ValueType m3Type = m3_GetRetType(handler, retIndex); - char tag = m3_type_to_tag(m3Type); + //NOTE: check function signature + int retCount = m3_GetRetCount(handler); + int argCount = m3_GetArgCount(handler); + if(retCount == desc->retTags.len && argCount == desc->argTags.len) + { + checked = true; + for(int retIndex = 0; retIndex < retCount; retIndex++) + { + M3ValueType m3Type = m3_GetRetType(handler, retIndex); + char tag = m3_type_to_tag(m3Type); - if(tag != desc->retTags.ptr[retIndex]) - { - checked = false; - break; - } - } - if(checked) - { - for(int argIndex = 0; argIndex < argCount; argIndex++) - { - M3ValueType m3Type = m3_GetArgType(handler, argIndex); - char tag = m3_type_to_tag(m3Type); + if(tag != desc->retTags.ptr[retIndex]) + { + checked = false; + break; + } + } + if(checked) + { + for(int argIndex = 0; argIndex < argCount; argIndex++) + { + M3ValueType m3Type = m3_GetArgType(handler, argIndex); + char tag = m3_type_to_tag(m3Type); - if(tag != desc->argTags.ptr[argIndex]) - { - checked = false; - break; - } - } - } - } + if(tag != desc->argTags.ptr[argIndex]) + { + checked = false; + break; + } + } + } + } - if(checked) - { - app->runtime.exports[i] = handler; - } - else - { - oc_log_error("type mismatch for event handler %.*s\n", (int)desc->name.len, desc->name.ptr); - } - } - } + if(checked) + { + app->runtime.exports[i] = handler; + } + else + { + oc_log_error("type mismatch for event handler %.*s\n", (int)desc->name.len, desc->name.ptr); + } + } + } - //NOTE: get location of the raw event slot - IM3Global rawEventGlobal = m3_FindGlobal(app->runtime.m3Module, "oc_rawEvent"); - app->runtime.rawEventOffset = (u32)rawEventGlobal->intValue; + //NOTE: get location of the raw event slot + IM3Global rawEventGlobal = m3_FindGlobal(app->runtime.m3Module, "oc_rawEvent"); + app->runtime.rawEventOffset = (u32)rawEventGlobal->intValue; - //NOTE: preopen the app local root dir - { - oc_str8 localRootPath = oc_path_executable_relative(oc_scratch(), OC_STR8("../app/data")); + //NOTE: preopen the app local root dir + { + oc_str8 localRootPath = oc_path_executable_relative(oc_scratch(), OC_STR8("../app/data")); - oc_io_req req = {.op = OC_IO_OPEN_AT, - .open.rights = OC_FILE_ACCESS_READ|OC_FILE_ACCESS_WRITE, - .size = localRootPath.len, - .buffer = localRootPath.ptr}; - oc_io_cmp cmp = oc_io_wait_single_req_with_table(&req, &app->fileTable); - app->rootDir = cmp.handle; - } + oc_io_req req = { .op = OC_IO_OPEN_AT, + .open.rights = OC_FILE_ACCESS_READ | OC_FILE_ACCESS_WRITE, + .size = localRootPath.len, + .buffer = localRootPath.ptr }; + oc_io_cmp cmp = oc_io_wait_single_req_with_table(&req, &app->fileTable); + app->rootDir = cmp.handle; + } - IM3Function* exports = app->runtime.exports; + IM3Function* exports = app->runtime.exports; - //NOTE: call init handler - if(exports[OC_EXPORT_ON_INIT]) - { - M3Result res = m3_Call(exports[OC_EXPORT_ON_INIT], 0, 0); - if(res) - { - ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); - } - } + //NOTE: call init handler + if(exports[OC_EXPORT_ON_INIT]) + { + M3Result res = m3_Call(exports[OC_EXPORT_ON_INIT], 0, 0); + if(res) + { + ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); + } + } - if(exports[OC_EXPORT_FRAME_RESIZE]) - { - oc_rect content = oc_window_get_content_rect(app->window); - u32 width = (u32)content.w; - u32 height = (u32)content.h; - const void* args[2] = {&width, &height}; - M3Result res = m3_Call(exports[OC_EXPORT_FRAME_RESIZE], 2, args); - if(res) - { - ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); - } - } + if(exports[OC_EXPORT_FRAME_RESIZE]) + { + oc_rect content = oc_window_get_content_rect(app->window); + u32 width = (u32)content.w; + u32 height = (u32)content.h; + const void* args[2] = { &width, &height }; + M3Result res = m3_Call(exports[OC_EXPORT_FRAME_RESIZE], 2, args); + if(res) + { + ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); + } + } - oc_ui_set_context(&app->debugOverlay.ui); + oc_ui_set_context(&app->debugOverlay.ui); - while(!oc_should_quit()) - { - oc_event* event = 0; - while((event = oc_next_event(oc_scratch())) != 0) - { + while(!oc_should_quit()) + { + oc_event* event = 0; + while((event = oc_next_event(oc_scratch())) != 0) + { - if(app->debugOverlay.show) - { - oc_ui_process_event(event); - } + if(app->debugOverlay.show) + { + oc_ui_process_event(event); + } - if(exports[OC_EXPORT_RAW_EVENT]) - { - #ifndef M3_BIG_ENDIAN - oc_event* eventPtr = (oc_event*)wasm_memory_offset_to_ptr(&app->runtime.wasmMemory, app->runtime.rawEventOffset); - memcpy(eventPtr, event, sizeof(*event)); + if(exports[OC_EXPORT_RAW_EVENT]) + { +#ifndef M3_BIG_ENDIAN + oc_event* eventPtr = (oc_event*)wasm_memory_offset_to_ptr(&app->runtime.wasmMemory, app->runtime.rawEventOffset); + memcpy(eventPtr, event, sizeof(*event)); - const void* args[1] = {&app->runtime.rawEventOffset}; - M3Result res = m3_Call(exports[OC_EXPORT_RAW_EVENT], 1, args); - if(res) - { - ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); - } - #else - oc_log_error("oc_on_raw_event() is not supported on big endian platforms"); - #endif - } + const void* args[1] = { &app->runtime.rawEventOffset }; + M3Result res = m3_Call(exports[OC_EXPORT_RAW_EVENT], 1, args); + if(res) + { + ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); + } +#else + oc_log_error("oc_on_raw_event() is not supported on big endian platforms"); +#endif + } - switch(event->type) - { - case OC_EVENT_WINDOW_CLOSE: - { - oc_request_quit(); - } break; + switch(event->type) + { + case OC_EVENT_WINDOW_CLOSE: + { + oc_request_quit(); + } + break; - case OC_EVENT_WINDOW_RESIZE: - { - oc_rect frame = {0, 0, event->move.frame.w, event->move.frame.h}; + case OC_EVENT_WINDOW_RESIZE: + { + oc_rect frame = { 0, 0, event->move.frame.w, event->move.frame.h }; - if(exports[OC_EXPORT_FRAME_RESIZE]) - { - u32 width = (u32)event->move.content.w; - u32 height = (u32)event->move.content.h; - const void* args[2] = {&width, &height}; - M3Result res = m3_Call(exports[OC_EXPORT_FRAME_RESIZE], 2, args); - if(res) - { - ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); - } - } - } break; + if(exports[OC_EXPORT_FRAME_RESIZE]) + { + u32 width = (u32)event->move.content.w; + u32 height = (u32)event->move.content.h; + const void* args[2] = { &width, &height }; + M3Result res = m3_Call(exports[OC_EXPORT_FRAME_RESIZE], 2, args); + if(res) + { + ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); + } + } + } + break; - case OC_EVENT_MOUSE_BUTTON: - { - if(event->key.action == OC_KEY_PRESS) - { - if(exports[OC_EXPORT_MOUSE_DOWN]) - { - int key = event->key.code; - const void* args[1] = {&key}; - M3Result res = m3_Call(exports[OC_EXPORT_MOUSE_DOWN], 1, args); - if(res) - { - ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); - } - } - } - else - { - if(exports[OC_EXPORT_MOUSE_UP]) - { - int key = event->key.code; - const void* args[1] = {&key}; - M3Result res = m3_Call(exports[OC_EXPORT_MOUSE_UP], 1, args); - if(res) - { - ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); - } - } - } - } break; + case OC_EVENT_MOUSE_BUTTON: + { + if(event->key.action == OC_KEY_PRESS) + { + if(exports[OC_EXPORT_MOUSE_DOWN]) + { + int key = event->key.code; + const void* args[1] = { &key }; + M3Result res = m3_Call(exports[OC_EXPORT_MOUSE_DOWN], 1, args); + if(res) + { + ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); + } + } + } + else + { + if(exports[OC_EXPORT_MOUSE_UP]) + { + int key = event->key.code; + const void* args[1] = { &key }; + M3Result res = m3_Call(exports[OC_EXPORT_MOUSE_UP], 1, args); + if(res) + { + ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); + } + } + } + } + break; - case OC_EVENT_MOUSE_MOVE: - { - if(exports[OC_EXPORT_MOUSE_MOVE]) - { - const void* args[4] = {&event->mouse.x, &event->mouse.y, &event->mouse.deltaX, &event->mouse.deltaY}; - M3Result res = m3_Call(exports[OC_EXPORT_MOUSE_MOVE], 4, args); - if(res) - { - ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); - } - } - } break; + case OC_EVENT_MOUSE_MOVE: + { + if(exports[OC_EXPORT_MOUSE_MOVE]) + { + const void* args[4] = { &event->mouse.x, &event->mouse.y, &event->mouse.deltaX, &event->mouse.deltaY }; + M3Result res = m3_Call(exports[OC_EXPORT_MOUSE_MOVE], 4, args); + if(res) + { + ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); + } + } + } + break; - case OC_EVENT_KEYBOARD_KEY: - { - if(event->key.action == OC_KEY_PRESS) - { - if(event->key.code == OC_KEY_D && (event->key.mods & (OC_KEYMOD_SHIFT | OC_KEYMOD_CMD))) - { - #if 1 // EPILEPSY WARNING! on windows this has a bug which causes a pretty strong stroboscopic effect - debug_overlay_toggle(&app->debugOverlay); - #endif - } + case OC_EVENT_KEYBOARD_KEY: + { + if(event->key.action == OC_KEY_PRESS) + { + if(event->key.code == OC_KEY_D && (event->key.mods & (OC_KEYMOD_SHIFT | OC_KEYMOD_CMD))) + { +#if 1 // EPILEPSY WARNING! on windows this has a bug which causes a pretty strong stroboscopic effect + debug_overlay_toggle(&app->debugOverlay); +#endif + } - if(exports[OC_EXPORT_KEY_DOWN]) - { - const void* args[1] = {&event->key.code}; - M3Result res = m3_Call(exports[OC_EXPORT_KEY_DOWN], 1, args); - if(res) - { - ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); - } - } - } - else if(event->key.action == OC_KEY_RELEASE) - { - if(exports[OC_EXPORT_KEY_UP]) - { - const void* args[1] = {&event->key.code}; - M3Result res = m3_Call(exports[OC_EXPORT_KEY_UP], 1, args); - if(res) - { - ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); - } - } - } - } break; + if(exports[OC_EXPORT_KEY_DOWN]) + { + const void* args[1] = { &event->key.code }; + M3Result res = m3_Call(exports[OC_EXPORT_KEY_DOWN], 1, args); + if(res) + { + ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); + } + } + } + else if(event->key.action == OC_KEY_RELEASE) + { + if(exports[OC_EXPORT_KEY_UP]) + { + const void* args[1] = { &event->key.code }; + M3Result res = m3_Call(exports[OC_EXPORT_KEY_UP], 1, args); + if(res) + { + ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); + } + } + } + } + break; - default: - break; - } - } + default: + break; + } + } - if(app->debugOverlay.show) - { - oc_ui_style debugUIDefaultStyle = {.bgColor = {0}, - .color = {1, 1, 1, 1}, - .font = app->debugOverlay.fontReg, - .fontSize = 16, - .borderColor = {1, 0, 0, 1}, - .borderSize = 2}; + if(app->debugOverlay.show) + { + oc_ui_style debugUIDefaultStyle = { .bgColor = { 0 }, + .color = { 1, 1, 1, 1 }, + .font = app->debugOverlay.fontReg, + .fontSize = 16, + .borderColor = { 1, 0, 0, 1 }, + .borderSize = 2 }; - oc_ui_style_mask debugUIDefaultMask = OC_UI_STYLE_BG_COLOR - | OC_UI_STYLE_COLOR - | OC_UI_STYLE_BORDER_COLOR - | OC_UI_STYLE_BORDER_SIZE - | OC_UI_STYLE_FONT - | OC_UI_STYLE_FONT_SIZE; + oc_ui_style_mask debugUIDefaultMask = OC_UI_STYLE_BG_COLOR + | OC_UI_STYLE_COLOR + | OC_UI_STYLE_BORDER_COLOR + | OC_UI_STYLE_BORDER_SIZE + | OC_UI_STYLE_FONT + | OC_UI_STYLE_FONT_SIZE; - oc_vec2 frameSize = oc_surface_get_size(app->debugOverlay.surface); + oc_vec2 frameSize = oc_surface_get_size(app->debugOverlay.surface); - oc_ui_frame(frameSize, &debugUIDefaultStyle, debugUIDefaultMask) - { - oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1}, - .size.height = {OC_UI_SIZE_PARENT, 1, 1}}, - OC_UI_STYLE_SIZE); + oc_ui_frame(frameSize, &debugUIDefaultStyle, debugUIDefaultMask) + { + oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 }, + .size.height = { OC_UI_SIZE_PARENT, 1, 1 } }, + OC_UI_STYLE_SIZE); - oc_ui_container("overlay area", 0) - { - //... - } + oc_ui_container("overlay area", 0) + { + //... + } - oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1}, - .size.height = {OC_UI_SIZE_PARENT, 0.4}, - .layout.axis = OC_UI_AXIS_Y, - .bgColor = {0, 0, 0, 0.5}}, - OC_UI_STYLE_SIZE - |OC_UI_STYLE_LAYOUT_AXIS - |OC_UI_STYLE_BG_COLOR); + oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 }, + .size.height = { OC_UI_SIZE_PARENT, 0.4 }, + .layout.axis = OC_UI_AXIS_Y, + .bgColor = { 0, 0, 0, 0.5 } }, + OC_UI_STYLE_SIZE + | OC_UI_STYLE_LAYOUT_AXIS + | OC_UI_STYLE_BG_COLOR); - oc_ui_container("log console", OC_UI_FLAG_DRAW_BACKGROUND) - { - oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1}, - .size.height = {OC_UI_SIZE_CHILDREN}, - .layout.axis = OC_UI_AXIS_X, - .layout.spacing = 10, - .layout.margin.x = 10, - .layout.margin.y = 10}, - OC_UI_STYLE_SIZE - |OC_UI_STYLE_LAYOUT); + oc_ui_container("log console", OC_UI_FLAG_DRAW_BACKGROUND) + { + oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 }, + .size.height = { OC_UI_SIZE_CHILDREN }, + .layout.axis = OC_UI_AXIS_X, + .layout.spacing = 10, + .layout.margin.x = 10, + .layout.margin.y = 10 }, + OC_UI_STYLE_SIZE + | OC_UI_STYLE_LAYOUT); - oc_ui_container("log toolbar", 0) - { - oc_ui_style buttonStyle = {.layout.margin.x = 4, - .layout.margin.y = 4, - .roundness = 2, - .bgColor = {0, 0, 0, 0.5}, - .color = {1, 1, 1, 1}}; + oc_ui_container("log toolbar", 0) + { + oc_ui_style buttonStyle = { .layout.margin.x = 4, + .layout.margin.y = 4, + .roundness = 2, + .bgColor = { 0, 0, 0, 0.5 }, + .color = { 1, 1, 1, 1 } }; - oc_ui_style_mask buttonStyleMask = OC_UI_STYLE_LAYOUT_MARGINS - | OC_UI_STYLE_ROUNDNESS - | OC_UI_STYLE_BG_COLOR - | OC_UI_STYLE_COLOR; + oc_ui_style_mask buttonStyleMask = OC_UI_STYLE_LAYOUT_MARGINS + | OC_UI_STYLE_ROUNDNESS + | OC_UI_STYLE_BG_COLOR + | OC_UI_STYLE_COLOR; - oc_ui_style_match_after(oc_ui_pattern_all(), &buttonStyle, buttonStyleMask); - if(oc_ui_button("Clear").clicked) - { - oc_list_for_safe(&app->debugOverlay.logEntries, entry, log_entry, listElt) - { - oc_list_remove(&app->debugOverlay.logEntries, &entry->listElt); - oc_list_push(&app->debugOverlay.logFreeList, &entry->listElt); - app->debugOverlay.entryCount--; - } - } - } + oc_ui_style_match_after(oc_ui_pattern_all(), &buttonStyle, buttonStyleMask); + if(oc_ui_button("Clear").clicked) + { + oc_list_for_safe(&app->debugOverlay.logEntries, entry, log_entry, listElt) + { + oc_list_remove(&app->debugOverlay.logEntries, &entry->listElt); + oc_list_push(&app->debugOverlay.logFreeList, &entry->listElt); + app->debugOverlay.entryCount--; + } + } + } - oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1}, - .size.height = {OC_UI_SIZE_PARENT, 1, 1}}, - OC_UI_STYLE_SIZE); + oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 }, + .size.height = { OC_UI_SIZE_PARENT, 1, 1 } }, + OC_UI_STYLE_SIZE); - //TODO: this is annoying to have to do that. Basically there's another 'contents' box inside oc_ui_panel, - // and we need to change that to size according to its parent (whereas the default is sizing according - // to its children) - oc_ui_pattern pattern = {0}; - oc_ui_pattern_push(oc_scratch(), &pattern, (oc_ui_selector){.kind = OC_UI_SEL_OWNER}); - oc_ui_pattern_push(oc_scratch(), &pattern, (oc_ui_selector){.kind = OC_UI_SEL_TEXT, .text = OC_STR8("contents")}); - oc_ui_style_match_after(pattern, &(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1}}, OC_UI_STYLE_SIZE_WIDTH); + //TODO: this is annoying to have to do that. Basically there's another 'contents' box inside oc_ui_panel, + // and we need to change that to size according to its parent (whereas the default is sizing according + // to its children) + oc_ui_pattern pattern = { 0 }; + oc_ui_pattern_push(oc_scratch(), &pattern, (oc_ui_selector){ .kind = OC_UI_SEL_OWNER }); + oc_ui_pattern_push(oc_scratch(), &pattern, (oc_ui_selector){ .kind = OC_UI_SEL_TEXT, .text = OC_STR8("contents") }); + oc_ui_style_match_after(pattern, &(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 } }, OC_UI_STYLE_SIZE_WIDTH); - oc_ui_box* panel = oc_ui_box_lookup("log view"); - f32 scrollY = 0; - if(panel) - { - scrollY = panel->scroll.y; - } + oc_ui_box* panel = oc_ui_box_lookup("log view"); + f32 scrollY = 0; + if(panel) + { + scrollY = panel->scroll.y; + } - oc_ui_panel("log view", OC_UI_FLAG_SCROLL_WHEEL_Y) - { - panel = oc_ui_box_top(); + oc_ui_panel("log view", OC_UI_FLAG_SCROLL_WHEEL_Y) + { + panel = oc_ui_box_top(); - oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1}, - .size.height = {OC_UI_SIZE_CHILDREN}, - .layout.axis = OC_UI_AXIS_Y, - .layout.margin.y = 5}, - OC_UI_STYLE_SIZE - |OC_UI_STYLE_LAYOUT_AXIS); + oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 }, + .size.height = { OC_UI_SIZE_CHILDREN }, + .layout.axis = OC_UI_AXIS_Y, + .layout.margin.y = 5 }, + OC_UI_STYLE_SIZE + | OC_UI_STYLE_LAYOUT_AXIS); - oc_ui_container("contents", 0) - { - oc_list_for(&app->debugOverlay.logEntries, entry, log_entry, listElt) - { - log_entry_ui(&app->debugOverlay, entry); - } - } - } - if(app->debugOverlay.logScrollToLast) - { - if(panel->scroll.y >= scrollY) - { - panel->scroll.y = oc_clamp_low(panel->childrenSum[1] - panel->rect.h, 0); - } - else - { - app->debugOverlay.logScrollToLast = false; - } - } - else if(panel->scroll.y >= (panel->childrenSum[1] - panel->rect.h) - 1) - { - app->debugOverlay.logScrollToLast = true; - } - } - } + oc_ui_container("contents", 0) + { + oc_list_for(&app->debugOverlay.logEntries, entry, log_entry, listElt) + { + log_entry_ui(&app->debugOverlay, entry); + } + } + } + if(app->debugOverlay.logScrollToLast) + { + if(panel->scroll.y >= scrollY) + { + panel->scroll.y = oc_clamp_low(panel->childrenSum[1] - panel->rect.h, 0); + } + else + { + app->debugOverlay.logScrollToLast = false; + } + } + else if(panel->scroll.y >= (panel->childrenSum[1] - panel->rect.h) - 1) + { + app->debugOverlay.logScrollToLast = true; + } + } + } - oc_surface_select(app->debugOverlay.surface); - oc_canvas_set_current(app->debugOverlay.canvas); - oc_ui_draw(); + oc_surface_select(app->debugOverlay.surface); + oc_canvas_set_current(app->debugOverlay.canvas); + oc_ui_draw(); - oc_render(app->debugOverlay.surface, app->debugOverlay.canvas); - } + oc_render(app->debugOverlay.surface, app->debugOverlay.canvas); + } - if(exports[OC_EXPORT_FRAME_REFRESH]) - { - M3Result res = m3_Call(exports[OC_EXPORT_FRAME_REFRESH], 0, 0); - if(res) - { - ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); - } - } + if(exports[OC_EXPORT_FRAME_REFRESH]) + { + M3Result res = m3_Call(exports[OC_EXPORT_FRAME_REFRESH], 0, 0); + if(res) + { + ORCA_WASM3_ABORT(app->runtime.m3Runtime, res, "Runtime error"); + } + } - if(app->debugOverlay.show) - { - oc_surface_select(app->debugOverlay.surface); - oc_surface_present(app->debugOverlay.surface); - } + if(app->debugOverlay.show) + { + oc_surface_select(app->debugOverlay.surface); + oc_surface_present(app->debugOverlay.surface); + } - oc_arena_clear(oc_scratch()); - } + oc_arena_clear(oc_scratch()); + } - return(0); + return (0); } int main(int argc, char** argv) { - oc_log_set_level(OC_LOG_LEVEL_INFO); + oc_log_set_level(OC_LOG_LEVEL_INFO); - oc_init(); - oc_clock_init(); + oc_init(); + oc_clock_init(); - oc_runtime* app = &__orcaApp; + oc_runtime* app = &__orcaApp; - //NOTE: create window and surfaces - oc_rect windowRect = {.x = 100, .y = 100, .w = 810, .h = 610}; - app->window = oc_window_create(windowRect, OC_STR8("orca"), 0); + //NOTE: create window and surfaces + oc_rect windowRect = { .x = 100, .y = 100, .w = 810, .h = 610 }; + app->window = oc_window_create(windowRect, OC_STR8("orca"), 0); - app->debugOverlay.show = false; - app->debugOverlay.surface = oc_surface_create_for_window(app->window, OC_CANVAS); - app->debugOverlay.canvas = oc_canvas_create(); - app->debugOverlay.fontReg = orca_font_create("../resources/Menlo.ttf"); - app->debugOverlay.fontBold = orca_font_create("../resources/Menlo Bold.ttf"); - app->debugOverlay.maxEntries = 200; - oc_arena_init(&app->debugOverlay.logArena); + app->debugOverlay.show = false; + app->debugOverlay.surface = oc_surface_create_for_window(app->window, OC_CANVAS); + app->debugOverlay.canvas = oc_canvas_create(); + app->debugOverlay.fontReg = orca_font_create("../resources/Menlo.ttf"); + app->debugOverlay.fontBold = orca_font_create("../resources/Menlo Bold.ttf"); + app->debugOverlay.maxEntries = 200; + oc_arena_init(&app->debugOverlay.logArena); - oc_surface_swap_interval(app->debugOverlay.surface, 0); + oc_surface_swap_interval(app->debugOverlay.surface, 0); - oc_surface_set_hidden(app->debugOverlay.surface, true); + oc_surface_set_hidden(app->debugOverlay.surface, true); - oc_surface_deselect(); + oc_surface_deselect(); - //WARN: this is a workaround to avoid stalling the first few times we acquire drawables from - // the surfaces... This should probably be fixed in the implementation of mtl_surface! + //WARN: this is a workaround to avoid stalling the first few times we acquire drawables from + // the surfaces... This should probably be fixed in the implementation of mtl_surface! - for(int i=0; i<3; i++) - { - oc_surface_select(app->debugOverlay.surface); - oc_canvas_set_current(app->debugOverlay.canvas); - oc_render(app->debugOverlay.surface, app->debugOverlay.canvas); - oc_surface_present(app->debugOverlay.surface); - } + for(int i = 0; i < 3; i++) + { + oc_surface_select(app->debugOverlay.surface); + oc_canvas_set_current(app->debugOverlay.canvas); + oc_render(app->debugOverlay.surface, app->debugOverlay.canvas); + oc_surface_present(app->debugOverlay.surface); + } - oc_ui_init(&app->debugOverlay.ui); + oc_ui_init(&app->debugOverlay.ui); - //NOTE: show window and start runloop - oc_window_bring_to_front(app->window); - oc_window_focus(app->window); - oc_window_center(app->window); + //NOTE: show window and start runloop + oc_window_bring_to_front(app->window); + oc_window_focus(app->window); + oc_window_center(app->window); - oc_thread* runloopThread = oc_thread_create(orca_runloop, 0); + oc_thread* runloopThread = oc_thread_create(orca_runloop, 0); - while(!oc_should_quit()) - { - oc_pump_events(-1); - //TODO: what to do with mem scratch here? - } + while(!oc_should_quit()) + { + oc_pump_events(-1); + //TODO: what to do with mem scratch here? + } - oc_thread_join(runloopThread, NULL); + oc_thread_join(runloopThread, NULL); - oc_canvas_destroy(app->debugOverlay.canvas); - oc_surface_destroy(app->debugOverlay.surface); + oc_canvas_destroy(app->debugOverlay.canvas); + oc_surface_destroy(app->debugOverlay.surface); - oc_window_destroy(app->window); + oc_window_destroy(app->window); - oc_terminate(); - return(0); + oc_terminate(); + return (0); } diff --git a/src/runtime.h b/src/runtime.h index d6b29fc..aa7bcec 100644 --- a/src/runtime.h +++ b/src/runtime.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: runtime.h * @author: Martin Fouilleul @@ -8,116 +8,116 @@ #ifndef __RUNTIME_H_ #define __RUNTIME_H_ -#include"platform/platform_io_internal.h" +#include "platform/platform_io_internal.h" -#include"wasm3.h" -#include"m3_env.h" -#include"m3_compile.h" +#include "m3_compile.h" +#include "m3_env.h" +#include "wasm3.h" -#define OC_EXPORTS(X) \ - X(OC_EXPORT_ON_INIT, "oc_on_init", "", "") \ - X(OC_EXPORT_MOUSE_DOWN, "oc_on_mouse_down", "", "i") \ - X(OC_EXPORT_MOUSE_UP, "oc_on_mouse_up", "", "i") \ - X(OC_EXPORT_MOUSE_ENTER, "oc_on_mouse_enter", "", "") \ - X(OC_EXPORT_MOUSE_LEAVE, "oc_on_mouse_leave", "", "") \ - X(OC_EXPORT_MOUSE_MOVE, "oc_on_mouse_move", "", "ffff") \ - X(OC_EXPORT_MOUSE_WHEEL, "oc_on_mouse_wheel", "", "ff") \ - X(OC_EXPORT_KEY_DOWN, "oc_on_key_down", "", "i") \ - X(OC_EXPORT_KEY_UP, "oc_on_key_up", "", "i") \ - X(OC_EXPORT_FRAME_REFRESH, "oc_on_frame_refresh", "", "") \ - X(OC_EXPORT_FRAME_RESIZE, "oc_on_resize", "", "ii") \ - X(OC_EXPORT_RAW_EVENT, "oc_on_raw_event", "", "i") \ +#define OC_EXPORTS(X) \ + X(OC_EXPORT_ON_INIT, "oc_on_init", "", "") \ + X(OC_EXPORT_MOUSE_DOWN, "oc_on_mouse_down", "", "i") \ + X(OC_EXPORT_MOUSE_UP, "oc_on_mouse_up", "", "i") \ + X(OC_EXPORT_MOUSE_ENTER, "oc_on_mouse_enter", "", "") \ + X(OC_EXPORT_MOUSE_LEAVE, "oc_on_mouse_leave", "", "") \ + X(OC_EXPORT_MOUSE_MOVE, "oc_on_mouse_move", "", "ffff") \ + X(OC_EXPORT_MOUSE_WHEEL, "oc_on_mouse_wheel", "", "ff") \ + X(OC_EXPORT_KEY_DOWN, "oc_on_key_down", "", "i") \ + X(OC_EXPORT_KEY_UP, "oc_on_key_up", "", "i") \ + X(OC_EXPORT_FRAME_REFRESH, "oc_on_frame_refresh", "", "") \ + X(OC_EXPORT_FRAME_RESIZE, "oc_on_resize", "", "ii") \ + X(OC_EXPORT_RAW_EVENT, "oc_on_raw_event", "", "i") -typedef enum { - #define OC_EXPORT_KIND(kind, ...) kind, - OC_EXPORTS(OC_EXPORT_KIND) - OC_EXPORT_COUNT +typedef enum +{ + +#define OC_EXPORT_KIND(kind, ...) kind, + OC_EXPORTS(OC_EXPORT_KIND) + OC_EXPORT_COUNT } guest_export_kind; - typedef struct oc_export_desc { - oc_str8 name; - oc_str8 retTags; - oc_str8 argTags; + oc_str8 name; + oc_str8 retTags; + oc_str8 argTags; } oc_export_desc; const oc_export_desc OC_EXPORT_DESC[] = { - #define OC_EXPORT_DESC_ENTRY(kind, name, rets, args) {OC_STR8_LIT(name), OC_STR8_LIT(rets), OC_STR8_LIT(args)}, +#define OC_EXPORT_DESC_ENTRY(kind, name, rets, args) { OC_STR8_LIT(name), OC_STR8_LIT(rets), OC_STR8_LIT(args) }, - OC_EXPORTS(OC_EXPORT_DESC_ENTRY) + OC_EXPORTS(OC_EXPORT_DESC_ENTRY) - #undef OC_EXPORT_DESC_ENTRY - #undef OC_STR8_LIT +#undef OC_EXPORT_DESC_ENTRY +#undef OC_STR8_LIT }; typedef struct wasm_memory { - char* ptr; - u64 reserved; - u64 committed; + char* ptr; + u64 reserved; + u64 committed; } wasm_memory; typedef struct oc_runtime_env { - oc_str8 wasmBytecode; - wasm_memory wasmMemory; + oc_str8 wasmBytecode; + wasm_memory wasmMemory; - // wasm3 data - IM3Environment m3Env; - IM3Runtime m3Runtime; - IM3Module m3Module; - IM3Function exports[OC_EXPORT_COUNT]; - u32 rawEventOffset; + // wasm3 data + IM3Environment m3Env; + IM3Runtime m3Runtime; + IM3Module m3Module; + IM3Function exports[OC_EXPORT_COUNT]; + u32 rawEventOffset; } oc_runtime_env; typedef struct log_entry { - oc_list_elt listElt; - u64 cap; + oc_list_elt listElt; + u64 cap; - oc_log_level level; - oc_str8 file; - oc_str8 function; - int line; - oc_str8 msg; + oc_log_level level; + oc_str8 file; + oc_str8 function; + int line; + oc_str8 msg; - u64 recordIndex; + u64 recordIndex; } log_entry; typedef struct oc_debug_overlay { - bool show; - oc_surface surface; - oc_canvas canvas; - oc_font fontReg; - oc_font fontBold; - oc_ui_context ui; + bool show; + oc_surface surface; + oc_canvas canvas; + oc_font fontReg; + oc_font fontBold; + oc_ui_context ui; - - oc_arena logArena; - oc_list logEntries; - oc_list logFreeList; - u32 entryCount; - u32 maxEntries; - u64 logEntryTotalCount; - bool logScrollToLast; + oc_arena logArena; + oc_list logEntries; + oc_list logFreeList; + u32 entryCount; + u32 maxEntries; + u64 logEntryTotalCount; + bool logScrollToLast; } oc_debug_overlay; typedef struct oc_runtime { - oc_window window; + oc_window window; - oc_file_table fileTable; - oc_file rootDir; + oc_file_table fileTable; + oc_file rootDir; - oc_runtime_env runtime; + oc_runtime_env runtime; - oc_debug_overlay debugOverlay; + oc_debug_overlay debugOverlay; } oc_runtime; diff --git a/src/runtime_io.c b/src/runtime_io.c index 31e14a3..cfdcd90 100644 --- a/src/runtime_io.c +++ b/src/runtime_io.c @@ -1,44 +1,44 @@ -/************************************************************//** +/************************************************************/ /** * * @file: runtime_io.c * @author: Martin Fouilleul * @date: 09/05/2023 * *****************************************************************/ -#include"platform/platform_io_internal.h" -#include"runtime.h" +#include "platform/platform_io_internal.h" +#include "runtime.h" oc_io_cmp oc_runtime_io_wait_single_req(oc_io_req* wasmReq) { - oc_runtime* orca = oc_runtime_get(); - oc_arena* scratch = oc_scratch(); + oc_runtime* orca = oc_runtime_get(); + oc_arena* scratch = oc_scratch(); - oc_io_cmp cmp = {0}; - oc_io_req req = *wasmReq; - //NOTE: convert the req->buffer wasm pointer to a native pointer - // for some reason, wasm3 memory doesn't start at the beginning of the block we give it. - u64 bufferIndex = (u64)req.buffer & 0xffffffff; - u32 memSize = 0; - char* memory = (char*)m3_GetMemory(orca->runtime.m3Runtime, &memSize, 0); + oc_io_cmp cmp = { 0 }; + oc_io_req req = *wasmReq; + //NOTE: convert the req->buffer wasm pointer to a native pointer + // for some reason, wasm3 memory doesn't start at the beginning of the block we give it. + u64 bufferIndex = (u64)req.buffer & 0xffffffff; + u32 memSize = 0; + char* memory = (char*)m3_GetMemory(orca->runtime.m3Runtime, &memSize, 0); - if(bufferIndex + req.size > memSize) - { - cmp.error = OC_IO_ERR_ARG; - } - else - { - req.buffer = memory + bufferIndex; + if(bufferIndex + req.size > memSize) + { + cmp.error = OC_IO_ERR_ARG; + } + else + { + req.buffer = memory + bufferIndex; - if(req.op == OC_IO_OPEN_AT) - { - if(req.handle.h == 0) - { - //NOTE: change root to app local folder - req.handle = orca->rootDir; - req.open.flags |= OC_FILE_OPEN_RESTRICT; - } - } - cmp = oc_io_wait_single_req_with_table(&req, &orca->fileTable); - } - return(cmp); + if(req.op == OC_IO_OPEN_AT) + { + if(req.handle.h == 0) + { + //NOTE: change root to app local folder + req.handle = orca->rootDir; + req.open.flags |= OC_FILE_OPEN_RESTRICT; + } + } + cmp = oc_io_wait_single_req_with_table(&req, &orca->fileTable); + } + return (cmp); } diff --git a/src/runtime_memory.c b/src/runtime_memory.c index cbdc74d..1c0158c 100644 --- a/src/runtime_memory.c +++ b/src/runtime_memory.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: runtime_memory.c * @author: Martin Fouilleul @@ -6,61 +6,61 @@ * *****************************************************************/ -#include"runtime.h" +#include "runtime.h" void* wasm_memory_resize_callback(void* p, unsigned long size, void* userData) { - wasm_memory* memory = (wasm_memory*)userData; + wasm_memory* memory = (wasm_memory*)userData; - if(memory->committed >= size) - { - return(memory->ptr); - } - else if(memory->committed < memory->reserved) - { - u32 commitSize = size - memory->committed; + if(memory->committed >= size) + { + return (memory->ptr); + } + else if(memory->committed < memory->reserved) + { + u32 commitSize = size - memory->committed; - oc_base_allocator* allocator = oc_base_allocator_default(); - oc_base_commit(allocator, memory->ptr + memory->committed, commitSize); - memory->committed += commitSize; - return(memory->ptr); - } - else - { - OC_ABORT("Out of memory"); - return(0); - } + oc_base_allocator* allocator = oc_base_allocator_default(); + oc_base_commit(allocator, memory->ptr + memory->committed, commitSize); + memory->committed += commitSize; + return (memory->ptr); + } + else + { + OC_ABORT("Out of memory"); + return (0); + } } void wasm_memory_free_callback(void* p, void* userData) { - wasm_memory* memory = (wasm_memory*)userData; + wasm_memory* memory = (wasm_memory*)userData; - oc_base_allocator* allocator = oc_base_allocator_default(); - oc_base_release(allocator, memory->ptr, memory->reserved); - memset(memory, 0, sizeof(wasm_memory)); + oc_base_allocator* allocator = oc_base_allocator_default(); + oc_base_release(allocator, memory->ptr, memory->reserved); + memset(memory, 0, sizeof(wasm_memory)); } extern u32 oc_mem_grow(u64 size) { - oc_runtime_env* runtime = oc_runtime_env_get(); - wasm_memory* memory = &runtime->wasmMemory; + oc_runtime_env* runtime = oc_runtime_env_get(); + wasm_memory* memory = &runtime->wasmMemory; - size = oc_align_up_pow2(size, d_m3MemPageSize); - u64 totalSize = size + m3_GetMemorySize(runtime->m3Runtime); + size = oc_align_up_pow2(size, d_m3MemPageSize); + u64 totalSize = size + m3_GetMemorySize(runtime->m3Runtime); - u32 addr = memory->committed; + u32 addr = memory->committed; - //NOTE: call resize memory, which will call our custom resize callback... this is a bit involved because - // wasm3 doesn't allow resizing the memory directly - M3Result res = ResizeMemory(runtime->m3Runtime, totalSize/d_m3MemPageSize); + //NOTE: call resize memory, which will call our custom resize callback... this is a bit involved because + // wasm3 doesn't allow resizing the memory directly + M3Result res = ResizeMemory(runtime->m3Runtime, totalSize / d_m3MemPageSize); - return(addr); + return (addr); } void* wasm_memory_offset_to_ptr(wasm_memory* memory, u32 offset) { - M3MemoryHeader* header = (M3MemoryHeader*)(memory->ptr); - OC_DEBUG_ASSERT(offset < header->length, "Wasm offset exceeds memory length"); - return memory->ptr + sizeof(M3MemoryHeader) + offset; + M3MemoryHeader* header = (M3MemoryHeader*)(memory->ptr); + OC_DEBUG_ASSERT(offset < header->length, "Wasm offset exceeds memory length"); + return memory->ptr + sizeof(M3MemoryHeader) + offset; } diff --git a/src/ui/input_state.c b/src/ui/input_state.c index 5d7e2c1..313a00d 100644 --- a/src/ui/input_state.c +++ b/src/ui/input_state.c @@ -1,11 +1,11 @@ -/************************************************************//** +/************************************************************/ /** * * @file: input_state.c * @author: Martin Fouilleul * @date: 19/04/2023 * *****************************************************************/ -#include"input_state.h" +#include "input_state.h" //--------------------------------------------------------------- // Input state updating @@ -13,159 +13,164 @@ static void oc_update_key_state(oc_input_state* state, oc_key_state* key, oc_key_action action) { - u64 frameCounter = state->frameCounter; - if(key->lastUpdate != frameCounter) - { - key->transitionCount = 0; - key->repeatCount = 0; - key->sysClicked = false; - key->sysDoubleClicked = false; - key->lastUpdate = frameCounter; - } + u64 frameCounter = state->frameCounter; + if(key->lastUpdate != frameCounter) + { + key->transitionCount = 0; + key->repeatCount = 0; + key->sysClicked = false; + key->sysDoubleClicked = false; + key->lastUpdate = frameCounter; + } - switch(action) - { - case OC_KEY_PRESS: - { - if(!key->down) - { - key->transitionCount++; - } - key->down = true; - } break; + switch(action) + { + case OC_KEY_PRESS: + { + if(!key->down) + { + key->transitionCount++; + } + key->down = true; + } + break; - case OC_KEY_REPEAT: - { - key->repeatCount++; - key->down = true; - } break; + case OC_KEY_REPEAT: + { + key->repeatCount++; + key->down = true; + } + break; - case OC_KEY_RELEASE: - { - if(key->down) - { - key->transitionCount++; - } - key->down = false; - } break; + case OC_KEY_RELEASE: + { + if(key->down) + { + key->transitionCount++; + } + key->down = false; + } + break; - default: - break; - } + default: + break; + } } static void oc_update_key_mods(oc_input_state* state, oc_keymod_flags mods) { - state->keyboard.mods = mods; + state->keyboard.mods = mods; } static void oc_update_mouse_move(oc_input_state* state, f32 x, f32 y, f32 deltaX, f32 deltaY) { - u64 frameCounter = state->frameCounter; - oc_mouse_state* mouse = &state->mouse; - if(mouse->lastUpdate != frameCounter) - { - mouse->delta = (oc_vec2){0, 0}; - mouse->wheel = (oc_vec2){0, 0}; - mouse->lastUpdate = frameCounter; - } - mouse->pos = (oc_vec2){x, y}; - mouse->delta.x += deltaX; - mouse->delta.y += deltaY; + u64 frameCounter = state->frameCounter; + oc_mouse_state* mouse = &state->mouse; + if(mouse->lastUpdate != frameCounter) + { + mouse->delta = (oc_vec2){ 0, 0 }; + mouse->wheel = (oc_vec2){ 0, 0 }; + mouse->lastUpdate = frameCounter; + } + mouse->pos = (oc_vec2){ x, y }; + mouse->delta.x += deltaX; + mouse->delta.y += deltaY; } static void oc_update_mouse_wheel(oc_input_state* state, f32 deltaX, f32 deltaY) { - u64 frameCounter = state->frameCounter; - oc_mouse_state* mouse = &state->mouse; - if(mouse->lastUpdate != frameCounter) - { - mouse->delta = (oc_vec2){0, 0}; - mouse->wheel = (oc_vec2){0, 0}; - mouse->lastUpdate = frameCounter; - } - mouse->wheel.x += deltaX; - mouse->wheel.y += deltaY; + u64 frameCounter = state->frameCounter; + oc_mouse_state* mouse = &state->mouse; + if(mouse->lastUpdate != frameCounter) + { + mouse->delta = (oc_vec2){ 0, 0 }; + mouse->wheel = (oc_vec2){ 0, 0 }; + mouse->lastUpdate = frameCounter; + } + mouse->wheel.x += deltaX; + mouse->wheel.y += deltaY; } static void oc_update_text(oc_input_state* state, oc_utf32 codepoint) { - u64 frameCounter = state->frameCounter; - oc_text_state* text = &state->text; + u64 frameCounter = state->frameCounter; + oc_text_state* text = &state->text; - if(text->lastUpdate != frameCounter) - { - text->codePoints.len = 0; - text->lastUpdate = frameCounter; - } + if(text->lastUpdate != frameCounter) + { + text->codePoints.len = 0; + text->lastUpdate = frameCounter; + } - text->codePoints.ptr = text->backing; - if(text->codePoints.len < OC_INPUT_TEXT_BACKING_SIZE) - { - text->codePoints.ptr[text->codePoints.len] = codepoint; - text->codePoints.len++; - } - else - { - oc_log_warning("too many input codepoints per frame, dropping input"); - } + text->codePoints.ptr = text->backing; + if(text->codePoints.len < OC_INPUT_TEXT_BACKING_SIZE) + { + text->codePoints.ptr[text->codePoints.len] = codepoint; + text->codePoints.len++; + } + else + { + oc_log_warning("too many input codepoints per frame, dropping input"); + } } void oc_input_next_frame(oc_input_state* state) { - state->frameCounter++; + state->frameCounter++; } void oc_input_process_event(oc_input_state* state, oc_event* event) { - switch(event->type) - { - case OC_EVENT_KEYBOARD_KEY: - { - oc_key_state* key = &state->keyboard.keys[event->key.code]; - oc_update_key_state(state, key, event->key.action); - oc_update_key_mods(state, event->key.mods); - } break; + switch(event->type) + { + case OC_EVENT_KEYBOARD_KEY: + { + oc_key_state* key = &state->keyboard.keys[event->key.code]; + oc_update_key_state(state, key, event->key.action); + oc_update_key_mods(state, event->key.mods); + } + break; - case OC_EVENT_KEYBOARD_CHAR: - oc_update_text(state, event->character.codepoint); - break; + case OC_EVENT_KEYBOARD_CHAR: + oc_update_text(state, event->character.codepoint); + break; - case OC_EVENT_KEYBOARD_MODS: - oc_update_key_mods(state, event->key.mods); - break; + case OC_EVENT_KEYBOARD_MODS: + oc_update_key_mods(state, event->key.mods); + break; - case OC_EVENT_MOUSE_MOVE: - oc_update_mouse_move(state, event->mouse.x, event->mouse.y, event->mouse.deltaX, event->mouse.deltaY); - break; + case OC_EVENT_MOUSE_MOVE: + oc_update_mouse_move(state, event->mouse.x, event->mouse.y, event->mouse.deltaX, event->mouse.deltaY); + break; - case OC_EVENT_MOUSE_WHEEL: - oc_update_mouse_wheel(state, event->mouse.deltaX, event->mouse.deltaY); - break; + case OC_EVENT_MOUSE_WHEEL: + oc_update_mouse_wheel(state, event->mouse.deltaX, event->mouse.deltaY); + break; - case OC_EVENT_MOUSE_BUTTON: - { - oc_key_state* key = &state->mouse.buttons[event->key.code]; - oc_update_key_state(state, key, event->key.action); + case OC_EVENT_MOUSE_BUTTON: + { + oc_key_state* key = &state->mouse.buttons[event->key.code]; + oc_update_key_state(state, key, event->key.action); - if(event->key.action == OC_KEY_PRESS) - { - if(event->key.clickCount >= 1) - { - key->sysClicked = true; - } - if(event->key.clickCount >= 2) - { - key->sysDoubleClicked = true; - } - } + if(event->key.action == OC_KEY_PRESS) + { + if(event->key.clickCount >= 1) + { + key->sysClicked = true; + } + if(event->key.clickCount >= 2) + { + key->sysDoubleClicked = true; + } + } - oc_update_key_mods(state, event->key.mods); - } break; + oc_update_key_mods(state, event->key.mods); + } + break; - default: - break; - } + default: + break; + } } //-------------------------------------------------------------------- @@ -174,175 +179,175 @@ void oc_input_process_event(oc_input_state* state, oc_event* event) oc_key_state oc_key_get_state(oc_input_state* input, oc_key_code key) { - oc_key_state state = {0}; - if(key <= OC_KEY_COUNT) - { - state = input->keyboard.keys[key]; - } - return(state); + oc_key_state state = { 0 }; + if(key <= OC_KEY_COUNT) + { + state = input->keyboard.keys[key]; + } + return (state); } oc_key_state oc_mouse_button_get_state(oc_input_state* input, oc_mouse_button button) { - oc_key_state state = {0}; - if(button <= OC_MOUSE_BUTTON_COUNT) - { - state = input->mouse.buttons[button]; - } - return(state); + oc_key_state state = { 0 }; + if(button <= OC_MOUSE_BUTTON_COUNT) + { + state = input->mouse.buttons[button]; + } + return (state); } int oc_key_state_press_count(oc_input_state* input, oc_key_state* key) { - int count = 0; - if(key->lastUpdate == input->frameCounter) - { - count = key->transitionCount / 2; - if(key->down) - { - //NOTE: add one if state is down transition count is odd - count += (key->transitionCount & 0x01); - } - } - return(count); + int count = 0; + if(key->lastUpdate == input->frameCounter) + { + count = key->transitionCount / 2; + if(key->down) + { + //NOTE: add one if state is down transition count is odd + count += (key->transitionCount & 0x01); + } + } + return (count); } int oc_key_state_release_count(oc_input_state* input, oc_key_state* key) { - int count = 0; - if(key->lastUpdate == input->frameCounter) - { - count = key->transitionCount / 2; - if(!key->down) - { - //NOTE: add one if state is up and transition count is odd - count += (key->transitionCount & 0x01); - } - } - return(count); + int count = 0; + if(key->lastUpdate == input->frameCounter) + { + count = key->transitionCount / 2; + if(!key->down) + { + //NOTE: add one if state is up and transition count is odd + count += (key->transitionCount & 0x01); + } + } + return (count); } int oc_key_state_repeat_count(oc_input_state* input, oc_key_state* key) { - int count = 0; - if(key->lastUpdate == input->frameCounter) - { - count = key->repeatCount; - } - return(count); + int count = 0; + if(key->lastUpdate == input->frameCounter) + { + count = key->repeatCount; + } + return (count); } bool oc_key_down(oc_input_state* input, oc_key_code key) { - oc_key_state state = oc_key_get_state(input, key); - return(state.down); + oc_key_state state = oc_key_get_state(input, key); + return (state.down); } int oc_key_pressed(oc_input_state* input, oc_key_code key) { - oc_key_state state = oc_key_get_state(input, key); - int res = oc_key_state_press_count(input, &state); - return(res); + oc_key_state state = oc_key_get_state(input, key); + int res = oc_key_state_press_count(input, &state); + return (res); } int oc_key_released(oc_input_state* input, oc_key_code key) { - oc_key_state state = oc_key_get_state(input, key); - int res = oc_key_state_release_count(input, &state); - return(res); + oc_key_state state = oc_key_get_state(input, key); + int res = oc_key_state_release_count(input, &state); + return (res); } int oc_key_repeated(oc_input_state* input, oc_key_code key) { - oc_key_state state = oc_key_get_state(input, key); - int res = oc_key_state_repeat_count(input, &state); - return(res); + oc_key_state state = oc_key_get_state(input, key); + int res = oc_key_state_repeat_count(input, &state); + return (res); } bool oc_mouse_down(oc_input_state* input, oc_mouse_button button) { - oc_key_state state = oc_mouse_button_get_state(input, button); - return(state.down); + oc_key_state state = oc_mouse_button_get_state(input, button); + return (state.down); } int oc_mouse_pressed(oc_input_state* input, oc_mouse_button button) { - oc_key_state state = oc_mouse_button_get_state(input, button); - int res = oc_key_state_press_count(input, &state); - return(res); + oc_key_state state = oc_mouse_button_get_state(input, button); + int res = oc_key_state_press_count(input, &state); + return (res); } int oc_mouse_released(oc_input_state* input, oc_mouse_button button) { - oc_key_state state = oc_mouse_button_get_state(input, button); - int res = oc_key_state_release_count(input, &state); - return(res); + oc_key_state state = oc_mouse_button_get_state(input, button); + int res = oc_key_state_release_count(input, &state); + return (res); } bool oc_mouse_clicked(oc_input_state* input, oc_mouse_button button) { - oc_key_state state = oc_mouse_button_get_state(input, button); - bool clicked = state.sysClicked && (state.lastUpdate == input->frameCounter); - return(clicked); + oc_key_state state = oc_mouse_button_get_state(input, button); + bool clicked = state.sysClicked && (state.lastUpdate == input->frameCounter); + return (clicked); } bool oc_mouse_double_clicked(oc_input_state* input, oc_mouse_button button) { - oc_key_state state = oc_mouse_button_get_state(input, button); - bool doubleClicked = state.sysClicked && (state.lastUpdate == input->frameCounter); - return(doubleClicked); + oc_key_state state = oc_mouse_button_get_state(input, button); + bool doubleClicked = state.sysClicked && (state.lastUpdate == input->frameCounter); + return (doubleClicked); } oc_keymod_flags oc_key_mods(oc_input_state* input) { - return(input->keyboard.mods); + return (input->keyboard.mods); } oc_vec2 oc_mouse_position(oc_input_state* input) { - return(input->mouse.pos); + return (input->mouse.pos); } oc_vec2 oc_mouse_delta(oc_input_state* input) { - if(input->mouse.lastUpdate == input->frameCounter) - { - return(input->mouse.delta); - } - else - { - return((oc_vec2){0, 0}); - } + if(input->mouse.lastUpdate == input->frameCounter) + { + return (input->mouse.delta); + } + else + { + return ((oc_vec2){ 0, 0 }); + } } oc_vec2 oc_mouse_wheel(oc_input_state* input) { - if(input->mouse.lastUpdate == input->frameCounter) - { - return(input->mouse.wheel); - } - else - { - return((oc_vec2){0, 0}); - } + if(input->mouse.lastUpdate == input->frameCounter) + { + return (input->mouse.wheel); + } + else + { + return ((oc_vec2){ 0, 0 }); + } } oc_str32 oc_input_text_utf32(oc_input_state* input, oc_arena* arena) { - oc_str32 res = {0}; - if(input->text.lastUpdate == input->frameCounter) - { - res = oc_str32_push_copy(arena, input->text.codePoints); - } - return(res); + oc_str32 res = { 0 }; + if(input->text.lastUpdate == input->frameCounter) + { + res = oc_str32_push_copy(arena, input->text.codePoints); + } + return (res); } oc_str8 oc_input_text_utf8(oc_input_state* input, oc_arena* arena) { - oc_str8 res = {0}; - if(input->text.lastUpdate == input->frameCounter) - { - res = oc_utf8_push_from_codepoints(arena, input->text.codePoints); - } - return(res); + oc_str8 res = { 0 }; + if(input->text.lastUpdate == input->frameCounter) + { + res = oc_utf8_push_from_codepoints(arena, input->text.codePoints); + } + return (res); } diff --git a/src/ui/input_state.h b/src/ui/input_state.h index 0d9c81c..589ea72 100644 --- a/src/ui/input_state.h +++ b/src/ui/input_state.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: input_state.h * @author: Martin Fouilleul @@ -8,66 +8,70 @@ #ifndef __INPUT_STATE_H_ #define __INPUT_STATE_H_ -#include"platform/platform.h" -#include"util/typedefs.h" -#include"util/strings.h" -#include"util/utf8.h" -#include"app/app.h" +#include "app/app.h" +#include "platform/platform.h" +#include "util/strings.h" +#include "util/typedefs.h" +#include "util/utf8.h" typedef struct oc_key_state { - u64 lastUpdate; - u32 transitionCount; - u32 repeatCount; - bool down; - bool sysClicked; - bool sysDoubleClicked; + u64 lastUpdate; + u32 transitionCount; + u32 repeatCount; + bool down; + bool sysClicked; + bool sysDoubleClicked; } oc_key_state; typedef struct oc_keyboard_state { - oc_key_state keys[OC_KEY_COUNT]; - oc_keymod_flags mods; + oc_key_state keys[OC_KEY_COUNT]; + oc_keymod_flags mods; } oc_keyboard_state; typedef struct oc_mouse_state { - u64 lastUpdate; - bool posValid; - oc_vec2 pos; - oc_vec2 delta; - oc_vec2 wheel; + u64 lastUpdate; + bool posValid; + oc_vec2 pos; + oc_vec2 delta; + oc_vec2 wheel; - union - { - oc_key_state buttons[OC_MOUSE_BUTTON_COUNT]; - struct - { - oc_key_state left; - oc_key_state right; - oc_key_state middle; - oc_key_state ext1; - oc_key_state ext2; - }; - }; + union + { + oc_key_state buttons[OC_MOUSE_BUTTON_COUNT]; + + struct + { + oc_key_state left; + oc_key_state right; + oc_key_state middle; + oc_key_state ext1; + oc_key_state ext2; + }; + }; } oc_mouse_state; -enum { OC_INPUT_TEXT_BACKING_SIZE = 64 }; +enum +{ + OC_INPUT_TEXT_BACKING_SIZE = 64 +}; typedef struct oc_text_state { - u64 lastUpdate; - oc_utf32 backing[OC_INPUT_TEXT_BACKING_SIZE]; - oc_str32 codePoints; + u64 lastUpdate; + oc_utf32 backing[OC_INPUT_TEXT_BACKING_SIZE]; + oc_str32 codePoints; } oc_text_state; typedef struct oc_input_state { - u64 frameCounter; - oc_keyboard_state keyboard; - oc_mouse_state mouse; - oc_text_state text; + u64 frameCounter; + oc_keyboard_state keyboard; + oc_mouse_state mouse; + oc_text_state text; } oc_input_state; ORCA_API void oc_input_process_event(oc_input_state* state, oc_event* event); diff --git a/src/ui/ui.c b/src/ui/ui.c index ed5f744..f47872d 100644 --- a/src/ui/ui.c +++ b/src/ui/ui.c @@ -1,2820 +1,2801 @@ -/************************************************************//** +/************************************************************/ /** * * @file: ui.c * @author: Martin Fouilleul * @date: 08/08/2022 * @revision: * -*****************************************************************/ -#include"platform/platform.h" -#include"platform/platform_debug.h" -#include"platform/platform_clock.h" -#include"util/memory.h" -#include"util/hash.h" -#include"ui.h" - -static oc_ui_style OC_UI_STYLE_DEFAULTS = -{ - .size.width = {.kind = OC_UI_SIZE_CHILDREN, - .value = 0, - .relax = 0}, - .size.height = {.kind = OC_UI_SIZE_CHILDREN, - .value = 0, - .relax = 0}, - - .layout = {.axis = OC_UI_AXIS_Y, - .align = {OC_UI_ALIGN_START, - OC_UI_ALIGN_START}}, - .color = {0, 0, 0, 1}, - .fontSize = 16, -}; - -oc_thread_local oc_ui_context oc_uiThreadContext = {0}; -oc_thread_local oc_ui_context* oc_uiCurrentContext = 0; - -oc_ui_context* oc_ui_get_context(void) -{ - return(oc_uiCurrentContext); -} - -void oc_ui_set_context(oc_ui_context* context) -{ - oc_uiCurrentContext = context; -} - -//----------------------------------------------------------------------------- -// stacks -//----------------------------------------------------------------------------- -oc_ui_stack_elt* oc_ui_stack_push(oc_ui_context* ui, oc_ui_stack_elt** stack) -{ - oc_ui_stack_elt* elt = oc_arena_push_type(&ui->frameArena, oc_ui_stack_elt); - memset(elt, 0, sizeof(oc_ui_stack_elt)); - elt->parent = *stack; - *stack = elt; - return(elt); -} - -void oc_ui_stack_pop(oc_ui_stack_elt** stack) -{ - if(*stack) - { - *stack = (*stack)->parent; - } - else - { - oc_log_error("ui stack underflow\n"); - } -} - -oc_rect oc_ui_intersect_rects(oc_rect lhs, oc_rect rhs) -{ - //NOTE(martin): intersect with current clip - f32 x0 = oc_max(lhs.x, rhs.x); - f32 y0 = oc_max(lhs.y, rhs.y); - f32 x1 = oc_min(lhs.x + lhs.w, rhs.x + rhs.w); - f32 y1 = oc_min(lhs.y + lhs.h, rhs.y + rhs.h); - oc_rect r = {x0, y0, oc_max(0, x1-x0), oc_max(0, y1-y0)}; - return(r); -} - -oc_rect oc_ui_clip_top(void) -{ - oc_rect r = {-FLT_MAX/2, -FLT_MAX/2, FLT_MAX, FLT_MAX}; - oc_ui_context* ui = oc_ui_get_context(); - oc_ui_stack_elt* elt = ui->clipStack; - if(elt) - { - r = elt->clip; - } - return(r); -} - -void oc_ui_clip_push(oc_rect clip) -{ - oc_ui_context* ui = oc_ui_get_context(); - oc_rect current = oc_ui_clip_top(); - oc_ui_stack_elt* elt = oc_ui_stack_push(ui, &ui->clipStack); - elt->clip = oc_ui_intersect_rects(current, clip); -} - -void oc_ui_clip_pop(void) -{ - oc_ui_context* ui = oc_ui_get_context(); - oc_ui_stack_pop(&ui->clipStack); -} - -oc_ui_box* oc_ui_box_top(void) -{ - oc_ui_context* ui = oc_ui_get_context(); - oc_ui_stack_elt* elt = ui->boxStack; - oc_ui_box* box = elt ? elt->box : 0; - return(box); -} - -void oc_ui_box_push(oc_ui_box* box) -{ - oc_ui_context* ui = oc_ui_get_context(); - oc_ui_stack_elt* elt = oc_ui_stack_push(ui, &ui->boxStack); - elt->box = box; - if(box->flags & OC_UI_FLAG_CLIP) - { - oc_ui_clip_push(box->rect); - } -} - -void oc_ui_box_pop(void) -{ - oc_ui_context* ui = oc_ui_get_context(); - oc_ui_box* box = oc_ui_box_top(); - if(box) - { - if(box->flags & OC_UI_FLAG_CLIP) - { - oc_ui_clip_pop(); - } - oc_ui_stack_pop(&ui->boxStack); - } -} - -//----------------------------------------------------------------------------- -// tagging -//----------------------------------------------------------------------------- - -oc_ui_tag oc_ui_tag_make_str8(oc_str8 string) -{ - oc_ui_tag tag = {.hash = oc_hash_xx64_string(string)}; - return(tag); -} - -void oc_ui_tag_box_str8(oc_ui_box* box, oc_str8 string) -{ - oc_ui_context* ui = oc_ui_get_context(); - oc_ui_tag_elt* elt = oc_arena_push_type(&ui->frameArena, oc_ui_tag_elt); - elt->tag = oc_ui_tag_make_str8(string); - oc_list_append(&box->tags, &elt->listElt); -} - -void oc_ui_tag_next_str8(oc_str8 string) -{ - oc_ui_context* ui = oc_ui_get_context(); - oc_ui_tag_elt* elt = oc_arena_push_type(&ui->frameArena, oc_ui_tag_elt); - elt->tag = oc_ui_tag_make_str8(string); - oc_list_append(&ui->nextBoxTags, &elt->listElt); -} - -//----------------------------------------------------------------------------- -// key hashing and caching -//----------------------------------------------------------------------------- -oc_ui_key oc_ui_key_make_str8(oc_str8 string) -{ - oc_ui_context* ui = oc_ui_get_context(); - u64 seed = 0; - oc_ui_box* parent = oc_ui_box_top(); - if(parent) - { - seed = parent->key.hash; - } - - oc_ui_key key = {0}; - key.hash = oc_hash_xx64_string_seed(string, seed); - return(key); -} - -oc_ui_key oc_ui_key_make_path(oc_str8_list path) -{ - oc_ui_context* ui = oc_ui_get_context(); - u64 seed = 0; - oc_ui_box* parent = oc_ui_box_top(); - if(parent) - { - seed = parent->key.hash; - } - oc_list_for(&path.list, elt, oc_str8_elt, listElt) - { - seed = oc_hash_xx64_string_seed(elt->string, seed); - } - oc_ui_key key = {seed}; - return(key); -} - -bool oc_ui_key_equal(oc_ui_key a, oc_ui_key b) -{ - return(a.hash == b.hash); -} - -void oc_ui_box_cache(oc_ui_context* ui, oc_ui_box* box) -{ - u64 index = box->key.hash & (OC_UI_BOX_MAP_BUCKET_COUNT-1); - oc_list_append(&(ui->boxMap[index]), &box->bucketElt); -} - -oc_ui_box* oc_ui_box_lookup_key(oc_ui_key key) -{ - oc_ui_context* ui = oc_ui_get_context(); - u64 index = key.hash & (OC_UI_BOX_MAP_BUCKET_COUNT-1); - - oc_list_for(&ui->boxMap[index], box, oc_ui_box, bucketElt) - { - if(oc_ui_key_equal(key, box->key)) - { - return(box); - } - } - return(0); -} - -oc_ui_box* oc_ui_box_lookup_str8(oc_str8 string) -{ - oc_ui_key key = oc_ui_key_make_str8(string); - return(oc_ui_box_lookup_key(key)); -} - -//----------------------------------------------------------------------------- -// styling -//----------------------------------------------------------------------------- - -void oc_ui_pattern_push(oc_arena* arena, oc_ui_pattern* pattern, oc_ui_selector selector) -{ - oc_ui_selector* copy = oc_arena_push_type(arena, oc_ui_selector); - *copy = selector; - oc_list_append(&pattern->l, ©->listElt); -} - -oc_ui_pattern oc_ui_pattern_all(void) -{ - oc_ui_context* ui = oc_ui_get_context(); - oc_ui_pattern pattern = {0}; - oc_ui_pattern_push(&ui->frameArena, &pattern, (oc_ui_selector){.kind = OC_UI_SEL_ANY}); - return(pattern); -} - -oc_ui_pattern oc_ui_pattern_owner(void) -{ - oc_ui_context* ui = oc_ui_get_context(); - oc_ui_pattern pattern = {0}; - oc_ui_pattern_push(&ui->frameArena, &pattern, (oc_ui_selector){.kind = OC_UI_SEL_OWNER}); - return(pattern); -} - -void oc_ui_style_match_before(oc_ui_pattern pattern, oc_ui_style* style, oc_ui_style_mask mask) -{ - oc_ui_context* ui = oc_ui_get_context(); - if(ui) - { - oc_ui_style_rule* rule = oc_arena_push_type(&ui->frameArena, oc_ui_style_rule); - rule->pattern = pattern; - rule->mask = mask; - rule->style = oc_arena_push_type(&ui->frameArena, oc_ui_style); - *rule->style = *style; - - oc_list_append(&ui->nextBoxBeforeRules, &rule->boxElt); - } -} - -void oc_ui_style_match_after(oc_ui_pattern pattern, oc_ui_style* style, oc_ui_style_mask mask) -{ - oc_ui_context* ui = oc_ui_get_context(); - if(ui) - { - oc_ui_style_rule* rule = oc_arena_push_type(&ui->frameArena, oc_ui_style_rule); - rule->pattern = pattern; - rule->mask = mask; - rule->style = oc_arena_push_type(&ui->frameArena, oc_ui_style); - *rule->style = *style; - - oc_list_append(&ui->nextBoxAfterRules, &rule->boxElt); - } -} - -void oc_ui_style_next(oc_ui_style* style, oc_ui_style_mask mask) -{ - oc_ui_style_match_before(oc_ui_pattern_owner(), style, mask); -} - -void oc_ui_style_box_before(oc_ui_box* box, oc_ui_pattern pattern, oc_ui_style* style, oc_ui_style_mask mask) -{ - oc_ui_context* ui = oc_ui_get_context(); - if(ui) - { - oc_ui_style_rule* rule = oc_arena_push_type(&ui->frameArena, oc_ui_style_rule); - rule->pattern = pattern; - rule->mask = mask; - rule->style = oc_arena_push_type(&ui->frameArena, oc_ui_style); - *rule->style = *style; - - oc_list_append(&box->beforeRules, &rule->boxElt); - rule->owner = box; - } -} - -void oc_ui_style_box_after(oc_ui_box* box, oc_ui_pattern pattern, oc_ui_style* style, oc_ui_style_mask mask) -{ - oc_ui_context* ui = oc_ui_get_context(); - if(ui) - { - oc_ui_style_rule* rule = oc_arena_push_type(&ui->frameArena, oc_ui_style_rule); - rule->pattern = pattern; - rule->mask = mask; - rule->style = oc_arena_push_type(&ui->frameArena, oc_ui_style); - *rule->style = *style; - - oc_list_append(&box->afterRules, &rule->boxElt); - rule->owner = box; - } -} - -//----------------------------------------------------------------------------- -// input -//----------------------------------------------------------------------------- - -void oc_ui_process_event(oc_event* event) -{ - oc_ui_context* ui = oc_ui_get_context(); - oc_input_process_event(&ui->input, event); -} - -oc_vec2 oc_ui_mouse_position(void) -{ - oc_ui_context* ui = oc_ui_get_context(); - oc_vec2 mousePos = oc_mouse_position(&ui->input); - return(mousePos); -} - -oc_vec2 oc_ui_mouse_delta(void) -{ - oc_ui_context* ui = oc_ui_get_context(); - oc_vec2 delta = oc_mouse_delta(&ui->input); - return(delta); -} - -oc_vec2 oc_ui_mouse_wheel(void) -{ - oc_ui_context* ui = oc_ui_get_context(); - oc_vec2 delta = oc_mouse_wheel(&ui->input); - return(delta); -} - -//----------------------------------------------------------------------------- -// ui boxes -//----------------------------------------------------------------------------- - -bool oc_ui_rect_hit(oc_rect r, oc_vec2 p) -{ - return( (p.x > r.x) - &&(p.x < r.x + r.w) - &&(p.y > r.y) - &&(p.y < r.y + r.h)); -} - -bool oc_ui_box_hovering(oc_ui_box* box, oc_vec2 p) -{ - oc_ui_context* ui = oc_ui_get_context(); - - oc_rect clip = oc_ui_clip_top(); - oc_rect rect = oc_ui_intersect_rects(clip, box->rect); - bool hit = oc_ui_rect_hit(rect, p); - bool result = hit && (!ui->hovered || box->z >= ui->hovered->z); - return(result); -} - -oc_ui_box* oc_ui_box_make_str8(oc_str8 string, oc_ui_flags flags) -{ - oc_ui_context* ui = oc_ui_get_context(); - - oc_ui_key key = oc_ui_key_make_str8(string); - oc_ui_box* box = oc_ui_box_lookup_key(key); - - if(!box) - { - box = oc_pool_alloc_type(&ui->boxPool, oc_ui_box); - memset(box, 0, sizeof(oc_ui_box)); - - box->key = key; - box->fresh = true; - oc_ui_box_cache(ui, box); - } - else - { - box->fresh = false; - } - - //NOTE: setup hierarchy - if(box->frameCounter != ui->frameCounter) - { - oc_list_init(&box->children); - box->parent = oc_ui_box_top(); - if(box->parent) - { - oc_list_append(&box->parent->children, &box->listElt); - box->parentClosed = box->parent->closed || box->parent->parentClosed; - } - - if(box->flags & OC_UI_FLAG_OVERLAY) - { - oc_list_append(&ui->overlayList, &box->overlayElt); - } - } - else - { - //maybe this should be a warning that we're trying to make the box twice in the same frame? - oc_log_warning("trying to make ui box '%.*s' multiple times in the same frame\n", (int)box->string.len, box->string.ptr); - } - - //NOTE: setup per-frame state - box->frameCounter = ui->frameCounter; - box->string = oc_str8_push_copy(&ui->frameArena, string); - box->flags = flags; - - //NOTE: create style and setup non-inherited attributes to default values - box->targetStyle = oc_arena_push_type(&ui->frameArena, oc_ui_style); - oc_ui_apply_style_with_mask(box->targetStyle, &OC_UI_STYLE_DEFAULTS, ~0ULL); - - //NOTE: set tags, before rules and last box - box->tags = ui->nextBoxTags; - ui->nextBoxTags = (oc_list){0}; - - box->beforeRules = ui->nextBoxBeforeRules; - oc_list_for(&box->beforeRules, rule, oc_ui_style_rule, boxElt) - { - rule->owner = box; - } - ui->nextBoxBeforeRules = (oc_list){0}; - - box->afterRules = ui->nextBoxAfterRules; - oc_list_for(&box->afterRules, rule, oc_ui_style_rule, boxElt) - { - rule->owner = box; - } - ui->nextBoxAfterRules = (oc_list){0}; - - - //NOTE: set scroll - if(oc_ui_box_hovering(box, oc_ui_mouse_position())) - { - oc_vec2 wheel = oc_ui_mouse_wheel(); - if(box->flags & OC_UI_FLAG_SCROLL_WHEEL_X) - { - box->scroll.x += wheel.x; - } - if(box->flags & OC_UI_FLAG_SCROLL_WHEEL_Y) - { - box->scroll.y += wheel.y; - } - } - return(box); -} - -oc_ui_box* oc_ui_box_begin_str8(oc_str8 string, oc_ui_flags flags) -{ - oc_ui_context* ui = oc_ui_get_context(); - oc_ui_box* box = oc_ui_box_make_str8(string, flags); - oc_ui_box_push(box); - return(box); -} - -oc_ui_box* oc_ui_box_end(void) -{ - oc_ui_context* ui = oc_ui_get_context(); - oc_ui_box* box = oc_ui_box_top(); - OC_DEBUG_ASSERT(box, "box stack underflow"); - - oc_ui_box_pop(); - - return(box); -} - -void oc_ui_box_set_draw_proc(oc_ui_box* box, oc_ui_box_draw_proc proc, void* data) -{ - box->drawProc = proc; - box->drawData = data; -} - -void oc_ui_box_set_closed(oc_ui_box* box, bool closed) -{ - box->closed = closed; -} - -bool oc_ui_box_closed(oc_ui_box* box) -{ - return(box->closed); -} - -void oc_ui_box_activate(oc_ui_box* box) -{ - box->active = true; -} - -void oc_ui_box_deactivate(oc_ui_box* box) -{ - box->active = false; -} - -bool oc_ui_box_active(oc_ui_box* box) -{ - return(box->active); -} - -void oc_ui_box_set_hot(oc_ui_box* box, bool hot) -{ - box->hot = hot; -} - -bool oc_ui_box_hot(oc_ui_box* box) -{ - return(box->hot); -} - -oc_ui_sig oc_ui_box_sig(oc_ui_box* box) -{ - //NOTE: compute input signals - oc_ui_sig sig = {0}; - - oc_ui_context* ui = oc_ui_get_context(); - oc_input_state* input = &ui->input; - - sig.box = box; - - if(!box->closed && !box->parentClosed) - { - oc_vec2 mousePos = oc_ui_mouse_position(); - - sig.mouse = (oc_vec2){mousePos.x - box->rect.x, mousePos.y - box->rect.y}; - sig.delta = oc_ui_mouse_delta(); - sig.wheel = oc_ui_mouse_wheel(); - sig.hovering = oc_ui_box_hovering(box, mousePos); - - if(box->flags & OC_UI_FLAG_CLICKABLE) - { - if(sig.hovering) - { - sig.pressed = oc_mouse_pressed(input, OC_MOUSE_LEFT); - if(sig.pressed) - { - if(!box->dragging) - { - box->pressedMouse = sig.mouse; - } - box->dragging = true; - } - sig.doubleClicked = oc_mouse_double_clicked(input, OC_MOUSE_LEFT); - sig.rightPressed = oc_mouse_pressed(input, OC_MOUSE_RIGHT); - } - - sig.released = oc_mouse_released(input, OC_MOUSE_LEFT); - if(sig.released) - { - if(box->dragging && sig.hovering) - { - sig.clicked = true; - } - } - - if(!oc_mouse_down(input, OC_MOUSE_LEFT)) - { - box->dragging = false; - } - - sig.dragging = box->dragging; - } - - } - return(sig); -} - -bool oc_ui_box_hidden(oc_ui_box* box) -{ - return(box->closed || box->parentClosed); -} - -//----------------------------------------------------------------------------- -// Auto-layout -//----------------------------------------------------------------------------- - -void oc_ui_animate_f32(oc_ui_context* ui, f32* value, f32 target, f32 animationTime) -{ - if( animationTime < 1e-6 - || fabs(*value - target) < 0.001) - { - *value = target; - } - else - { - - /*NOTE: +*****************************************************************/ +#include "ui.h" +#include "platform/platform.h" +#include "platform/platform_clock.h" +#include "platform/platform_debug.h" +#include "util/hash.h" +#include "util/memory.h" + +static oc_ui_style OC_UI_STYLE_DEFAULTS = { + .size.width = { .kind = OC_UI_SIZE_CHILDREN, + .value = 0, + .relax = 0 }, + .size.height = { .kind = OC_UI_SIZE_CHILDREN, + .value = 0, + .relax = 0 }, + + .layout = { .axis = OC_UI_AXIS_Y, + .align = { OC_UI_ALIGN_START, + OC_UI_ALIGN_START } }, + .color = { 0, 0, 0, 1 }, + .fontSize = 16, +}; + +oc_thread_local oc_ui_context oc_uiThreadContext = { 0 }; +oc_thread_local oc_ui_context* oc_uiCurrentContext = 0; + +oc_ui_context* oc_ui_get_context(void) +{ + return (oc_uiCurrentContext); +} + +void oc_ui_set_context(oc_ui_context* context) +{ + oc_uiCurrentContext = context; +} + +//----------------------------------------------------------------------------- +// stacks +//----------------------------------------------------------------------------- +oc_ui_stack_elt* oc_ui_stack_push(oc_ui_context* ui, oc_ui_stack_elt** stack) +{ + oc_ui_stack_elt* elt = oc_arena_push_type(&ui->frameArena, oc_ui_stack_elt); + memset(elt, 0, sizeof(oc_ui_stack_elt)); + elt->parent = *stack; + *stack = elt; + return (elt); +} + +void oc_ui_stack_pop(oc_ui_stack_elt** stack) +{ + if(*stack) + { + *stack = (*stack)->parent; + } + else + { + oc_log_error("ui stack underflow\n"); + } +} + +oc_rect oc_ui_intersect_rects(oc_rect lhs, oc_rect rhs) +{ + //NOTE(martin): intersect with current clip + f32 x0 = oc_max(lhs.x, rhs.x); + f32 y0 = oc_max(lhs.y, rhs.y); + f32 x1 = oc_min(lhs.x + lhs.w, rhs.x + rhs.w); + f32 y1 = oc_min(lhs.y + lhs.h, rhs.y + rhs.h); + oc_rect r = { x0, y0, oc_max(0, x1 - x0), oc_max(0, y1 - y0) }; + return (r); +} + +oc_rect oc_ui_clip_top(void) +{ + oc_rect r = { -FLT_MAX / 2, -FLT_MAX / 2, FLT_MAX, FLT_MAX }; + oc_ui_context* ui = oc_ui_get_context(); + oc_ui_stack_elt* elt = ui->clipStack; + if(elt) + { + r = elt->clip; + } + return (r); +} + +void oc_ui_clip_push(oc_rect clip) +{ + oc_ui_context* ui = oc_ui_get_context(); + oc_rect current = oc_ui_clip_top(); + oc_ui_stack_elt* elt = oc_ui_stack_push(ui, &ui->clipStack); + elt->clip = oc_ui_intersect_rects(current, clip); +} + +void oc_ui_clip_pop(void) +{ + oc_ui_context* ui = oc_ui_get_context(); + oc_ui_stack_pop(&ui->clipStack); +} + +oc_ui_box* oc_ui_box_top(void) +{ + oc_ui_context* ui = oc_ui_get_context(); + oc_ui_stack_elt* elt = ui->boxStack; + oc_ui_box* box = elt ? elt->box : 0; + return (box); +} + +void oc_ui_box_push(oc_ui_box* box) +{ + oc_ui_context* ui = oc_ui_get_context(); + oc_ui_stack_elt* elt = oc_ui_stack_push(ui, &ui->boxStack); + elt->box = box; + if(box->flags & OC_UI_FLAG_CLIP) + { + oc_ui_clip_push(box->rect); + } +} + +void oc_ui_box_pop(void) +{ + oc_ui_context* ui = oc_ui_get_context(); + oc_ui_box* box = oc_ui_box_top(); + if(box) + { + if(box->flags & OC_UI_FLAG_CLIP) + { + oc_ui_clip_pop(); + } + oc_ui_stack_pop(&ui->boxStack); + } +} + +//----------------------------------------------------------------------------- +// tagging +//----------------------------------------------------------------------------- + +oc_ui_tag oc_ui_tag_make_str8(oc_str8 string) +{ + oc_ui_tag tag = { .hash = oc_hash_xx64_string(string) }; + return (tag); +} + +void oc_ui_tag_box_str8(oc_ui_box* box, oc_str8 string) +{ + oc_ui_context* ui = oc_ui_get_context(); + oc_ui_tag_elt* elt = oc_arena_push_type(&ui->frameArena, oc_ui_tag_elt); + elt->tag = oc_ui_tag_make_str8(string); + oc_list_append(&box->tags, &elt->listElt); +} + +void oc_ui_tag_next_str8(oc_str8 string) +{ + oc_ui_context* ui = oc_ui_get_context(); + oc_ui_tag_elt* elt = oc_arena_push_type(&ui->frameArena, oc_ui_tag_elt); + elt->tag = oc_ui_tag_make_str8(string); + oc_list_append(&ui->nextBoxTags, &elt->listElt); +} + +//----------------------------------------------------------------------------- +// key hashing and caching +//----------------------------------------------------------------------------- +oc_ui_key oc_ui_key_make_str8(oc_str8 string) +{ + oc_ui_context* ui = oc_ui_get_context(); + u64 seed = 0; + oc_ui_box* parent = oc_ui_box_top(); + if(parent) + { + seed = parent->key.hash; + } + + oc_ui_key key = { 0 }; + key.hash = oc_hash_xx64_string_seed(string, seed); + return (key); +} + +oc_ui_key oc_ui_key_make_path(oc_str8_list path) +{ + oc_ui_context* ui = oc_ui_get_context(); + u64 seed = 0; + oc_ui_box* parent = oc_ui_box_top(); + if(parent) + { + seed = parent->key.hash; + } + oc_list_for(&path.list, elt, oc_str8_elt, listElt) + { + seed = oc_hash_xx64_string_seed(elt->string, seed); + } + oc_ui_key key = { seed }; + return (key); +} + +bool oc_ui_key_equal(oc_ui_key a, oc_ui_key b) +{ + return (a.hash == b.hash); +} + +void oc_ui_box_cache(oc_ui_context* ui, oc_ui_box* box) +{ + u64 index = box->key.hash & (OC_UI_BOX_MAP_BUCKET_COUNT - 1); + oc_list_append(&(ui->boxMap[index]), &box->bucketElt); +} + +oc_ui_box* oc_ui_box_lookup_key(oc_ui_key key) +{ + oc_ui_context* ui = oc_ui_get_context(); + u64 index = key.hash & (OC_UI_BOX_MAP_BUCKET_COUNT - 1); + + oc_list_for(&ui->boxMap[index], box, oc_ui_box, bucketElt) + { + if(oc_ui_key_equal(key, box->key)) + { + return (box); + } + } + return (0); +} + +oc_ui_box* oc_ui_box_lookup_str8(oc_str8 string) +{ + oc_ui_key key = oc_ui_key_make_str8(string); + return (oc_ui_box_lookup_key(key)); +} + +//----------------------------------------------------------------------------- +// styling +//----------------------------------------------------------------------------- + +void oc_ui_pattern_push(oc_arena* arena, oc_ui_pattern* pattern, oc_ui_selector selector) +{ + oc_ui_selector* copy = oc_arena_push_type(arena, oc_ui_selector); + *copy = selector; + oc_list_append(&pattern->l, ©->listElt); +} + +oc_ui_pattern oc_ui_pattern_all(void) +{ + oc_ui_context* ui = oc_ui_get_context(); + oc_ui_pattern pattern = { 0 }; + oc_ui_pattern_push(&ui->frameArena, &pattern, (oc_ui_selector){ .kind = OC_UI_SEL_ANY }); + return (pattern); +} + +oc_ui_pattern oc_ui_pattern_owner(void) +{ + oc_ui_context* ui = oc_ui_get_context(); + oc_ui_pattern pattern = { 0 }; + oc_ui_pattern_push(&ui->frameArena, &pattern, (oc_ui_selector){ .kind = OC_UI_SEL_OWNER }); + return (pattern); +} + +void oc_ui_style_match_before(oc_ui_pattern pattern, oc_ui_style* style, oc_ui_style_mask mask) +{ + oc_ui_context* ui = oc_ui_get_context(); + if(ui) + { + oc_ui_style_rule* rule = oc_arena_push_type(&ui->frameArena, oc_ui_style_rule); + rule->pattern = pattern; + rule->mask = mask; + rule->style = oc_arena_push_type(&ui->frameArena, oc_ui_style); + *rule->style = *style; + + oc_list_append(&ui->nextBoxBeforeRules, &rule->boxElt); + } +} + +void oc_ui_style_match_after(oc_ui_pattern pattern, oc_ui_style* style, oc_ui_style_mask mask) +{ + oc_ui_context* ui = oc_ui_get_context(); + if(ui) + { + oc_ui_style_rule* rule = oc_arena_push_type(&ui->frameArena, oc_ui_style_rule); + rule->pattern = pattern; + rule->mask = mask; + rule->style = oc_arena_push_type(&ui->frameArena, oc_ui_style); + *rule->style = *style; + + oc_list_append(&ui->nextBoxAfterRules, &rule->boxElt); + } +} + +void oc_ui_style_next(oc_ui_style* style, oc_ui_style_mask mask) +{ + oc_ui_style_match_before(oc_ui_pattern_owner(), style, mask); +} + +void oc_ui_style_box_before(oc_ui_box* box, oc_ui_pattern pattern, oc_ui_style* style, oc_ui_style_mask mask) +{ + oc_ui_context* ui = oc_ui_get_context(); + if(ui) + { + oc_ui_style_rule* rule = oc_arena_push_type(&ui->frameArena, oc_ui_style_rule); + rule->pattern = pattern; + rule->mask = mask; + rule->style = oc_arena_push_type(&ui->frameArena, oc_ui_style); + *rule->style = *style; + + oc_list_append(&box->beforeRules, &rule->boxElt); + rule->owner = box; + } +} + +void oc_ui_style_box_after(oc_ui_box* box, oc_ui_pattern pattern, oc_ui_style* style, oc_ui_style_mask mask) +{ + oc_ui_context* ui = oc_ui_get_context(); + if(ui) + { + oc_ui_style_rule* rule = oc_arena_push_type(&ui->frameArena, oc_ui_style_rule); + rule->pattern = pattern; + rule->mask = mask; + rule->style = oc_arena_push_type(&ui->frameArena, oc_ui_style); + *rule->style = *style; + + oc_list_append(&box->afterRules, &rule->boxElt); + rule->owner = box; + } +} + +//----------------------------------------------------------------------------- +// input +//----------------------------------------------------------------------------- + +void oc_ui_process_event(oc_event* event) +{ + oc_ui_context* ui = oc_ui_get_context(); + oc_input_process_event(&ui->input, event); +} + +oc_vec2 oc_ui_mouse_position(void) +{ + oc_ui_context* ui = oc_ui_get_context(); + oc_vec2 mousePos = oc_mouse_position(&ui->input); + return (mousePos); +} + +oc_vec2 oc_ui_mouse_delta(void) +{ + oc_ui_context* ui = oc_ui_get_context(); + oc_vec2 delta = oc_mouse_delta(&ui->input); + return (delta); +} + +oc_vec2 oc_ui_mouse_wheel(void) +{ + oc_ui_context* ui = oc_ui_get_context(); + oc_vec2 delta = oc_mouse_wheel(&ui->input); + return (delta); +} + +//----------------------------------------------------------------------------- +// ui boxes +//----------------------------------------------------------------------------- + +bool oc_ui_rect_hit(oc_rect r, oc_vec2 p) +{ + return ((p.x > r.x) + && (p.x < r.x + r.w) + && (p.y > r.y) + && (p.y < r.y + r.h)); +} + +bool oc_ui_box_hovering(oc_ui_box* box, oc_vec2 p) +{ + oc_ui_context* ui = oc_ui_get_context(); + + oc_rect clip = oc_ui_clip_top(); + oc_rect rect = oc_ui_intersect_rects(clip, box->rect); + bool hit = oc_ui_rect_hit(rect, p); + bool result = hit && (!ui->hovered || box->z >= ui->hovered->z); + return (result); +} + +oc_ui_box* oc_ui_box_make_str8(oc_str8 string, oc_ui_flags flags) +{ + oc_ui_context* ui = oc_ui_get_context(); + + oc_ui_key key = oc_ui_key_make_str8(string); + oc_ui_box* box = oc_ui_box_lookup_key(key); + + if(!box) + { + box = oc_pool_alloc_type(&ui->boxPool, oc_ui_box); + memset(box, 0, sizeof(oc_ui_box)); + + box->key = key; + box->fresh = true; + oc_ui_box_cache(ui, box); + } + else + { + box->fresh = false; + } + + //NOTE: setup hierarchy + if(box->frameCounter != ui->frameCounter) + { + oc_list_init(&box->children); + box->parent = oc_ui_box_top(); + if(box->parent) + { + oc_list_append(&box->parent->children, &box->listElt); + box->parentClosed = box->parent->closed || box->parent->parentClosed; + } + + if(box->flags & OC_UI_FLAG_OVERLAY) + { + oc_list_append(&ui->overlayList, &box->overlayElt); + } + } + else + { + //maybe this should be a warning that we're trying to make the box twice in the same frame? + oc_log_warning("trying to make ui box '%.*s' multiple times in the same frame\n", (int)box->string.len, box->string.ptr); + } + + //NOTE: setup per-frame state + box->frameCounter = ui->frameCounter; + box->string = oc_str8_push_copy(&ui->frameArena, string); + box->flags = flags; + + //NOTE: create style and setup non-inherited attributes to default values + box->targetStyle = oc_arena_push_type(&ui->frameArena, oc_ui_style); + oc_ui_apply_style_with_mask(box->targetStyle, &OC_UI_STYLE_DEFAULTS, ~0ULL); + + //NOTE: set tags, before rules and last box + box->tags = ui->nextBoxTags; + ui->nextBoxTags = (oc_list){ 0 }; + + box->beforeRules = ui->nextBoxBeforeRules; + oc_list_for(&box->beforeRules, rule, oc_ui_style_rule, boxElt) + { + rule->owner = box; + } + ui->nextBoxBeforeRules = (oc_list){ 0 }; + + box->afterRules = ui->nextBoxAfterRules; + oc_list_for(&box->afterRules, rule, oc_ui_style_rule, boxElt) + { + rule->owner = box; + } + ui->nextBoxAfterRules = (oc_list){ 0 }; + + //NOTE: set scroll + if(oc_ui_box_hovering(box, oc_ui_mouse_position())) + { + oc_vec2 wheel = oc_ui_mouse_wheel(); + if(box->flags & OC_UI_FLAG_SCROLL_WHEEL_X) + { + box->scroll.x += wheel.x; + } + if(box->flags & OC_UI_FLAG_SCROLL_WHEEL_Y) + { + box->scroll.y += wheel.y; + } + } + return (box); +} + +oc_ui_box* oc_ui_box_begin_str8(oc_str8 string, oc_ui_flags flags) +{ + oc_ui_context* ui = oc_ui_get_context(); + oc_ui_box* box = oc_ui_box_make_str8(string, flags); + oc_ui_box_push(box); + return (box); +} + +oc_ui_box* oc_ui_box_end(void) +{ + oc_ui_context* ui = oc_ui_get_context(); + oc_ui_box* box = oc_ui_box_top(); + OC_DEBUG_ASSERT(box, "box stack underflow"); + + oc_ui_box_pop(); + + return (box); +} + +void oc_ui_box_set_draw_proc(oc_ui_box* box, oc_ui_box_draw_proc proc, void* data) +{ + box->drawProc = proc; + box->drawData = data; +} + +void oc_ui_box_set_closed(oc_ui_box* box, bool closed) +{ + box->closed = closed; +} + +bool oc_ui_box_closed(oc_ui_box* box) +{ + return (box->closed); +} + +void oc_ui_box_activate(oc_ui_box* box) +{ + box->active = true; +} + +void oc_ui_box_deactivate(oc_ui_box* box) +{ + box->active = false; +} + +bool oc_ui_box_active(oc_ui_box* box) +{ + return (box->active); +} + +void oc_ui_box_set_hot(oc_ui_box* box, bool hot) +{ + box->hot = hot; +} + +bool oc_ui_box_hot(oc_ui_box* box) +{ + return (box->hot); +} + +oc_ui_sig oc_ui_box_sig(oc_ui_box* box) +{ + //NOTE: compute input signals + oc_ui_sig sig = { 0 }; + + oc_ui_context* ui = oc_ui_get_context(); + oc_input_state* input = &ui->input; + + sig.box = box; + + if(!box->closed && !box->parentClosed) + { + oc_vec2 mousePos = oc_ui_mouse_position(); + + sig.mouse = (oc_vec2){ mousePos.x - box->rect.x, mousePos.y - box->rect.y }; + sig.delta = oc_ui_mouse_delta(); + sig.wheel = oc_ui_mouse_wheel(); + sig.hovering = oc_ui_box_hovering(box, mousePos); + + if(box->flags & OC_UI_FLAG_CLICKABLE) + { + if(sig.hovering) + { + sig.pressed = oc_mouse_pressed(input, OC_MOUSE_LEFT); + if(sig.pressed) + { + if(!box->dragging) + { + box->pressedMouse = sig.mouse; + } + box->dragging = true; + } + sig.doubleClicked = oc_mouse_double_clicked(input, OC_MOUSE_LEFT); + sig.rightPressed = oc_mouse_pressed(input, OC_MOUSE_RIGHT); + } + + sig.released = oc_mouse_released(input, OC_MOUSE_LEFT); + if(sig.released) + { + if(box->dragging && sig.hovering) + { + sig.clicked = true; + } + } + + if(!oc_mouse_down(input, OC_MOUSE_LEFT)) + { + box->dragging = false; + } + + sig.dragging = box->dragging; + } + } + return (sig); +} + +bool oc_ui_box_hidden(oc_ui_box* box) +{ + return (box->closed || box->parentClosed); +} + +//----------------------------------------------------------------------------- +// Auto-layout +//----------------------------------------------------------------------------- + +void oc_ui_animate_f32(oc_ui_context* ui, f32* value, f32 target, f32 animationTime) +{ + if(animationTime < 1e-6 + || fabs(*value - target) < 0.001) + { + *value = target; + } + else + { + + /*NOTE: we use the euler approximation for df/dt = alpha(target - f) the implicit form is f(t) = target*(1-e^(-alpha*t)) for the rising front, and f(t) = e^(-alpha*t) for the falling front (e.g. classic RC circuit charge/discharge) Here we bake alpha = 1/tau = -ln(0.05)/tr, with tr the rise time to 95% of target - */ - f32 alpha = 3/animationTime; - f32 dt = ui->lastFrameDuration; - - *value += (target - *value)*alpha*dt; - } -} - -void oc_ui_animate_color(oc_ui_context* ui, oc_color* color, oc_color target, f32 animationTime) -{ - for(int i=0; i<4; i++) - { - oc_ui_animate_f32(ui, &color->c[i], target.c[i], animationTime); - } -} - -void oc_ui_animate_oc_ui_size(oc_ui_context* ui, oc_ui_size* size, oc_ui_size target, f32 animationTime) -{ - size->kind = target.kind; - oc_ui_animate_f32(ui, &size->value, target.value, animationTime); - oc_ui_animate_f32(ui, &size->relax, target.relax, animationTime); -} - -void oc_ui_box_animate_style(oc_ui_context* ui, oc_ui_box* box) -{ - oc_ui_style* targetStyle = box->targetStyle; - OC_DEBUG_ASSERT(targetStyle); - - f32 animationTime = targetStyle->animationTime; - - //NOTE: interpolate based on transition values - oc_ui_style_mask mask = box->targetStyle->animationMask; - - if(box->fresh) - { - box->style = *targetStyle; - } - else - { - if(mask & OC_UI_STYLE_SIZE_WIDTH) - { - oc_ui_animate_oc_ui_size(ui, &box->style.size.c[OC_UI_AXIS_X], targetStyle->size.c[OC_UI_AXIS_X], animationTime); - } - else - { - box->style.size.c[OC_UI_AXIS_X] = targetStyle->size.c[OC_UI_AXIS_X]; - } - - if(mask & OC_UI_STYLE_SIZE_HEIGHT) - { - oc_ui_animate_oc_ui_size(ui, &box->style.size.c[OC_UI_AXIS_Y], targetStyle->size.c[OC_UI_AXIS_Y], animationTime); - } - else - { - box->style.size.c[OC_UI_AXIS_Y] = targetStyle->size.c[OC_UI_AXIS_Y]; - } - - if(mask & OC_UI_STYLE_COLOR) - { - oc_ui_animate_color(ui, &box->style.color, targetStyle->color, animationTime); - } - else - { - box->style.color = targetStyle->color; - } - - - if(mask & OC_UI_STYLE_BG_COLOR) - { - oc_ui_animate_color(ui, &box->style.bgColor, targetStyle->bgColor, animationTime); - } - else - { - box->style.bgColor = targetStyle->bgColor; - } - - if(mask & OC_UI_STYLE_BORDER_COLOR) - { - oc_ui_animate_color(ui, &box->style.borderColor, targetStyle->borderColor, animationTime); - } - else - { - box->style.borderColor = targetStyle->borderColor; - } - - if(mask & OC_UI_STYLE_FONT_SIZE) - { - oc_ui_animate_f32(ui, &box->style.fontSize, targetStyle->fontSize, animationTime); - } - else - { - box->style.fontSize = targetStyle->fontSize; - } - - if(mask & OC_UI_STYLE_BORDER_SIZE) - { - oc_ui_animate_f32(ui, &box->style.borderSize, targetStyle->borderSize, animationTime); - } - else - { - box->style.borderSize = targetStyle->borderSize; - } - - if(mask & OC_UI_STYLE_ROUNDNESS) - { - oc_ui_animate_f32(ui, &box->style.roundness, targetStyle->roundness, animationTime); - } - else - { - box->style.roundness = targetStyle->roundness; - } - - //NOTE: float target is animated in compute rect - box->style.floatTarget = targetStyle->floatTarget; - - //TODO: non animatable attributes. use mask - box->style.layout = targetStyle->layout; - box->style.font = targetStyle->font; - } -} - -void oc_ui_apply_style_with_mask(oc_ui_style* dst, oc_ui_style* src, oc_ui_style_mask mask) -{ - if(mask & OC_UI_STYLE_SIZE_WIDTH) - { - dst->size.c[OC_UI_AXIS_X] = src->size.c[OC_UI_AXIS_X]; - } - if(mask & OC_UI_STYLE_SIZE_HEIGHT) - { - dst->size.c[OC_UI_AXIS_Y] = src->size.c[OC_UI_AXIS_Y]; - } - if(mask & OC_UI_STYLE_LAYOUT_AXIS) - { - dst->layout.axis = src->layout.axis; - } - if(mask & OC_UI_STYLE_LAYOUT_ALIGN_X) - { - dst->layout.align.x = src->layout.align.x; - } - if(mask & OC_UI_STYLE_LAYOUT_ALIGN_Y) - { - dst->layout.align.y = src->layout.align.y; - } - if(mask & OC_UI_STYLE_LAYOUT_SPACING) - { - dst->layout.spacing = src->layout.spacing; - } - if(mask & OC_UI_STYLE_LAYOUT_MARGIN_X) - { - dst->layout.margin.x = src->layout.margin.x; - } - if(mask & OC_UI_STYLE_LAYOUT_MARGIN_Y) - { - dst->layout.margin.y = src->layout.margin.y; - } - if(mask & OC_UI_STYLE_FLOAT_X) - { - dst->floating.c[OC_UI_AXIS_X] = src->floating.c[OC_UI_AXIS_X]; - dst->floatTarget.x = src->floatTarget.x; - } - if(mask & OC_UI_STYLE_FLOAT_Y) - { - dst->floating.c[OC_UI_AXIS_Y] = src->floating.c[OC_UI_AXIS_Y]; - dst->floatTarget.y = src->floatTarget.y; - } - if(mask & OC_UI_STYLE_COLOR) - { - dst->color = src->color; - } - if(mask & OC_UI_STYLE_BG_COLOR) - { - dst->bgColor = src->bgColor; - } - if(mask & OC_UI_STYLE_BORDER_COLOR) - { - dst->borderColor = src->borderColor; - } - if(mask & OC_UI_STYLE_BORDER_SIZE) - { - dst->borderSize = src->borderSize; - } - if(mask & OC_UI_STYLE_ROUNDNESS) - { - dst->roundness = src->roundness; - } - if(mask & OC_UI_STYLE_FONT) - { - dst->font = src->font; - } - if(mask & OC_UI_STYLE_FONT_SIZE) - { - dst->fontSize = src->fontSize; - } - if(mask & OC_UI_STYLE_ANIMATION_TIME) - { - dst->animationTime = src->animationTime; - } - if(mask & OC_UI_STYLE_ANIMATION_MASK) - { - dst->animationMask = src->animationMask; - } -} - - -bool oc_ui_style_selector_match(oc_ui_box* box, oc_ui_style_rule* rule, oc_ui_selector* selector) -{ - bool res = false; - switch(selector->kind) - { - case OC_UI_SEL_ANY: - res = true; - break; - - case OC_UI_SEL_OWNER: - res = (box == rule->owner); - break; - - case OC_UI_SEL_TEXT: - res = !oc_str8_cmp(box->string, selector->text); - break; - - case OC_UI_SEL_TAG: - { - oc_list_for(&box->tags, elt, oc_ui_tag_elt, listElt) - { - if(elt->tag.hash == selector->tag.hash) - { - res = true; - break; - } - } - } break; - - case OC_UI_SEL_STATUS: - { - res = true; - if(selector->status & OC_UI_HOVER) - { - res = res && oc_ui_box_hovering(box, oc_ui_mouse_position()); - } - if(selector->status & OC_UI_ACTIVE) - { - res = res && box->active; - } - if(selector->status & OC_UI_DRAGGING) - { - res = res && box->dragging; - } - } break; - - case OC_UI_SEL_KEY: - res = oc_ui_key_equal(box->key, selector->key); - default: - break; - } - return(res); -} - -void oc_ui_style_rule_match(oc_ui_context* ui, oc_ui_box* box, oc_ui_style_rule* rule, oc_list* buildList, oc_list* tmpList) -{ - oc_ui_selector* selector = oc_list_first_entry(&rule->pattern.l, oc_ui_selector, listElt); - bool match = oc_ui_style_selector_match(box, rule, selector); - - selector = oc_list_next_entry(&rule->pattern.l, selector, oc_ui_selector, listElt); - while(match && selector && selector->op == OC_UI_SEL_AND) - { - match = match && oc_ui_style_selector_match(box, rule, selector); - selector = oc_list_next_entry(&rule->pattern.l, selector, oc_ui_selector, listElt); - } - - if(match) - { - if(!selector) - { - oc_ui_apply_style_with_mask(box->targetStyle, rule->style, rule->mask); - } - else - { - //NOTE create derived rule if there's more than one selector - oc_ui_style_rule* derived = oc_arena_push_type(&ui->frameArena, oc_ui_style_rule); - derived->mask = rule->mask; - derived->style = rule->style; - derived->pattern.l = (oc_list){&selector->listElt, rule->pattern.l.last}; - - oc_list_append(buildList, &derived->buildElt); - oc_list_append(tmpList, &derived->tmpElt); - } - } -} - -void oc_ui_styling_prepass(oc_ui_context* ui, oc_ui_box* box, oc_list* before, oc_list* after) -{ - //NOTE: inherit style from parent - if(box->parent) - { - oc_ui_apply_style_with_mask(box->targetStyle, - box->parent->targetStyle, - OC_UI_STYLE_MASK_INHERITED); - } - - - //NOTE: append box before rules to before and tmp - oc_list tmpBefore = {0}; - oc_list_for(&box->beforeRules, rule, oc_ui_style_rule, boxElt) - { - oc_list_append(before, &rule->buildElt); - oc_list_append(&tmpBefore, &rule->tmpElt); - } - //NOTE: match before rules - oc_list_for(before, rule, oc_ui_style_rule, buildElt) - { - oc_ui_style_rule_match(ui, box, rule, before, &tmpBefore); - } - - //NOTE: prepend box after rules to after and append them to tmp - oc_list tmpAfter = {0}; - oc_list_for_reverse(&box->afterRules, rule, oc_ui_style_rule, boxElt) - { - oc_list_push(after, &rule->buildElt); - oc_list_append(&tmpAfter, &rule->tmpElt); - } - - //NOTE: match after rules - oc_list_for(after, rule, oc_ui_style_rule, buildElt) - { - oc_ui_style_rule_match(ui, box, rule, after, &tmpAfter); - } - - //NOTE: compute static sizes - oc_ui_box_animate_style(ui, box); - - if(oc_ui_box_hidden(box)) - { - return; - } - - oc_ui_style* style = &box->style; - - oc_rect textBox = {0}; - oc_ui_size desiredSize[2] = {box->style.size.c[OC_UI_AXIS_X], - box->style.size.c[OC_UI_AXIS_Y]}; - - if( desiredSize[OC_UI_AXIS_X].kind == OC_UI_SIZE_TEXT - ||desiredSize[OC_UI_AXIS_Y].kind == OC_UI_SIZE_TEXT) - { - textBox = oc_text_bounding_box(style->font, style->fontSize, box->string); - } - - for(int i=0; ilayout.margin.c[i]; - box->rect.c[2+i] = textBox.c[2+i] + margin*2; - } - else if(size.kind == OC_UI_SIZE_PIXELS) - { - box->rect.c[2+i] = size.value; - } - } - - //NOTE: descend in children - oc_list_for(&box->children, child, oc_ui_box, listElt) - { - oc_ui_styling_prepass(ui, child, before, after); - } - - //NOTE: remove temporary rules - oc_list_for(&tmpBefore, rule, oc_ui_style_rule, tmpElt) - { - oc_list_remove(before, &rule->buildElt); - } - oc_list_for(&tmpAfter, rule, oc_ui_style_rule, tmpElt) - { - oc_list_remove(after, &rule->buildElt); - } -} - -bool oc_ui_layout_downward_dependency(oc_ui_box* child, int axis) -{ - return( !oc_ui_box_hidden(child) - && !child->style.floating.c[axis] - && child->style.size.c[axis].kind != OC_UI_SIZE_PARENT - && child->style.size.c[axis].kind != OC_UI_SIZE_PARENT_MINUS_PIXELS); -} - -void oc_ui_layout_downward_dependent_size(oc_ui_context* ui, oc_ui_box* box, int axis) -{ - //NOTE: layout children and compute spacing - f32 count = 0; - oc_list_for(&box->children, child, oc_ui_box, listElt) - { - if(!oc_ui_box_hidden(child)) - { - oc_ui_layout_downward_dependent_size(ui, child, axis); - - if( box->style.layout.axis == axis - && !child->style.floating.c[axis]) - { - count++; - } - } - } - box->spacing[axis] = oc_max(0, count-1)*box->style.layout.spacing; - - oc_ui_size* size = &box->style.size.c[axis]; - if(size->kind == OC_UI_SIZE_CHILDREN) - { - //NOTE: if box is dependent on children, compute children's size. If we're in the layout - // axis this is the sum of each child size, otherwise it is the maximum child size - f32 sum = 0; - - if(box->style.layout.axis == axis) - { - oc_list_for(&box->children, child, oc_ui_box, listElt) - { - if(oc_ui_layout_downward_dependency(child, axis)) - { - sum += child->rect.c[2+axis]; - } - } - } - else - { - oc_list_for(&box->children, child, oc_ui_box, listElt) - { - if(oc_ui_layout_downward_dependency(child, axis)) - { - sum = oc_max(sum, child->rect.c[2+axis]); - } - } - } - f32 margin = box->style.layout.margin.c[axis]; - box->rect.c[2+axis] = sum + box->spacing[axis] + 2*margin; - } -} - -void oc_ui_layout_upward_dependent_size(oc_ui_context* ui, oc_ui_box* box, int axis) -{ - //NOTE: re-compute/set size of children that depend on box's size - - f32 margin = box->style.layout.margin.c[axis]; - f32 availableSize = oc_max(0, box->rect.c[2+axis] - box->spacing[axis] - 2*margin); - - oc_list_for(&box->children, child, oc_ui_box, listElt) - { - oc_ui_size* size = &child->style.size.c[axis]; - if(size->kind == OC_UI_SIZE_PARENT) - { - child->rect.c[2+axis] = availableSize * size->value; - } - else if(size->kind == OC_UI_SIZE_PARENT_MINUS_PIXELS) - { - child->rect.c[2+axis] = oc_max(0, availableSize - size->value); - } - } - - //NOTE: solve downard conflicts - int overflowFlag = (OC_UI_FLAG_ALLOW_OVERFLOW_X << axis); - f32 sum = 0; - - if(box->style.layout.axis == axis) - { - //NOTE: if we're solving in the layout axis, first compute total sum of children and - // total slack available - f32 slack = 0; - - oc_list_for(&box->children, child, oc_ui_box, listElt) - { - if( !oc_ui_box_hidden(child) - && !child->style.floating.c[axis]) - { - sum += child->rect.c[2+axis]; - slack += child->rect.c[2+axis] * child->style.size.c[axis].relax; - } - } - - if(!(box->flags & overflowFlag)) - { - //NOTE: then remove excess proportionally to each box slack, and recompute children sum. - f32 totalContents = sum + box->spacing[axis] + 2*box->style.layout.margin.c[axis]; - f32 excess = oc_clamp_low(totalContents - box->rect.c[2+axis], 0); - f32 alpha = oc_clamp(excess / slack, 0, 1); - - sum = 0; - oc_list_for(&box->children, child, oc_ui_box, listElt) - { - f32 relax = child->style.size.c[axis].relax; - child->rect.c[2+axis] -= alpha * child->rect.c[2+axis] * relax; - sum += child->rect.c[2+axis]; - } - } - } - else - { - //NOTE: if we're solving on the secondary axis, we remove excess to each box individually - // according to its own slack. Children sum is the maximum child size. - - oc_list_for(&box->children, child, oc_ui_box, listElt) - { - if(!oc_ui_box_hidden(child) && !child->style.floating.c[axis]) - { - if(!(box->flags & overflowFlag)) - { - f32 totalContents = child->rect.c[2+axis] + 2*box->style.layout.margin.c[axis]; - f32 excess = oc_clamp_low(totalContents - box->rect.c[2+axis], 0); - f32 relax = child->style.size.c[axis].relax; - child->rect.c[2+axis] -= oc_min(excess, child->rect.c[2+axis]*relax); - } - sum = oc_max(sum, child->rect.c[2+axis]); - } - } - } - - box->childrenSum[axis] = sum; - - //NOTE: recurse in children - oc_list_for(&box->children, child, oc_ui_box, listElt) - { - oc_ui_layout_upward_dependent_size(ui, child, axis); - } -} - -void oc_ui_layout_compute_rect(oc_ui_context* ui, oc_ui_box* box, oc_vec2 pos) -{ - if(oc_ui_box_hidden(box)) - { - return; - } - - box->rect.x = pos.x; - box->rect.y = pos.y; - box->z = ui->z; - ui->z++; - - oc_ui_axis layoutAxis = box->style.layout.axis; - oc_ui_axis secondAxis = (layoutAxis == OC_UI_AXIS_X) ? OC_UI_AXIS_Y : OC_UI_AXIS_X; - f32 spacing = box->style.layout.spacing; - - oc_ui_align* align = box->style.layout.align.c; - - oc_vec2 origin = {box->rect.x, - box->rect.y}; - oc_vec2 currentPos = origin; - - oc_vec2 margin = {box->style.layout.margin.x, - box->style.layout.margin.y}; - - currentPos.x += margin.x; - currentPos.y += margin.y; - - for(int i=0; irect.c[2+i] - (box->childrenSum[i] + box->spacing[i] + margin.c[i]); - } - } - if(align[layoutAxis] == OC_UI_ALIGN_CENTER) - { - currentPos.c[layoutAxis] = origin.c[layoutAxis] - + 0.5*(box->rect.c[2+layoutAxis] - - (box->childrenSum[layoutAxis] + box->spacing[layoutAxis])); - } - - currentPos.x -= box->scroll.x; - currentPos.y -= box->scroll.y; - - oc_list_for(&box->children, child, oc_ui_box, listElt) - { - if(align[secondAxis] == OC_UI_ALIGN_CENTER) - { - currentPos.c[secondAxis] = origin.c[secondAxis] + 0.5*(box->rect.c[2+secondAxis] - child->rect.c[2+secondAxis]); - } - - oc_vec2 childPos = currentPos; - for(int i=0; istyle.floating.c[i]) - { - oc_ui_style* style = child->targetStyle; - if((child->targetStyle->animationMask & (OC_UI_STYLE_FLOAT_X << i)) - && !child->fresh) - { - oc_ui_animate_f32(ui, &child->floatPos.c[i], child->style.floatTarget.c[i], style->animationTime); - } - else - { - child->floatPos.c[i] = child->style.floatTarget.c[i]; - } - childPos.c[i] = origin.c[i] + child->floatPos.c[i]; - } - } - - oc_ui_layout_compute_rect(ui, child, childPos); - - if(!child->style.floating.c[layoutAxis]) - { - currentPos.c[layoutAxis] += child->rect.c[2+layoutAxis] + spacing; - } - } -} - -void oc_ui_layout_find_next_hovered_recursive(oc_ui_context* ui, oc_ui_box* box, oc_vec2 p) -{ - if(oc_ui_box_hidden(box)) - { - return; - } - - bool hit = oc_ui_rect_hit(box->rect, p); - if(hit && (box->flags & OC_UI_FLAG_BLOCK_MOUSE)) - { - ui->hovered = box; - } - if(hit || !(box->flags & OC_UI_FLAG_CLIP)) - { - oc_list_for(&box->children, child, oc_ui_box, listElt) - { - oc_ui_layout_find_next_hovered_recursive(ui, child, p); - } - } -} - -void oc_ui_layout_find_next_hovered(oc_ui_context* ui, oc_vec2 p) -{ - ui->hovered = 0; - oc_ui_layout_find_next_hovered_recursive(ui, ui->root, p); -} - -void oc_ui_solve_layout(oc_ui_context* ui) -{ - oc_list beforeRules = {0}; - oc_list afterRules = {0}; - - //NOTE: style and compute static sizes - oc_ui_styling_prepass(ui, ui->root, &beforeRules, &afterRules); - - //NOTE: reparent overlay boxes - oc_list_for(&ui->overlayList, box, oc_ui_box, overlayElt) - { - if(box->parent) - { - oc_list_remove(&box->parent->children, &box->listElt); - oc_list_append(&ui->overlay->children, &box->listElt); - } - } - - //NOTE: compute layout - for(int axis=0; axisroot, axis); - oc_ui_layout_upward_dependent_size(ui, ui->root, axis); - } - oc_ui_layout_compute_rect(ui, ui->root, (oc_vec2){0, 0}); - - oc_vec2 p = oc_ui_mouse_position(); - oc_ui_layout_find_next_hovered(ui, p); -} - -//----------------------------------------------------------------------------- -// Drawing -//----------------------------------------------------------------------------- - -void oc_ui_rectangle_fill(oc_rect rect, f32 roundness) -{ - if(roundness) - { - oc_rounded_rectangle_fill(rect.x, rect.y, rect.w, rect.h, roundness); - } - else - { - oc_rectangle_fill(rect.x, rect.y, rect.w, rect.h); - } -} - -void oc_ui_rectangle_stroke(oc_rect rect, f32 roundness) -{ - if(roundness) - { - oc_rounded_rectangle_stroke(rect.x, rect.y, rect.w, rect.h, roundness); - } - else - { - oc_rectangle_stroke(rect.x, rect.y, rect.w, rect.h); - } -} - -void oc_ui_draw_box(oc_ui_box* box) -{ - if(oc_ui_box_hidden(box)) - { - return; - } - - oc_ui_style* style = &box->style; - - if(box->flags & OC_UI_FLAG_CLIP) - { - oc_clip_push(box->rect.x, box->rect.y, box->rect.w, box->rect.h); - } - - if(box->flags & OC_UI_FLAG_DRAW_BACKGROUND) - { - oc_set_color(style->bgColor); - oc_ui_rectangle_fill(box->rect, style->roundness); - } - - if((box->flags & OC_UI_FLAG_DRAW_PROC) && box->drawProc) - { - box->drawProc(box, box->drawData); - } - - oc_list_for(&box->children, child, oc_ui_box, listElt) - { - oc_ui_draw_box(child); - } - - if(box->flags & OC_UI_FLAG_DRAW_TEXT) - { - oc_rect textBox = oc_text_bounding_box(style->font, style->fontSize, box->string); - - f32 x = 0; - f32 y = 0; - switch(style->layout.align.x) - { - case OC_UI_ALIGN_START: - x = box->rect.x + style->layout.margin.x; - break; - - case OC_UI_ALIGN_END: - x = box->rect.x + box->rect.w - style->layout.margin.x - textBox.w; - break; - - case OC_UI_ALIGN_CENTER: - x = box->rect.x + 0.5*(box->rect.w - textBox.w); - break; - } - - switch(style->layout.align.y) - { - case OC_UI_ALIGN_START: - y = box->rect.y + style->layout.margin.y - textBox.y; - break; - - case OC_UI_ALIGN_END: - y = box->rect.y + box->rect.h - style->layout.margin.y - textBox.h + textBox.y; - break; - - case OC_UI_ALIGN_CENTER: - y = box->rect.y + 0.5*(box->rect.h - textBox.h) - textBox.y; - break; - } - - oc_set_font(style->font); - oc_set_font_size(style->fontSize); - oc_set_color(style->color); - - oc_move_to(x, y); - oc_text_outlines(box->string); - oc_fill(); - } - - if(box->flags & OC_UI_FLAG_CLIP) - { - oc_clip_pop(); - } - - if(box->flags & OC_UI_FLAG_DRAW_BORDER) - { - oc_set_width(style->borderSize); - oc_set_color(style->borderColor); - oc_ui_rectangle_stroke(box->rect, style->roundness); - } -} - -void oc_ui_draw() -{ - oc_ui_context* ui = oc_ui_get_context(); - - //NOTE: draw - bool oldTextFlip = oc_get_text_flip(); - oc_set_text_flip(false); - - oc_ui_draw_box(ui->root); - - oc_set_text_flip(oldTextFlip); -} - -//----------------------------------------------------------------------------- -// frame begin/end -//----------------------------------------------------------------------------- - -void oc_ui_begin_frame(oc_vec2 size, oc_ui_style* defaultStyle, oc_ui_style_mask defaultMask) -{ - oc_ui_context* ui = oc_ui_get_context(); - - oc_arena_clear(&ui->frameArena); - - ui->frameCounter++; - f64 time = oc_clock_time(OC_CLOCK_MONOTONIC); - ui->lastFrameDuration = time - ui->frameTime; - ui->frameTime = time; - - ui->clipStack = 0; - ui->z = 0; - - defaultMask &= OC_UI_STYLE_COLOR - | OC_UI_STYLE_BG_COLOR - | OC_UI_STYLE_BORDER_COLOR - | OC_UI_STYLE_FONT - | OC_UI_STYLE_FONT_SIZE; - - oc_ui_style_match_before(oc_ui_pattern_all(), defaultStyle, defaultMask); - oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PIXELS, size.x}, - .size.height = {OC_UI_SIZE_PIXELS, size.y}}, - OC_UI_STYLE_SIZE); - - ui->root = oc_ui_box_begin("_root_", 0); - - oc_ui_style_mask contentStyleMask = OC_UI_STYLE_SIZE - | OC_UI_STYLE_LAYOUT - | OC_UI_STYLE_FLOAT; - - oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1}, - .size.height = {OC_UI_SIZE_PARENT, 1}, - .layout = {OC_UI_AXIS_Y, OC_UI_ALIGN_START, OC_UI_ALIGN_START}, - .floating = {true, true}, - .floatTarget = {0, 0}}, - contentStyleMask); - - oc_ui_box* contents = oc_ui_box_make("_contents_", 0); - - oc_ui_style_next(&(oc_ui_style){.layout = {OC_UI_AXIS_Y, OC_UI_ALIGN_START, OC_UI_ALIGN_START}, - .floating = {true, true}, - .floatTarget = {0, 0}}, - OC_UI_STYLE_LAYOUT | OC_UI_STYLE_FLOAT_X | OC_UI_STYLE_FLOAT_Y); - - ui->overlay = oc_ui_box_make("_overlay_", 0); - ui->overlayList = (oc_list){0}; - - ui->nextBoxBeforeRules = (oc_list){0}; - ui->nextBoxAfterRules = (oc_list){0}; - ui->nextBoxTags = (oc_list){0}; - - oc_ui_box_push(contents); -} - -void oc_ui_end_frame(void) -{ - oc_ui_context* ui = oc_ui_get_context(); - - oc_ui_box_pop(); - - oc_ui_box* box = oc_ui_box_end(); - OC_DEBUG_ASSERT(box == ui->root, "unbalanced box stack"); - - //TODO: check balancing of style stacks - - //NOTE: layout - oc_ui_solve_layout(ui); - - //NOTE: prune unused boxes - for(int i=0; iboxMap[i], box, oc_ui_box, bucketElt) - { - if(box->frameCounter < ui->frameCounter) - { - oc_list_remove(&ui->boxMap[i], &box->bucketElt); - } - } - } - - oc_input_next_frame(&ui->input); -} - -//----------------------------------------------------------------------------- -// Init / cleanup -//----------------------------------------------------------------------------- -void oc_ui_init(oc_ui_context* ui) -{ - oc_uiCurrentContext = &oc_uiThreadContext; - - memset(ui, 0, sizeof(oc_ui_context)); - oc_arena_init(&ui->frameArena); - oc_pool_init(&ui->boxPool, sizeof(oc_ui_box)); - ui->init = true; - - oc_ui_set_context(ui); -} - -void oc_ui_cleanup(void) -{ - oc_ui_context* ui = oc_ui_get_context(); - oc_arena_cleanup(&ui->frameArena); - oc_pool_cleanup(&ui->boxPool); - ui->init = false; -} - - -//----------------------------------------------------------------------------- -// label -//----------------------------------------------------------------------------- - -oc_ui_sig oc_ui_label_str8(oc_str8 label) -{ - oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_TEXT, 0, 0}, - .size.height = {OC_UI_SIZE_TEXT, 0, 0}}, - OC_UI_STYLE_SIZE_WIDTH | OC_UI_STYLE_SIZE_HEIGHT); - - oc_ui_flags flags = OC_UI_FLAG_CLIP - | OC_UI_FLAG_DRAW_TEXT; - oc_ui_box* box = oc_ui_box_make_str8(label, flags); - - oc_ui_sig sig = oc_ui_box_sig(box); - return(sig); -} - -oc_ui_sig oc_ui_label(const char* label) -{ - return(oc_ui_label_str8(OC_STR8((char*)label))); -} - -//------------------------------------------------------------------------------ -// button -//------------------------------------------------------------------------------ - -oc_ui_sig oc_ui_button_behavior(oc_ui_box* box) -{ - oc_ui_sig sig = oc_ui_box_sig(box); - - if(sig.hovering) - { - oc_ui_box_set_hot(box, true); - if(sig.dragging) - { - oc_ui_box_activate(box); - } - } - else - { - oc_ui_box_set_hot(box, false); - } - if(!sig.dragging) - { - oc_ui_box_deactivate(box); - } - return(sig); -} - -oc_ui_sig oc_ui_button_str8(oc_str8 label) -{ - oc_ui_context* ui = oc_ui_get_context(); - - oc_ui_style defaultStyle = {.size.width = {OC_UI_SIZE_TEXT}, - .size.height = {OC_UI_SIZE_TEXT}, - .layout.align.x = OC_UI_ALIGN_CENTER, - .layout.align.y = OC_UI_ALIGN_CENTER, - .layout.margin.x = 5, - .layout.margin.y = 5, - .bgColor = {0.5, 0.5, 0.5, 1}, - .borderColor = {0.2, 0.2, 0.2, 1}, - .borderSize = 1, - .roundness = 10}; - - oc_ui_style_mask defaultMask = OC_UI_STYLE_SIZE_WIDTH - | OC_UI_STYLE_SIZE_HEIGHT - | OC_UI_STYLE_LAYOUT_MARGIN_X - | OC_UI_STYLE_LAYOUT_MARGIN_Y - | OC_UI_STYLE_LAYOUT_ALIGN_X - | OC_UI_STYLE_LAYOUT_ALIGN_Y - | OC_UI_STYLE_BG_COLOR - | OC_UI_STYLE_BORDER_COLOR - | OC_UI_STYLE_BORDER_SIZE - | OC_UI_STYLE_ROUNDNESS; - - oc_ui_style_next(&defaultStyle, defaultMask); - - oc_ui_style activeStyle = {.bgColor = {0.3, 0.3, 0.3, 1}, - .borderColor = {0.2, 0.2, 0.2, 1}, - .borderSize = 2}; - oc_ui_style_mask activeMask = OC_UI_STYLE_BG_COLOR - | OC_UI_STYLE_BORDER_COLOR - | OC_UI_STYLE_BORDER_SIZE; - oc_ui_pattern activePattern = {0}; - oc_ui_pattern_push(&ui->frameArena, - &activePattern, - (oc_ui_selector){.kind = OC_UI_SEL_STATUS, - .status = OC_UI_ACTIVE|OC_UI_HOVER}); - oc_ui_style_match_before(activePattern, &activeStyle, activeMask); - - oc_ui_flags flags = OC_UI_FLAG_CLICKABLE - | OC_UI_FLAG_CLIP - | OC_UI_FLAG_DRAW_BACKGROUND - | OC_UI_FLAG_DRAW_BORDER - | OC_UI_FLAG_DRAW_TEXT - | OC_UI_FLAG_HOT_ANIMATION - | OC_UI_FLAG_ACTIVE_ANIMATION; - - oc_ui_box* box = oc_ui_box_make_str8(label, flags); - oc_ui_tag_box(box, "button"); - - oc_ui_sig sig = oc_ui_button_behavior(box); - return(sig); -} - -oc_ui_sig oc_ui_button(const char* label) -{ - return(oc_ui_button_str8(OC_STR8((char*)label))); -} - -void oc_ui_checkbox_draw(oc_ui_box* box, void* data) -{ - bool checked = *(bool*)data; - if(checked) - { - oc_move_to(box->rect.x + 0.2*box->rect.w, box->rect.y + 0.5*box->rect.h); - oc_line_to(box->rect.x + 0.4*box->rect.w, box->rect.y + 0.75*box->rect.h); - oc_line_to(box->rect.x + 0.8*box->rect.w, box->rect.y + 0.2*box->rect.h); - - oc_set_color(box->style.color); - oc_set_width(0.2*box->rect.w); - oc_set_joint(OC_JOINT_MITER); - oc_set_max_joint_excursion(0.2 * box->rect.h); - oc_stroke(); - } -} - -oc_ui_sig oc_ui_checkbox(const char* name, bool* checked) -{ - oc_ui_context* ui = oc_ui_get_context(); - - oc_ui_style defaultStyle = {.size.width = {OC_UI_SIZE_PIXELS, 20}, - .size.height = {OC_UI_SIZE_PIXELS, 20}, - .bgColor = {1, 1, 1, 1}, - .color = {0, 0, 0, 1}, - .borderColor = {0.2, 0.2, 0.2, 1}, - .borderSize = 1, - .roundness = 5}; - - oc_ui_style_mask defaultMask = OC_UI_STYLE_SIZE_WIDTH - | OC_UI_STYLE_SIZE_HEIGHT - | OC_UI_STYLE_BG_COLOR - | OC_UI_STYLE_COLOR - | OC_UI_STYLE_BORDER_COLOR - | OC_UI_STYLE_BORDER_SIZE - | OC_UI_STYLE_ROUNDNESS; - - oc_ui_style_next(&defaultStyle, defaultMask); - - oc_ui_style activeStyle = {.bgColor = {0.5, 0.5, 0.5, 1}, - .borderColor = {0.2, 0.2, 0.2, 1}, - .borderSize = 2}; - oc_ui_style_mask activeMask = OC_UI_STYLE_BG_COLOR - | OC_UI_STYLE_BORDER_COLOR - | OC_UI_STYLE_BORDER_SIZE; - oc_ui_pattern activePattern = {0}; - oc_ui_pattern_push(&ui->frameArena, - &activePattern, - (oc_ui_selector){.kind = OC_UI_SEL_STATUS, - .status = OC_UI_ACTIVE|OC_UI_HOVER}); - oc_ui_style_match_before(activePattern, &activeStyle, activeMask); - - oc_ui_flags flags = OC_UI_FLAG_CLICKABLE - | OC_UI_FLAG_CLIP - | OC_UI_FLAG_DRAW_BACKGROUND - | OC_UI_FLAG_DRAW_PROC - | OC_UI_FLAG_DRAW_BORDER - | OC_UI_FLAG_HOT_ANIMATION - | OC_UI_FLAG_ACTIVE_ANIMATION; - - oc_ui_box* box = oc_ui_box_make(name, flags); - oc_ui_tag_box(box, "checkbox"); - - oc_ui_sig sig = oc_ui_button_behavior(box); - if(sig.clicked) - { - *checked = !*checked; - } - oc_ui_box_set_draw_proc(box, oc_ui_checkbox_draw, checked); - - return(sig); -} - -//------------------------------------------------------------------------------ -// slider / scrollbar -//------------------------------------------------------------------------------ -oc_ui_box* oc_ui_slider(const char* label, f32 thumbRatio, f32* scrollValue) -{ - oc_ui_style_match_before(oc_ui_pattern_all(), &(oc_ui_style){0}, OC_UI_STYLE_LAYOUT); - oc_ui_box* frame = oc_ui_box_begin(label, 0); - { - f32 beforeRatio = (*scrollValue) * (1. - thumbRatio); - f32 afterRatio = (1. - *scrollValue) * (1. - thumbRatio); - - oc_ui_axis trackAxis = (frame->rect.w > frame->rect.h) ? OC_UI_AXIS_X : OC_UI_AXIS_Y; - oc_ui_axis secondAxis = (trackAxis == OC_UI_AXIS_Y) ? OC_UI_AXIS_X : OC_UI_AXIS_Y; - f32 roundness = 0.5*frame->rect.c[2+secondAxis]; - f32 animationTime = 0.5; - - oc_ui_style trackStyle = {.size.width = {OC_UI_SIZE_PARENT, 1}, - .size.height = {OC_UI_SIZE_PARENT, 1}, - .layout.axis = trackAxis, - .layout.align.x = OC_UI_ALIGN_START, - .layout.align.y = OC_UI_ALIGN_START, - .bgColor = {0.5, 0.5, 0.5, 1}, - .roundness = roundness}; - - oc_ui_style beforeStyle = trackStyle; - beforeStyle.size.c[trackAxis] = (oc_ui_size){OC_UI_SIZE_PARENT, beforeRatio}; - - oc_ui_style afterStyle = trackStyle; - afterStyle.size.c[trackAxis] = (oc_ui_size){OC_UI_SIZE_PARENT, afterRatio}; - - oc_ui_style thumbStyle = trackStyle; - thumbStyle.size.c[trackAxis] = (oc_ui_size){OC_UI_SIZE_PARENT, thumbRatio}; - thumbStyle.bgColor = (oc_color){0.3, 0.3, 0.3, 1}; - - oc_ui_style_mask styleMask = OC_UI_STYLE_SIZE_WIDTH - | OC_UI_STYLE_SIZE_HEIGHT - | OC_UI_STYLE_LAYOUT - | OC_UI_STYLE_BG_COLOR - | OC_UI_STYLE_ROUNDNESS; - - oc_ui_flags trackFlags = OC_UI_FLAG_CLIP - | OC_UI_FLAG_DRAW_BACKGROUND - | OC_UI_FLAG_HOT_ANIMATION - | OC_UI_FLAG_ACTIVE_ANIMATION; - - oc_ui_style_next(&trackStyle, styleMask); - oc_ui_box* track = oc_ui_box_begin("track", trackFlags); - - oc_ui_style_next(&beforeStyle, OC_UI_STYLE_SIZE_WIDTH|OC_UI_STYLE_SIZE_HEIGHT); - oc_ui_box* beforeSpacer = oc_ui_box_make("before", 0); - - - oc_ui_flags thumbFlags = OC_UI_FLAG_CLICKABLE - | OC_UI_FLAG_DRAW_BACKGROUND - | OC_UI_FLAG_HOT_ANIMATION - | OC_UI_FLAG_ACTIVE_ANIMATION; - - oc_ui_style_next(&thumbStyle, styleMask); - oc_ui_box* thumb = oc_ui_box_make("thumb", thumbFlags); - - - oc_ui_style_next(&afterStyle, OC_UI_STYLE_SIZE_WIDTH|OC_UI_STYLE_SIZE_HEIGHT); - oc_ui_box* afterSpacer = oc_ui_box_make("after", 0); - - oc_ui_box_end(); - - //NOTE: interaction - oc_ui_sig thumbSig = oc_ui_box_sig(thumb); - oc_ui_sig trackSig = oc_ui_box_sig(track); - if(thumbSig.dragging) - { - f32 trackExtents = track->rect.c[2+trackAxis] - thumb->rect.c[2+trackAxis]; - *scrollValue = (trackSig.mouse.c[trackAxis] - thumb->pressedMouse.c[trackAxis]) / trackExtents; - *scrollValue = oc_clamp(*scrollValue, 0, 1); - } - - if(oc_ui_box_active(frame)) - { - //NOTE: activated from outside - oc_ui_box_set_hot(track, true); - oc_ui_box_set_hot(thumb, true); - oc_ui_box_activate(track); - oc_ui_box_activate(thumb); - } - - if(trackSig.hovering) - { - oc_ui_box_set_hot(track, true); - oc_ui_box_set_hot(thumb, true); - } - else if(thumbSig.wheel.c[trackAxis] == 0) - { - oc_ui_box_set_hot(track, false); - oc_ui_box_set_hot(thumb, false); - } - - if(thumbSig.dragging) - { - oc_ui_box_activate(track); - oc_ui_box_activate(thumb); - } - else if(thumbSig.wheel.c[trackAxis] == 0) - { - oc_ui_box_deactivate(track); - oc_ui_box_deactivate(thumb); - oc_ui_box_deactivate(frame); - } - - } oc_ui_box_end(); - - return(frame); -} - -//------------------------------------------------------------------------------ -// panels -//------------------------------------------------------------------------------ -void oc_ui_panel_begin(const char* str, oc_ui_flags flags) -{ - flags = flags - | OC_UI_FLAG_CLIP - | OC_UI_FLAG_BLOCK_MOUSE - | OC_UI_FLAG_ALLOW_OVERFLOW_X - | OC_UI_FLAG_ALLOW_OVERFLOW_Y - | OC_UI_FLAG_SCROLL_WHEEL_X - | OC_UI_FLAG_SCROLL_WHEEL_Y; - - oc_ui_box_begin(str, flags); -} - -void oc_ui_panel_end(void) -{ - oc_ui_box* panel = oc_ui_box_top(); - oc_ui_sig sig = oc_ui_box_sig(panel); - - f32 contentsW = oc_clamp_low(panel->childrenSum[0], panel->rect.w); - f32 contentsH = oc_clamp_low(panel->childrenSum[1], panel->rect.h); - - contentsW = oc_clamp_low(contentsW, 1); - contentsH = oc_clamp_low(contentsH, 1); - - oc_ui_box* scrollBarX = 0; - oc_ui_box* scrollBarY = 0; - - bool needsScrollX = contentsW > panel->rect.w; - bool needsScrollY = contentsH > panel->rect.h; - - if(needsScrollX) - { - f32 thumbRatioX = panel->rect.w / contentsW; - f32 sliderX = panel->scroll.x /(contentsW - panel->rect.w); - - oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1., 0}, - .size.height = {OC_UI_SIZE_PIXELS, 10, 0}, - .floating.x = true, - .floating.y = true, - .floatTarget = {0, panel->rect.h - 10}}, - OC_UI_STYLE_SIZE - |OC_UI_STYLE_FLOAT); - - scrollBarX = oc_ui_slider("scrollerX", thumbRatioX, &sliderX); - - panel->scroll.x = sliderX * (contentsW - panel->rect.w); - if(sig.hovering) - { - oc_ui_box_activate(scrollBarX); - } - } - - if(needsScrollY) - { - f32 thumbRatioY = panel->rect.h / contentsH; - f32 sliderY = panel->scroll.y /(contentsH - panel->rect.h); - - f32 spacerSize = needsScrollX ? 10 : 0; - - oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PIXELS, 10, 0}, - .size.height = {OC_UI_SIZE_PARENT_MINUS_PIXELS, spacerSize, 0}, - .floating.x = true, - .floating.y = true, - .floatTarget = {panel->rect.w - 10, 0}}, - OC_UI_STYLE_SIZE - |OC_UI_STYLE_FLOAT); - - scrollBarY = oc_ui_slider("scrollerY", thumbRatioY, &sliderY); - - panel->scroll.y = sliderY * (contentsH - panel->rect.h); - if(sig.hovering) - { - oc_ui_box_activate(scrollBarY); - } - } - panel->scroll.x = oc_clamp(panel->scroll.x, 0, contentsW - panel->rect.w); - panel->scroll.y = oc_clamp(panel->scroll.y, 0, contentsH - panel->rect.h); - - oc_ui_box_end(); -} - -//------------------------------------------------------------------------------ -// tooltips -//------------------------------------------------------------------------------ - -oc_ui_sig oc_ui_tooltip_begin(const char* name) -{ - oc_ui_context* ui = oc_ui_get_context(); - - oc_vec2 p = oc_ui_mouse_position(); - - oc_ui_style style = {.size.width = {OC_UI_SIZE_CHILDREN}, - .size.height = {OC_UI_SIZE_CHILDREN}, - .floating.x = true, - .floating.y = true, - .floatTarget = {p.x, p.y}}; - oc_ui_style_mask mask = OC_UI_STYLE_SIZE | OC_UI_STYLE_FLOAT; - - oc_ui_style_next(&style, mask); - - oc_ui_flags flags = OC_UI_FLAG_OVERLAY - | OC_UI_FLAG_DRAW_BACKGROUND - | OC_UI_FLAG_DRAW_BORDER; - - oc_ui_box* tooltip = oc_ui_box_make(name, flags); - oc_ui_box_push(tooltip); - - return(oc_ui_box_sig(tooltip)); -} - -void oc_ui_tooltip_end(void) -{ - oc_ui_box_pop(); // tooltip -} - -//------------------------------------------------------------------------------ -// Menus -//------------------------------------------------------------------------------ - -void oc_ui_menu_bar_begin(const char* name) -{ - oc_ui_style style = {.size.width = {OC_UI_SIZE_PARENT, 1, 0}, - .size.height = {OC_UI_SIZE_CHILDREN}, - .layout.axis = OC_UI_AXIS_X, - .layout.spacing = 20,}; - oc_ui_style_mask mask = OC_UI_STYLE_SIZE - | OC_UI_STYLE_LAYOUT_AXIS - | OC_UI_STYLE_LAYOUT_SPACING; - - oc_ui_style_next(&style, mask); - oc_ui_box* bar = oc_ui_box_begin(name, OC_UI_FLAG_DRAW_BACKGROUND); - - oc_ui_sig sig = oc_ui_box_sig(bar); - oc_ui_context* ui = oc_ui_get_context(); - if(!sig.hovering && oc_mouse_released(&ui->input, OC_MOUSE_LEFT)) - { - oc_ui_box_deactivate(bar); - } -} - -void oc_ui_menu_bar_end(void) -{ - oc_ui_box_end(); // menu bar -} - -void oc_ui_menu_begin(const char* label) -{ - oc_ui_box* container = oc_ui_box_make(label, 0); - oc_ui_box_push(container); - - oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_TEXT}, - .size.height = {OC_UI_SIZE_TEXT}}, - OC_UI_STYLE_SIZE); - - oc_ui_box* button = oc_ui_box_make(label, OC_UI_FLAG_CLICKABLE | OC_UI_FLAG_DRAW_TEXT); - oc_ui_box* bar = container->parent; - - oc_ui_sig sig = oc_ui_box_sig(button); - oc_ui_sig barSig = oc_ui_box_sig(bar); - - oc_ui_context* ui = oc_ui_get_context(); - - oc_ui_style style = {.size.width = {OC_UI_SIZE_CHILDREN}, - .size.height = {OC_UI_SIZE_CHILDREN}, - .floating.x = true, - .floating.y = true, - .floatTarget = {button->rect.x, - button->rect.y + button->rect.h}, - .layout.axis = OC_UI_AXIS_Y, - .layout.spacing = 5, - .layout.margin.x = 0, - .layout.margin.y = 5, - .bgColor = {0.2, 0.2, 0.2, 1}}; - - oc_ui_style_mask mask = OC_UI_STYLE_SIZE - | OC_UI_STYLE_FLOAT - | OC_UI_STYLE_LAYOUT - | OC_UI_STYLE_BG_COLOR; - - oc_ui_flags flags = OC_UI_FLAG_OVERLAY - | OC_UI_FLAG_DRAW_BACKGROUND - | OC_UI_FLAG_DRAW_BORDER; - - oc_ui_style_next(&style, mask); - oc_ui_box* menu = oc_ui_box_make("panel", flags); - - if(oc_ui_box_active(bar)) - { - if(sig.hovering) - { - oc_ui_box_activate(button); - } - else if(barSig.hovering) - { - oc_ui_box_deactivate(button); - } - } - else - { - oc_ui_box_deactivate(button); - if(sig.pressed) - { - oc_ui_box_activate(bar); - oc_ui_box_activate(button); - } - } - - oc_ui_box_set_closed(menu, !oc_ui_box_active(button)); - oc_ui_box_push(menu); -} - -void oc_ui_menu_end(void) -{ - oc_ui_box_pop(); // menu - oc_ui_box_pop(); // container -} - -oc_ui_sig oc_ui_menu_button(const char* name) -{ - oc_ui_context* ui = oc_ui_get_context(); - - oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_TEXT}, - .size.height = {OC_UI_SIZE_TEXT}, - .layout.margin.x = 5, - .bgColor = {0, 0, 0, 0}}, - OC_UI_STYLE_SIZE - |OC_UI_STYLE_LAYOUT_MARGIN_X - |OC_UI_STYLE_BG_COLOR); - - oc_ui_pattern pattern = {0}; - oc_ui_pattern_push(&ui->frameArena, &pattern, (oc_ui_selector){.kind = OC_UI_SEL_STATUS, .status = OC_UI_HOVER}); - - oc_ui_style style = {.bgColor = {0, 0, 1, 1}}; - oc_ui_style_mask mask = OC_UI_STYLE_BG_COLOR; - oc_ui_style_match_before(pattern, &style, mask); - - oc_ui_flags flags = OC_UI_FLAG_CLICKABLE - | OC_UI_FLAG_CLIP - | OC_UI_FLAG_DRAW_TEXT - | OC_UI_FLAG_DRAW_BACKGROUND; - - oc_ui_box* box = oc_ui_box_make(name, flags); - oc_ui_sig sig = oc_ui_box_sig(box); - return(sig); -} - -void oc_ui_select_popup_draw_arrow(oc_ui_box* box, void* data) -{ - f32 r = oc_min(box->parent->style.roundness, box->rect.w); - f32 cr = r*4*(sqrt(2)-1)/3; - - oc_move_to(box->rect.x, box->rect.y); - oc_line_to(box->rect.x + box->rect.w - r, box->rect.y); - oc_cubic_to(box->rect.x + box->rect.w - cr, box->rect.y, - box->rect.x + box->rect.w, box->rect.y + cr, - box->rect.x + box->rect.w, box->rect.y + r); - oc_line_to(box->rect.x + box->rect.w, box->rect.y + box->rect.h - r); - oc_cubic_to(box->rect.x + box->rect.w, box->rect.y + box->rect.h - cr, - box->rect.x + box->rect.w - cr, box->rect.y + box->rect.h, - box->rect.x + box->rect.w - r, box->rect.y + box->rect.h); - oc_line_to(box->rect.x, box->rect.y + box->rect.h); - - oc_set_color(box->style.bgColor); - oc_fill(); - - oc_move_to(box->rect.x + 0.25*box->rect.w, box->rect.y + 0.45*box->rect.h); - oc_line_to(box->rect.x + 0.5*box->rect.w, box->rect.y + 0.75*box->rect.h); - oc_line_to(box->rect.x + 0.75*box->rect.w, box->rect.y + 0.45*box->rect.h); - oc_close_path(); - - oc_set_color(box->style.color); - oc_fill(); -} - -oc_ui_select_popup_info oc_ui_select_popup(const char* name, oc_ui_select_popup_info* info) -{ - oc_ui_select_popup_info result = *info; - - oc_ui_context* ui = oc_ui_get_context(); - - oc_ui_container(name, 0) - { - oc_ui_box* button = oc_ui_box_make("button", - OC_UI_FLAG_CLICKABLE - |OC_UI_FLAG_DRAW_BACKGROUND - |OC_UI_FLAG_DRAW_BORDER - |OC_UI_FLAG_ALLOW_OVERFLOW_X - |OC_UI_FLAG_CLIP); - - f32 maxOptionWidth = 0; - f32 lineHeight = 0; - oc_rect bbox = {0}; - for(int i=0; ioptionCount; i++) - { - bbox = oc_text_bounding_box(button->style.font, button->style.fontSize, info->options[i]); - maxOptionWidth = oc_max(maxOptionWidth, bbox.w); - } - f32 buttonWidth = maxOptionWidth + 2*button->style.layout.margin.x + button->rect.h; - - oc_ui_style_box_before(button, - oc_ui_pattern_owner(), - &(oc_ui_style){.size.width = {OC_UI_SIZE_PIXELS, buttonWidth}, - .size.height = {OC_UI_SIZE_CHILDREN}, - .layout.margin.x = 5, - .layout.margin.y = 1, - .roundness = 5, - .borderSize = 1, - .borderColor = {0.3, 0.3, 0.3, 1}}, - OC_UI_STYLE_SIZE - |OC_UI_STYLE_LAYOUT_MARGIN_X - |OC_UI_STYLE_LAYOUT_MARGIN_Y - |OC_UI_STYLE_ROUNDNESS - |OC_UI_STYLE_BORDER_SIZE - |OC_UI_STYLE_BORDER_COLOR); - oc_ui_box_push(button); - { - oc_ui_label_str8(info->options[info->selectedIndex]); - - oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PIXELS, button->rect.h}, - .size.height = {OC_UI_SIZE_PIXELS, button->rect.h}, - .floating.x = true, - .floating.y = true, - .floatTarget = {button->rect.w - button->rect.h, 0}, - .color = {0, 0, 0, 1}, - .bgColor = {0.7, 0.7, 0.7, 1}}, - OC_UI_STYLE_SIZE - |OC_UI_STYLE_FLOAT - |OC_UI_STYLE_COLOR - |OC_UI_STYLE_BG_COLOR); - - oc_ui_box* arrow = oc_ui_box_make("arrow", OC_UI_FLAG_DRAW_PROC); - oc_ui_box_set_draw_proc(arrow, oc_ui_select_popup_draw_arrow, 0); - - } oc_ui_box_pop(); - - //panel - oc_ui_box* panel = oc_ui_box_make("panel", - OC_UI_FLAG_DRAW_BACKGROUND - |OC_UI_FLAG_BLOCK_MOUSE - |OC_UI_FLAG_OVERLAY); - - //TODO: set width to max(button.w, max child...) - f32 containerWidth = oc_max(maxOptionWidth + 2*panel->style.layout.margin.x, - button->rect.w); - - oc_ui_style_box_before(panel, - oc_ui_pattern_owner(), - &(oc_ui_style){.size.width = {OC_UI_SIZE_PIXELS, containerWidth}, - .size.height = {OC_UI_SIZE_CHILDREN}, - .floating.x = true, - .floating.y = true, - .floatTarget = {button->rect.x, - button->rect.y + button->rect.h}, - .layout.axis = OC_UI_AXIS_Y, - .layout.margin.x = 0, - .layout.margin.y = 5, - .bgColor = {0.2, 0.2, 0.2, 1}}, - OC_UI_STYLE_SIZE - |OC_UI_STYLE_FLOAT - |OC_UI_STYLE_LAYOUT - |OC_UI_STYLE_BG_COLOR); - - oc_ui_box_push(panel); - { - for(int i=0; ioptionCount; i++) - { - oc_ui_style_next(&(oc_ui_style){.size.width = {OC_UI_SIZE_PARENT, 1}, - .size.height = {OC_UI_SIZE_TEXT}, - .layout.axis = OC_UI_AXIS_Y, - .layout.align.x = OC_UI_ALIGN_START, - .layout.margin.x = 5, - .layout.margin.y = 2.5}, - OC_UI_STYLE_SIZE - |OC_UI_STYLE_LAYOUT_AXIS - |OC_UI_STYLE_LAYOUT_ALIGN_X - |OC_UI_STYLE_LAYOUT_MARGIN_X - |OC_UI_STYLE_LAYOUT_MARGIN_Y); - - - oc_ui_pattern pattern = {0}; - oc_ui_pattern_push(&ui->frameArena, &pattern, (oc_ui_selector){.kind = OC_UI_SEL_STATUS, .status = OC_UI_HOVER}); - oc_ui_style_match_before(pattern, &(oc_ui_style){.bgColor = {0, 0, 1, 1}}, OC_UI_STYLE_BG_COLOR); - - oc_ui_box* box = oc_ui_box_make_str8(info->options[i], - OC_UI_FLAG_DRAW_TEXT - |OC_UI_FLAG_CLICKABLE - |OC_UI_FLAG_DRAW_BACKGROUND); - oc_ui_sig sig = oc_ui_box_sig(box); - if(sig.pressed) - { - result.selectedIndex = i; - } - } - } - oc_ui_box_pop(); - - oc_ui_context* ui = oc_ui_get_context(); - if(oc_ui_box_active(panel) && oc_mouse_pressed(&ui->input, OC_MOUSE_LEFT)) - { - oc_ui_box_deactivate(panel); - } - else if(oc_ui_box_sig(button).pressed) - { - oc_ui_box_activate(panel); - } - oc_ui_box_set_closed(panel, !oc_ui_box_active(panel)); - } - return(result); -} - -//------------------------------------------------------------------------------ -// text box -//------------------------------------------------------------------------------ -oc_str32 oc_ui_edit_replace_selection_with_codepoints(oc_ui_context* ui, oc_str32 codepoints, oc_str32 input) -{ - u32 start = oc_min(ui->editCursor, ui->editMark); - u32 end = oc_max(ui->editCursor, ui->editMark); - - oc_str32 before = oc_str32_slice(codepoints, 0, start); - oc_str32 after = oc_str32_slice(codepoints, end, codepoints.len); - - oc_str32_list list = {0}; - oc_str32_list_push(&ui->frameArena, &list, before); - oc_str32_list_push(&ui->frameArena, &list, input); - oc_str32_list_push(&ui->frameArena, &list, after); - - codepoints = oc_str32_list_join(&ui->frameArena, list); - - ui->editCursor = start + input.len; - ui->editMark = ui->editCursor; - return(codepoints); -} - -oc_str32 oc_ui_edit_delete_selection(oc_ui_context* ui, oc_str32 codepoints) -{ - return(oc_ui_edit_replace_selection_with_codepoints(ui, codepoints, (oc_str32){0})); -} - -void oc_ui_edit_copy_selection_to_clipboard(oc_ui_context* ui, oc_str32 codepoints) -{ - #if !OC_PLATFORM_ORCA - if(ui->editCursor == ui->editMark) - { - return; - } - u32 start = oc_min(ui->editCursor, ui->editMark); - u32 end = oc_max(ui->editCursor, ui->editMark); - oc_str32 selection = oc_str32_slice(codepoints, start, end); - oc_str8 string = oc_utf8_push_from_codepoints(&ui->frameArena, selection); - - oc_clipboard_clear(); - oc_clipboard_set_string(string); - #endif -} - -oc_str32 oc_ui_edit_replace_selection_with_clipboard(oc_ui_context* ui, oc_str32 codepoints) -{ - #if OC_PLATFORM_ORCA - oc_str32 result = {0}; - #else - oc_str8 string = oc_clipboard_get_string(&ui->frameArena); - oc_str32 input = oc_utf8_push_to_codepoints(&ui->frameArena, string); - oc_str32 result = oc_ui_edit_replace_selection_with_codepoints(ui, codepoints, input); - #endif - return(result); -} - -typedef enum { - OC_UI_EDIT_MOVE, - OC_UI_EDIT_SELECT, - OC_UI_EDIT_SELECT_EXTEND, - OC_UI_EDIT_DELETE, - OC_UI_EDIT_CUT, - OC_UI_EDIT_COPY, - OC_UI_EDIT_PASTE, - OC_UI_EDIT_SELECT_ALL } oc_ui_edit_op; - -typedef enum { - OC_UI_EDIT_MOVE_NONE = 0, - OC_UI_EDIT_MOVE_ONE, - OC_UI_EDIT_MOVE_WORD, - OC_UI_EDIT_MOVE_LINE } oc_ui_edit_move; - -typedef struct oc_ui_edit_command -{ - oc_key_code key; - oc_keymod_flags mods; - - oc_ui_edit_op operation; - oc_ui_edit_move move; - int direction; - -} oc_ui_edit_command; - -const oc_ui_edit_command OC_UI_EDIT_COMMANDS[] = { - //NOTE(martin): move one left - { - .key = OC_KEY_LEFT, - .operation = OC_UI_EDIT_MOVE, - .move = OC_UI_EDIT_MOVE_ONE, - .direction = -1 - }, - //NOTE(martin): move one right - { - .key = OC_KEY_RIGHT, - .operation = OC_UI_EDIT_MOVE, - .move = OC_UI_EDIT_MOVE_ONE, - .direction = 1 - }, - //NOTE(martin): move start - { - .key = OC_KEY_Q, - .mods = OC_KEYMOD_CTRL, - .operation = OC_UI_EDIT_MOVE, - .move = OC_UI_EDIT_MOVE_LINE, - .direction = -1 - }, - { - .key = OC_KEY_UP, - .operation = OC_UI_EDIT_MOVE, - .move = OC_UI_EDIT_MOVE_LINE, - .direction = -1 - }, - //NOTE(martin): move end - { - .key = OC_KEY_E, - .mods = OC_KEYMOD_CTRL, - .operation = OC_UI_EDIT_MOVE, - .move = OC_UI_EDIT_MOVE_LINE, - .direction = 1 - }, - { - .key = OC_KEY_DOWN, - .operation = OC_UI_EDIT_MOVE, - .move = OC_UI_EDIT_MOVE_LINE, - .direction = 1 - }, - //NOTE(martin): select one left - { - .key = OC_KEY_LEFT, - .mods = OC_KEYMOD_SHIFT, - .operation = OC_UI_EDIT_SELECT, - .move = OC_UI_EDIT_MOVE_ONE, - .direction = -1 - }, - //NOTE(martin): select one right - { - .key = OC_KEY_RIGHT, - .mods = OC_KEYMOD_SHIFT, - .operation = OC_UI_EDIT_SELECT, - .move = OC_UI_EDIT_MOVE_ONE, - .direction = 1 - }, - //NOTE(martin): extend select to start - { - .key = OC_KEY_Q, - .mods = OC_KEYMOD_CTRL | OC_KEYMOD_SHIFT, - .operation = OC_UI_EDIT_SELECT_EXTEND, - .move = OC_UI_EDIT_MOVE_LINE, - .direction = -1 - }, - { - .key = OC_KEY_UP, - .mods = OC_KEYMOD_SHIFT, - .operation = OC_UI_EDIT_SELECT_EXTEND, - .move = OC_UI_EDIT_MOVE_LINE, - .direction = -1 - }, - //NOTE(martin): extend select to end - { - .key = OC_KEY_E, - .mods = OC_KEYMOD_CTRL | OC_KEYMOD_SHIFT, - .operation = OC_UI_EDIT_SELECT_EXTEND, - .move = OC_UI_EDIT_MOVE_LINE, - .direction = 1 - }, - { - .key = OC_KEY_DOWN, - .mods = OC_KEYMOD_SHIFT, - .operation = OC_UI_EDIT_SELECT_EXTEND, - .move = OC_UI_EDIT_MOVE_LINE, - .direction = 1 - }, - //NOTE(martin): select all - { - .key = OC_KEY_Q, - .mods = OC_KEYMOD_MAIN_MODIFIER, - .operation = OC_UI_EDIT_SELECT_ALL, - .move = OC_UI_EDIT_MOVE_NONE - }, - //NOTE(martin): delete - { - .key = OC_KEY_DELETE, - .operation = OC_UI_EDIT_DELETE, - .move = OC_UI_EDIT_MOVE_ONE, - .direction = 1 - }, - //NOTE(martin): backspace - { - .key = OC_KEY_BACKSPACE, - .operation = OC_UI_EDIT_DELETE, - .move = OC_UI_EDIT_MOVE_ONE, - .direction = -1 - }, - //NOTE(martin): cut - { - .key = OC_KEY_X, - .mods = OC_KEYMOD_MAIN_MODIFIER, - .operation = OC_UI_EDIT_CUT, - .move = OC_UI_EDIT_MOVE_NONE - }, - //NOTE(martin): copy - { - .key = OC_KEY_C, - .mods = OC_KEYMOD_MAIN_MODIFIER, - .operation = OC_UI_EDIT_COPY, - .move = OC_UI_EDIT_MOVE_NONE - }, - //NOTE(martin): paste - { - .key = OC_KEY_V, - .mods = OC_KEYMOD_MAIN_MODIFIER, - .operation = OC_UI_EDIT_PASTE, - .move = OC_UI_EDIT_MOVE_NONE - } -}; - -const u32 OC_UI_EDIT_COMMAND_COUNT = sizeof(OC_UI_EDIT_COMMANDS)/sizeof(oc_ui_edit_command); - -void oc_ui_edit_perform_move(oc_ui_context* ui, oc_ui_edit_move move, int direction, u32 textLen) -{ - switch(move) - { - case OC_UI_EDIT_MOVE_NONE: - break; - - case OC_UI_EDIT_MOVE_ONE: - { - if(direction < 0 && ui->editCursor > 0) - { - ui->editCursor--; - } - else if(direction > 0 && ui->editCursor < textLen) - { - ui->editCursor++; - } - } break; - - case OC_UI_EDIT_MOVE_LINE: - { - if(direction < 0) - { - ui->editCursor = 0; - } - else if(direction > 0) - { - ui->editCursor = textLen; - } - } break; - - case OC_UI_EDIT_MOVE_WORD: - OC_DEBUG_ASSERT(0, "not implemented yet"); - break; - } -} - -oc_str32 oc_ui_edit_perform_operation(oc_ui_context* ui, oc_ui_edit_op operation, oc_ui_edit_move move, int direction, oc_str32 codepoints) -{ - switch(operation) - { - case OC_UI_EDIT_MOVE: - { - //NOTE(martin): we place the cursor on the direction-most side of the selection - // before performing the move - u32 cursor = direction < 0 ? - oc_min(ui->editCursor, ui->editMark) : - oc_max(ui->editCursor, ui->editMark); - ui->editCursor = cursor; - - if(ui->editCursor == ui->editMark || move != OC_UI_EDIT_MOVE_ONE) - { - //NOTE: we special case move-one when there is a selection - // (just place the cursor at begining/end of selection) - oc_ui_edit_perform_move(ui, move, direction, codepoints.len); - } - ui->editMark = ui->editCursor; - } break; - - case OC_UI_EDIT_SELECT: - { - oc_ui_edit_perform_move(ui, move, direction, codepoints.len); - } break; - - case OC_UI_EDIT_SELECT_EXTEND: - { - if((direction > 0) != (ui->editCursor > ui->editMark)) - { - u32 tmp = ui->editCursor; - ui->editCursor = ui->editMark; - ui->editMark = tmp; - } - oc_ui_edit_perform_move(ui, move, direction, codepoints.len); - } break; - - case OC_UI_EDIT_DELETE: - { - if(ui->editCursor == ui->editMark) - { - oc_ui_edit_perform_move(ui, move, direction, codepoints.len); - } - codepoints = oc_ui_edit_delete_selection(ui, codepoints); - ui->editMark = ui->editCursor; - } break; - - case OC_UI_EDIT_CUT: - { - oc_ui_edit_copy_selection_to_clipboard(ui, codepoints); - codepoints = oc_ui_edit_delete_selection(ui, codepoints); - } break; - - case OC_UI_EDIT_COPY: - { - oc_ui_edit_copy_selection_to_clipboard(ui, codepoints); - } break; - - case OC_UI_EDIT_PASTE: - { - codepoints = oc_ui_edit_replace_selection_with_clipboard(ui, codepoints); - } break; - - case OC_UI_EDIT_SELECT_ALL: - { - ui->editCursor = 0; - ui->editMark = codepoints.len; - } break; - } - ui->editCursorBlinkStart = ui->frameTime; - - return(codepoints); -} - -void oc_ui_text_box_render(oc_ui_box* box, void* data) -{ - oc_str32 codepoints = *(oc_str32*)data; - oc_ui_context* ui = oc_ui_get_context(); - - u32 firstDisplayedChar = 0; - if(oc_ui_box_active(box)) - { - firstDisplayedChar = ui->editFirstDisplayedChar; - } - - oc_ui_style* style = &box->style; - oc_font_extents extents = oc_font_get_scaled_extents(style->font, style->fontSize); - f32 lineHeight = extents.ascent + extents.descent; - - oc_str32 before = oc_str32_slice(codepoints, 0, firstDisplayedChar); - oc_rect beforeBox = oc_text_bounding_box_utf32(style->font, style->fontSize, before); - - f32 textMargin = 5; //TODO: make that configurable - - f32 textX = textMargin + box->rect.x - beforeBox.w; - f32 textTop = box->rect.y + 0.5*(box->rect.h - lineHeight); - f32 textY = textTop + extents.ascent ; - - if(box->active) - { - u32 selectStart = oc_min(ui->editCursor, ui->editMark); - u32 selectEnd = oc_max(ui->editCursor, ui->editMark); - - oc_str32 beforeSelect = oc_str32_slice(codepoints, 0, selectStart); - oc_rect beforeSelectBox = oc_text_bounding_box_utf32(style->font, style->fontSize, beforeSelect); - beforeSelectBox.x += textX; - beforeSelectBox.y += textY; - - if(selectStart != selectEnd) - { - oc_str32 select = oc_str32_slice(codepoints, selectStart, selectEnd); - oc_str32 afterSelect = oc_str32_slice(codepoints, selectEnd, codepoints.len); - oc_rect selectBox = oc_text_bounding_box_utf32(style->font, style->fontSize, select); - oc_rect afterSelectBox = oc_text_bounding_box_utf32(style->font, style->fontSize, afterSelect); - - selectBox.x += beforeSelectBox.x + beforeSelectBox.w; - selectBox.y += textY; - - oc_set_color_rgba(0, 0, 1, 1); - oc_rectangle_fill(selectBox.x, selectBox.y, selectBox.w, lineHeight); - - oc_set_font(style->font); - oc_set_font_size(style->fontSize); - oc_set_color(style->color); - - oc_move_to(textX, textY); - oc_codepoints_outlines(beforeSelect); - oc_fill(); - - oc_set_color_rgba(1, 1, 1, 1); - oc_codepoints_outlines(select); - oc_fill(); - - oc_set_color(style->color); - oc_codepoints_outlines(afterSelect); - oc_fill(); - } - else - { - if(!((u64)(2*(ui->frameTime - ui->editCursorBlinkStart)) & 1)) - { - f32 caretX = box->rect.x + textMargin - beforeBox.w + beforeSelectBox.w; - f32 caretY = textTop; - oc_set_color(style->color); - oc_rectangle_fill(caretX, caretY, 1, lineHeight); - } - oc_set_font(style->font); - oc_set_font_size(style->fontSize); - oc_set_color(style->color); - - oc_move_to(textX, textY); - oc_codepoints_outlines(codepoints); - oc_fill(); - } - } - else - { - oc_set_font(style->font); - oc_set_font_size(style->fontSize); - oc_set_color(style->color); - - oc_move_to(textX, textY); - oc_codepoints_outlines(codepoints); - oc_fill(); - } -} - -oc_ui_text_box_result oc_ui_text_box(const char* name, oc_arena* arena, oc_str8 text) -{ - oc_ui_context* ui = oc_ui_get_context(); - - oc_ui_text_box_result result = {.text = text}; - - oc_ui_flags frameFlags = OC_UI_FLAG_CLICKABLE - | OC_UI_FLAG_DRAW_BACKGROUND - | OC_UI_FLAG_DRAW_BORDER - | OC_UI_FLAG_CLIP - | OC_UI_FLAG_DRAW_PROC; - - oc_ui_box* frame = oc_ui_box_make(name, frameFlags); - oc_ui_style* style = &frame->style; - f32 textMargin = 5; //TODO parameterize this margin! must be the same as in oc_ui_text_box_render - - oc_font_extents extents = oc_font_get_scaled_extents(style->font, style->fontSize); - - oc_ui_sig sig = oc_ui_box_sig(frame); - - if(sig.pressed) - { - if(!oc_ui_box_active(frame)) - { - oc_ui_box_activate(frame); - - //NOTE: focus - ui->focus = frame; - ui->editFirstDisplayedChar = 0; - ui->editCursor = 0; - ui->editMark = 0; - } - ui->editCursorBlinkStart = ui->frameTime; - } - - if(sig.pressed || sig.dragging) - { - //NOTE: set cursor/extend selection on mouse press or drag - oc_vec2 pos = oc_ui_mouse_position(); - f32 cursorX = pos.x - frame->rect.x - textMargin; - - oc_str32 codepoints = oc_utf8_push_to_codepoints(&ui->frameArena, text); - i32 newCursor = codepoints.len; - f32 x = 0; - for(int i = ui->editFirstDisplayedChar; ifont, style->fontSize, oc_str32_slice(codepoints, i, i+1)); - if(x + 0.5*bbox.w > cursorX) - { - newCursor = i; - break; - } - x += bbox.w; - } - //NOTE: put cursor the closest to new cursor (this maximizes the resulting selection, - // and seems to be the standard behaviour across a number of text editor) - if(sig.pressed && abs(newCursor - ui->editCursor) > abs(newCursor - ui->editMark)) - { - i32 tmp = ui->editCursor; - ui->editCursor = ui->editMark; - ui->editMark = tmp; - } - //NOTE: set the new cursor, and set or leave the mark depending on mode - ui->editCursor = newCursor; - if(sig.pressed && !(oc_key_mods(&ui->input) & OC_KEYMOD_SHIFT)) - { - ui->editMark = ui->editCursor; - } - } - - if(sig.hovering) - { - oc_ui_box_set_hot(frame, true); - } - else - { - oc_ui_box_set_hot(frame, false); - - if(oc_mouse_pressed(&ui->input, OC_MOUSE_LEFT) || - oc_mouse_pressed(&ui->input, OC_MOUSE_RIGHT) || - oc_mouse_pressed(&ui->input, OC_MOUSE_MIDDLE)) - { - if(oc_ui_box_active(frame)) - { - oc_ui_box_deactivate(frame); - - //NOTE loose focus - ui->focus = 0; - } - } - } - - if(oc_ui_box_active(frame)) - { - oc_str32 oldCodepoints = oc_utf8_push_to_codepoints(&ui->frameArena, text); - oc_str32 codepoints = oldCodepoints; - ui->editCursor = oc_clamp(ui->editCursor, 0, codepoints.len); - ui->editMark = oc_clamp(ui->editMark, 0, codepoints.len); - - //NOTE replace selection with input codepoints - oc_str32 input = oc_input_text_utf32(&ui->input, &ui->frameArena); - if(input.len) - { - codepoints = oc_ui_edit_replace_selection_with_codepoints(ui, codepoints, input); - ui->editCursorBlinkStart = ui->frameTime; - } - - //NOTE handle shortcuts - oc_keymod_flags mods = oc_key_mods(&ui->input); - - for(int i=0; iinput, command->key) || oc_key_repeated(&ui->input, command->key)) - && mods == command->mods) - { - codepoints = oc_ui_edit_perform_operation(ui, command->operation, command->move, command->direction, codepoints); - break; - } - } - - //NOTE(martin): check changed/accepted - if(oldCodepoints.ptr != codepoints.ptr) - { - result.changed = true; - result.text = oc_utf8_push_from_codepoints(arena, codepoints); - } - - if(oc_key_pressed(&ui->input, OC_KEY_ENTER)) - { - //TODO(martin): extract in gui_edit_complete() (and use below) - result.accepted = true; - oc_ui_box_deactivate(frame); - ui->focus = 0; - } - - //NOTE slide contents - { - if(ui->editCursor < ui->editFirstDisplayedChar) - { - ui->editFirstDisplayedChar = ui->editCursor; - } - else - { - i32 firstDisplayedChar = ui->editFirstDisplayedChar; - oc_str32 firstToCursor = oc_str32_slice(codepoints, firstDisplayedChar, ui->editCursor); - oc_rect firstToCursorBox = oc_text_bounding_box_utf32(style->font, style->fontSize, firstToCursor); - - while(firstToCursorBox.w > (frame->rect.w - 2*textMargin)) - { - firstDisplayedChar++; - firstToCursor = oc_str32_slice(codepoints, firstDisplayedChar, ui->editCursor); - firstToCursorBox = oc_text_bounding_box_utf32(style->font, style->fontSize, firstToCursor); - } - - ui->editFirstDisplayedChar = firstDisplayedChar; - } - } - - //NOTE: set renderer - oc_str32* renderCodepoints = oc_arena_push_type(&ui->frameArena, oc_str32); - *renderCodepoints = oc_str32_push_copy(&ui->frameArena, codepoints); - oc_ui_box_set_draw_proc(frame, oc_ui_text_box_render, renderCodepoints); - } - else - { - //NOTE: set renderer - oc_str32* renderCodepoints = oc_arena_push_type(&ui->frameArena, oc_str32); - *renderCodepoints = oc_utf8_push_to_codepoints(&ui->frameArena, text); - oc_ui_box_set_draw_proc(frame, oc_ui_text_box_render, renderCodepoints); - } - - return(result); -} + */ + f32 alpha = 3 / animationTime; + f32 dt = ui->lastFrameDuration; + + *value += (target - *value) * alpha * dt; + } +} + +void oc_ui_animate_color(oc_ui_context* ui, oc_color* color, oc_color target, f32 animationTime) +{ + for(int i = 0; i < 4; i++) + { + oc_ui_animate_f32(ui, &color->c[i], target.c[i], animationTime); + } +} + +void oc_ui_animate_oc_ui_size(oc_ui_context* ui, oc_ui_size* size, oc_ui_size target, f32 animationTime) +{ + size->kind = target.kind; + oc_ui_animate_f32(ui, &size->value, target.value, animationTime); + oc_ui_animate_f32(ui, &size->relax, target.relax, animationTime); +} + +void oc_ui_box_animate_style(oc_ui_context* ui, oc_ui_box* box) +{ + oc_ui_style* targetStyle = box->targetStyle; + OC_DEBUG_ASSERT(targetStyle); + + f32 animationTime = targetStyle->animationTime; + + //NOTE: interpolate based on transition values + oc_ui_style_mask mask = box->targetStyle->animationMask; + + if(box->fresh) + { + box->style = *targetStyle; + } + else + { + if(mask & OC_UI_STYLE_SIZE_WIDTH) + { + oc_ui_animate_oc_ui_size(ui, &box->style.size.c[OC_UI_AXIS_X], targetStyle->size.c[OC_UI_AXIS_X], animationTime); + } + else + { + box->style.size.c[OC_UI_AXIS_X] = targetStyle->size.c[OC_UI_AXIS_X]; + } + + if(mask & OC_UI_STYLE_SIZE_HEIGHT) + { + oc_ui_animate_oc_ui_size(ui, &box->style.size.c[OC_UI_AXIS_Y], targetStyle->size.c[OC_UI_AXIS_Y], animationTime); + } + else + { + box->style.size.c[OC_UI_AXIS_Y] = targetStyle->size.c[OC_UI_AXIS_Y]; + } + + if(mask & OC_UI_STYLE_COLOR) + { + oc_ui_animate_color(ui, &box->style.color, targetStyle->color, animationTime); + } + else + { + box->style.color = targetStyle->color; + } + + if(mask & OC_UI_STYLE_BG_COLOR) + { + oc_ui_animate_color(ui, &box->style.bgColor, targetStyle->bgColor, animationTime); + } + else + { + box->style.bgColor = targetStyle->bgColor; + } + + if(mask & OC_UI_STYLE_BORDER_COLOR) + { + oc_ui_animate_color(ui, &box->style.borderColor, targetStyle->borderColor, animationTime); + } + else + { + box->style.borderColor = targetStyle->borderColor; + } + + if(mask & OC_UI_STYLE_FONT_SIZE) + { + oc_ui_animate_f32(ui, &box->style.fontSize, targetStyle->fontSize, animationTime); + } + else + { + box->style.fontSize = targetStyle->fontSize; + } + + if(mask & OC_UI_STYLE_BORDER_SIZE) + { + oc_ui_animate_f32(ui, &box->style.borderSize, targetStyle->borderSize, animationTime); + } + else + { + box->style.borderSize = targetStyle->borderSize; + } + + if(mask & OC_UI_STYLE_ROUNDNESS) + { + oc_ui_animate_f32(ui, &box->style.roundness, targetStyle->roundness, animationTime); + } + else + { + box->style.roundness = targetStyle->roundness; + } + + //NOTE: float target is animated in compute rect + box->style.floatTarget = targetStyle->floatTarget; + + //TODO: non animatable attributes. use mask + box->style.layout = targetStyle->layout; + box->style.font = targetStyle->font; + } +} + +void oc_ui_apply_style_with_mask(oc_ui_style* dst, oc_ui_style* src, oc_ui_style_mask mask) +{ + if(mask & OC_UI_STYLE_SIZE_WIDTH) + { + dst->size.c[OC_UI_AXIS_X] = src->size.c[OC_UI_AXIS_X]; + } + if(mask & OC_UI_STYLE_SIZE_HEIGHT) + { + dst->size.c[OC_UI_AXIS_Y] = src->size.c[OC_UI_AXIS_Y]; + } + if(mask & OC_UI_STYLE_LAYOUT_AXIS) + { + dst->layout.axis = src->layout.axis; + } + if(mask & OC_UI_STYLE_LAYOUT_ALIGN_X) + { + dst->layout.align.x = src->layout.align.x; + } + if(mask & OC_UI_STYLE_LAYOUT_ALIGN_Y) + { + dst->layout.align.y = src->layout.align.y; + } + if(mask & OC_UI_STYLE_LAYOUT_SPACING) + { + dst->layout.spacing = src->layout.spacing; + } + if(mask & OC_UI_STYLE_LAYOUT_MARGIN_X) + { + dst->layout.margin.x = src->layout.margin.x; + } + if(mask & OC_UI_STYLE_LAYOUT_MARGIN_Y) + { + dst->layout.margin.y = src->layout.margin.y; + } + if(mask & OC_UI_STYLE_FLOAT_X) + { + dst->floating.c[OC_UI_AXIS_X] = src->floating.c[OC_UI_AXIS_X]; + dst->floatTarget.x = src->floatTarget.x; + } + if(mask & OC_UI_STYLE_FLOAT_Y) + { + dst->floating.c[OC_UI_AXIS_Y] = src->floating.c[OC_UI_AXIS_Y]; + dst->floatTarget.y = src->floatTarget.y; + } + if(mask & OC_UI_STYLE_COLOR) + { + dst->color = src->color; + } + if(mask & OC_UI_STYLE_BG_COLOR) + { + dst->bgColor = src->bgColor; + } + if(mask & OC_UI_STYLE_BORDER_COLOR) + { + dst->borderColor = src->borderColor; + } + if(mask & OC_UI_STYLE_BORDER_SIZE) + { + dst->borderSize = src->borderSize; + } + if(mask & OC_UI_STYLE_ROUNDNESS) + { + dst->roundness = src->roundness; + } + if(mask & OC_UI_STYLE_FONT) + { + dst->font = src->font; + } + if(mask & OC_UI_STYLE_FONT_SIZE) + { + dst->fontSize = src->fontSize; + } + if(mask & OC_UI_STYLE_ANIMATION_TIME) + { + dst->animationTime = src->animationTime; + } + if(mask & OC_UI_STYLE_ANIMATION_MASK) + { + dst->animationMask = src->animationMask; + } +} + +bool oc_ui_style_selector_match(oc_ui_box* box, oc_ui_style_rule* rule, oc_ui_selector* selector) +{ + bool res = false; + switch(selector->kind) + { + case OC_UI_SEL_ANY: + res = true; + break; + + case OC_UI_SEL_OWNER: + res = (box == rule->owner); + break; + + case OC_UI_SEL_TEXT: + res = !oc_str8_cmp(box->string, selector->text); + break; + + case OC_UI_SEL_TAG: + { + oc_list_for(&box->tags, elt, oc_ui_tag_elt, listElt) + { + if(elt->tag.hash == selector->tag.hash) + { + res = true; + break; + } + } + } + break; + + case OC_UI_SEL_STATUS: + { + res = true; + if(selector->status & OC_UI_HOVER) + { + res = res && oc_ui_box_hovering(box, oc_ui_mouse_position()); + } + if(selector->status & OC_UI_ACTIVE) + { + res = res && box->active; + } + if(selector->status & OC_UI_DRAGGING) + { + res = res && box->dragging; + } + } + break; + + case OC_UI_SEL_KEY: + res = oc_ui_key_equal(box->key, selector->key); + default: + break; + } + return (res); +} + +void oc_ui_style_rule_match(oc_ui_context* ui, oc_ui_box* box, oc_ui_style_rule* rule, oc_list* buildList, oc_list* tmpList) +{ + oc_ui_selector* selector = oc_list_first_entry(&rule->pattern.l, oc_ui_selector, listElt); + bool match = oc_ui_style_selector_match(box, rule, selector); + + selector = oc_list_next_entry(&rule->pattern.l, selector, oc_ui_selector, listElt); + while(match && selector && selector->op == OC_UI_SEL_AND) + { + match = match && oc_ui_style_selector_match(box, rule, selector); + selector = oc_list_next_entry(&rule->pattern.l, selector, oc_ui_selector, listElt); + } + + if(match) + { + if(!selector) + { + oc_ui_apply_style_with_mask(box->targetStyle, rule->style, rule->mask); + } + else + { + //NOTE create derived rule if there's more than one selector + oc_ui_style_rule* derived = oc_arena_push_type(&ui->frameArena, oc_ui_style_rule); + derived->mask = rule->mask; + derived->style = rule->style; + derived->pattern.l = (oc_list){ &selector->listElt, rule->pattern.l.last }; + + oc_list_append(buildList, &derived->buildElt); + oc_list_append(tmpList, &derived->tmpElt); + } + } +} + +void oc_ui_styling_prepass(oc_ui_context* ui, oc_ui_box* box, oc_list* before, oc_list* after) +{ + //NOTE: inherit style from parent + if(box->parent) + { + oc_ui_apply_style_with_mask(box->targetStyle, + box->parent->targetStyle, + OC_UI_STYLE_MASK_INHERITED); + } + + //NOTE: append box before rules to before and tmp + oc_list tmpBefore = { 0 }; + oc_list_for(&box->beforeRules, rule, oc_ui_style_rule, boxElt) + { + oc_list_append(before, &rule->buildElt); + oc_list_append(&tmpBefore, &rule->tmpElt); + } + //NOTE: match before rules + oc_list_for(before, rule, oc_ui_style_rule, buildElt) + { + oc_ui_style_rule_match(ui, box, rule, before, &tmpBefore); + } + + //NOTE: prepend box after rules to after and append them to tmp + oc_list tmpAfter = { 0 }; + oc_list_for_reverse(&box->afterRules, rule, oc_ui_style_rule, boxElt) + { + oc_list_push(after, &rule->buildElt); + oc_list_append(&tmpAfter, &rule->tmpElt); + } + + //NOTE: match after rules + oc_list_for(after, rule, oc_ui_style_rule, buildElt) + { + oc_ui_style_rule_match(ui, box, rule, after, &tmpAfter); + } + + //NOTE: compute static sizes + oc_ui_box_animate_style(ui, box); + + if(oc_ui_box_hidden(box)) + { + return; + } + + oc_ui_style* style = &box->style; + + oc_rect textBox = { 0 }; + oc_ui_size desiredSize[2] = { box->style.size.c[OC_UI_AXIS_X], + box->style.size.c[OC_UI_AXIS_Y] }; + + if(desiredSize[OC_UI_AXIS_X].kind == OC_UI_SIZE_TEXT + || desiredSize[OC_UI_AXIS_Y].kind == OC_UI_SIZE_TEXT) + { + textBox = oc_text_bounding_box(style->font, style->fontSize, box->string); + } + + for(int i = 0; i < OC_UI_AXIS_COUNT; i++) + { + oc_ui_size size = desiredSize[i]; + + if(size.kind == OC_UI_SIZE_TEXT) + { + f32 margin = style->layout.margin.c[i]; + box->rect.c[2 + i] = textBox.c[2 + i] + margin * 2; + } + else if(size.kind == OC_UI_SIZE_PIXELS) + { + box->rect.c[2 + i] = size.value; + } + } + + //NOTE: descend in children + oc_list_for(&box->children, child, oc_ui_box, listElt) + { + oc_ui_styling_prepass(ui, child, before, after); + } + + //NOTE: remove temporary rules + oc_list_for(&tmpBefore, rule, oc_ui_style_rule, tmpElt) + { + oc_list_remove(before, &rule->buildElt); + } + oc_list_for(&tmpAfter, rule, oc_ui_style_rule, tmpElt) + { + oc_list_remove(after, &rule->buildElt); + } +} + +bool oc_ui_layout_downward_dependency(oc_ui_box* child, int axis) +{ + return (!oc_ui_box_hidden(child) + && !child->style.floating.c[axis] + && child->style.size.c[axis].kind != OC_UI_SIZE_PARENT + && child->style.size.c[axis].kind != OC_UI_SIZE_PARENT_MINUS_PIXELS); +} + +void oc_ui_layout_downward_dependent_size(oc_ui_context* ui, oc_ui_box* box, int axis) +{ + //NOTE: layout children and compute spacing + f32 count = 0; + oc_list_for(&box->children, child, oc_ui_box, listElt) + { + if(!oc_ui_box_hidden(child)) + { + oc_ui_layout_downward_dependent_size(ui, child, axis); + + if(box->style.layout.axis == axis + && !child->style.floating.c[axis]) + { + count++; + } + } + } + box->spacing[axis] = oc_max(0, count - 1) * box->style.layout.spacing; + + oc_ui_size* size = &box->style.size.c[axis]; + if(size->kind == OC_UI_SIZE_CHILDREN) + { + //NOTE: if box is dependent on children, compute children's size. If we're in the layout + // axis this is the sum of each child size, otherwise it is the maximum child size + f32 sum = 0; + + if(box->style.layout.axis == axis) + { + oc_list_for(&box->children, child, oc_ui_box, listElt) + { + if(oc_ui_layout_downward_dependency(child, axis)) + { + sum += child->rect.c[2 + axis]; + } + } + } + else + { + oc_list_for(&box->children, child, oc_ui_box, listElt) + { + if(oc_ui_layout_downward_dependency(child, axis)) + { + sum = oc_max(sum, child->rect.c[2 + axis]); + } + } + } + f32 margin = box->style.layout.margin.c[axis]; + box->rect.c[2 + axis] = sum + box->spacing[axis] + 2 * margin; + } +} + +void oc_ui_layout_upward_dependent_size(oc_ui_context* ui, oc_ui_box* box, int axis) +{ + //NOTE: re-compute/set size of children that depend on box's size + + f32 margin = box->style.layout.margin.c[axis]; + f32 availableSize = oc_max(0, box->rect.c[2 + axis] - box->spacing[axis] - 2 * margin); + + oc_list_for(&box->children, child, oc_ui_box, listElt) + { + oc_ui_size* size = &child->style.size.c[axis]; + if(size->kind == OC_UI_SIZE_PARENT) + { + child->rect.c[2 + axis] = availableSize * size->value; + } + else if(size->kind == OC_UI_SIZE_PARENT_MINUS_PIXELS) + { + child->rect.c[2 + axis] = oc_max(0, availableSize - size->value); + } + } + + //NOTE: solve downard conflicts + int overflowFlag = (OC_UI_FLAG_ALLOW_OVERFLOW_X << axis); + f32 sum = 0; + + if(box->style.layout.axis == axis) + { + //NOTE: if we're solving in the layout axis, first compute total sum of children and + // total slack available + f32 slack = 0; + + oc_list_for(&box->children, child, oc_ui_box, listElt) + { + if(!oc_ui_box_hidden(child) + && !child->style.floating.c[axis]) + { + sum += child->rect.c[2 + axis]; + slack += child->rect.c[2 + axis] * child->style.size.c[axis].relax; + } + } + + if(!(box->flags & overflowFlag)) + { + //NOTE: then remove excess proportionally to each box slack, and recompute children sum. + f32 totalContents = sum + box->spacing[axis] + 2 * box->style.layout.margin.c[axis]; + f32 excess = oc_clamp_low(totalContents - box->rect.c[2 + axis], 0); + f32 alpha = oc_clamp(excess / slack, 0, 1); + + sum = 0; + oc_list_for(&box->children, child, oc_ui_box, listElt) + { + f32 relax = child->style.size.c[axis].relax; + child->rect.c[2 + axis] -= alpha * child->rect.c[2 + axis] * relax; + sum += child->rect.c[2 + axis]; + } + } + } + else + { + //NOTE: if we're solving on the secondary axis, we remove excess to each box individually + // according to its own slack. Children sum is the maximum child size. + + oc_list_for(&box->children, child, oc_ui_box, listElt) + { + if(!oc_ui_box_hidden(child) && !child->style.floating.c[axis]) + { + if(!(box->flags & overflowFlag)) + { + f32 totalContents = child->rect.c[2 + axis] + 2 * box->style.layout.margin.c[axis]; + f32 excess = oc_clamp_low(totalContents - box->rect.c[2 + axis], 0); + f32 relax = child->style.size.c[axis].relax; + child->rect.c[2 + axis] -= oc_min(excess, child->rect.c[2 + axis] * relax); + } + sum = oc_max(sum, child->rect.c[2 + axis]); + } + } + } + + box->childrenSum[axis] = sum; + + //NOTE: recurse in children + oc_list_for(&box->children, child, oc_ui_box, listElt) + { + oc_ui_layout_upward_dependent_size(ui, child, axis); + } +} + +void oc_ui_layout_compute_rect(oc_ui_context* ui, oc_ui_box* box, oc_vec2 pos) +{ + if(oc_ui_box_hidden(box)) + { + return; + } + + box->rect.x = pos.x; + box->rect.y = pos.y; + box->z = ui->z; + ui->z++; + + oc_ui_axis layoutAxis = box->style.layout.axis; + oc_ui_axis secondAxis = (layoutAxis == OC_UI_AXIS_X) ? OC_UI_AXIS_Y : OC_UI_AXIS_X; + f32 spacing = box->style.layout.spacing; + + oc_ui_align* align = box->style.layout.align.c; + + oc_vec2 origin = { box->rect.x, + box->rect.y }; + oc_vec2 currentPos = origin; + + oc_vec2 margin = { box->style.layout.margin.x, + box->style.layout.margin.y }; + + currentPos.x += margin.x; + currentPos.y += margin.y; + + for(int i = 0; i < OC_UI_AXIS_COUNT; i++) + { + if(align[i] == OC_UI_ALIGN_END) + { + currentPos.c[i] = origin.c[i] + box->rect.c[2 + i] - (box->childrenSum[i] + box->spacing[i] + margin.c[i]); + } + } + if(align[layoutAxis] == OC_UI_ALIGN_CENTER) + { + currentPos.c[layoutAxis] = origin.c[layoutAxis] + + 0.5 * (box->rect.c[2 + layoutAxis] - (box->childrenSum[layoutAxis] + box->spacing[layoutAxis])); + } + + currentPos.x -= box->scroll.x; + currentPos.y -= box->scroll.y; + + oc_list_for(&box->children, child, oc_ui_box, listElt) + { + if(align[secondAxis] == OC_UI_ALIGN_CENTER) + { + currentPos.c[secondAxis] = origin.c[secondAxis] + 0.5 * (box->rect.c[2 + secondAxis] - child->rect.c[2 + secondAxis]); + } + + oc_vec2 childPos = currentPos; + for(int i = 0; i < OC_UI_AXIS_COUNT; i++) + { + if(child->style.floating.c[i]) + { + oc_ui_style* style = child->targetStyle; + if((child->targetStyle->animationMask & (OC_UI_STYLE_FLOAT_X << i)) + && !child->fresh) + { + oc_ui_animate_f32(ui, &child->floatPos.c[i], child->style.floatTarget.c[i], style->animationTime); + } + else + { + child->floatPos.c[i] = child->style.floatTarget.c[i]; + } + childPos.c[i] = origin.c[i] + child->floatPos.c[i]; + } + } + + oc_ui_layout_compute_rect(ui, child, childPos); + + if(!child->style.floating.c[layoutAxis]) + { + currentPos.c[layoutAxis] += child->rect.c[2 + layoutAxis] + spacing; + } + } +} + +void oc_ui_layout_find_next_hovered_recursive(oc_ui_context* ui, oc_ui_box* box, oc_vec2 p) +{ + if(oc_ui_box_hidden(box)) + { + return; + } + + bool hit = oc_ui_rect_hit(box->rect, p); + if(hit && (box->flags & OC_UI_FLAG_BLOCK_MOUSE)) + { + ui->hovered = box; + } + if(hit || !(box->flags & OC_UI_FLAG_CLIP)) + { + oc_list_for(&box->children, child, oc_ui_box, listElt) + { + oc_ui_layout_find_next_hovered_recursive(ui, child, p); + } + } +} + +void oc_ui_layout_find_next_hovered(oc_ui_context* ui, oc_vec2 p) +{ + ui->hovered = 0; + oc_ui_layout_find_next_hovered_recursive(ui, ui->root, p); +} + +void oc_ui_solve_layout(oc_ui_context* ui) +{ + oc_list beforeRules = { 0 }; + oc_list afterRules = { 0 }; + + //NOTE: style and compute static sizes + oc_ui_styling_prepass(ui, ui->root, &beforeRules, &afterRules); + + //NOTE: reparent overlay boxes + oc_list_for(&ui->overlayList, box, oc_ui_box, overlayElt) + { + if(box->parent) + { + oc_list_remove(&box->parent->children, &box->listElt); + oc_list_append(&ui->overlay->children, &box->listElt); + } + } + + //NOTE: compute layout + for(int axis = 0; axis < OC_UI_AXIS_COUNT; axis++) + { + oc_ui_layout_downward_dependent_size(ui, ui->root, axis); + oc_ui_layout_upward_dependent_size(ui, ui->root, axis); + } + oc_ui_layout_compute_rect(ui, ui->root, (oc_vec2){ 0, 0 }); + + oc_vec2 p = oc_ui_mouse_position(); + oc_ui_layout_find_next_hovered(ui, p); +} + +//----------------------------------------------------------------------------- +// Drawing +//----------------------------------------------------------------------------- + +void oc_ui_rectangle_fill(oc_rect rect, f32 roundness) +{ + if(roundness) + { + oc_rounded_rectangle_fill(rect.x, rect.y, rect.w, rect.h, roundness); + } + else + { + oc_rectangle_fill(rect.x, rect.y, rect.w, rect.h); + } +} + +void oc_ui_rectangle_stroke(oc_rect rect, f32 roundness) +{ + if(roundness) + { + oc_rounded_rectangle_stroke(rect.x, rect.y, rect.w, rect.h, roundness); + } + else + { + oc_rectangle_stroke(rect.x, rect.y, rect.w, rect.h); + } +} + +void oc_ui_draw_box(oc_ui_box* box) +{ + if(oc_ui_box_hidden(box)) + { + return; + } + + oc_ui_style* style = &box->style; + + if(box->flags & OC_UI_FLAG_CLIP) + { + oc_clip_push(box->rect.x, box->rect.y, box->rect.w, box->rect.h); + } + + if(box->flags & OC_UI_FLAG_DRAW_BACKGROUND) + { + oc_set_color(style->bgColor); + oc_ui_rectangle_fill(box->rect, style->roundness); + } + + if((box->flags & OC_UI_FLAG_DRAW_PROC) && box->drawProc) + { + box->drawProc(box, box->drawData); + } + + oc_list_for(&box->children, child, oc_ui_box, listElt) + { + oc_ui_draw_box(child); + } + + if(box->flags & OC_UI_FLAG_DRAW_TEXT) + { + oc_rect textBox = oc_text_bounding_box(style->font, style->fontSize, box->string); + + f32 x = 0; + f32 y = 0; + switch(style->layout.align.x) + { + case OC_UI_ALIGN_START: + x = box->rect.x + style->layout.margin.x; + break; + + case OC_UI_ALIGN_END: + x = box->rect.x + box->rect.w - style->layout.margin.x - textBox.w; + break; + + case OC_UI_ALIGN_CENTER: + x = box->rect.x + 0.5 * (box->rect.w - textBox.w); + break; + } + + switch(style->layout.align.y) + { + case OC_UI_ALIGN_START: + y = box->rect.y + style->layout.margin.y - textBox.y; + break; + + case OC_UI_ALIGN_END: + y = box->rect.y + box->rect.h - style->layout.margin.y - textBox.h + textBox.y; + break; + + case OC_UI_ALIGN_CENTER: + y = box->rect.y + 0.5 * (box->rect.h - textBox.h) - textBox.y; + break; + } + + oc_set_font(style->font); + oc_set_font_size(style->fontSize); + oc_set_color(style->color); + + oc_move_to(x, y); + oc_text_outlines(box->string); + oc_fill(); + } + + if(box->flags & OC_UI_FLAG_CLIP) + { + oc_clip_pop(); + } + + if(box->flags & OC_UI_FLAG_DRAW_BORDER) + { + oc_set_width(style->borderSize); + oc_set_color(style->borderColor); + oc_ui_rectangle_stroke(box->rect, style->roundness); + } +} + +void oc_ui_draw() +{ + oc_ui_context* ui = oc_ui_get_context(); + + //NOTE: draw + bool oldTextFlip = oc_get_text_flip(); + oc_set_text_flip(false); + + oc_ui_draw_box(ui->root); + + oc_set_text_flip(oldTextFlip); +} + +//----------------------------------------------------------------------------- +// frame begin/end +//----------------------------------------------------------------------------- + +void oc_ui_begin_frame(oc_vec2 size, oc_ui_style* defaultStyle, oc_ui_style_mask defaultMask) +{ + oc_ui_context* ui = oc_ui_get_context(); + + oc_arena_clear(&ui->frameArena); + + ui->frameCounter++; + f64 time = oc_clock_time(OC_CLOCK_MONOTONIC); + ui->lastFrameDuration = time - ui->frameTime; + ui->frameTime = time; + + ui->clipStack = 0; + ui->z = 0; + + defaultMask &= OC_UI_STYLE_COLOR + | OC_UI_STYLE_BG_COLOR + | OC_UI_STYLE_BORDER_COLOR + | OC_UI_STYLE_FONT + | OC_UI_STYLE_FONT_SIZE; + + oc_ui_style_match_before(oc_ui_pattern_all(), defaultStyle, defaultMask); + oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PIXELS, size.x }, + .size.height = { OC_UI_SIZE_PIXELS, size.y } }, + OC_UI_STYLE_SIZE); + + ui->root = oc_ui_box_begin("_root_", 0); + + oc_ui_style_mask contentStyleMask = OC_UI_STYLE_SIZE + | OC_UI_STYLE_LAYOUT + | OC_UI_STYLE_FLOAT; + + oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 }, + .size.height = { OC_UI_SIZE_PARENT, 1 }, + .layout = { OC_UI_AXIS_Y, OC_UI_ALIGN_START, OC_UI_ALIGN_START }, + .floating = { true, true }, + .floatTarget = { 0, 0 } }, + contentStyleMask); + + oc_ui_box* contents = oc_ui_box_make("_contents_", 0); + + oc_ui_style_next(&(oc_ui_style){ .layout = { OC_UI_AXIS_Y, OC_UI_ALIGN_START, OC_UI_ALIGN_START }, + .floating = { true, true }, + .floatTarget = { 0, 0 } }, + OC_UI_STYLE_LAYOUT | OC_UI_STYLE_FLOAT_X | OC_UI_STYLE_FLOAT_Y); + + ui->overlay = oc_ui_box_make("_overlay_", 0); + ui->overlayList = (oc_list){ 0 }; + + ui->nextBoxBeforeRules = (oc_list){ 0 }; + ui->nextBoxAfterRules = (oc_list){ 0 }; + ui->nextBoxTags = (oc_list){ 0 }; + + oc_ui_box_push(contents); +} + +void oc_ui_end_frame(void) +{ + oc_ui_context* ui = oc_ui_get_context(); + + oc_ui_box_pop(); + + oc_ui_box* box = oc_ui_box_end(); + OC_DEBUG_ASSERT(box == ui->root, "unbalanced box stack"); + + //TODO: check balancing of style stacks + + //NOTE: layout + oc_ui_solve_layout(ui); + + //NOTE: prune unused boxes + for(int i = 0; i < OC_UI_BOX_MAP_BUCKET_COUNT; i++) + { + oc_list_for_safe(&ui->boxMap[i], box, oc_ui_box, bucketElt) + { + if(box->frameCounter < ui->frameCounter) + { + oc_list_remove(&ui->boxMap[i], &box->bucketElt); + } + } + } + + oc_input_next_frame(&ui->input); +} + +//----------------------------------------------------------------------------- +// Init / cleanup +//----------------------------------------------------------------------------- +void oc_ui_init(oc_ui_context* ui) +{ + oc_uiCurrentContext = &oc_uiThreadContext; + + memset(ui, 0, sizeof(oc_ui_context)); + oc_arena_init(&ui->frameArena); + oc_pool_init(&ui->boxPool, sizeof(oc_ui_box)); + ui->init = true; + + oc_ui_set_context(ui); +} + +void oc_ui_cleanup(void) +{ + oc_ui_context* ui = oc_ui_get_context(); + oc_arena_cleanup(&ui->frameArena); + oc_pool_cleanup(&ui->boxPool); + ui->init = false; +} + +//----------------------------------------------------------------------------- +// label +//----------------------------------------------------------------------------- + +oc_ui_sig oc_ui_label_str8(oc_str8 label) +{ + oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_TEXT, 0, 0 }, + .size.height = { OC_UI_SIZE_TEXT, 0, 0 } }, + OC_UI_STYLE_SIZE_WIDTH | OC_UI_STYLE_SIZE_HEIGHT); + + oc_ui_flags flags = OC_UI_FLAG_CLIP + | OC_UI_FLAG_DRAW_TEXT; + oc_ui_box* box = oc_ui_box_make_str8(label, flags); + + oc_ui_sig sig = oc_ui_box_sig(box); + return (sig); +} + +oc_ui_sig oc_ui_label(const char* label) +{ + return (oc_ui_label_str8(OC_STR8((char*)label))); +} + +//------------------------------------------------------------------------------ +// button +//------------------------------------------------------------------------------ + +oc_ui_sig oc_ui_button_behavior(oc_ui_box* box) +{ + oc_ui_sig sig = oc_ui_box_sig(box); + + if(sig.hovering) + { + oc_ui_box_set_hot(box, true); + if(sig.dragging) + { + oc_ui_box_activate(box); + } + } + else + { + oc_ui_box_set_hot(box, false); + } + if(!sig.dragging) + { + oc_ui_box_deactivate(box); + } + return (sig); +} + +oc_ui_sig oc_ui_button_str8(oc_str8 label) +{ + oc_ui_context* ui = oc_ui_get_context(); + + oc_ui_style defaultStyle = { .size.width = { OC_UI_SIZE_TEXT }, + .size.height = { OC_UI_SIZE_TEXT }, + .layout.align.x = OC_UI_ALIGN_CENTER, + .layout.align.y = OC_UI_ALIGN_CENTER, + .layout.margin.x = 5, + .layout.margin.y = 5, + .bgColor = { 0.5, 0.5, 0.5, 1 }, + .borderColor = { 0.2, 0.2, 0.2, 1 }, + .borderSize = 1, + .roundness = 10 }; + + oc_ui_style_mask defaultMask = OC_UI_STYLE_SIZE_WIDTH + | OC_UI_STYLE_SIZE_HEIGHT + | OC_UI_STYLE_LAYOUT_MARGIN_X + | OC_UI_STYLE_LAYOUT_MARGIN_Y + | OC_UI_STYLE_LAYOUT_ALIGN_X + | OC_UI_STYLE_LAYOUT_ALIGN_Y + | OC_UI_STYLE_BG_COLOR + | OC_UI_STYLE_BORDER_COLOR + | OC_UI_STYLE_BORDER_SIZE + | OC_UI_STYLE_ROUNDNESS; + + oc_ui_style_next(&defaultStyle, defaultMask); + + oc_ui_style activeStyle = { .bgColor = { 0.3, 0.3, 0.3, 1 }, + .borderColor = { 0.2, 0.2, 0.2, 1 }, + .borderSize = 2 }; + oc_ui_style_mask activeMask = OC_UI_STYLE_BG_COLOR + | OC_UI_STYLE_BORDER_COLOR + | OC_UI_STYLE_BORDER_SIZE; + oc_ui_pattern activePattern = { 0 }; + oc_ui_pattern_push(&ui->frameArena, + &activePattern, + (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, + .status = OC_UI_ACTIVE | OC_UI_HOVER }); + oc_ui_style_match_before(activePattern, &activeStyle, activeMask); + + oc_ui_flags flags = OC_UI_FLAG_CLICKABLE + | OC_UI_FLAG_CLIP + | OC_UI_FLAG_DRAW_BACKGROUND + | OC_UI_FLAG_DRAW_BORDER + | OC_UI_FLAG_DRAW_TEXT + | OC_UI_FLAG_HOT_ANIMATION + | OC_UI_FLAG_ACTIVE_ANIMATION; + + oc_ui_box* box = oc_ui_box_make_str8(label, flags); + oc_ui_tag_box(box, "button"); + + oc_ui_sig sig = oc_ui_button_behavior(box); + return (sig); +} + +oc_ui_sig oc_ui_button(const char* label) +{ + return (oc_ui_button_str8(OC_STR8((char*)label))); +} + +void oc_ui_checkbox_draw(oc_ui_box* box, void* data) +{ + bool checked = *(bool*)data; + if(checked) + { + oc_move_to(box->rect.x + 0.2 * box->rect.w, box->rect.y + 0.5 * box->rect.h); + oc_line_to(box->rect.x + 0.4 * box->rect.w, box->rect.y + 0.75 * box->rect.h); + oc_line_to(box->rect.x + 0.8 * box->rect.w, box->rect.y + 0.2 * box->rect.h); + + oc_set_color(box->style.color); + oc_set_width(0.2 * box->rect.w); + oc_set_joint(OC_JOINT_MITER); + oc_set_max_joint_excursion(0.2 * box->rect.h); + oc_stroke(); + } +} + +oc_ui_sig oc_ui_checkbox(const char* name, bool* checked) +{ + oc_ui_context* ui = oc_ui_get_context(); + + oc_ui_style defaultStyle = { .size.width = { OC_UI_SIZE_PIXELS, 20 }, + .size.height = { OC_UI_SIZE_PIXELS, 20 }, + .bgColor = { 1, 1, 1, 1 }, + .color = { 0, 0, 0, 1 }, + .borderColor = { 0.2, 0.2, 0.2, 1 }, + .borderSize = 1, + .roundness = 5 }; + + oc_ui_style_mask defaultMask = OC_UI_STYLE_SIZE_WIDTH + | OC_UI_STYLE_SIZE_HEIGHT + | OC_UI_STYLE_BG_COLOR + | OC_UI_STYLE_COLOR + | OC_UI_STYLE_BORDER_COLOR + | OC_UI_STYLE_BORDER_SIZE + | OC_UI_STYLE_ROUNDNESS; + + oc_ui_style_next(&defaultStyle, defaultMask); + + oc_ui_style activeStyle = { .bgColor = { 0.5, 0.5, 0.5, 1 }, + .borderColor = { 0.2, 0.2, 0.2, 1 }, + .borderSize = 2 }; + oc_ui_style_mask activeMask = OC_UI_STYLE_BG_COLOR + | OC_UI_STYLE_BORDER_COLOR + | OC_UI_STYLE_BORDER_SIZE; + oc_ui_pattern activePattern = { 0 }; + oc_ui_pattern_push(&ui->frameArena, + &activePattern, + (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, + .status = OC_UI_ACTIVE | OC_UI_HOVER }); + oc_ui_style_match_before(activePattern, &activeStyle, activeMask); + + oc_ui_flags flags = OC_UI_FLAG_CLICKABLE + | OC_UI_FLAG_CLIP + | OC_UI_FLAG_DRAW_BACKGROUND + | OC_UI_FLAG_DRAW_PROC + | OC_UI_FLAG_DRAW_BORDER + | OC_UI_FLAG_HOT_ANIMATION + | OC_UI_FLAG_ACTIVE_ANIMATION; + + oc_ui_box* box = oc_ui_box_make(name, flags); + oc_ui_tag_box(box, "checkbox"); + + oc_ui_sig sig = oc_ui_button_behavior(box); + if(sig.clicked) + { + *checked = !*checked; + } + oc_ui_box_set_draw_proc(box, oc_ui_checkbox_draw, checked); + + return (sig); +} + +//------------------------------------------------------------------------------ +// slider / scrollbar +//------------------------------------------------------------------------------ +oc_ui_box* oc_ui_slider(const char* label, f32 thumbRatio, f32* scrollValue) +{ + oc_ui_style_match_before(oc_ui_pattern_all(), &(oc_ui_style){ 0 }, OC_UI_STYLE_LAYOUT); + oc_ui_box* frame = oc_ui_box_begin(label, 0); + { + f32 beforeRatio = (*scrollValue) * (1. - thumbRatio); + f32 afterRatio = (1. - *scrollValue) * (1. - thumbRatio); + + oc_ui_axis trackAxis = (frame->rect.w > frame->rect.h) ? OC_UI_AXIS_X : OC_UI_AXIS_Y; + oc_ui_axis secondAxis = (trackAxis == OC_UI_AXIS_Y) ? OC_UI_AXIS_X : OC_UI_AXIS_Y; + f32 roundness = 0.5 * frame->rect.c[2 + secondAxis]; + f32 animationTime = 0.5; + + oc_ui_style trackStyle = { .size.width = { OC_UI_SIZE_PARENT, 1 }, + .size.height = { OC_UI_SIZE_PARENT, 1 }, + .layout.axis = trackAxis, + .layout.align.x = OC_UI_ALIGN_START, + .layout.align.y = OC_UI_ALIGN_START, + .bgColor = { 0.5, 0.5, 0.5, 1 }, + .roundness = roundness }; + + oc_ui_style beforeStyle = trackStyle; + beforeStyle.size.c[trackAxis] = (oc_ui_size){ OC_UI_SIZE_PARENT, beforeRatio }; + + oc_ui_style afterStyle = trackStyle; + afterStyle.size.c[trackAxis] = (oc_ui_size){ OC_UI_SIZE_PARENT, afterRatio }; + + oc_ui_style thumbStyle = trackStyle; + thumbStyle.size.c[trackAxis] = (oc_ui_size){ OC_UI_SIZE_PARENT, thumbRatio }; + thumbStyle.bgColor = (oc_color){ 0.3, 0.3, 0.3, 1 }; + + oc_ui_style_mask styleMask = OC_UI_STYLE_SIZE_WIDTH + | OC_UI_STYLE_SIZE_HEIGHT + | OC_UI_STYLE_LAYOUT + | OC_UI_STYLE_BG_COLOR + | OC_UI_STYLE_ROUNDNESS; + + oc_ui_flags trackFlags = OC_UI_FLAG_CLIP + | OC_UI_FLAG_DRAW_BACKGROUND + | OC_UI_FLAG_HOT_ANIMATION + | OC_UI_FLAG_ACTIVE_ANIMATION; + + oc_ui_style_next(&trackStyle, styleMask); + oc_ui_box* track = oc_ui_box_begin("track", trackFlags); + + oc_ui_style_next(&beforeStyle, OC_UI_STYLE_SIZE_WIDTH | OC_UI_STYLE_SIZE_HEIGHT); + oc_ui_box* beforeSpacer = oc_ui_box_make("before", 0); + + oc_ui_flags thumbFlags = OC_UI_FLAG_CLICKABLE + | OC_UI_FLAG_DRAW_BACKGROUND + | OC_UI_FLAG_HOT_ANIMATION + | OC_UI_FLAG_ACTIVE_ANIMATION; + + oc_ui_style_next(&thumbStyle, styleMask); + oc_ui_box* thumb = oc_ui_box_make("thumb", thumbFlags); + + oc_ui_style_next(&afterStyle, OC_UI_STYLE_SIZE_WIDTH | OC_UI_STYLE_SIZE_HEIGHT); + oc_ui_box* afterSpacer = oc_ui_box_make("after", 0); + + oc_ui_box_end(); + + //NOTE: interaction + oc_ui_sig thumbSig = oc_ui_box_sig(thumb); + oc_ui_sig trackSig = oc_ui_box_sig(track); + if(thumbSig.dragging) + { + f32 trackExtents = track->rect.c[2 + trackAxis] - thumb->rect.c[2 + trackAxis]; + *scrollValue = (trackSig.mouse.c[trackAxis] - thumb->pressedMouse.c[trackAxis]) / trackExtents; + *scrollValue = oc_clamp(*scrollValue, 0, 1); + } + + if(oc_ui_box_active(frame)) + { + //NOTE: activated from outside + oc_ui_box_set_hot(track, true); + oc_ui_box_set_hot(thumb, true); + oc_ui_box_activate(track); + oc_ui_box_activate(thumb); + } + + if(trackSig.hovering) + { + oc_ui_box_set_hot(track, true); + oc_ui_box_set_hot(thumb, true); + } + else if(thumbSig.wheel.c[trackAxis] == 0) + { + oc_ui_box_set_hot(track, false); + oc_ui_box_set_hot(thumb, false); + } + + if(thumbSig.dragging) + { + oc_ui_box_activate(track); + oc_ui_box_activate(thumb); + } + else if(thumbSig.wheel.c[trackAxis] == 0) + { + oc_ui_box_deactivate(track); + oc_ui_box_deactivate(thumb); + oc_ui_box_deactivate(frame); + } + } + oc_ui_box_end(); + + return (frame); +} + +//------------------------------------------------------------------------------ +// panels +//------------------------------------------------------------------------------ +void oc_ui_panel_begin(const char* str, oc_ui_flags flags) +{ + flags = flags + | OC_UI_FLAG_CLIP + | OC_UI_FLAG_BLOCK_MOUSE + | OC_UI_FLAG_ALLOW_OVERFLOW_X + | OC_UI_FLAG_ALLOW_OVERFLOW_Y + | OC_UI_FLAG_SCROLL_WHEEL_X + | OC_UI_FLAG_SCROLL_WHEEL_Y; + + oc_ui_box_begin(str, flags); +} + +void oc_ui_panel_end(void) +{ + oc_ui_box* panel = oc_ui_box_top(); + oc_ui_sig sig = oc_ui_box_sig(panel); + + f32 contentsW = oc_clamp_low(panel->childrenSum[0], panel->rect.w); + f32 contentsH = oc_clamp_low(panel->childrenSum[1], panel->rect.h); + + contentsW = oc_clamp_low(contentsW, 1); + contentsH = oc_clamp_low(contentsH, 1); + + oc_ui_box* scrollBarX = 0; + oc_ui_box* scrollBarY = 0; + + bool needsScrollX = contentsW > panel->rect.w; + bool needsScrollY = contentsH > panel->rect.h; + + if(needsScrollX) + { + f32 thumbRatioX = panel->rect.w / contentsW; + f32 sliderX = panel->scroll.x / (contentsW - panel->rect.w); + + oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1., 0 }, + .size.height = { OC_UI_SIZE_PIXELS, 10, 0 }, + .floating.x = true, + .floating.y = true, + .floatTarget = { 0, panel->rect.h - 10 } }, + OC_UI_STYLE_SIZE + | OC_UI_STYLE_FLOAT); + + scrollBarX = oc_ui_slider("scrollerX", thumbRatioX, &sliderX); + + panel->scroll.x = sliderX * (contentsW - panel->rect.w); + if(sig.hovering) + { + oc_ui_box_activate(scrollBarX); + } + } + + if(needsScrollY) + { + f32 thumbRatioY = panel->rect.h / contentsH; + f32 sliderY = panel->scroll.y / (contentsH - panel->rect.h); + + f32 spacerSize = needsScrollX ? 10 : 0; + + oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PIXELS, 10, 0 }, + .size.height = { OC_UI_SIZE_PARENT_MINUS_PIXELS, spacerSize, 0 }, + .floating.x = true, + .floating.y = true, + .floatTarget = { panel->rect.w - 10, 0 } }, + OC_UI_STYLE_SIZE + | OC_UI_STYLE_FLOAT); + + scrollBarY = oc_ui_slider("scrollerY", thumbRatioY, &sliderY); + + panel->scroll.y = sliderY * (contentsH - panel->rect.h); + if(sig.hovering) + { + oc_ui_box_activate(scrollBarY); + } + } + panel->scroll.x = oc_clamp(panel->scroll.x, 0, contentsW - panel->rect.w); + panel->scroll.y = oc_clamp(panel->scroll.y, 0, contentsH - panel->rect.h); + + oc_ui_box_end(); +} + +//------------------------------------------------------------------------------ +// tooltips +//------------------------------------------------------------------------------ + +oc_ui_sig oc_ui_tooltip_begin(const char* name) +{ + oc_ui_context* ui = oc_ui_get_context(); + + oc_vec2 p = oc_ui_mouse_position(); + + oc_ui_style style = { .size.width = { OC_UI_SIZE_CHILDREN }, + .size.height = { OC_UI_SIZE_CHILDREN }, + .floating.x = true, + .floating.y = true, + .floatTarget = { p.x, p.y } }; + oc_ui_style_mask mask = OC_UI_STYLE_SIZE | OC_UI_STYLE_FLOAT; + + oc_ui_style_next(&style, mask); + + oc_ui_flags flags = OC_UI_FLAG_OVERLAY + | OC_UI_FLAG_DRAW_BACKGROUND + | OC_UI_FLAG_DRAW_BORDER; + + oc_ui_box* tooltip = oc_ui_box_make(name, flags); + oc_ui_box_push(tooltip); + + return (oc_ui_box_sig(tooltip)); +} + +void oc_ui_tooltip_end(void) +{ + oc_ui_box_pop(); // tooltip +} + +//------------------------------------------------------------------------------ +// Menus +//------------------------------------------------------------------------------ + +void oc_ui_menu_bar_begin(const char* name) +{ + oc_ui_style style = { + .size.width = { OC_UI_SIZE_PARENT, 1, 0 }, + .size.height = { OC_UI_SIZE_CHILDREN }, + .layout.axis = OC_UI_AXIS_X, + .layout.spacing = 20, + }; + oc_ui_style_mask mask = OC_UI_STYLE_SIZE + | OC_UI_STYLE_LAYOUT_AXIS + | OC_UI_STYLE_LAYOUT_SPACING; + + oc_ui_style_next(&style, mask); + oc_ui_box* bar = oc_ui_box_begin(name, OC_UI_FLAG_DRAW_BACKGROUND); + + oc_ui_sig sig = oc_ui_box_sig(bar); + oc_ui_context* ui = oc_ui_get_context(); + if(!sig.hovering && oc_mouse_released(&ui->input, OC_MOUSE_LEFT)) + { + oc_ui_box_deactivate(bar); + } +} + +void oc_ui_menu_bar_end(void) +{ + oc_ui_box_end(); // menu bar +} + +void oc_ui_menu_begin(const char* label) +{ + oc_ui_box* container = oc_ui_box_make(label, 0); + oc_ui_box_push(container); + + oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_TEXT }, + .size.height = { OC_UI_SIZE_TEXT } }, + OC_UI_STYLE_SIZE); + + oc_ui_box* button = oc_ui_box_make(label, OC_UI_FLAG_CLICKABLE | OC_UI_FLAG_DRAW_TEXT); + oc_ui_box* bar = container->parent; + + oc_ui_sig sig = oc_ui_box_sig(button); + oc_ui_sig barSig = oc_ui_box_sig(bar); + + oc_ui_context* ui = oc_ui_get_context(); + + oc_ui_style style = { .size.width = { OC_UI_SIZE_CHILDREN }, + .size.height = { OC_UI_SIZE_CHILDREN }, + .floating.x = true, + .floating.y = true, + .floatTarget = { button->rect.x, + button->rect.y + button->rect.h }, + .layout.axis = OC_UI_AXIS_Y, + .layout.spacing = 5, + .layout.margin.x = 0, + .layout.margin.y = 5, + .bgColor = { 0.2, 0.2, 0.2, 1 } }; + + oc_ui_style_mask mask = OC_UI_STYLE_SIZE + | OC_UI_STYLE_FLOAT + | OC_UI_STYLE_LAYOUT + | OC_UI_STYLE_BG_COLOR; + + oc_ui_flags flags = OC_UI_FLAG_OVERLAY + | OC_UI_FLAG_DRAW_BACKGROUND + | OC_UI_FLAG_DRAW_BORDER; + + oc_ui_style_next(&style, mask); + oc_ui_box* menu = oc_ui_box_make("panel", flags); + + if(oc_ui_box_active(bar)) + { + if(sig.hovering) + { + oc_ui_box_activate(button); + } + else if(barSig.hovering) + { + oc_ui_box_deactivate(button); + } + } + else + { + oc_ui_box_deactivate(button); + if(sig.pressed) + { + oc_ui_box_activate(bar); + oc_ui_box_activate(button); + } + } + + oc_ui_box_set_closed(menu, !oc_ui_box_active(button)); + oc_ui_box_push(menu); +} + +void oc_ui_menu_end(void) +{ + oc_ui_box_pop(); // menu + oc_ui_box_pop(); // container +} + +oc_ui_sig oc_ui_menu_button(const char* name) +{ + oc_ui_context* ui = oc_ui_get_context(); + + oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_TEXT }, + .size.height = { OC_UI_SIZE_TEXT }, + .layout.margin.x = 5, + .bgColor = { 0, 0, 0, 0 } }, + OC_UI_STYLE_SIZE + | OC_UI_STYLE_LAYOUT_MARGIN_X + | OC_UI_STYLE_BG_COLOR); + + oc_ui_pattern pattern = { 0 }; + oc_ui_pattern_push(&ui->frameArena, &pattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_HOVER }); + + oc_ui_style style = { .bgColor = { 0, 0, 1, 1 } }; + oc_ui_style_mask mask = OC_UI_STYLE_BG_COLOR; + oc_ui_style_match_before(pattern, &style, mask); + + oc_ui_flags flags = OC_UI_FLAG_CLICKABLE + | OC_UI_FLAG_CLIP + | OC_UI_FLAG_DRAW_TEXT + | OC_UI_FLAG_DRAW_BACKGROUND; + + oc_ui_box* box = oc_ui_box_make(name, flags); + oc_ui_sig sig = oc_ui_box_sig(box); + return (sig); +} + +void oc_ui_select_popup_draw_arrow(oc_ui_box* box, void* data) +{ + f32 r = oc_min(box->parent->style.roundness, box->rect.w); + f32 cr = r * 4 * (sqrt(2) - 1) / 3; + + oc_move_to(box->rect.x, box->rect.y); + oc_line_to(box->rect.x + box->rect.w - r, box->rect.y); + oc_cubic_to(box->rect.x + box->rect.w - cr, box->rect.y, + box->rect.x + box->rect.w, box->rect.y + cr, + box->rect.x + box->rect.w, box->rect.y + r); + oc_line_to(box->rect.x + box->rect.w, box->rect.y + box->rect.h - r); + oc_cubic_to(box->rect.x + box->rect.w, box->rect.y + box->rect.h - cr, + box->rect.x + box->rect.w - cr, box->rect.y + box->rect.h, + box->rect.x + box->rect.w - r, box->rect.y + box->rect.h); + oc_line_to(box->rect.x, box->rect.y + box->rect.h); + + oc_set_color(box->style.bgColor); + oc_fill(); + + oc_move_to(box->rect.x + 0.25 * box->rect.w, box->rect.y + 0.45 * box->rect.h); + oc_line_to(box->rect.x + 0.5 * box->rect.w, box->rect.y + 0.75 * box->rect.h); + oc_line_to(box->rect.x + 0.75 * box->rect.w, box->rect.y + 0.45 * box->rect.h); + oc_close_path(); + + oc_set_color(box->style.color); + oc_fill(); +} + +oc_ui_select_popup_info oc_ui_select_popup(const char* name, oc_ui_select_popup_info* info) +{ + oc_ui_select_popup_info result = *info; + + oc_ui_context* ui = oc_ui_get_context(); + + oc_ui_container(name, 0) + { + oc_ui_box* button = oc_ui_box_make("button", + OC_UI_FLAG_CLICKABLE + | OC_UI_FLAG_DRAW_BACKGROUND + | OC_UI_FLAG_DRAW_BORDER + | OC_UI_FLAG_ALLOW_OVERFLOW_X + | OC_UI_FLAG_CLIP); + + f32 maxOptionWidth = 0; + f32 lineHeight = 0; + oc_rect bbox = { 0 }; + for(int i = 0; i < info->optionCount; i++) + { + bbox = oc_text_bounding_box(button->style.font, button->style.fontSize, info->options[i]); + maxOptionWidth = oc_max(maxOptionWidth, bbox.w); + } + f32 buttonWidth = maxOptionWidth + 2 * button->style.layout.margin.x + button->rect.h; + + oc_ui_style_box_before(button, + oc_ui_pattern_owner(), + &(oc_ui_style){ .size.width = { OC_UI_SIZE_PIXELS, buttonWidth }, + .size.height = { OC_UI_SIZE_CHILDREN }, + .layout.margin.x = 5, + .layout.margin.y = 1, + .roundness = 5, + .borderSize = 1, + .borderColor = { 0.3, 0.3, 0.3, 1 } }, + OC_UI_STYLE_SIZE + | OC_UI_STYLE_LAYOUT_MARGIN_X + | OC_UI_STYLE_LAYOUT_MARGIN_Y + | OC_UI_STYLE_ROUNDNESS + | OC_UI_STYLE_BORDER_SIZE + | OC_UI_STYLE_BORDER_COLOR); + oc_ui_box_push(button); + { + oc_ui_label_str8(info->options[info->selectedIndex]); + + oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PIXELS, button->rect.h }, + .size.height = { OC_UI_SIZE_PIXELS, button->rect.h }, + .floating.x = true, + .floating.y = true, + .floatTarget = { button->rect.w - button->rect.h, 0 }, + .color = { 0, 0, 0, 1 }, + .bgColor = { 0.7, 0.7, 0.7, 1 } }, + OC_UI_STYLE_SIZE + | OC_UI_STYLE_FLOAT + | OC_UI_STYLE_COLOR + | OC_UI_STYLE_BG_COLOR); + + oc_ui_box* arrow = oc_ui_box_make("arrow", OC_UI_FLAG_DRAW_PROC); + oc_ui_box_set_draw_proc(arrow, oc_ui_select_popup_draw_arrow, 0); + } + oc_ui_box_pop(); + + //panel + oc_ui_box* panel = oc_ui_box_make("panel", + OC_UI_FLAG_DRAW_BACKGROUND + | OC_UI_FLAG_BLOCK_MOUSE + | OC_UI_FLAG_OVERLAY); + + //TODO: set width to max(button.w, max child...) + f32 containerWidth = oc_max(maxOptionWidth + 2 * panel->style.layout.margin.x, + button->rect.w); + + oc_ui_style_box_before(panel, + oc_ui_pattern_owner(), + &(oc_ui_style){ .size.width = { OC_UI_SIZE_PIXELS, containerWidth }, + .size.height = { OC_UI_SIZE_CHILDREN }, + .floating.x = true, + .floating.y = true, + .floatTarget = { button->rect.x, + button->rect.y + button->rect.h }, + .layout.axis = OC_UI_AXIS_Y, + .layout.margin.x = 0, + .layout.margin.y = 5, + .bgColor = { 0.2, 0.2, 0.2, 1 } }, + OC_UI_STYLE_SIZE + | OC_UI_STYLE_FLOAT + | OC_UI_STYLE_LAYOUT + | OC_UI_STYLE_BG_COLOR); + + oc_ui_box_push(panel); + { + for(int i = 0; i < info->optionCount; i++) + { + oc_ui_style_next(&(oc_ui_style){ .size.width = { OC_UI_SIZE_PARENT, 1 }, + .size.height = { OC_UI_SIZE_TEXT }, + .layout.axis = OC_UI_AXIS_Y, + .layout.align.x = OC_UI_ALIGN_START, + .layout.margin.x = 5, + .layout.margin.y = 2.5 }, + OC_UI_STYLE_SIZE + | OC_UI_STYLE_LAYOUT_AXIS + | OC_UI_STYLE_LAYOUT_ALIGN_X + | OC_UI_STYLE_LAYOUT_MARGIN_X + | OC_UI_STYLE_LAYOUT_MARGIN_Y); + + oc_ui_pattern pattern = { 0 }; + oc_ui_pattern_push(&ui->frameArena, &pattern, (oc_ui_selector){ .kind = OC_UI_SEL_STATUS, .status = OC_UI_HOVER }); + oc_ui_style_match_before(pattern, &(oc_ui_style){ .bgColor = { 0, 0, 1, 1 } }, OC_UI_STYLE_BG_COLOR); + + oc_ui_box* box = oc_ui_box_make_str8(info->options[i], + OC_UI_FLAG_DRAW_TEXT + | OC_UI_FLAG_CLICKABLE + | OC_UI_FLAG_DRAW_BACKGROUND); + oc_ui_sig sig = oc_ui_box_sig(box); + if(sig.pressed) + { + result.selectedIndex = i; + } + } + } + oc_ui_box_pop(); + + oc_ui_context* ui = oc_ui_get_context(); + if(oc_ui_box_active(panel) && oc_mouse_pressed(&ui->input, OC_MOUSE_LEFT)) + { + oc_ui_box_deactivate(panel); + } + else if(oc_ui_box_sig(button).pressed) + { + oc_ui_box_activate(panel); + } + oc_ui_box_set_closed(panel, !oc_ui_box_active(panel)); + } + return (result); +} + +//------------------------------------------------------------------------------ +// text box +//------------------------------------------------------------------------------ +oc_str32 oc_ui_edit_replace_selection_with_codepoints(oc_ui_context* ui, oc_str32 codepoints, oc_str32 input) +{ + u32 start = oc_min(ui->editCursor, ui->editMark); + u32 end = oc_max(ui->editCursor, ui->editMark); + + oc_str32 before = oc_str32_slice(codepoints, 0, start); + oc_str32 after = oc_str32_slice(codepoints, end, codepoints.len); + + oc_str32_list list = { 0 }; + oc_str32_list_push(&ui->frameArena, &list, before); + oc_str32_list_push(&ui->frameArena, &list, input); + oc_str32_list_push(&ui->frameArena, &list, after); + + codepoints = oc_str32_list_join(&ui->frameArena, list); + + ui->editCursor = start + input.len; + ui->editMark = ui->editCursor; + return (codepoints); +} + +oc_str32 oc_ui_edit_delete_selection(oc_ui_context* ui, oc_str32 codepoints) +{ + return (oc_ui_edit_replace_selection_with_codepoints(ui, codepoints, (oc_str32){ 0 })); +} + +void oc_ui_edit_copy_selection_to_clipboard(oc_ui_context* ui, oc_str32 codepoints) +{ +#if !OC_PLATFORM_ORCA + if(ui->editCursor == ui->editMark) + { + return; + } + u32 start = oc_min(ui->editCursor, ui->editMark); + u32 end = oc_max(ui->editCursor, ui->editMark); + oc_str32 selection = oc_str32_slice(codepoints, start, end); + oc_str8 string = oc_utf8_push_from_codepoints(&ui->frameArena, selection); + + oc_clipboard_clear(); + oc_clipboard_set_string(string); +#endif +} + +oc_str32 oc_ui_edit_replace_selection_with_clipboard(oc_ui_context* ui, oc_str32 codepoints) +{ +#if OC_PLATFORM_ORCA + oc_str32 result = { 0 }; +#else + oc_str8 string = oc_clipboard_get_string(&ui->frameArena); + oc_str32 input = oc_utf8_push_to_codepoints(&ui->frameArena, string); + oc_str32 result = oc_ui_edit_replace_selection_with_codepoints(ui, codepoints, input); +#endif + return (result); +} + +typedef enum +{ + OC_UI_EDIT_MOVE, + OC_UI_EDIT_SELECT, + OC_UI_EDIT_SELECT_EXTEND, + OC_UI_EDIT_DELETE, + OC_UI_EDIT_CUT, + OC_UI_EDIT_COPY, + OC_UI_EDIT_PASTE, + OC_UI_EDIT_SELECT_ALL +} oc_ui_edit_op; + +typedef enum +{ + OC_UI_EDIT_MOVE_NONE = 0, + OC_UI_EDIT_MOVE_ONE, + OC_UI_EDIT_MOVE_WORD, + OC_UI_EDIT_MOVE_LINE +} oc_ui_edit_move; + +typedef struct oc_ui_edit_command +{ + oc_key_code key; + oc_keymod_flags mods; + + oc_ui_edit_op operation; + oc_ui_edit_move move; + int direction; + +} oc_ui_edit_command; + +const oc_ui_edit_command OC_UI_EDIT_COMMANDS[] = { + //NOTE(martin): move one left + { + .key = OC_KEY_LEFT, + .operation = OC_UI_EDIT_MOVE, + .move = OC_UI_EDIT_MOVE_ONE, + .direction = -1 }, + //NOTE(martin): move one right + { + .key = OC_KEY_RIGHT, + .operation = OC_UI_EDIT_MOVE, + .move = OC_UI_EDIT_MOVE_ONE, + .direction = 1 }, + //NOTE(martin): move start + { + .key = OC_KEY_Q, + .mods = OC_KEYMOD_CTRL, + .operation = OC_UI_EDIT_MOVE, + .move = OC_UI_EDIT_MOVE_LINE, + .direction = -1 }, + { .key = OC_KEY_UP, + .operation = OC_UI_EDIT_MOVE, + .move = OC_UI_EDIT_MOVE_LINE, + .direction = -1 }, + //NOTE(martin): move end + { + .key = OC_KEY_E, + .mods = OC_KEYMOD_CTRL, + .operation = OC_UI_EDIT_MOVE, + .move = OC_UI_EDIT_MOVE_LINE, + .direction = 1 }, + { .key = OC_KEY_DOWN, + .operation = OC_UI_EDIT_MOVE, + .move = OC_UI_EDIT_MOVE_LINE, + .direction = 1 }, + //NOTE(martin): select one left + { + .key = OC_KEY_LEFT, + .mods = OC_KEYMOD_SHIFT, + .operation = OC_UI_EDIT_SELECT, + .move = OC_UI_EDIT_MOVE_ONE, + .direction = -1 }, + //NOTE(martin): select one right + { + .key = OC_KEY_RIGHT, + .mods = OC_KEYMOD_SHIFT, + .operation = OC_UI_EDIT_SELECT, + .move = OC_UI_EDIT_MOVE_ONE, + .direction = 1 }, + //NOTE(martin): extend select to start + { + .key = OC_KEY_Q, + .mods = OC_KEYMOD_CTRL | OC_KEYMOD_SHIFT, + .operation = OC_UI_EDIT_SELECT_EXTEND, + .move = OC_UI_EDIT_MOVE_LINE, + .direction = -1 }, + { .key = OC_KEY_UP, + .mods = OC_KEYMOD_SHIFT, + .operation = OC_UI_EDIT_SELECT_EXTEND, + .move = OC_UI_EDIT_MOVE_LINE, + .direction = -1 }, + //NOTE(martin): extend select to end + { + .key = OC_KEY_E, + .mods = OC_KEYMOD_CTRL | OC_KEYMOD_SHIFT, + .operation = OC_UI_EDIT_SELECT_EXTEND, + .move = OC_UI_EDIT_MOVE_LINE, + .direction = 1 }, + { .key = OC_KEY_DOWN, + .mods = OC_KEYMOD_SHIFT, + .operation = OC_UI_EDIT_SELECT_EXTEND, + .move = OC_UI_EDIT_MOVE_LINE, + .direction = 1 }, + //NOTE(martin): select all + { + .key = OC_KEY_Q, + .mods = OC_KEYMOD_MAIN_MODIFIER, + .operation = OC_UI_EDIT_SELECT_ALL, + .move = OC_UI_EDIT_MOVE_NONE }, + //NOTE(martin): delete + { + .key = OC_KEY_DELETE, + .operation = OC_UI_EDIT_DELETE, + .move = OC_UI_EDIT_MOVE_ONE, + .direction = 1 }, + //NOTE(martin): backspace + { + .key = OC_KEY_BACKSPACE, + .operation = OC_UI_EDIT_DELETE, + .move = OC_UI_EDIT_MOVE_ONE, + .direction = -1 }, + //NOTE(martin): cut + { + .key = OC_KEY_X, + .mods = OC_KEYMOD_MAIN_MODIFIER, + .operation = OC_UI_EDIT_CUT, + .move = OC_UI_EDIT_MOVE_NONE }, + //NOTE(martin): copy + { + .key = OC_KEY_C, + .mods = OC_KEYMOD_MAIN_MODIFIER, + .operation = OC_UI_EDIT_COPY, + .move = OC_UI_EDIT_MOVE_NONE }, + //NOTE(martin): paste + { + .key = OC_KEY_V, + .mods = OC_KEYMOD_MAIN_MODIFIER, + .operation = OC_UI_EDIT_PASTE, + .move = OC_UI_EDIT_MOVE_NONE } +}; + +const u32 OC_UI_EDIT_COMMAND_COUNT = sizeof(OC_UI_EDIT_COMMANDS) / sizeof(oc_ui_edit_command); + +void oc_ui_edit_perform_move(oc_ui_context* ui, oc_ui_edit_move move, int direction, u32 textLen) +{ + switch(move) + { + case OC_UI_EDIT_MOVE_NONE: + break; + + case OC_UI_EDIT_MOVE_ONE: + { + if(direction < 0 && ui->editCursor > 0) + { + ui->editCursor--; + } + else if(direction > 0 && ui->editCursor < textLen) + { + ui->editCursor++; + } + } + break; + + case OC_UI_EDIT_MOVE_LINE: + { + if(direction < 0) + { + ui->editCursor = 0; + } + else if(direction > 0) + { + ui->editCursor = textLen; + } + } + break; + + case OC_UI_EDIT_MOVE_WORD: + OC_DEBUG_ASSERT(0, "not implemented yet"); + break; + } +} + +oc_str32 oc_ui_edit_perform_operation(oc_ui_context* ui, oc_ui_edit_op operation, oc_ui_edit_move move, int direction, oc_str32 codepoints) +{ + switch(operation) + { + case OC_UI_EDIT_MOVE: + { + //NOTE(martin): we place the cursor on the direction-most side of the selection + // before performing the move + u32 cursor = direction < 0 ? oc_min(ui->editCursor, ui->editMark) : oc_max(ui->editCursor, ui->editMark); + ui->editCursor = cursor; + + if(ui->editCursor == ui->editMark || move != OC_UI_EDIT_MOVE_ONE) + { + //NOTE: we special case move-one when there is a selection + // (just place the cursor at begining/end of selection) + oc_ui_edit_perform_move(ui, move, direction, codepoints.len); + } + ui->editMark = ui->editCursor; + } + break; + + case OC_UI_EDIT_SELECT: + { + oc_ui_edit_perform_move(ui, move, direction, codepoints.len); + } + break; + + case OC_UI_EDIT_SELECT_EXTEND: + { + if((direction > 0) != (ui->editCursor > ui->editMark)) + { + u32 tmp = ui->editCursor; + ui->editCursor = ui->editMark; + ui->editMark = tmp; + } + oc_ui_edit_perform_move(ui, move, direction, codepoints.len); + } + break; + + case OC_UI_EDIT_DELETE: + { + if(ui->editCursor == ui->editMark) + { + oc_ui_edit_perform_move(ui, move, direction, codepoints.len); + } + codepoints = oc_ui_edit_delete_selection(ui, codepoints); + ui->editMark = ui->editCursor; + } + break; + + case OC_UI_EDIT_CUT: + { + oc_ui_edit_copy_selection_to_clipboard(ui, codepoints); + codepoints = oc_ui_edit_delete_selection(ui, codepoints); + } + break; + + case OC_UI_EDIT_COPY: + { + oc_ui_edit_copy_selection_to_clipboard(ui, codepoints); + } + break; + + case OC_UI_EDIT_PASTE: + { + codepoints = oc_ui_edit_replace_selection_with_clipboard(ui, codepoints); + } + break; + + case OC_UI_EDIT_SELECT_ALL: + { + ui->editCursor = 0; + ui->editMark = codepoints.len; + } + break; + } + ui->editCursorBlinkStart = ui->frameTime; + + return (codepoints); +} + +void oc_ui_text_box_render(oc_ui_box* box, void* data) +{ + oc_str32 codepoints = *(oc_str32*)data; + oc_ui_context* ui = oc_ui_get_context(); + + u32 firstDisplayedChar = 0; + if(oc_ui_box_active(box)) + { + firstDisplayedChar = ui->editFirstDisplayedChar; + } + + oc_ui_style* style = &box->style; + oc_font_extents extents = oc_font_get_scaled_extents(style->font, style->fontSize); + f32 lineHeight = extents.ascent + extents.descent; + + oc_str32 before = oc_str32_slice(codepoints, 0, firstDisplayedChar); + oc_rect beforeBox = oc_text_bounding_box_utf32(style->font, style->fontSize, before); + + f32 textMargin = 5; //TODO: make that configurable + + f32 textX = textMargin + box->rect.x - beforeBox.w; + f32 textTop = box->rect.y + 0.5 * (box->rect.h - lineHeight); + f32 textY = textTop + extents.ascent; + + if(box->active) + { + u32 selectStart = oc_min(ui->editCursor, ui->editMark); + u32 selectEnd = oc_max(ui->editCursor, ui->editMark); + + oc_str32 beforeSelect = oc_str32_slice(codepoints, 0, selectStart); + oc_rect beforeSelectBox = oc_text_bounding_box_utf32(style->font, style->fontSize, beforeSelect); + beforeSelectBox.x += textX; + beforeSelectBox.y += textY; + + if(selectStart != selectEnd) + { + oc_str32 select = oc_str32_slice(codepoints, selectStart, selectEnd); + oc_str32 afterSelect = oc_str32_slice(codepoints, selectEnd, codepoints.len); + oc_rect selectBox = oc_text_bounding_box_utf32(style->font, style->fontSize, select); + oc_rect afterSelectBox = oc_text_bounding_box_utf32(style->font, style->fontSize, afterSelect); + + selectBox.x += beforeSelectBox.x + beforeSelectBox.w; + selectBox.y += textY; + + oc_set_color_rgba(0, 0, 1, 1); + oc_rectangle_fill(selectBox.x, selectBox.y, selectBox.w, lineHeight); + + oc_set_font(style->font); + oc_set_font_size(style->fontSize); + oc_set_color(style->color); + + oc_move_to(textX, textY); + oc_codepoints_outlines(beforeSelect); + oc_fill(); + + oc_set_color_rgba(1, 1, 1, 1); + oc_codepoints_outlines(select); + oc_fill(); + + oc_set_color(style->color); + oc_codepoints_outlines(afterSelect); + oc_fill(); + } + else + { + if(!((u64)(2 * (ui->frameTime - ui->editCursorBlinkStart)) & 1)) + { + f32 caretX = box->rect.x + textMargin - beforeBox.w + beforeSelectBox.w; + f32 caretY = textTop; + oc_set_color(style->color); + oc_rectangle_fill(caretX, caretY, 1, lineHeight); + } + oc_set_font(style->font); + oc_set_font_size(style->fontSize); + oc_set_color(style->color); + + oc_move_to(textX, textY); + oc_codepoints_outlines(codepoints); + oc_fill(); + } + } + else + { + oc_set_font(style->font); + oc_set_font_size(style->fontSize); + oc_set_color(style->color); + + oc_move_to(textX, textY); + oc_codepoints_outlines(codepoints); + oc_fill(); + } +} + +oc_ui_text_box_result oc_ui_text_box(const char* name, oc_arena* arena, oc_str8 text) +{ + oc_ui_context* ui = oc_ui_get_context(); + + oc_ui_text_box_result result = { .text = text }; + + oc_ui_flags frameFlags = OC_UI_FLAG_CLICKABLE + | OC_UI_FLAG_DRAW_BACKGROUND + | OC_UI_FLAG_DRAW_BORDER + | OC_UI_FLAG_CLIP + | OC_UI_FLAG_DRAW_PROC; + + oc_ui_box* frame = oc_ui_box_make(name, frameFlags); + oc_ui_style* style = &frame->style; + f32 textMargin = 5; //TODO parameterize this margin! must be the same as in oc_ui_text_box_render + + oc_font_extents extents = oc_font_get_scaled_extents(style->font, style->fontSize); + + oc_ui_sig sig = oc_ui_box_sig(frame); + + if(sig.pressed) + { + if(!oc_ui_box_active(frame)) + { + oc_ui_box_activate(frame); + + //NOTE: focus + ui->focus = frame; + ui->editFirstDisplayedChar = 0; + ui->editCursor = 0; + ui->editMark = 0; + } + ui->editCursorBlinkStart = ui->frameTime; + } + + if(sig.pressed || sig.dragging) + { + //NOTE: set cursor/extend selection on mouse press or drag + oc_vec2 pos = oc_ui_mouse_position(); + f32 cursorX = pos.x - frame->rect.x - textMargin; + + oc_str32 codepoints = oc_utf8_push_to_codepoints(&ui->frameArena, text); + i32 newCursor = codepoints.len; + f32 x = 0; + for(int i = ui->editFirstDisplayedChar; i < codepoints.len; i++) + { + oc_rect bbox = oc_text_bounding_box_utf32(style->font, style->fontSize, oc_str32_slice(codepoints, i, i + 1)); + if(x + 0.5 * bbox.w > cursorX) + { + newCursor = i; + break; + } + x += bbox.w; + } + //NOTE: put cursor the closest to new cursor (this maximizes the resulting selection, + // and seems to be the standard behaviour across a number of text editor) + if(sig.pressed && abs(newCursor - ui->editCursor) > abs(newCursor - ui->editMark)) + { + i32 tmp = ui->editCursor; + ui->editCursor = ui->editMark; + ui->editMark = tmp; + } + //NOTE: set the new cursor, and set or leave the mark depending on mode + ui->editCursor = newCursor; + if(sig.pressed && !(oc_key_mods(&ui->input) & OC_KEYMOD_SHIFT)) + { + ui->editMark = ui->editCursor; + } + } + + if(sig.hovering) + { + oc_ui_box_set_hot(frame, true); + } + else + { + oc_ui_box_set_hot(frame, false); + + if(oc_mouse_pressed(&ui->input, OC_MOUSE_LEFT) || oc_mouse_pressed(&ui->input, OC_MOUSE_RIGHT) || oc_mouse_pressed(&ui->input, OC_MOUSE_MIDDLE)) + { + if(oc_ui_box_active(frame)) + { + oc_ui_box_deactivate(frame); + + //NOTE loose focus + ui->focus = 0; + } + } + } + + if(oc_ui_box_active(frame)) + { + oc_str32 oldCodepoints = oc_utf8_push_to_codepoints(&ui->frameArena, text); + oc_str32 codepoints = oldCodepoints; + ui->editCursor = oc_clamp(ui->editCursor, 0, codepoints.len); + ui->editMark = oc_clamp(ui->editMark, 0, codepoints.len); + + //NOTE replace selection with input codepoints + oc_str32 input = oc_input_text_utf32(&ui->input, &ui->frameArena); + if(input.len) + { + codepoints = oc_ui_edit_replace_selection_with_codepoints(ui, codepoints, input); + ui->editCursorBlinkStart = ui->frameTime; + } + + //NOTE handle shortcuts + oc_keymod_flags mods = oc_key_mods(&ui->input); + + for(int i = 0; i < OC_UI_EDIT_COMMAND_COUNT; i++) + { + const oc_ui_edit_command* command = &(OC_UI_EDIT_COMMANDS[i]); + + if((oc_key_pressed(&ui->input, command->key) || oc_key_repeated(&ui->input, command->key)) + && mods == command->mods) + { + codepoints = oc_ui_edit_perform_operation(ui, command->operation, command->move, command->direction, codepoints); + break; + } + } + + //NOTE(martin): check changed/accepted + if(oldCodepoints.ptr != codepoints.ptr) + { + result.changed = true; + result.text = oc_utf8_push_from_codepoints(arena, codepoints); + } + + if(oc_key_pressed(&ui->input, OC_KEY_ENTER)) + { + //TODO(martin): extract in gui_edit_complete() (and use below) + result.accepted = true; + oc_ui_box_deactivate(frame); + ui->focus = 0; + } + + //NOTE slide contents + { + if(ui->editCursor < ui->editFirstDisplayedChar) + { + ui->editFirstDisplayedChar = ui->editCursor; + } + else + { + i32 firstDisplayedChar = ui->editFirstDisplayedChar; + oc_str32 firstToCursor = oc_str32_slice(codepoints, firstDisplayedChar, ui->editCursor); + oc_rect firstToCursorBox = oc_text_bounding_box_utf32(style->font, style->fontSize, firstToCursor); + + while(firstToCursorBox.w > (frame->rect.w - 2 * textMargin)) + { + firstDisplayedChar++; + firstToCursor = oc_str32_slice(codepoints, firstDisplayedChar, ui->editCursor); + firstToCursorBox = oc_text_bounding_box_utf32(style->font, style->fontSize, firstToCursor); + } + + ui->editFirstDisplayedChar = firstDisplayedChar; + } + } + + //NOTE: set renderer + oc_str32* renderCodepoints = oc_arena_push_type(&ui->frameArena, oc_str32); + *renderCodepoints = oc_str32_push_copy(&ui->frameArena, codepoints); + oc_ui_box_set_draw_proc(frame, oc_ui_text_box_render, renderCodepoints); + } + else + { + //NOTE: set renderer + oc_str32* renderCodepoints = oc_arena_push_type(&ui->frameArena, oc_str32); + *renderCodepoints = oc_utf8_push_to_codepoints(&ui->frameArena, text); + oc_ui_box_set_draw_proc(frame, oc_ui_text_box_render, renderCodepoints); + } + + return (result); +} diff --git a/src/ui/ui.h b/src/ui/ui.h index 4a24fa6..6fe35af 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -1,550 +1,574 @@ -/************************************************************//** +/************************************************************/ /** * * @file: ui.h * @author: Martin Fouilleul * @date: 08/08/2022 * @revision: * -*****************************************************************/ -#ifndef __UI_H_ -#define __UI_H_ - -#include"util/typedefs.h" -#include"util/lists.h" -#include"input_state.h" -#include"graphics/graphics.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct oc_ui_key -{ - u64 hash; -} oc_ui_key; - -typedef enum -{ - OC_UI_AXIS_X, - OC_UI_AXIS_Y, - OC_UI_AXIS_COUNT -} oc_ui_axis; - -typedef enum -{ - OC_UI_ALIGN_START, - OC_UI_ALIGN_END, - OC_UI_ALIGN_CENTER, -} oc_ui_align; - -typedef union oc_ui_layout_align -{ - struct - { - oc_ui_align x; - oc_ui_align y; - }; - oc_ui_align c[OC_UI_AXIS_COUNT]; -} oc_ui_layout_align; - -typedef struct oc_ui_layout -{ - oc_ui_axis axis; - f32 spacing; - union - { - struct - { - f32 x; - f32 y; - }; - f32 c[OC_UI_AXIS_COUNT]; - } margin; - oc_ui_layout_align align; - -} oc_ui_layout; - -typedef enum oc_ui_size_kind -{ - OC_UI_SIZE_TEXT, - OC_UI_SIZE_PIXELS, - OC_UI_SIZE_CHILDREN, - OC_UI_SIZE_PARENT, - OC_UI_SIZE_PARENT_MINUS_PIXELS, - -} oc_ui_size_kind; - -typedef struct oc_ui_size -{ - oc_ui_size_kind kind; - f32 value; - f32 relax; -} oc_ui_size; - -typedef union oc_ui_box_size -{ - struct - { - oc_ui_size width; - oc_ui_size height; - }; - oc_ui_size c[OC_UI_AXIS_COUNT]; -} oc_ui_box_size; - -typedef union oc_ui_box_floating -{ - struct - { - bool x; - bool y; - }; - bool c[OC_UI_AXIS_COUNT]; -} oc_ui_box_floating; - -//NOTE: flags for axis-dependent properties (e.g. OC_UI_STYLE_FLOAT_X/Y) need to be consecutive bits -// in order to play well with axis agnostic functions -typedef u64 oc_ui_style_mask; -enum -{ - OC_UI_STYLE_NONE = 0, - OC_UI_STYLE_SIZE_WIDTH = 1<<1, - OC_UI_STYLE_SIZE_HEIGHT = 1<<2, - OC_UI_STYLE_LAYOUT_AXIS = 1<<3, - OC_UI_STYLE_LAYOUT_ALIGN_X = 1<<4, - OC_UI_STYLE_LAYOUT_ALIGN_Y = 1<<5, - OC_UI_STYLE_LAYOUT_SPACING = 1<<6, - OC_UI_STYLE_LAYOUT_MARGIN_X = 1<<7, - OC_UI_STYLE_LAYOUT_MARGIN_Y = 1<<8, - OC_UI_STYLE_FLOAT_X = 1<<9, - OC_UI_STYLE_FLOAT_Y = 1<<10, - OC_UI_STYLE_COLOR = 1<<11, - OC_UI_STYLE_BG_COLOR = 1<<12, - OC_UI_STYLE_BORDER_COLOR = 1<<13, - OC_UI_STYLE_BORDER_SIZE = 1<<14, - OC_UI_STYLE_ROUNDNESS = 1<<15, - OC_UI_STYLE_FONT = 1<<16, - OC_UI_STYLE_FONT_SIZE = 1<<17, - OC_UI_STYLE_ANIMATION_TIME = 1<<18, - OC_UI_STYLE_ANIMATION_MASK = 1<<19, - - //masks - OC_UI_STYLE_SIZE = OC_UI_STYLE_SIZE_WIDTH - | OC_UI_STYLE_SIZE_HEIGHT, - - OC_UI_STYLE_LAYOUT_MARGINS = OC_UI_STYLE_LAYOUT_MARGIN_X - | OC_UI_STYLE_LAYOUT_MARGIN_Y, - - OC_UI_STYLE_LAYOUT = OC_UI_STYLE_LAYOUT_AXIS - | OC_UI_STYLE_LAYOUT_ALIGN_X - | OC_UI_STYLE_LAYOUT_ALIGN_Y - | OC_UI_STYLE_LAYOUT_SPACING - | OC_UI_STYLE_LAYOUT_MARGIN_X - | OC_UI_STYLE_LAYOUT_MARGIN_Y, - - OC_UI_STYLE_FLOAT = OC_UI_STYLE_FLOAT_X - | OC_UI_STYLE_FLOAT_Y, - - OC_UI_STYLE_MASK_INHERITED = OC_UI_STYLE_COLOR - | OC_UI_STYLE_FONT - | OC_UI_STYLE_FONT_SIZE - | OC_UI_STYLE_ANIMATION_TIME - | OC_UI_STYLE_ANIMATION_MASK, -}; - -typedef struct oc_ui_style -{ - oc_ui_box_size size; - oc_ui_layout layout; - oc_ui_box_floating floating; - oc_vec2 floatTarget; - oc_color color; - oc_color bgColor; - oc_color borderColor; - oc_font font; - f32 fontSize; - f32 borderSize; - f32 roundness; - f32 animationTime; - oc_ui_style_mask animationMask; -} oc_ui_style; - -typedef struct oc_ui_tag { u64 hash; } oc_ui_tag; - -typedef enum -{ - OC_UI_SEL_ANY, - OC_UI_SEL_OWNER, - OC_UI_SEL_TEXT, - OC_UI_SEL_TAG, - OC_UI_SEL_STATUS, - OC_UI_SEL_KEY, - //... -} oc_ui_selector_kind; - -typedef u8 oc_ui_status; -enum -{ - OC_UI_NONE = 0, - OC_UI_HOVER = 1<<1, - OC_UI_ACTIVE = 1<<2, - OC_UI_DRAGGING = 1<<3, -}; - -typedef enum -{ - OC_UI_SEL_DESCENDANT = 0, - OC_UI_SEL_AND = 1, - //... -} oc_ui_selector_op; - -typedef struct oc_ui_selector -{ - oc_list_elt listElt; - oc_ui_selector_kind kind; - oc_ui_selector_op op; - union - { - oc_str8 text; - oc_ui_key key; - oc_ui_tag tag; - oc_ui_status status; - //... - }; -} oc_ui_selector; - -typedef struct oc_ui_pattern { oc_list l; } oc_ui_pattern; - -typedef struct oc_ui_box oc_ui_box; - -typedef struct oc_ui_style_rule -{ - oc_list_elt boxElt; - oc_list_elt buildElt; - oc_list_elt tmpElt; - - oc_ui_box* owner; - oc_ui_pattern pattern; - oc_ui_style_mask mask; - oc_ui_style* style; -} oc_ui_style_rule; - -typedef struct oc_ui_sig -{ - oc_ui_box* box; - - oc_vec2 mouse; - oc_vec2 delta; - oc_vec2 wheel; - - bool pressed; - bool released; - bool clicked; - bool doubleClicked; - bool rightPressed; - - bool dragging; - bool hovering; - -} oc_ui_sig; - -typedef void(*oc_ui_box_draw_proc)(oc_ui_box* box, void* data); - -typedef enum -{ - OC_UI_FLAG_CLICKABLE = (1<<0), - OC_UI_FLAG_SCROLL_WHEEL_X = (1<<1), - OC_UI_FLAG_SCROLL_WHEEL_Y = (1<<2), - OC_UI_FLAG_BLOCK_MOUSE = (1<<3), - OC_UI_FLAG_HOT_ANIMATION = (1<<4), - OC_UI_FLAG_ACTIVE_ANIMATION = (1<<5), - //WARN: these two following flags need to be kept as consecutive bits to - // play well with axis-agnostic functions - OC_UI_FLAG_ALLOW_OVERFLOW_X = (1<<6), - OC_UI_FLAG_ALLOW_OVERFLOW_Y = (1<<7), - OC_UI_FLAG_CLIP = (1<<8), - OC_UI_FLAG_DRAW_BACKGROUND = (1<<9), - OC_UI_FLAG_DRAW_FOREGROUND = (1<<10), - OC_UI_FLAG_DRAW_BORDER = (1<<11), - OC_UI_FLAG_DRAW_TEXT = (1<<12), - OC_UI_FLAG_DRAW_PROC = (1<<13), - - OC_UI_FLAG_OVERLAY = (1<<14), -} oc_ui_flags; - -struct oc_ui_box -{ - // hierarchy - oc_list_elt listElt; - oc_list children; - oc_ui_box* parent; - - oc_list_elt overlayElt; - - // keying and caching - oc_list_elt bucketElt; - oc_ui_key key; - u64 frameCounter; - - // builder-provided info - oc_ui_flags flags; - oc_str8 string; - oc_list tags; - - oc_ui_box_draw_proc drawProc; - void* drawData; - - // styling - oc_list beforeRules; - oc_list afterRules; - - //oc_ui_style_tag tag; - oc_ui_style* targetStyle; - oc_ui_style style; - u32 z; - - oc_vec2 floatPos; - f32 childrenSum[2]; - f32 spacing[2]; - oc_rect rect; - - // signals - oc_ui_sig* sig; - - // stateful behaviour - bool fresh; - bool closed; - bool parentClosed; - bool dragging; - bool hot; - bool active; - oc_vec2 scroll; - oc_vec2 pressedMouse; - - // animation data - f32 hotTransition; - f32 activeTransition; -}; - -//----------------------------------------------------------------------------- -// context -//----------------------------------------------------------------------------- - -enum { OC_UI_MAX_INPUT_CHAR_PER_FRAME = 64 }; - -typedef struct oc_ui_input_text -{ - u8 count; - oc_utf32 codePoints[OC_UI_MAX_INPUT_CHAR_PER_FRAME]; - -} oc_ui_input_text; - -typedef struct oc_ui_stack_elt oc_ui_stack_elt; -struct oc_ui_stack_elt -{ - oc_ui_stack_elt* parent; - union - { - oc_ui_box* box; - oc_ui_size size; - oc_rect clip; - }; -}; - -typedef struct oc_ui_tag_elt -{ - oc_list_elt listElt; - oc_ui_tag tag; -} oc_ui_tag_elt; - -enum { OC_UI_BOX_MAP_BUCKET_COUNT = 1024 }; - -typedef struct oc_ui_context -{ - bool init; - - oc_input_state input; - - u64 frameCounter; - f64 frameTime; - f64 lastFrameDuration; - - oc_arena frameArena; - oc_pool boxPool; - oc_list boxMap[OC_UI_BOX_MAP_BUCKET_COUNT]; - - oc_ui_box* root; - oc_ui_box* overlay; - oc_list overlayList; - oc_ui_stack_elt* boxStack; - oc_ui_stack_elt* clipStack; - - oc_list nextBoxBeforeRules; - oc_list nextBoxAfterRules; - oc_list nextBoxTags; - - u32 z; - oc_ui_box* hovered; - - oc_ui_box* focus; - i32 editCursor; - i32 editMark; - i32 editFirstDisplayedChar; - f64 editCursorBlinkStart; - -} oc_ui_context; - -//------------------------------------------------------------------------------------- -// UI context initialization and frame cycle -//------------------------------------------------------------------------------------- -ORCA_API void oc_ui_init(oc_ui_context* context); -ORCA_API oc_ui_context* oc_ui_get_context(void); -ORCA_API void oc_ui_set_context(oc_ui_context* context); - -ORCA_API void oc_ui_process_event(oc_event* event); -ORCA_API void oc_ui_begin_frame(oc_vec2 size, oc_ui_style* defaultStyle, oc_ui_style_mask mask); -ORCA_API void oc_ui_end_frame(void); -ORCA_API void oc_ui_draw(void); - -#define oc_ui_frame(size, style, mask) oc_defer_loop(oc_ui_begin_frame((size), (style), (mask)), oc_ui_end_frame()) - -//------------------------------------------------------------------------------------- -// Box keys -//------------------------------------------------------------------------------------- -ORCA_API oc_ui_key oc_ui_key_make_str8(oc_str8 string); -ORCA_API oc_ui_key oc_ui_key_make_path(oc_str8_list path); - -ORCA_API oc_ui_box* oc_ui_box_lookup_key(oc_ui_key key); -ORCA_API oc_ui_box* oc_ui_box_lookup_str8(oc_str8 string); - -// C-string helper -#define oc_ui_key_make(s) oc_ui_key_make_str8(OC_STR8(s)) -#define oc_ui_box_lookup(s) oc_ui_box_lookup_str8(OC_STR8(s)) - -//------------------------------------------------------------------------------------- -// Box hierarchy building -//------------------------------------------------------------------------------------- -ORCA_API oc_ui_box* oc_ui_box_make_str8(oc_str8 string, oc_ui_flags flags); -ORCA_API oc_ui_box* oc_ui_box_begin_str8(oc_str8 string, oc_ui_flags flags); - -ORCA_API oc_ui_box* oc_ui_box_end(void); -#define oc_ui_container(name, flags) oc_defer_loop(oc_ui_box_begin(name, flags), oc_ui_box_end()) -#define oc_ui_container_str8(name, flags) oc_defer_loop(oc_ui_box_begin_str8(name, flags), oc_ui_box_end()) - -ORCA_API void oc_ui_box_push(oc_ui_box* box); -ORCA_API void oc_ui_box_pop(void); -ORCA_API oc_ui_box* oc_ui_box_top(void); - -ORCA_API void oc_ui_box_set_draw_proc(oc_ui_box* box, oc_ui_box_draw_proc proc, void* data); - -// C-string helpers -#define oc_ui_box_lookup(s) oc_ui_box_lookup_str8(OC_STR8(s)) -#define oc_ui_box_make(s, flags) oc_ui_box_make_str8(OC_STR8(s), flags) -#define oc_ui_box_begin(s, flags) oc_ui_box_begin_str8(OC_STR8(s), flags) - -//------------------------------------------------------------------------------------- -// Box status and signals -//------------------------------------------------------------------------------------- -ORCA_API bool oc_ui_box_closed(oc_ui_box* box); -ORCA_API void oc_ui_box_set_closed(oc_ui_box* box, bool closed); - -ORCA_API bool oc_ui_box_active(oc_ui_box* box); -ORCA_API void oc_ui_box_activate(oc_ui_box* box); -ORCA_API void oc_ui_box_deactivate(oc_ui_box* box); - -ORCA_API bool oc_ui_box_hot(oc_ui_box* box); -ORCA_API void oc_ui_box_set_hot(oc_ui_box* box, bool hot); - -ORCA_API oc_ui_sig oc_ui_box_sig(oc_ui_box* box); - -//------------------------------------------------------------------------------------- -// Tagging -//------------------------------------------------------------------------------------- -ORCA_API oc_ui_tag oc_ui_tag_make_str8(oc_str8 string); -ORCA_API void oc_ui_tag_box_str8(oc_ui_box* box, oc_str8 string); -ORCA_API void oc_ui_tag_next_str8(oc_str8 string); - -// C-string helpers -#define oc_ui_tag_make(s) oc_ui_tag_make_str8(OC_STR8(s)) -#define oc_ui_tag_box(b, s) oc_ui_tag_box_str8(b, OC_STR8(s)) -#define oc_ui_tag_next(s) oc_ui_tag_next_str8(OC_STR8(s)) - -//------------------------------------------------------------------------------------- -// Styling -//------------------------------------------------------------------------------------- -//NOTE: styling API -//WARN: You can use a pattern in multiple rules, but be aware that a pattern is references an underlying list of selectors, -// hence pushing to a pattern also modifies rules in which the pattern was previously used! -ORCA_API void oc_ui_apply_style_with_mask(oc_ui_style* dst, oc_ui_style* src, oc_ui_style_mask mask); - -ORCA_API void oc_ui_pattern_push(oc_arena* arena, oc_ui_pattern* pattern, oc_ui_selector selector); -ORCA_API oc_ui_pattern oc_ui_pattern_all(void); -ORCA_API oc_ui_pattern oc_ui_pattern_owner(void); - -ORCA_API void oc_ui_style_next(oc_ui_style* style, oc_ui_style_mask mask); -ORCA_API void oc_ui_style_match_before(oc_ui_pattern pattern, oc_ui_style* style, oc_ui_style_mask mask); -ORCA_API void oc_ui_style_match_after(oc_ui_pattern pattern, oc_ui_style* style, oc_ui_style_mask mask); - -//------------------------------------------------------------------------- -// Basic widget helpers -//------------------------------------------------------------------------- -enum { - OC_UI_STYLE_TAG_USER_MAX = 1<<16, - OC_UI_STYLE_TAG_LABEL, - OC_UI_STYLE_TAG_BUTTON, - OC_UI_STYLE_TAG_SCROLLBAR, - OC_UI_STYLE_TAG_PANEL, - OC_UI_STYLE_TAG_TOOLTIP, - OC_UI_STYLE_TAG_MENU -}; - -ORCA_API oc_ui_sig oc_ui_label(const char* label); -ORCA_API oc_ui_sig oc_ui_label_str8(oc_str8 label); - -ORCA_API oc_ui_sig oc_ui_button(const char* label); -ORCA_API oc_ui_sig oc_ui_checkbox(const char* name, bool* checked); -ORCA_API oc_ui_box* oc_ui_slider(const char* label, f32 thumbRatio, f32* scrollValue); - -ORCA_API void oc_ui_panel_begin(const char* name, oc_ui_flags flags); -ORCA_API void oc_ui_panel_end(void); -#define oc_ui_panel(s, f) oc_defer_loop(oc_ui_panel_begin(s, f), oc_ui_panel_end()) - -ORCA_API oc_ui_sig oc_ui_tooltip_begin(const char* name); -ORCA_API void oc_ui_tooltip_end(void); -#define oc_ui_tooltip(name) oc_defer_loop(oc_ui_tooltip_begin(name), oc_ui_tooltip_end()) - -ORCA_API void oc_ui_menu_bar_begin(const char* label); -ORCA_API void oc_ui_menu_bar_end(void); -#define oc_ui_menu_bar(name) oc_defer_loop(oc_ui_menu_bar_begin(name), oc_ui_menu_bar_end()) - -ORCA_API void oc_ui_menu_begin(const char* label); -ORCA_API void oc_ui_menu_end(void); -#define oc_ui_menu(name) oc_defer_loop(oc_ui_menu_begin(name), oc_ui_menu_end()) - -ORCA_API oc_ui_sig oc_ui_menu_button(const char* name); - -typedef struct oc_ui_text_box_result -{ - bool changed; - bool accepted; - oc_str8 text; - -}oc_ui_text_box_result; - -ORCA_API oc_ui_text_box_result oc_ui_text_box(const char* name, oc_arena* arena, oc_str8 text); - - -typedef struct oc_ui_select_popup_info -{ - bool changed; - int selectedIndex; - int optionCount; - oc_str8* options; -} oc_ui_select_popup_info; - -ORCA_API oc_ui_select_popup_info oc_ui_select_popup(const char* name, oc_ui_select_popup_info* info); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif //__UI_H_ +*****************************************************************/ +#ifndef __UI_H_ +#define __UI_H_ + +#include "graphics/graphics.h" +#include "input_state.h" +#include "util/lists.h" +#include "util/typedefs.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + typedef struct oc_ui_key + { + u64 hash; + } oc_ui_key; + + typedef enum + { + OC_UI_AXIS_X, + OC_UI_AXIS_Y, + OC_UI_AXIS_COUNT + } oc_ui_axis; + + typedef enum + { + OC_UI_ALIGN_START, + OC_UI_ALIGN_END, + OC_UI_ALIGN_CENTER, + } oc_ui_align; + + typedef union oc_ui_layout_align + { + struct + { + oc_ui_align x; + oc_ui_align y; + }; + + oc_ui_align c[OC_UI_AXIS_COUNT]; + } oc_ui_layout_align; + + typedef struct oc_ui_layout + { + oc_ui_axis axis; + f32 spacing; + + union + { + struct + { + f32 x; + f32 y; + }; + + f32 c[OC_UI_AXIS_COUNT]; + } margin; + + oc_ui_layout_align align; + + } oc_ui_layout; + + typedef enum oc_ui_size_kind + { + OC_UI_SIZE_TEXT, + OC_UI_SIZE_PIXELS, + OC_UI_SIZE_CHILDREN, + OC_UI_SIZE_PARENT, + OC_UI_SIZE_PARENT_MINUS_PIXELS, + + } oc_ui_size_kind; + + typedef struct oc_ui_size + { + oc_ui_size_kind kind; + f32 value; + f32 relax; + } oc_ui_size; + + typedef union oc_ui_box_size + { + struct + { + oc_ui_size width; + oc_ui_size height; + }; + + oc_ui_size c[OC_UI_AXIS_COUNT]; + } oc_ui_box_size; + + typedef union oc_ui_box_floating + { + struct + { + bool x; + bool y; + }; + + bool c[OC_UI_AXIS_COUNT]; + } oc_ui_box_floating; + + //NOTE: flags for axis-dependent properties (e.g. OC_UI_STYLE_FLOAT_X/Y) need to be consecutive bits + // in order to play well with axis agnostic functions + typedef u64 oc_ui_style_mask; + + enum + { + OC_UI_STYLE_NONE = 0, + OC_UI_STYLE_SIZE_WIDTH = 1 << 1, + OC_UI_STYLE_SIZE_HEIGHT = 1 << 2, + OC_UI_STYLE_LAYOUT_AXIS = 1 << 3, + OC_UI_STYLE_LAYOUT_ALIGN_X = 1 << 4, + OC_UI_STYLE_LAYOUT_ALIGN_Y = 1 << 5, + OC_UI_STYLE_LAYOUT_SPACING = 1 << 6, + OC_UI_STYLE_LAYOUT_MARGIN_X = 1 << 7, + OC_UI_STYLE_LAYOUT_MARGIN_Y = 1 << 8, + OC_UI_STYLE_FLOAT_X = 1 << 9, + OC_UI_STYLE_FLOAT_Y = 1 << 10, + OC_UI_STYLE_COLOR = 1 << 11, + OC_UI_STYLE_BG_COLOR = 1 << 12, + OC_UI_STYLE_BORDER_COLOR = 1 << 13, + OC_UI_STYLE_BORDER_SIZE = 1 << 14, + OC_UI_STYLE_ROUNDNESS = 1 << 15, + OC_UI_STYLE_FONT = 1 << 16, + OC_UI_STYLE_FONT_SIZE = 1 << 17, + OC_UI_STYLE_ANIMATION_TIME = 1 << 18, + OC_UI_STYLE_ANIMATION_MASK = 1 << 19, + + //masks + OC_UI_STYLE_SIZE = OC_UI_STYLE_SIZE_WIDTH + | OC_UI_STYLE_SIZE_HEIGHT, + + OC_UI_STYLE_LAYOUT_MARGINS = OC_UI_STYLE_LAYOUT_MARGIN_X + | OC_UI_STYLE_LAYOUT_MARGIN_Y, + + OC_UI_STYLE_LAYOUT = OC_UI_STYLE_LAYOUT_AXIS + | OC_UI_STYLE_LAYOUT_ALIGN_X + | OC_UI_STYLE_LAYOUT_ALIGN_Y + | OC_UI_STYLE_LAYOUT_SPACING + | OC_UI_STYLE_LAYOUT_MARGIN_X + | OC_UI_STYLE_LAYOUT_MARGIN_Y, + + OC_UI_STYLE_FLOAT = OC_UI_STYLE_FLOAT_X + | OC_UI_STYLE_FLOAT_Y, + + OC_UI_STYLE_MASK_INHERITED = OC_UI_STYLE_COLOR + | OC_UI_STYLE_FONT + | OC_UI_STYLE_FONT_SIZE + | OC_UI_STYLE_ANIMATION_TIME + | OC_UI_STYLE_ANIMATION_MASK, + }; + + typedef struct oc_ui_style + { + oc_ui_box_size size; + oc_ui_layout layout; + oc_ui_box_floating floating; + oc_vec2 floatTarget; + oc_color color; + oc_color bgColor; + oc_color borderColor; + oc_font font; + f32 fontSize; + f32 borderSize; + f32 roundness; + f32 animationTime; + oc_ui_style_mask animationMask; + } oc_ui_style; + + typedef struct oc_ui_tag + { + u64 hash; + } oc_ui_tag; + + typedef enum + { + OC_UI_SEL_ANY, + OC_UI_SEL_OWNER, + OC_UI_SEL_TEXT, + OC_UI_SEL_TAG, + OC_UI_SEL_STATUS, + OC_UI_SEL_KEY, + //... + } oc_ui_selector_kind; + + typedef u8 oc_ui_status; + + enum + { + OC_UI_NONE = 0, + OC_UI_HOVER = 1 << 1, + OC_UI_ACTIVE = 1 << 2, + OC_UI_DRAGGING = 1 << 3, + }; + + typedef enum + { + OC_UI_SEL_DESCENDANT = 0, + OC_UI_SEL_AND = 1, + //... + } oc_ui_selector_op; + + typedef struct oc_ui_selector + { + oc_list_elt listElt; + oc_ui_selector_kind kind; + oc_ui_selector_op op; + + union + { + oc_str8 text; + oc_ui_key key; + oc_ui_tag tag; + oc_ui_status status; + //... + }; + } oc_ui_selector; + + typedef struct oc_ui_pattern + { + oc_list l; + } oc_ui_pattern; + + typedef struct oc_ui_box oc_ui_box; + + typedef struct oc_ui_style_rule + { + oc_list_elt boxElt; + oc_list_elt buildElt; + oc_list_elt tmpElt; + + oc_ui_box* owner; + oc_ui_pattern pattern; + oc_ui_style_mask mask; + oc_ui_style* style; + } oc_ui_style_rule; + + typedef struct oc_ui_sig + { + oc_ui_box* box; + + oc_vec2 mouse; + oc_vec2 delta; + oc_vec2 wheel; + + bool pressed; + bool released; + bool clicked; + bool doubleClicked; + bool rightPressed; + + bool dragging; + bool hovering; + + } oc_ui_sig; + + typedef void (*oc_ui_box_draw_proc)(oc_ui_box* box, void* data); + + typedef enum + { + OC_UI_FLAG_CLICKABLE = (1 << 0), + OC_UI_FLAG_SCROLL_WHEEL_X = (1 << 1), + OC_UI_FLAG_SCROLL_WHEEL_Y = (1 << 2), + OC_UI_FLAG_BLOCK_MOUSE = (1 << 3), + OC_UI_FLAG_HOT_ANIMATION = (1 << 4), + OC_UI_FLAG_ACTIVE_ANIMATION = (1 << 5), + //WARN: these two following flags need to be kept as consecutive bits to + // play well with axis-agnostic functions + OC_UI_FLAG_ALLOW_OVERFLOW_X = (1 << 6), + OC_UI_FLAG_ALLOW_OVERFLOW_Y = (1 << 7), + OC_UI_FLAG_CLIP = (1 << 8), + OC_UI_FLAG_DRAW_BACKGROUND = (1 << 9), + OC_UI_FLAG_DRAW_FOREGROUND = (1 << 10), + OC_UI_FLAG_DRAW_BORDER = (1 << 11), + OC_UI_FLAG_DRAW_TEXT = (1 << 12), + OC_UI_FLAG_DRAW_PROC = (1 << 13), + + OC_UI_FLAG_OVERLAY = (1 << 14), + } oc_ui_flags; + + struct oc_ui_box + { + // hierarchy + oc_list_elt listElt; + oc_list children; + oc_ui_box* parent; + + oc_list_elt overlayElt; + + // keying and caching + oc_list_elt bucketElt; + oc_ui_key key; + u64 frameCounter; + + // builder-provided info + oc_ui_flags flags; + oc_str8 string; + oc_list tags; + + oc_ui_box_draw_proc drawProc; + void* drawData; + + // styling + oc_list beforeRules; + oc_list afterRules; + + //oc_ui_style_tag tag; + oc_ui_style* targetStyle; + oc_ui_style style; + u32 z; + + oc_vec2 floatPos; + f32 childrenSum[2]; + f32 spacing[2]; + oc_rect rect; + + // signals + oc_ui_sig* sig; + + // stateful behaviour + bool fresh; + bool closed; + bool parentClosed; + bool dragging; + bool hot; + bool active; + oc_vec2 scroll; + oc_vec2 pressedMouse; + + // animation data + f32 hotTransition; + f32 activeTransition; + }; + + //----------------------------------------------------------------------------- + // context + //----------------------------------------------------------------------------- + + enum + { + OC_UI_MAX_INPUT_CHAR_PER_FRAME = 64 + }; + + typedef struct oc_ui_input_text + { + u8 count; + oc_utf32 codePoints[OC_UI_MAX_INPUT_CHAR_PER_FRAME]; + + } oc_ui_input_text; + + typedef struct oc_ui_stack_elt oc_ui_stack_elt; + + struct oc_ui_stack_elt + { + oc_ui_stack_elt* parent; + + union + { + oc_ui_box* box; + oc_ui_size size; + oc_rect clip; + }; + }; + + typedef struct oc_ui_tag_elt + { + oc_list_elt listElt; + oc_ui_tag tag; + } oc_ui_tag_elt; + + enum + { + OC_UI_BOX_MAP_BUCKET_COUNT = 1024 + }; + + typedef struct oc_ui_context + { + bool init; + + oc_input_state input; + + u64 frameCounter; + f64 frameTime; + f64 lastFrameDuration; + + oc_arena frameArena; + oc_pool boxPool; + oc_list boxMap[OC_UI_BOX_MAP_BUCKET_COUNT]; + + oc_ui_box* root; + oc_ui_box* overlay; + oc_list overlayList; + oc_ui_stack_elt* boxStack; + oc_ui_stack_elt* clipStack; + + oc_list nextBoxBeforeRules; + oc_list nextBoxAfterRules; + oc_list nextBoxTags; + + u32 z; + oc_ui_box* hovered; + + oc_ui_box* focus; + i32 editCursor; + i32 editMark; + i32 editFirstDisplayedChar; + f64 editCursorBlinkStart; + + } oc_ui_context; + + //------------------------------------------------------------------------------------- + // UI context initialization and frame cycle + //------------------------------------------------------------------------------------- + ORCA_API void oc_ui_init(oc_ui_context* context); + ORCA_API oc_ui_context* oc_ui_get_context(void); + ORCA_API void oc_ui_set_context(oc_ui_context* context); + + ORCA_API void oc_ui_process_event(oc_event* event); + ORCA_API void oc_ui_begin_frame(oc_vec2 size, oc_ui_style* defaultStyle, oc_ui_style_mask mask); + ORCA_API void oc_ui_end_frame(void); + ORCA_API void oc_ui_draw(void); + +#define oc_ui_frame(size, style, mask) oc_defer_loop(oc_ui_begin_frame((size), (style), (mask)), oc_ui_end_frame()) + + //------------------------------------------------------------------------------------- + // Box keys + //------------------------------------------------------------------------------------- + ORCA_API oc_ui_key oc_ui_key_make_str8(oc_str8 string); + ORCA_API oc_ui_key oc_ui_key_make_path(oc_str8_list path); + + ORCA_API oc_ui_box* oc_ui_box_lookup_key(oc_ui_key key); + ORCA_API oc_ui_box* oc_ui_box_lookup_str8(oc_str8 string); + +// C-string helper +#define oc_ui_key_make(s) oc_ui_key_make_str8(OC_STR8(s)) +#define oc_ui_box_lookup(s) oc_ui_box_lookup_str8(OC_STR8(s)) + + //------------------------------------------------------------------------------------- + // Box hierarchy building + //------------------------------------------------------------------------------------- + ORCA_API oc_ui_box* oc_ui_box_make_str8(oc_str8 string, oc_ui_flags flags); + ORCA_API oc_ui_box* oc_ui_box_begin_str8(oc_str8 string, oc_ui_flags flags); + + ORCA_API oc_ui_box* oc_ui_box_end(void); +#define oc_ui_container(name, flags) oc_defer_loop(oc_ui_box_begin(name, flags), oc_ui_box_end()) +#define oc_ui_container_str8(name, flags) oc_defer_loop(oc_ui_box_begin_str8(name, flags), oc_ui_box_end()) + + ORCA_API void oc_ui_box_push(oc_ui_box* box); + ORCA_API void oc_ui_box_pop(void); + ORCA_API oc_ui_box* oc_ui_box_top(void); + + ORCA_API void oc_ui_box_set_draw_proc(oc_ui_box* box, oc_ui_box_draw_proc proc, void* data); + +// C-string helpers +#define oc_ui_box_lookup(s) oc_ui_box_lookup_str8(OC_STR8(s)) +#define oc_ui_box_make(s, flags) oc_ui_box_make_str8(OC_STR8(s), flags) +#define oc_ui_box_begin(s, flags) oc_ui_box_begin_str8(OC_STR8(s), flags) + + //------------------------------------------------------------------------------------- + // Box status and signals + //------------------------------------------------------------------------------------- + ORCA_API bool oc_ui_box_closed(oc_ui_box* box); + ORCA_API void oc_ui_box_set_closed(oc_ui_box* box, bool closed); + + ORCA_API bool oc_ui_box_active(oc_ui_box* box); + ORCA_API void oc_ui_box_activate(oc_ui_box* box); + ORCA_API void oc_ui_box_deactivate(oc_ui_box* box); + + ORCA_API bool oc_ui_box_hot(oc_ui_box* box); + ORCA_API void oc_ui_box_set_hot(oc_ui_box* box, bool hot); + + ORCA_API oc_ui_sig oc_ui_box_sig(oc_ui_box* box); + + //------------------------------------------------------------------------------------- + // Tagging + //------------------------------------------------------------------------------------- + ORCA_API oc_ui_tag oc_ui_tag_make_str8(oc_str8 string); + ORCA_API void oc_ui_tag_box_str8(oc_ui_box* box, oc_str8 string); + ORCA_API void oc_ui_tag_next_str8(oc_str8 string); + +// C-string helpers +#define oc_ui_tag_make(s) oc_ui_tag_make_str8(OC_STR8(s)) +#define oc_ui_tag_box(b, s) oc_ui_tag_box_str8(b, OC_STR8(s)) +#define oc_ui_tag_next(s) oc_ui_tag_next_str8(OC_STR8(s)) + + //------------------------------------------------------------------------------------- + // Styling + //------------------------------------------------------------------------------------- + //NOTE: styling API + //WARN: You can use a pattern in multiple rules, but be aware that a pattern is references an underlying list of selectors, + // hence pushing to a pattern also modifies rules in which the pattern was previously used! + ORCA_API void oc_ui_apply_style_with_mask(oc_ui_style* dst, oc_ui_style* src, oc_ui_style_mask mask); + + ORCA_API void oc_ui_pattern_push(oc_arena* arena, oc_ui_pattern* pattern, oc_ui_selector selector); + ORCA_API oc_ui_pattern oc_ui_pattern_all(void); + ORCA_API oc_ui_pattern oc_ui_pattern_owner(void); + + ORCA_API void oc_ui_style_next(oc_ui_style* style, oc_ui_style_mask mask); + ORCA_API void oc_ui_style_match_before(oc_ui_pattern pattern, oc_ui_style* style, oc_ui_style_mask mask); + ORCA_API void oc_ui_style_match_after(oc_ui_pattern pattern, oc_ui_style* style, oc_ui_style_mask mask); + + //------------------------------------------------------------------------- + // Basic widget helpers + //------------------------------------------------------------------------- + enum + { + OC_UI_STYLE_TAG_USER_MAX = 1 << 16, + OC_UI_STYLE_TAG_LABEL, + OC_UI_STYLE_TAG_BUTTON, + OC_UI_STYLE_TAG_SCROLLBAR, + OC_UI_STYLE_TAG_PANEL, + OC_UI_STYLE_TAG_TOOLTIP, + OC_UI_STYLE_TAG_MENU + }; + + ORCA_API oc_ui_sig oc_ui_label(const char* label); + ORCA_API oc_ui_sig oc_ui_label_str8(oc_str8 label); + + ORCA_API oc_ui_sig oc_ui_button(const char* label); + ORCA_API oc_ui_sig oc_ui_checkbox(const char* name, bool* checked); + ORCA_API oc_ui_box* oc_ui_slider(const char* label, f32 thumbRatio, f32* scrollValue); + + ORCA_API void oc_ui_panel_begin(const char* name, oc_ui_flags flags); + ORCA_API void oc_ui_panel_end(void); +#define oc_ui_panel(s, f) oc_defer_loop(oc_ui_panel_begin(s, f), oc_ui_panel_end()) + + ORCA_API oc_ui_sig oc_ui_tooltip_begin(const char* name); + ORCA_API void oc_ui_tooltip_end(void); +#define oc_ui_tooltip(name) oc_defer_loop(oc_ui_tooltip_begin(name), oc_ui_tooltip_end()) + + ORCA_API void oc_ui_menu_bar_begin(const char* label); + ORCA_API void oc_ui_menu_bar_end(void); +#define oc_ui_menu_bar(name) oc_defer_loop(oc_ui_menu_bar_begin(name), oc_ui_menu_bar_end()) + + ORCA_API void oc_ui_menu_begin(const char* label); + ORCA_API void oc_ui_menu_end(void); +#define oc_ui_menu(name) oc_defer_loop(oc_ui_menu_begin(name), oc_ui_menu_end()) + + ORCA_API oc_ui_sig oc_ui_menu_button(const char* name); + + typedef struct oc_ui_text_box_result + { + bool changed; + bool accepted; + oc_str8 text; + + } oc_ui_text_box_result; + + ORCA_API oc_ui_text_box_result oc_ui_text_box(const char* name, oc_arena* arena, oc_str8 text); + + typedef struct oc_ui_select_popup_info + { + bool changed; + int selectedIndex; + int optionCount; + oc_str8* options; + } oc_ui_select_popup_info; + + ORCA_API oc_ui_select_popup_info oc_ui_select_popup(const char* name, oc_ui_select_popup_info* info); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif //__UI_H_ diff --git a/src/util/algebra.c b/src/util/algebra.c index 2afe1e4..82bc6b1 100644 --- a/src/util/algebra.c +++ b/src/util/algebra.c @@ -1,55 +1,55 @@ -/************************************************************//** +/************************************************************/ /** * * @file: algebra.c * @author: Martin Fouilleul * @date: 15/08/2023 * *****************************************************************/ -#include"algebra.h" +#include "algebra.h" bool oc_vec2_equal(oc_vec2 v0, oc_vec2 v1) { - return(v0.x == v1.x && v0.y == v1.y); + return (v0.x == v1.x && v0.y == v1.y); } oc_vec2 oc_vec2_mul(f32 f, oc_vec2 v) { - return((oc_vec2){f*v.x, f*v.y}); + return ((oc_vec2){ f * v.x, f * v.y }); } oc_vec2 oc_vec2_add(oc_vec2 v0, oc_vec2 v1) { - return((oc_vec2){v0.x + v1.x, v0.y + v1.y}); + return ((oc_vec2){ v0.x + v1.x, v0.y + v1.y }); } oc_mat2x3 oc_mat2x3_mul_m(oc_mat2x3 lhs, oc_mat2x3 rhs) { - oc_mat2x3 res; - res.m[0] = lhs.m[0]*rhs.m[0] + lhs.m[1]*rhs.m[3]; - res.m[1] = lhs.m[0]*rhs.m[1] + lhs.m[1]*rhs.m[4]; - res.m[2] = lhs.m[0]*rhs.m[2] + lhs.m[1]*rhs.m[5] + lhs.m[2]; - res.m[3] = lhs.m[3]*rhs.m[0] + lhs.m[4]*rhs.m[3]; - res.m[4] = lhs.m[3]*rhs.m[1] + lhs.m[4]*rhs.m[4]; - res.m[5] = lhs.m[3]*rhs.m[2] + lhs.m[4]*rhs.m[5] + lhs.m[5]; + oc_mat2x3 res; + res.m[0] = lhs.m[0] * rhs.m[0] + lhs.m[1] * rhs.m[3]; + res.m[1] = lhs.m[0] * rhs.m[1] + lhs.m[1] * rhs.m[4]; + res.m[2] = lhs.m[0] * rhs.m[2] + lhs.m[1] * rhs.m[5] + lhs.m[2]; + res.m[3] = lhs.m[3] * rhs.m[0] + lhs.m[4] * rhs.m[3]; + res.m[4] = lhs.m[3] * rhs.m[1] + lhs.m[4] * rhs.m[4]; + res.m[5] = lhs.m[3] * rhs.m[2] + lhs.m[4] * rhs.m[5] + lhs.m[5]; - return(res); + return (res); } oc_mat2x3 oc_mat2x3_inv(oc_mat2x3 x) { - oc_mat2x3 res; - res.m[0] = x.m[4]/(x.m[0]*x.m[4] - x.m[1]*x.m[3]); - res.m[1] = x.m[1]/(x.m[1]*x.m[3] - x.m[0]*x.m[4]); - res.m[3] = x.m[3]/(x.m[1]*x.m[3] - x.m[0]*x.m[4]); - res.m[4] = x.m[0]/(x.m[0]*x.m[4] - x.m[1]*x.m[3]); - res.m[2] = -(x.m[2]*res.m[0] + x.m[5]*res.m[1]); - res.m[5] = -(x.m[2]*res.m[3] + x.m[5]*res.m[4]); - return(res); + oc_mat2x3 res; + res.m[0] = x.m[4] / (x.m[0] * x.m[4] - x.m[1] * x.m[3]); + res.m[1] = x.m[1] / (x.m[1] * x.m[3] - x.m[0] * x.m[4]); + res.m[3] = x.m[3] / (x.m[1] * x.m[3] - x.m[0] * x.m[4]); + res.m[4] = x.m[0] / (x.m[0] * x.m[4] - x.m[1] * x.m[3]); + res.m[2] = -(x.m[2] * res.m[0] + x.m[5] * res.m[1]); + res.m[5] = -(x.m[2] * res.m[3] + x.m[5] * res.m[4]); + return (res); } oc_vec2 oc_mat2x3_mul(oc_mat2x3 m, oc_vec2 p) { - f32 x = p.x*m.m[0] + p.y*m.m[1] + m.m[2]; - f32 y = p.x*m.m[3] + p.y*m.m[4] + m.m[5]; - return((oc_vec2){x, y}); + f32 x = p.x * m.m[0] + p.y * m.m[1] + m.m[2]; + f32 y = p.x * m.m[3] + p.y * m.m[4] + m.m[5]; + return ((oc_vec2){ x, y }); } diff --git a/src/util/algebra.h b/src/util/algebra.h index 9edc283..dc838c6 100644 --- a/src/util/algebra.h +++ b/src/util/algebra.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: algebra.h * @author: Martin Fouilleul @@ -8,7 +8,7 @@ #ifndef __ALGEBRA_H_ #define __ALGEBRA_H_ -#include"typedefs.h" +#include "typedefs.h" bool oc_vec2_equal(oc_vec2 v0, oc_vec2 v1); oc_vec2 oc_vec2_mul(f32 f, oc_vec2 v); diff --git a/src/util/debug.h b/src/util/debug.h index 5bca2ed..44e571c 100644 --- a/src/util/debug.h +++ b/src/util/debug.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: debug.h * @author: Martin Fouilleul @@ -8,8 +8,8 @@ #ifndef __DEBUG_H_ #define __DEBUG_H_ -#include"platform/platform_debug.h" -#include"util/macros.h" +#include "platform/platform_debug.h" +#include "util/macros.h" //---------------------------------------------------------------- // Logging @@ -19,24 +19,24 @@ #define oc_log_error(msg, ...) oc_log_generic(OC_LOG_LEVEL_ERROR, msg, ##__VA_ARGS__) #ifndef OC_LOG_COMPILE_WARNING - #define OC_LOG_COMPILE_WARNING 1 + #define OC_LOG_COMPILE_WARNING 1 #endif #ifndef OC_LOG_COMPILE_INFO - #define OC_LOG_COMPILE_INFO 1 + #define OC_LOG_COMPILE_INFO 1 #endif #if OC_LOG_COMPILE_WARNING || OC_LOG_COMPILE_INFO - #define oc_log_warning(msg, ...) oc_log_generic(OC_LOG_LEVEL_WARNING, msg, ##__VA_ARGS__) + #define oc_log_warning(msg, ...) oc_log_generic(OC_LOG_LEVEL_WARNING, msg, ##__VA_ARGS__) - #if OC_LOG_COMPILE_INFO - #define oc_log_info(msg, ...) oc_log_generic(OC_LOG_LEVEL_INFO, msg, ##__VA_ARGS__ ) - #else - #define oc_log_info(msg, ...) - #endif + #if OC_LOG_COMPILE_INFO + #define oc_log_info(msg, ...) oc_log_generic(OC_LOG_LEVEL_INFO, msg, ##__VA_ARGS__) + #else + #define oc_log_info(msg, ...) + #endif #else - #define oc_log_warning(msg, ...) - #define oc_log_info(msg, ...) + #define oc_log_warning(msg, ...) + #define oc_log_info(msg, ...) #endif //---------------------------------------------------------------- @@ -46,18 +46,17 @@ #define OC_ABORT(fmt, ...) oc_abort_ext(__FILE__, __FUNCTION__, __LINE__, fmt, ##__VA_ARGS__) #ifdef OC_NO_ASSERT - #define OC_ASSERT(x, ...) - #define OC_DEBUG_ASSERT(x, ...) + #define OC_ASSERT(x, ...) + #define OC_DEBUG_ASSERT(x, ...) #else - #define _OC_ASSERT_(test, fmt, ...) ((test) || (oc_assert_fail(__FILE__, __FUNCTION__, __LINE__, #test, fmt, ##__VA_ARGS__), 0)) - #define OC_ASSERT(test, ...) _OC_ASSERT_(test, OC_VA_NOPT("", ##__VA_ARGS__) OC_ARG1(__VA_ARGS__) OC_VA_COMMA_TAIL(__VA_ARGS__)) + #define _OC_ASSERT_(test, fmt, ...) ((test) || (oc_assert_fail(__FILE__, __FUNCTION__, __LINE__, #test, fmt, ##__VA_ARGS__), 0)) + #define OC_ASSERT(test, ...) _OC_ASSERT_(test, OC_VA_NOPT("", ##__VA_ARGS__) OC_ARG1(__VA_ARGS__) OC_VA_COMMA_TAIL(__VA_ARGS__)) - #ifdef OC_DEBUG - #define OC_DEBUG_ASSERT(x, ...) OC_ASSERT(x, ##__VA_ARGS__ ) - #else - #define OC_DEBUG_ASSERT(x, ...) - #endif + #ifdef OC_DEBUG + #define OC_DEBUG_ASSERT(x, ...) OC_ASSERT(x, ##__VA_ARGS__) + #else + #define OC_DEBUG_ASSERT(x, ...) + #endif #endif - #endif //__DEBUG_H_ diff --git a/src/util/hash.c b/src/util/hash.c index d2d526f..92cff75 100644 --- a/src/util/hash.c +++ b/src/util/hash.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: hash.cpp * @author: Martin Fouilleul @@ -6,190 +6,201 @@ * @revision: * *****************************************************************/ -#include"hash.h" -#include"platform/platform.h" +#include "hash.h" +#include "platform/platform.h" #if OC_ARCH_X64 -#include + #include u64 oc_hash_aes_u64(u64 x) { - u8 seed[16] = { - 0xaa, 0x9b, 0xbd, 0xb8, - 0xa1, 0x98, 0xac, 0x3f, - 0x1f, 0x94, 0x07, 0xb3, - 0x8c, 0x27, 0x93, 0x69 }; + u8 seed[16] = { + 0xaa, 0x9b, 0xbd, 0xb8, + 0xa1, 0x98, 0xac, 0x3f, + 0x1f, 0x94, 0x07, 0xb3, + 0x8c, 0x27, 0x93, 0x69 + }; - __m128i hash = _mm_set_epi64x(0L, x); - __m128i key = _mm_loadu_si128((__m128i*)seed); - hash = _mm_aesdec_si128(hash, key); - hash = _mm_aesdec_si128(hash, key); - u64 result = _mm_extract_epi64(hash, 0); + __m128i hash = _mm_set_epi64x(0L, x); + __m128i key = _mm_loadu_si128((__m128i*)seed); + hash = _mm_aesdec_si128(hash, key); + hash = _mm_aesdec_si128(hash, key); + u64 result = _mm_extract_epi64(hash, 0); - return(result); + return (result); } u64 oc_hash_aes_u64_x2(u64 x, u64 y) { - u8 seed[16] = { - 0xaa, 0x9b, 0xbd, 0xb8, - 0xa1, 0x98, 0xac, 0x3f, - 0x1f, 0x94, 0x07, 0xb3, - 0x8c, 0x27, 0x93, 0x69 }; + u8 seed[16] = { + 0xaa, 0x9b, 0xbd, 0xb8, + 0xa1, 0x98, 0xac, 0x3f, + 0x1f, 0x94, 0x07, 0xb3, + 0x8c, 0x27, 0x93, 0x69 + }; - __m128i hash = _mm_set_epi64x(x, y); - __m128i key = _mm_loadu_si128((__m128i*)seed); - hash = _mm_aesdec_si128(hash, key); - hash = _mm_aesdec_si128(hash, key); - u64 result = _mm_extract_epi64(hash, 0); + __m128i hash = _mm_set_epi64x(x, y); + __m128i key = _mm_loadu_si128((__m128i*)seed); + hash = _mm_aesdec_si128(hash, key); + hash = _mm_aesdec_si128(hash, key); + u64 result = _mm_extract_epi64(hash, 0); - return(result); + return (result); } u64 oc_hash_aes_string(oc_str8 string) { - u8 seed[16] = { - 0xaa, 0x9b, 0xbd, 0xb8, - 0xa1, 0x98, 0xac, 0x3f, - 0x1f, 0x94, 0x07, 0xb3, - 0x8c, 0x27, 0x93, 0x69 }; + u8 seed[16] = { + 0xaa, 0x9b, 0xbd, 0xb8, + 0xa1, 0x98, 0xac, 0x3f, + 0x1f, 0x94, 0x07, 0xb3, + 0x8c, 0x27, 0x93, 0x69 + }; - __m128i hash = _mm_loadu_si128((__m128i*)seed); + __m128i hash = _mm_loadu_si128((__m128i*)seed); - u64 chunkCount = string.len / 16; - char* at = string.ptr; + u64 chunkCount = string.len / 16; + char* at = string.ptr; - while(chunkCount--) - { - __m128i in = _mm_loadu_si128((__m128i*)at); - at += 16; + while(chunkCount--) + { + __m128i in = _mm_loadu_si128((__m128i*)at); + at += 16; - hash = _mm_xor_si128(hash, in); - hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); - hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); - hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); - hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); - } + hash = _mm_xor_si128(hash, in); + hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); + hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); + hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); + hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); + } - u64 restCount = string.len % 16; - char tmp[16]; - memset(tmp, 0, 16); - memmove(tmp, at, restCount); + u64 restCount = string.len % 16; + char tmp[16]; + memset(tmp, 0, 16); + memmove(tmp, at, restCount); - __m128i in = _mm_loadu_si128((__m128i*)tmp); - hash = _mm_xor_si128(hash, in); - hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); - hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); - hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); - hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); + __m128i in = _mm_loadu_si128((__m128i*)tmp); + hash = _mm_xor_si128(hash, in); + hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); + hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); + hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); + hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); - u64 result = _mm_extract_epi64(hash, 0); - return(result); + u64 result = _mm_extract_epi64(hash, 0); + return (result); } u64 oc_hash_aes_string_seed(oc_str8 string, u64 seed) { - u8 seed16[16]; - memcpy(seed16, &seed, 8); - memcpy(seed16+8, &seed, 8); + u8 seed16[16]; + memcpy(seed16, &seed, 8); + memcpy(seed16 + 8, &seed, 8); - __m128i hash = _mm_loadu_si64(&seed16); + __m128i hash = _mm_loadu_si64(&seed16); - u64 chunkCount = string.len / 16; - char* at = string.ptr; + u64 chunkCount = string.len / 16; + char* at = string.ptr; - while(chunkCount--) - { - __m128i in = _mm_loadu_si128((__m128i*)at); - at += 16; + while(chunkCount--) + { + __m128i in = _mm_loadu_si128((__m128i*)at); + at += 16; - hash = _mm_xor_si128(hash, in); - hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); - hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); - hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); - hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); - } + hash = _mm_xor_si128(hash, in); + hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); + hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); + hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); + hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); + } - u64 restCount = string.len % 16; - char tmp[16]; - memset(tmp, 0, 16); - memmove(tmp, at, restCount); + u64 restCount = string.len % 16; + char tmp[16]; + memset(tmp, 0, 16); + memmove(tmp, at, restCount); - __m128i in = _mm_loadu_si128((__m128i*)tmp); - hash = _mm_xor_si128(hash, in); - hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); - hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); - hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); - hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); + __m128i in = _mm_loadu_si128((__m128i*)tmp); + hash = _mm_xor_si128(hash, in); + hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); + hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); + hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); + hash = _mm_aesdec_si128(hash, _mm_setzero_si128()); - u64 result = _mm_extract_epi64(hash, 0); - return(result); + u64 result = _mm_extract_epi64(hash, 0); + return (result); } #endif // OC_ARCH_X64 //xxhash64, copy-pasted from https://github.com/demetri/scribbles/blob/master/hashing/hash_functions.c // Thanks to Demetri Spanos -uint64_t xxh_64 (const void *key, int len, uint64_t h) { - // primes used in mul-rot updates - uint64_t p1 = 0x9e3779b185ebca87, p2 = 0xc2b2ae3d27d4eb4f, - p3 = 0x165667b19e3779f9, p4 =0x85ebca77c2b2ae63, p5 = 0x27d4eb2f165667c5; +uint64_t xxh_64(const void* key, int len, uint64_t h) +{ + // primes used in mul-rot updates + uint64_t p1 = 0x9e3779b185ebca87, p2 = 0xc2b2ae3d27d4eb4f, + p3 = 0x165667b19e3779f9, p4 = 0x85ebca77c2b2ae63, p5 = 0x27d4eb2f165667c5; - // inital 32-byte (4x8) wide hash state - uint64_t s[4] = {h+p1+p2, h+p2, h, h-p1}; + // inital 32-byte (4x8) wide hash state + uint64_t s[4] = { h + p1 + p2, h + p2, h, h - p1 }; - // bulk work: process all 32 byte blocks - uint64_t *k32 = (uint64_t*) key; - for (int i=0; i < (len/32); i+=4) { - uint64_t b[4] = {k32[i+0], k32[i+1], k32[i+2], k32[i+3]}; - for (int j=0;j<4;j++) b[j] = b[j]*p2+s[j]; - for (int j=0;j<4;j++) s[j] = ((b[j] << 31) | (b[j] >> 33))*p1; - } - - // mix 32-byte state down to 8-byte state, initalize to value for short keys - uint64_t s64 = (s[2] + p5); - if (len > 32) { - s64 = ((s[0] << 1) | (s[0] >> 63)) + ((s[1] << 7) | (s[1] >> 57)) + - ((s[2] << 12) | (s[2] >> 52)) + ((s[3] << 18) | (s[3] >> 46)); - for (int i=0; i<4;i++) { - uint64_t ps = (((s[i]*p2) << 31) | ((s[i]*p2) >> 33))*p1; - s64 = (s64 ^ ps)*p1 + p4; + // bulk work: process all 32 byte blocks + uint64_t* k32 = (uint64_t*)key; + for(int i = 0; i < (len / 32); i += 4) + { + uint64_t b[4] = { k32[i + 0], k32[i + 1], k32[i + 2], k32[i + 3] }; + for(int j = 0; j < 4; j++) + b[j] = b[j] * p2 + s[j]; + for(int j = 0; j < 4; j++) + s[j] = ((b[j] << 31) | (b[j] >> 33)) * p1; } - } - s64 += len; - // up to 31 bytes remain, process 0-3 8 byte blocks - uint8_t *tail = (uint8_t *) (((char*)key) + (len/32)*32); - for (int i=0;i < (len & 31) / 8; i++,tail+=8) { - uint64_t b = (*((uint64_t*) tail))*p2; - b = (((b << 31)| (b >> 33))*p1) ^ s64; - s64 = ((b << 27) | (b >> 37))*p1 + p4; - } + // mix 32-byte state down to 8-byte state, initalize to value for short keys + uint64_t s64 = (s[2] + p5); + if(len > 32) + { + s64 = ((s[0] << 1) | (s[0] >> 63)) + ((s[1] << 7) | (s[1] >> 57)) + ((s[2] << 12) | (s[2] >> 52)) + ((s[3] << 18) | (s[3] >> 46)); + for(int i = 0; i < 4; i++) + { + uint64_t ps = (((s[i] * p2) << 31) | ((s[i] * p2) >> 33)) * p1; + s64 = (s64 ^ ps) * p1 + p4; + } + } + s64 += len; - // up to 7 bytes remain, process 0-1 4 byte block - for (int i=0;i< (len & 7) / 4; i++, tail +=4) { - uint64_t b = s64 ^ (*(uint32_t*)tail)*p1; - s64 = ((b << 23) | (b >> 41))*p2 + p3; - } + // up to 31 bytes remain, process 0-3 8 byte blocks + uint8_t* tail = (uint8_t*)(((char*)key) + (len / 32) * 32); + for(int i = 0; i < (len & 31) / 8; i++, tail += 8) + { + uint64_t b = (*((uint64_t*)tail)) * p2; + b = (((b << 31) | (b >> 33)) * p1) ^ s64; + s64 = ((b << 27) | (b >> 37)) * p1 + p4; + } - // up to 3 bytes remain, process 0-3 1 byte blocks - for (int i=0;i<(len & 3); i++,tail++) { - uint64_t b = s64 ^ (*tail)*p5; - s64 = ((b << 11) | (b >> 53))*p1; - } + // up to 7 bytes remain, process 0-1 4 byte block + for(int i = 0; i < (len & 7) / 4; i++, tail += 4) + { + uint64_t b = s64 ^ (*(uint32_t*)tail) * p1; + s64 = ((b << 23) | (b >> 41)) * p2 + p3; + } - // finalization mix - s64 = (s64 ^ (s64 >> 33))*p2; - s64 = (s64 ^ (s64 >> 29))*p3; - return (s64 ^ (s64 >> 32)); + // up to 3 bytes remain, process 0-3 1 byte blocks + for(int i = 0; i < (len & 3); i++, tail++) + { + uint64_t b = s64 ^ (*tail) * p5; + s64 = ((b << 11) | (b >> 53)) * p1; + } + + // finalization mix + s64 = (s64 ^ (s64 >> 33)) * p2; + s64 = (s64 ^ (s64 >> 29)) * p3; + return (s64 ^ (s64 >> 32)); } u64 oc_hash_xx64_string_seed(oc_str8 string, u64 seed) { - return(xxh_64(string.ptr, string.len, seed)); + return (xxh_64(string.ptr, string.len, seed)); } u64 oc_hash_xx64_string(oc_str8 string) { - return(xxh_64(string.ptr, string.len, 0)); + return (xxh_64(string.ptr, string.len, 0)); } diff --git a/src/util/hash.h b/src/util/hash.h index c11800e..2d0399b 100644 --- a/src/util/hash.h +++ b/src/util/hash.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: hash.h * @author: Martin Fouilleul @@ -9,25 +9,24 @@ #ifndef __HASH_H_ #define __HASH_H_ -#include"typedefs.h" -#include"strings.h" +#include "strings.h" +#include "typedefs.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -ORCA_API u64 oc_hash_aes_u64(u64 x); -ORCA_API u64 oc_hash_aes_u64_x2(u64 x, u64 y); -ORCA_API u64 oc_hash_aes_string(oc_str8 string); -ORCA_API u64 oc_hash_aes_string_seed(oc_str8 string, u64 seed); - -ORCA_API u64 oc_hash_xx64_string_seed(oc_str8 string, u64 seed); -ORCA_API u64 oc_hash_xx64_string(oc_str8 string); + ORCA_API u64 oc_hash_aes_u64(u64 x); + ORCA_API u64 oc_hash_aes_u64_x2(u64 x, u64 y); + ORCA_API u64 oc_hash_aes_string(oc_str8 string); + ORCA_API u64 oc_hash_aes_string_seed(oc_str8 string, u64 seed); + ORCA_API u64 oc_hash_xx64_string_seed(oc_str8 string, u64 seed); + ORCA_API u64 oc_hash_xx64_string(oc_str8 string); #ifdef __cplusplus } // extern "C" #endif - #endif //__HASH_H_ diff --git a/src/util/lists.h b/src/util/lists.h index f02c26c..b4cd5cb 100644 --- a/src/util/lists.h +++ b/src/util/lists.h @@ -1,222 +1,225 @@ -/************************************************************//** +/************************************************************/ /** * * @file: lists.h * @author: Martin Fouilleul * @date: 22/11/2017 * @brief: Implements generic intrusive linked list and dynamic array * -****************************************************************/ -#ifndef __CONTAINERS_H_ -#define __CONTAINERS_H_ - -#include"util/macros.h" -#include"platform/platform_debug.h" - -#ifdef __cplusplus -extern "C" { -#endif - -//------------------------------------------------------------------------- -// Intrusive linked lists -//------------------------------------------------------------------------- - -#define oc_list_entry(ptr, type, member) \ - oc_container_of(ptr, type, member) - -#define oc_list_next(elt) (elt)->next -#define oc_list_prev(elt) (elt)->prev - -#define oc_list_next_entry(list, elt, type, member) \ - ((elt->member.next != oc_list_end(list)) ? oc_list_entry(elt->member.next, type, member) : 0) - -#define oc_list_prev_entry(list, elt, type, member) \ - ((elt->member.prev != oc_list_end(list)) ? oc_list_entry(elt->member.prev, type, member) : 0) - -#define oc_list_checked_entry(list, type, member) \ - (((list) != 0) ? oc_list_entry(list, type, member) : 0) - -#define oc_list_first_entry(list, type, member) \ - (oc_list_checked_entry(oc_list_begin(list), type, member)) - -#define oc_list_last_entry(list, type, member) \ - (oc_list_checked_entry(oc_list_last(list), type, member)) - -#define oc_list_for(list, elt, type, member) \ - for(type* elt = oc_list_checked_entry(oc_list_begin(list), type, member); \ - elt != 0; \ - elt = oc_list_checked_entry(elt->member.next, type, member)) \ - -#define oc_list_for_reverse(list, elt, type, member) \ - for(type* elt = oc_list_checked_entry(oc_list_last(list), type, member); \ - elt != 0; \ - elt = oc_list_checked_entry(elt->member.prev, type, member)) \ - -#define oc_list_for_safe(list, elt, type, member) \ - for(type* elt = oc_list_checked_entry(oc_list_begin(list), type, member), \ - *__tmp = elt ? oc_list_checked_entry(elt->member.next, type, member) : 0 ; \ - elt != 0; \ - elt = __tmp, \ - __tmp = elt ? oc_list_checked_entry(elt->member.next, type, member) : 0) \ - -#define oc_list_pop_entry(list, type, member) (oc_list_empty(list) ? 0 : oc_list_entry(oc_list_pop(list), type, member)) - -typedef struct oc_list_elt oc_list_elt; -struct oc_list_elt -{ - oc_list_elt* next; - oc_list_elt* prev; -}; - -typedef struct oc_list -{ - oc_list_elt* first; - oc_list_elt* last; -} oc_list; - -static inline void oc_list_init(oc_list* list) -{ - list->first = list->last = 0; -} - -static inline oc_list_elt* oc_list_begin(oc_list* list) -{ - return(list->first); -} -static inline oc_list_elt* oc_list_end(oc_list* list) -{ - return(0); -} - -static inline oc_list_elt* oc_list_last(oc_list* list) -{ - return(list->last); -} - -static inline void oc_list_insert(oc_list* list, oc_list_elt* afterElt, oc_list_elt* elt) -{ - elt->prev = afterElt; - elt->next = afterElt->next; - if(afterElt->next) - { - afterElt->next->prev = elt; - } - else - { - list->last = elt; - } - afterElt->next = elt; - - OC_DEBUG_ASSERT(elt->next != elt, "oc_list_insert(): can't insert an element into itself"); -} - -static inline void oc_list_insert_before(oc_list* list, oc_list_elt* beforeElt, oc_list_elt* elt) -{ - elt->next = beforeElt; - elt->prev = beforeElt->prev; - - if(beforeElt->prev) - { - beforeElt->prev->next = elt; - } - else - { - list->first = elt; - } - beforeElt->prev = elt; - - OC_DEBUG_ASSERT(elt->next != elt, "oc_list_insert_before(): can't insert an element into itself"); -} - -static inline void oc_list_remove(oc_list* list, oc_list_elt* elt) -{ - if(elt->prev) - { - elt->prev->next = elt->next; - } - else - { - OC_DEBUG_ASSERT(list->first == elt); - list->first = elt->next; - } - if(elt->next) - { - elt->next->prev = elt->prev; - } - else - { - OC_DEBUG_ASSERT(list->last == elt); - list->last = elt->prev; - } - elt->prev = elt->next = 0; -} - -static inline void oc_list_push(oc_list* list, oc_list_elt* elt) -{ - elt->next = list->first; - elt->prev = 0; - if(list->first) - { - list->first->prev = elt; - } - else - { - list->last = elt; - } - list->first = elt; -} - -static inline oc_list_elt* oc_list_pop(oc_list* list) -{ - oc_list_elt* elt = oc_list_begin(list); - if(elt != oc_list_end(list)) - { - oc_list_remove(list, elt); - return(elt); - } - else - { - return(0); - } -} - -static inline void oc_list_push_back(oc_list* list, oc_list_elt* elt) -{ - elt->prev = list->last; - elt->next = 0; - if(list->last) - { - list->last->next = elt; - } - else - { - list->first = elt; - } - list->last = elt; -} -#define oc_list_append(a, b) oc_list_push_back(a, b) - - -static inline oc_list_elt* oc_list_pop_back(oc_list* list) -{ - oc_list_elt* elt = oc_list_last(list); - if(elt != oc_list_end(list)) - { - oc_list_remove(list, elt); - return(elt); - } - else - { - return(0); - } -} - -static inline bool oc_list_empty(oc_list* list) -{ - return(list->first == 0 || list->last == 0); -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif //__CONTAINERS_H_ +****************************************************************/ +#ifndef __CONTAINERS_H_ +#define __CONTAINERS_H_ + +#include "platform/platform_debug.h" +#include "util/macros.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + + //------------------------------------------------------------------------- + // Intrusive linked lists + //------------------------------------------------------------------------- + +#define oc_list_entry(ptr, type, member) \ + oc_container_of(ptr, type, member) + +#define oc_list_next(elt) (elt)->next +#define oc_list_prev(elt) (elt)->prev + +#define oc_list_next_entry(list, elt, type, member) \ + ((elt->member.next != oc_list_end(list)) ? oc_list_entry(elt->member.next, type, member) : 0) + +#define oc_list_prev_entry(list, elt, type, member) \ + ((elt->member.prev != oc_list_end(list)) ? oc_list_entry(elt->member.prev, type, member) : 0) + +#define oc_list_checked_entry(list, type, member) \ + (((list) != 0) ? oc_list_entry(list, type, member) : 0) + +#define oc_list_first_entry(list, type, member) \ + (oc_list_checked_entry(oc_list_begin(list), type, member)) + +#define oc_list_last_entry(list, type, member) \ + (oc_list_checked_entry(oc_list_last(list), type, member)) + +#define oc_list_for(list, elt, type, member) \ + for(type* elt = oc_list_checked_entry(oc_list_begin(list), type, member); \ + elt != 0; \ + elt = oc_list_checked_entry(elt->member.next, type, member)) + +#define oc_list_for_reverse(list, elt, type, member) \ + for(type* elt = oc_list_checked_entry(oc_list_last(list), type, member); \ + elt != 0; \ + elt = oc_list_checked_entry(elt->member.prev, type, member)) + +#define oc_list_for_safe(list, elt, type, member) \ + for(type* elt = oc_list_checked_entry(oc_list_begin(list), type, member), \ + *__tmp = elt ? oc_list_checked_entry(elt->member.next, type, member) : 0; \ + elt != 0; \ + elt = __tmp, \ + __tmp = elt ? oc_list_checked_entry(elt->member.next, type, member) : 0) + +#define oc_list_pop_entry(list, type, member) (oc_list_empty(list) ? 0 : oc_list_entry(oc_list_pop(list), type, member)) + + typedef struct oc_list_elt oc_list_elt; + + struct oc_list_elt + { + oc_list_elt* next; + oc_list_elt* prev; + }; + + typedef struct oc_list + { + oc_list_elt* first; + oc_list_elt* last; + } oc_list; + + static inline void oc_list_init(oc_list* list) + { + list->first = list->last = 0; + } + + static inline oc_list_elt* oc_list_begin(oc_list* list) + { + return (list->first); + } + + static inline oc_list_elt* oc_list_end(oc_list* list) + { + return (0); + } + + static inline oc_list_elt* oc_list_last(oc_list* list) + { + return (list->last); + } + + static inline void oc_list_insert(oc_list* list, oc_list_elt* afterElt, oc_list_elt* elt) + { + elt->prev = afterElt; + elt->next = afterElt->next; + if(afterElt->next) + { + afterElt->next->prev = elt; + } + else + { + list->last = elt; + } + afterElt->next = elt; + + OC_DEBUG_ASSERT(elt->next != elt, "oc_list_insert(): can't insert an element into itself"); + } + + static inline void oc_list_insert_before(oc_list* list, oc_list_elt* beforeElt, oc_list_elt* elt) + { + elt->next = beforeElt; + elt->prev = beforeElt->prev; + + if(beforeElt->prev) + { + beforeElt->prev->next = elt; + } + else + { + list->first = elt; + } + beforeElt->prev = elt; + + OC_DEBUG_ASSERT(elt->next != elt, "oc_list_insert_before(): can't insert an element into itself"); + } + + static inline void oc_list_remove(oc_list* list, oc_list_elt* elt) + { + if(elt->prev) + { + elt->prev->next = elt->next; + } + else + { + OC_DEBUG_ASSERT(list->first == elt); + list->first = elt->next; + } + if(elt->next) + { + elt->next->prev = elt->prev; + } + else + { + OC_DEBUG_ASSERT(list->last == elt); + list->last = elt->prev; + } + elt->prev = elt->next = 0; + } + + static inline void oc_list_push(oc_list* list, oc_list_elt* elt) + { + elt->next = list->first; + elt->prev = 0; + if(list->first) + { + list->first->prev = elt; + } + else + { + list->last = elt; + } + list->first = elt; + } + + static inline oc_list_elt* oc_list_pop(oc_list* list) + { + oc_list_elt* elt = oc_list_begin(list); + if(elt != oc_list_end(list)) + { + oc_list_remove(list, elt); + return (elt); + } + else + { + return (0); + } + } + + static inline void oc_list_push_back(oc_list* list, oc_list_elt* elt) + { + elt->prev = list->last; + elt->next = 0; + if(list->last) + { + list->last->next = elt; + } + else + { + list->first = elt; + } + list->last = elt; + } + +#define oc_list_append(a, b) oc_list_push_back(a, b) + + static inline oc_list_elt* oc_list_pop_back(oc_list* list) + { + oc_list_elt* elt = oc_list_last(list); + if(elt != oc_list_end(list)) + { + oc_list_remove(list, elt); + return (elt); + } + else + { + return (0); + } + } + + static inline bool oc_list_empty(oc_list* list) + { + return (list->first == 0 || list->last == 0); + } + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif //__CONTAINERS_H_ diff --git a/src/util/macros.h b/src/util/macros.h index 7a951a7..d5084fd 100644 --- a/src/util/macros.h +++ b/src/util/macros.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: macros.h * @author: Martin Fouilleul @@ -9,8 +9,8 @@ #ifndef __MACROS_H_ #define __MACROS_H_ -#include"util/typedefs.h" -#include"platform/platform.h" +#include "platform/platform.h" +#include "util/typedefs.h" //---------------------------------------------------------------------------------------- // utility macros @@ -30,13 +30,13 @@ #define OC_VA_COMMA_TAIL(a, ...) , ##__VA_ARGS__ //NOTE: this expands to opt if __VA_ARGS__ is empty, and to , va1, va2, ... opt otherwise -#define OC_VA_NOPT_UTIL(opt, ...) ,##__VA_ARGS__ opt +#define OC_VA_NOPT_UTIL(opt, ...) , ##__VA_ARGS__ opt //NOTE: this expands to opt if __VA_ARGS__ is empty, and to nothing otherwise #define OC_VA_NOPT(opt, ...) OC_PASS(OC_ARG1, OC_VA_NOPT_UTIL(opt, ##__VA_ARGS__)) //NOTE: this expands to opt if __VA_ARGS__ is non empty, and to nothing otherwise -#define OC_VA_OPT(opt, ...) OC_PASS(OC_CAT2, OC_EXPAND , OC_VA_NOPT(_NIL, ##__VA_ARGS__))(opt) +#define OC_VA_OPT(opt, ...) OC_PASS(OC_CAT2, OC_EXPAND, OC_VA_NOPT(_NIL, ##__VA_ARGS__))(opt) //---------------------------------------------------------------------------------------- // misc @@ -44,103 +44,111 @@ //NOTE: this computes the address of a struct given an address to one of its members #ifdef __cplusplus - #define oc_container_of(ptr, type, member) ({ \ + #define oc_container_of(ptr, type, member) ({ \ const decltype( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) + (type *)( (char *)__mptr - offsetof(type,member) ); }) #else - #define oc_container_of(ptr, type, member) (type *)((char*)(ptr) - offsetof(type,member)) + #define oc_container_of(ptr, type, member) (type*)((char*)(ptr)-offsetof(type, member)) #endif - -#define oc_defer_loop(begin, end) begin; for(int __i__=0; __i__<1; __i__++, end) +#define oc_defer_loop(begin, end) \ + begin; \ + for(int __i__ = 0; __i__ < 1; __i__++, end) //---------------------------------------------------------------------------------------- //NOTE(martin): bit-twiddling & arithmetic helpers //---------------------------------------------------------------------------------------- -#define oc_align_up_pow2(x, a) (((x) + (a) - 1) & ~((a)-1)) +#define oc_align_up_pow2(x, a) (((x) + (a)-1) & ~((a)-1)) #define oc_align_down_pow2(x, a) ((x) & ~((a)-1)) static inline u64 oc_next_pow2(u64 x) { - x--; - x |= x>>1; - x |= x>>2; - x |= x>>4; - x |= x>>8; - x |= x>>16; - x |= x>>32; - x++; - return(x); + x--; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x |= x >> 32; + x++; + return (x); } //NOTE(martin): 'hygienic' max/min/square/cube macros. #ifdef __cplusplus - //NOTE(martin): in C++ we use templates and decltype/declval - // (overloaded functions would be ambiguous because of the - // overload resolution and conversion/promotion rules) - #include + //NOTE(martin): in C++ we use templates and decltype/declval + // (overloaded functions would be ambiguous because of the + // overload resolution and conversion/promotion rules) + #include - template - inline decltype(std::declval()+std::declval()) oc_min(Ta a, Tb b) - { - return(a < b ? a : b); - } - template - inline decltype(std::declval()+std::declval()) oc_max(Ta a, Tb b) - { - return(a > b ? a : b); - } - template - inline T oc_square(T a) - { - return(a*a); - } - template - inline T oc_cube(T a) - { - return(a*a*a); - } +template +inline decltype(std::declval() + std::declval()) oc_min(Ta a, Tb b) +{ + return (a < b ? a : b); +} + +template +inline decltype(std::declval() + std::declval()) oc_max(Ta a, Tb b) +{ + return (a > b ? a : b); +} + +template +inline T oc_square(T a) +{ + return (a * a); +} + +template +inline T oc_cube(T a) +{ + return (a * a * a); +} #else - //NOTE(martin): this macros helps generate variants of a generic 'template' for all arithmetic types. - // the def parameter must be a macro that takes a type, and optional arguments - #define oc_tga_variants(def, ...) \ - def(u8, ##__VA_ARGS__) def(i8, ##__VA_ARGS__ ) def(u16, ##__VA_ARGS__) def(i16, ##__VA_ARGS__) \ - def(u32, ##__VA_ARGS__) def(i32, ##__VA_ARGS__) def(u64, ##__VA_ARGS__) def(i64, ##__VA_ARGS__) \ - def(f32, ##__VA_ARGS__) def(f64, ##__VA_ARGS__) + //NOTE(martin): this macros helps generate variants of a generic 'template' for all arithmetic types. + // the def parameter must be a macro that takes a type, and optional arguments + #define oc_tga_variants(def, ...) \ + def(u8, ##__VA_ARGS__) def(i8, ##__VA_ARGS__) def(u16, ##__VA_ARGS__) def(i16, ##__VA_ARGS__) \ + def(u32, ##__VA_ARGS__) def(i32, ##__VA_ARGS__) def(u64, ##__VA_ARGS__) def(i64, ##__VA_ARGS__) \ + def(f32, ##__VA_ARGS__) def(f64, ##__VA_ARGS__) - // This macro generates one _Generic association between a type and its variant - #define oc_tga_association(type, name) , type: OC_CAT3(name, _, type) + // This macro generates one _Generic association between a type and its variant + #define oc_tga_association(type, name) , type : OC_CAT3(name, _, type) - // This macros selects the appropriate variant for a 2 parameters functions - #define oc_tga_select_binary(name, a, b) \ - _Generic((a+b) oc_tga_variants(oc_tga_association, name))(a, b) + // This macros selects the appropriate variant for a 2 parameters functions + #define oc_tga_select_binary(name, a, b) \ + _Generic((a + b) oc_tga_variants(oc_tga_association, name))(a, b) - // This macros selects the appropriate variant for a 1 parameters functions - #define oc_tga_select_unary(name, a) \ - _Generic((a) oc_tga_variants(oc_tga_association, name))(a) + // This macros selects the appropriate variant for a 1 parameters functions + #define oc_tga_select_unary(name, a) \ + _Generic((a)oc_tga_variants(oc_tga_association, name))(a) - //NOTE(martin): type generic templates - #define oc_min_def(type) static inline type OC_CAT3(oc_min, _, type)(type a, type b) {return(a < b ? a : b);} - #define oc_max_def(type) static inline type OC_CAT3(oc_max, _, type)(type a, type b) {return(a > b ? a : b);} - #define oc_square_def(type) static inline type OC_CAT3(oc_square, _, type)(type a) {return(a*a);} - #define oc_cube_def(type) static inline type OC_CAT3(oc_cube, _, type)(type a) {return(a*a*a);} + //NOTE(martin): type generic templates + #define oc_min_def(type) \ + static inline type OC_CAT3(oc_min, _, type)(type a, type b) { return (a < b ? a : b); } + #define oc_max_def(type) \ + static inline type OC_CAT3(oc_max, _, type)(type a, type b) { return (a > b ? a : b); } + #define oc_square_def(type) \ + static inline type OC_CAT3(oc_square, _, type)(type a) { return (a * a); } + #define oc_cube_def(type) \ + static inline type OC_CAT3(oc_cube, _, type)(type a) { return (a * a * a); } - //NOTE(martin): instantiante our templates for all arithmetic types - oc_tga_variants(oc_min_def) - oc_tga_variants(oc_max_def) - oc_tga_variants(oc_square_def) - oc_tga_variants(oc_cube_def) +//NOTE(martin): instantiante our templates for all arithmetic types +oc_tga_variants(oc_min_def) + oc_tga_variants(oc_max_def) + oc_tga_variants(oc_square_def) + oc_tga_variants(oc_cube_def) - //NOTE(martin): generate the _Generic associations between each type and its associated variant - #define oc_min(a, b) oc_tga_select_binary(oc_min, a, b) - #define oc_max(a, b) oc_tga_select_binary(oc_max, a, b) - #define oc_square(a) oc_tga_select_unary(oc_square, a) - #define oc_cube(a) oc_tga_select_unary(oc_cube, a) + //NOTE(martin): generate the _Generic associations between each type and its associated variant + #define oc_min(a, b) oc_tga_select_binary(oc_min, a, b) + #define oc_max(a, b) oc_tga_select_binary(oc_max, a, b) + #define oc_square(a) oc_tga_select_unary(oc_square, a) + #define oc_cube(a) oc_tga_select_unary(oc_cube, a) #endif // __cplusplus else branch -#define oc_clamp_low(a, low) (oc_max((a), (low))) +#define oc_clamp_low(a, low) (oc_max((a), (low))) #define oc_clamp_high(a, high) (oc_min((a), (high))) -#define oc_clamp(a, low, high) (oc_clamp_low(oc_clamp_high((a), (high)), (low))) +#define oc_clamp(a, low, high) (oc_clamp_low(oc_clamp_high((a), (high)), (low))) #endif //__MACROS_H_ diff --git a/src/util/memory.c b/src/util/memory.c index a7118ab..445d70b 100644 --- a/src/util/memory.c +++ b/src/util/memory.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: memory.c * @author: Martin Fouilleul @@ -6,23 +6,26 @@ * @revision: * *****************************************************************/ -#include"platform/platform.h" -#include"memory.h" -#include"platform/platform_memory.h" -#include"macros.h" +#include "memory.h" +#include "macros.h" +#include "platform/platform.h" +#include "platform/platform_memory.h" #if OC_PLATFORM_ORCA - enum { - OC_ARENA_DEFAULT_RESERVE_SIZE = 1<<20 - }; +enum +{ + OC_ARENA_DEFAULT_RESERVE_SIZE = 1 << 20 +}; #else - enum { - OC_ARENA_DEFAULT_RESERVE_SIZE = 1<<30 - }; +enum +{ + OC_ARENA_DEFAULT_RESERVE_SIZE = 1 << 30 +}; #endif -enum { - OC_ARENA_COMMIT_ALIGNMENT = 4<<10 +enum +{ + OC_ARENA_COMMIT_ALIGNMENT = 4 << 10 }; //-------------------------------------------------------------------------------- @@ -31,115 +34,115 @@ enum { oc_arena_chunk* oc_arena_chunk_alloc(oc_arena* arena, u64 reserveSize) { - reserveSize = oc_align_up_pow2(reserveSize, OC_ARENA_COMMIT_ALIGNMENT); - u64 commitSize = oc_align_up_pow2(sizeof(oc_arena_chunk), OC_ARENA_COMMIT_ALIGNMENT); + reserveSize = oc_align_up_pow2(reserveSize, OC_ARENA_COMMIT_ALIGNMENT); + u64 commitSize = oc_align_up_pow2(sizeof(oc_arena_chunk), OC_ARENA_COMMIT_ALIGNMENT); - char* mem = oc_base_reserve(arena->base, reserveSize); - oc_base_commit(arena->base, mem, commitSize); + char* mem = oc_base_reserve(arena->base, reserveSize); + oc_base_commit(arena->base, mem, commitSize); - oc_arena_chunk* chunk = (oc_arena_chunk*)mem; + oc_arena_chunk* chunk = (oc_arena_chunk*)mem; - chunk->ptr = mem; - chunk->cap = reserveSize; - chunk->offset = sizeof(oc_arena_chunk); - chunk->committed = commitSize; + chunk->ptr = mem; + chunk->cap = reserveSize; + chunk->offset = sizeof(oc_arena_chunk); + chunk->committed = commitSize; - oc_list_push_back(&arena->chunks, &chunk->listElt); + oc_list_push_back(&arena->chunks, &chunk->listElt); - return(chunk); + return (chunk); } void oc_arena_init(oc_arena* arena) { - oc_arena_init_with_options(arena, &(oc_arena_options){0}); + oc_arena_init_with_options(arena, &(oc_arena_options){ 0 }); } void oc_arena_init_with_options(oc_arena* arena, oc_arena_options* options) { - memset(arena, 0, sizeof(oc_arena)); + memset(arena, 0, sizeof(oc_arena)); - arena->base = options->base ? options->base : oc_base_allocator_default(); + arena->base = options->base ? options->base : oc_base_allocator_default(); - u64 reserveSize = options->reserve ? (options->reserve + sizeof(oc_arena_chunk)) : OC_ARENA_DEFAULT_RESERVE_SIZE; + u64 reserveSize = options->reserve ? (options->reserve + sizeof(oc_arena_chunk)) : OC_ARENA_DEFAULT_RESERVE_SIZE; - arena->currentChunk = oc_arena_chunk_alloc(arena, reserveSize); + arena->currentChunk = oc_arena_chunk_alloc(arena, reserveSize); } void oc_arena_cleanup(oc_arena* arena) { - oc_list_for_safe(&arena->chunks, chunk, oc_arena_chunk, listElt) - { - oc_base_release(arena->base, chunk, chunk->cap); - } - memset(arena, 0, sizeof(oc_arena)); + oc_list_for_safe(&arena->chunks, chunk, oc_arena_chunk, listElt) + { + oc_base_release(arena->base, chunk, chunk->cap); + } + memset(arena, 0, sizeof(oc_arena)); } void* oc_arena_push(oc_arena* arena, u64 size) { - oc_arena_chunk* chunk = arena->currentChunk; - OC_ASSERT(chunk); + oc_arena_chunk* chunk = arena->currentChunk; + OC_ASSERT(chunk); - u64 nextOffset = chunk->offset + size; - u64 lastCap = chunk->cap; - while(nextOffset > chunk->cap) - { - chunk = oc_list_next_entry(&arena->chunks, chunk, oc_arena_chunk, listElt); - if(chunk) - { - nextOffset = chunk->offset + size; - lastCap = chunk->cap; - } - else - { - break; - } - } - if(!chunk) - { - u64 reserveSize = oc_max(lastCap * 1.5, size); + u64 nextOffset = chunk->offset + size; + u64 lastCap = chunk->cap; + while(nextOffset > chunk->cap) + { + chunk = oc_list_next_entry(&arena->chunks, chunk, oc_arena_chunk, listElt); + if(chunk) + { + nextOffset = chunk->offset + size; + lastCap = chunk->cap; + } + else + { + break; + } + } + if(!chunk) + { + u64 reserveSize = oc_max(lastCap * 1.5, size); - chunk = oc_arena_chunk_alloc(arena, reserveSize); - nextOffset = chunk->offset + size; - } - OC_ASSERT(nextOffset <= chunk->cap); + chunk = oc_arena_chunk_alloc(arena, reserveSize); + nextOffset = chunk->offset + size; + } + OC_ASSERT(nextOffset <= chunk->cap); - arena->currentChunk = chunk; + arena->currentChunk = chunk; - if(nextOffset > chunk->committed) - { - u64 nextCommitted = oc_align_up_pow2(nextOffset, OC_ARENA_COMMIT_ALIGNMENT); - nextCommitted = oc_clamp_high(nextCommitted, chunk->cap); - u64 commitSize = nextCommitted - chunk->committed; - oc_base_commit(arena->base, chunk->ptr + chunk->committed, commitSize); - chunk->committed = nextCommitted; - } - char* p = chunk->ptr + chunk->offset; - chunk->offset += size; + if(nextOffset > chunk->committed) + { + u64 nextCommitted = oc_align_up_pow2(nextOffset, OC_ARENA_COMMIT_ALIGNMENT); + nextCommitted = oc_clamp_high(nextCommitted, chunk->cap); + u64 commitSize = nextCommitted - chunk->committed; + oc_base_commit(arena->base, chunk->ptr + chunk->committed, commitSize); + chunk->committed = nextCommitted; + } + char* p = chunk->ptr + chunk->offset; + chunk->offset += size; - return(p); + return (p); } void oc_arena_clear(oc_arena* arena) { - oc_list_for(&arena->chunks, chunk, oc_arena_chunk, listElt) - { - chunk->offset = sizeof(oc_arena_chunk); - } - arena->currentChunk = oc_list_first_entry(&arena->chunks, oc_arena_chunk, listElt); + oc_list_for(&arena->chunks, chunk, oc_arena_chunk, listElt) + { + chunk->offset = sizeof(oc_arena_chunk); + } + arena->currentChunk = oc_list_first_entry(&arena->chunks, oc_arena_chunk, listElt); } oc_arena_scope oc_arena_scope_begin(oc_arena* arena) { - oc_arena_scope scope = {.arena = arena, - .chunk = arena->currentChunk, - .offset = arena->currentChunk->offset}; - return(scope); + oc_arena_scope scope = { .arena = arena, + .chunk = arena->currentChunk, + .offset = arena->currentChunk->offset }; + return (scope); } void oc_arena_scope_end(oc_arena_scope scope) { - scope.arena->currentChunk = scope.chunk; - scope.arena->currentChunk->offset = scope.offset; + scope.arena->currentChunk = scope.chunk; + scope.arena->currentChunk->offset = scope.offset; } //-------------------------------------------------------------------------------- @@ -147,108 +150,107 @@ void oc_arena_scope_end(oc_arena_scope scope) //-------------------------------------------------------------------------------- void oc_pool_init(oc_pool* pool, u64 blockSize) { - oc_pool_init_with_options(pool, blockSize, &(oc_pool_options){0}); + oc_pool_init_with_options(pool, blockSize, &(oc_pool_options){ 0 }); } + void oc_pool_init_with_options(oc_pool* pool, u64 blockSize, oc_pool_options* options) { - oc_arena_init_with_options(&pool->arena, &(oc_arena_options){.base = options->base, .reserve = options->reserve}); - pool->blockSize = oc_clamp_low(blockSize, sizeof(oc_list)); - oc_list_init(&pool->freeList); + oc_arena_init_with_options(&pool->arena, &(oc_arena_options){ .base = options->base, .reserve = options->reserve }); + pool->blockSize = oc_clamp_low(blockSize, sizeof(oc_list)); + oc_list_init(&pool->freeList); } void oc_pool_cleanup(oc_pool* pool) { - oc_arena_cleanup(&pool->arena); - memset(pool, 0, sizeof(oc_pool)); + oc_arena_cleanup(&pool->arena); + memset(pool, 0, sizeof(oc_pool)); } void* oc_pool_alloc(oc_pool* pool) { - if(oc_list_empty(&pool->freeList)) - { - return(oc_arena_push(&pool->arena, pool->blockSize)); - } - else - { - return(oc_list_pop(&pool->freeList)); - } + if(oc_list_empty(&pool->freeList)) + { + return (oc_arena_push(&pool->arena, pool->blockSize)); + } + else + { + return (oc_list_pop(&pool->freeList)); + } } void oc_pool_recycle(oc_pool* pool, void* ptr) { - oc_list_push(&pool->freeList, (oc_list_elt*)ptr); + oc_list_push(&pool->freeList, (oc_list_elt*)ptr); } void oc_pool_clear(oc_pool* pool) { - oc_arena_clear(&pool->arena); - oc_list_init(&pool->freeList); + oc_arena_clear(&pool->arena); + oc_list_init(&pool->freeList); } - //-------------------------------------------------------------------------------- //NOTE(martin): per-thread scratch arena //-------------------------------------------------------------------------------- enum { - OC_SCRATCH_POOL_SIZE = 8, - OC_SCRATCH_DEFAULT_SIZE = 4096, + OC_SCRATCH_POOL_SIZE = 8, + OC_SCRATCH_DEFAULT_SIZE = 4096, }; -oc_thread_local oc_arena __scratchPool[OC_SCRATCH_POOL_SIZE] = {0}; - +oc_thread_local oc_arena __scratchPool[OC_SCRATCH_POOL_SIZE] = { 0 }; static oc_arena* oc_scratch_at_index(int index) { - oc_arena* scratch = 0; + oc_arena* scratch = 0; - if(index >= 0 && index < OC_SCRATCH_POOL_SIZE) - { - if(__scratchPool[index].base == 0) - { - oc_arena_options options = {.reserve = OC_SCRATCH_DEFAULT_SIZE}; - oc_arena_init_with_options(&__scratchPool[index], &options); - } - scratch = &__scratchPool[index]; - } - return(scratch); + if(index >= 0 && index < OC_SCRATCH_POOL_SIZE) + { + if(__scratchPool[index].base == 0) + { + oc_arena_options options = { .reserve = OC_SCRATCH_DEFAULT_SIZE }; + oc_arena_init_with_options(&__scratchPool[index], &options); + } + scratch = &__scratchPool[index]; + } + return (scratch); } oc_arena* oc_scratch() { - return(oc_scratch_at_index(0)); + return (oc_scratch_at_index(0)); } ORCA_API oc_arena* oc_scratch_next(oc_arena* used) { - oc_arena* res = 0; - if( (used >= __scratchPool) - &&(used - __scratchPool < OC_SCRATCH_POOL_SIZE)) - { - u64 index = used - __scratchPool; - if(index + 1 < OC_SCRATCH_POOL_SIZE) - { - res = oc_scratch_at_index(index+1); - } - } - else - { - res = oc_scratch_at_index(0); - } - return(res); + oc_arena* res = 0; + if((used >= __scratchPool) + && (used - __scratchPool < OC_SCRATCH_POOL_SIZE)) + { + u64 index = used - __scratchPool; + if(index + 1 < OC_SCRATCH_POOL_SIZE) + { + res = oc_scratch_at_index(index + 1); + } + } + else + { + res = oc_scratch_at_index(0); + } + return (res); } ORCA_API oc_arena_scope oc_scratch_begin() { - oc_arena* scratch = oc_scratch(); - oc_arena_scope scope = oc_arena_scope_begin(scratch); - return(scope); + oc_arena* scratch = oc_scratch(); + oc_arena_scope scope = oc_arena_scope_begin(scratch); + return (scope); } ORCA_API oc_arena_scope oc_scratch_begin_next(oc_arena* used) { - oc_arena* scratch = oc_scratch_next(used); - oc_arena_scope scope = oc_arena_scope_begin(scratch); - return(scope); + oc_arena* scratch = oc_scratch_next(used); + oc_arena_scope scope = oc_arena_scope_begin(scratch); + return (scope); } diff --git a/src/util/memory.h b/src/util/memory.h index ebc3d02..a042203 100644 --- a/src/util/memory.h +++ b/src/util/memory.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: memory.h * @author: Martin Fouilleul @@ -9,98 +9,99 @@ #ifndef __MEMORY_H_ #define __MEMORY_H_ -#include"util/typedefs.h" -#include"util/lists.h" -#include"platform/platform_memory.h" +#include "platform/platform_memory.h" +#include "util/lists.h" +#include "util/typedefs.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -//-------------------------------------------------------------------------------- -//NOTE(martin): memory arena -//-------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------- + //NOTE(martin): memory arena + //-------------------------------------------------------------------------------- -typedef struct oc_arena_chunk -{ - oc_list_elt listElt; - char* ptr; - u64 offset; - u64 committed; - u64 cap; -} oc_arena_chunk; + typedef struct oc_arena_chunk + { + oc_list_elt listElt; + char* ptr; + u64 offset; + u64 committed; + u64 cap; + } oc_arena_chunk; -typedef struct oc_arena -{ - oc_base_allocator* base; - oc_list chunks; - oc_arena_chunk* currentChunk; + typedef struct oc_arena + { + oc_base_allocator* base; + oc_list chunks; + oc_arena_chunk* currentChunk; -} oc_arena; + } oc_arena; -typedef struct oc_arena_scope -{ - oc_arena* arena; - oc_arena_chunk* chunk; - u64 offset; -} oc_arena_scope; + typedef struct oc_arena_scope + { + oc_arena* arena; + oc_arena_chunk* chunk; + u64 offset; + } oc_arena_scope; -typedef struct oc_arena_options -{ - oc_base_allocator* base; - u64 reserve; -} oc_arena_options; + typedef struct oc_arena_options + { + oc_base_allocator* base; + u64 reserve; + } oc_arena_options; -ORCA_API void oc_arena_init(oc_arena* arena); -ORCA_API void oc_arena_init_with_options(oc_arena* arena, oc_arena_options* options); -ORCA_API void oc_arena_cleanup(oc_arena* arena); + ORCA_API void oc_arena_init(oc_arena* arena); + ORCA_API void oc_arena_init_with_options(oc_arena* arena, oc_arena_options* options); + ORCA_API void oc_arena_cleanup(oc_arena* arena); -ORCA_API void* oc_arena_push(oc_arena* arena, u64 size); -ORCA_API void oc_arena_clear(oc_arena* arena); + ORCA_API void* oc_arena_push(oc_arena* arena, u64 size); + ORCA_API void oc_arena_clear(oc_arena* arena); -ORCA_API oc_arena_scope oc_arena_scope_begin(oc_arena* arena); -ORCA_API void oc_arena_scope_end(oc_arena_scope scope); + ORCA_API oc_arena_scope oc_arena_scope_begin(oc_arena* arena); + ORCA_API void oc_arena_scope_end(oc_arena_scope scope); #define oc_arena_push_type(arena, type) ((type*)oc_arena_push(arena, sizeof(type))) -#define oc_arena_push_array(arena, type, count) ((type*)oc_arena_push(arena, sizeof(type)*(count))) +#define oc_arena_push_array(arena, type, count) ((type*)oc_arena_push(arena, sizeof(type) * (count))) -//-------------------------------------------------------------------------------- -//NOTE(martin): memory pool -//-------------------------------------------------------------------------------- + //-------------------------------------------------------------------------------- + //NOTE(martin): memory pool + //-------------------------------------------------------------------------------- -//TODO: we could probably remove pool. Most of the time we construct pool on top of -// arenas "manually" with different free lists per object types... + //TODO: we could probably remove pool. Most of the time we construct pool on top of + // arenas "manually" with different free lists per object types... -typedef struct oc_pool -{ - oc_arena arena; - oc_list freeList; - u64 blockSize; -} oc_pool; + typedef struct oc_pool + { + oc_arena arena; + oc_list freeList; + u64 blockSize; + } oc_pool; -typedef struct oc_pool_options -{ - oc_base_allocator* base; - u64 reserve; -} oc_pool_options; + typedef struct oc_pool_options + { + oc_base_allocator* base; + u64 reserve; + } oc_pool_options; -ORCA_API void oc_pool_init(oc_pool* pool, u64 blockSize); -ORCA_API void oc_pool_init_with_options(oc_pool* pool, u64 blockSize, oc_pool_options* options); -ORCA_API void oc_pool_cleanup(oc_pool* pool); + ORCA_API void oc_pool_init(oc_pool* pool, u64 blockSize); + ORCA_API void oc_pool_init_with_options(oc_pool* pool, u64 blockSize, oc_pool_options* options); + ORCA_API void oc_pool_cleanup(oc_pool* pool); -ORCA_API void* oc_pool_alloc(oc_pool* pool); -ORCA_API void oc_pool_recycle(oc_pool* pool, void* ptr); -ORCA_API void oc_pool_clear(oc_pool* pool); + ORCA_API void* oc_pool_alloc(oc_pool* pool); + ORCA_API void oc_pool_recycle(oc_pool* pool, void* ptr); + ORCA_API void oc_pool_clear(oc_pool* pool); #define oc_pool_alloc_type(arena, type) ((type*)oc_pool_alloc(arena)) -//-------------------------------------------------------------------------------- -//NOTE(martin): per-thread implicit scratch arena -//-------------------------------------------------------------------------------- -ORCA_API oc_arena* oc_scratch(); -ORCA_API oc_arena* oc_scratch_next(oc_arena* used); -ORCA_API oc_arena_scope oc_scratch_begin(); -ORCA_API oc_arena_scope oc_scratch_begin_next(oc_arena* used); + //-------------------------------------------------------------------------------- + //NOTE(martin): per-thread implicit scratch arena + //-------------------------------------------------------------------------------- + ORCA_API oc_arena* oc_scratch(); + ORCA_API oc_arena* oc_scratch_next(oc_arena* used); + ORCA_API oc_arena_scope oc_scratch_begin(); + ORCA_API oc_arena_scope oc_scratch_begin_next(oc_arena* used); #define oc_scratch_end(scope) oc_arena_scope_end(scope) diff --git a/src/util/ringbuffer.c b/src/util/ringbuffer.c index ba8bc9d..8cfe7cd 100644 --- a/src/util/ringbuffer.c +++ b/src/util/ringbuffer.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: ringbuffer.cpp * @author: Martin Fouilleul @@ -6,107 +6,107 @@ * @revision: * *****************************************************************/ -#include // malloc, free -#include"ringbuffer.h" +#include "ringbuffer.h" +#include // malloc, free void oc_ringbuffer_init(oc_ringbuffer* ring, u8 capExp) { - u64 cap = 1<mask = cap - 1; - ring->readIndex = 0; - ring->reserveIndex = 0; - ring->writeIndex = 0; - ring->buffer = (u8*)malloc(cap); + u64 cap = 1 << capExp; + ring->mask = cap - 1; + ring->readIndex = 0; + ring->reserveIndex = 0; + ring->writeIndex = 0; + ring->buffer = (u8*)malloc(cap); } void oc_ringbuffer_cleanup(oc_ringbuffer* ring) { - free(ring->buffer); + free(ring->buffer); } u64 oc_ringbuffer_read_available(oc_ringbuffer* ring) { - return((ring->writeIndex - ring->readIndex) & ring->mask); + return ((ring->writeIndex - ring->readIndex) & ring->mask); } u64 oc_ringbuffer_write_available(oc_ringbuffer* ring) { - //NOTE(martin): we keep one sentinel byte between write index and read index, - // when the buffer is full, to avoid overrunning read index. - return(((ring->readIndex - ring->reserveIndex) & ring->mask) - 1); + //NOTE(martin): we keep one sentinel byte between write index and read index, + // when the buffer is full, to avoid overrunning read index. + return (((ring->readIndex - ring->reserveIndex) & ring->mask) - 1); } u64 oc_ringbuffer_read(oc_ringbuffer* ring, u64 size, u8* data) { - u64 read = ring->readIndex; - u64 write = ring->writeIndex; + u64 read = ring->readIndex; + u64 write = ring->writeIndex; - u64 readAvailable = oc_ringbuffer_read_available(ring); - if(size > readAvailable) - { - size = readAvailable; - } + u64 readAvailable = oc_ringbuffer_read_available(ring); + if(size > readAvailable) + { + size = readAvailable; + } - if(read <= write) - { - memcpy(data, ring->buffer + read, size); - } - else - { - u64 copyCount = oc_min(size, ring->mask + 1 - read); - memcpy(data, ring->buffer + read, copyCount); + if(read <= write) + { + memcpy(data, ring->buffer + read, size); + } + else + { + u64 copyCount = oc_min(size, ring->mask + 1 - read); + memcpy(data, ring->buffer + read, copyCount); - data += copyCount; - copyCount = size - copyCount; - memcpy(data, ring->buffer, copyCount); - } - ring->readIndex = (read + size) & ring->mask; - return(size); + data += copyCount; + copyCount = size - copyCount; + memcpy(data, ring->buffer, copyCount); + } + ring->readIndex = (read + size) & ring->mask; + return (size); } u64 oc_ringbuffer_reserve(oc_ringbuffer* ring, u64 size, u8* data) { - u64 read = ring->readIndex; - u64 reserve = ring->reserveIndex; + u64 read = ring->readIndex; + u64 reserve = ring->reserveIndex; - u64 writeAvailable = oc_ringbuffer_write_available(ring); - if(size > writeAvailable) - { - OC_DEBUG_ASSERT("not enough space available"); - size = writeAvailable; - } + u64 writeAvailable = oc_ringbuffer_write_available(ring); + if(size > writeAvailable) + { + OC_DEBUG_ASSERT("not enough space available"); + size = writeAvailable; + } - if(read <= reserve) - { - u64 copyCount = oc_min(size, ring->mask + 1 - reserve); - memcpy(ring->buffer + reserve, data, copyCount); + if(read <= reserve) + { + u64 copyCount = oc_min(size, ring->mask + 1 - reserve); + memcpy(ring->buffer + reserve, data, copyCount); - data += copyCount; - copyCount = size - copyCount; - memcpy(ring->buffer, data, copyCount); - } - else - { - memcpy(ring->buffer + reserve, data, size); - } - ring->reserveIndex = (reserve + size) & ring->mask; - return(size); + data += copyCount; + copyCount = size - copyCount; + memcpy(ring->buffer, data, copyCount); + } + else + { + memcpy(ring->buffer + reserve, data, size); + } + ring->reserveIndex = (reserve + size) & ring->mask; + return (size); } u64 oc_ringbuffer_write(oc_ringbuffer* ring, u64 size, u8* data) { - oc_ringbuffer_commit(ring); - u64 res = oc_ringbuffer_reserve(ring, size, data); - oc_ringbuffer_commit(ring); - return(res); + oc_ringbuffer_commit(ring); + u64 res = oc_ringbuffer_reserve(ring, size, data); + oc_ringbuffer_commit(ring); + return (res); } void oc_ringbuffer_commit(oc_ringbuffer* ring) { - ring->writeIndex = ring->reserveIndex; + ring->writeIndex = ring->reserveIndex; } void oc_ringbuffer_rewind(oc_ringbuffer* ring) { - ring->reserveIndex = ring->writeIndex; + ring->reserveIndex = ring->writeIndex; } diff --git a/src/util/ringbuffer.h b/src/util/ringbuffer.h index c2ef438..cbe2ef7 100644 --- a/src/util/ringbuffer.h +++ b/src/util/ringbuffer.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: ringbuffer.h * @author: Martin Fouilleul @@ -9,34 +9,35 @@ #ifndef __RINGBUFFER_H_ #define __RINGBUFFER_H_ -#include +#include -#include"typedefs.h" +#include "typedefs.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -typedef struct ringbuffer -{ - u64 mask; - _Atomic(u64) readIndex; - _Atomic(u64) writeIndex; - u64 reserveIndex; + typedef struct ringbuffer + { + u64 mask; + _Atomic(u64) readIndex; + _Atomic(u64) writeIndex; + u64 reserveIndex; - u8* buffer; + u8* buffer; -} oc_ringbuffer; + } oc_ringbuffer; -void oc_ringbuffer_init(oc_ringbuffer* ring, u8 capExp); -void oc_ringbuffer_cleanup(oc_ringbuffer* ring); -u64 oc_ringbuffer_read_available(oc_ringbuffer* ring); -u64 oc_ringbuffer_write_available(oc_ringbuffer* ring); -u64 oc_ringbuffer_read(oc_ringbuffer* ring, u64 size, u8* data); -u64 oc_ringbuffer_write(oc_ringbuffer* ring, u64 size, u8* data); -u64 oc_ringbuffer_reserve(oc_ringbuffer* ring, u64 size, u8* data); -void oc_ringbuffer_commit(oc_ringbuffer* ring); -void oc_ringbuffer_rewind(oc_ringbuffer* ring); + void oc_ringbuffer_init(oc_ringbuffer* ring, u8 capExp); + void oc_ringbuffer_cleanup(oc_ringbuffer* ring); + u64 oc_ringbuffer_read_available(oc_ringbuffer* ring); + u64 oc_ringbuffer_write_available(oc_ringbuffer* ring); + u64 oc_ringbuffer_read(oc_ringbuffer* ring, u64 size, u8* data); + u64 oc_ringbuffer_write(oc_ringbuffer* ring, u64 size, u8* data); + u64 oc_ringbuffer_reserve(oc_ringbuffer* ring, u64 size, u8* data); + void oc_ringbuffer_commit(oc_ringbuffer* ring); + void oc_ringbuffer_rewind(oc_ringbuffer* ring); #ifdef __cplusplus } // extern "C" diff --git a/src/util/strings.c b/src/util/strings.c index 468eefa..c788774 100644 --- a/src/util/strings.c +++ b/src/util/strings.c @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: strings.c * @author: Martin Fouilleul @@ -6,8 +6,8 @@ * @revision: * *****************************************************************/ -#include"platform/platform_debug.h" -#include"strings.h" +#include "strings.h" +#include "platform/platform_debug.h" //---------------------------------------------------------------------------------- // string slices as values @@ -15,88 +15,88 @@ oc_str8 oc_str8_from_buffer(u64 len, char* buffer) { - return((oc_str8){.len = len, .ptr = buffer}); + return ((oc_str8){ .len = len, .ptr = buffer }); } oc_str8 oc_str8_slice(oc_str8 s, u64 start, u64 end) { - OC_ASSERT(start <= end && start <= s.len && end <= s.len); - return((oc_str8){.len = end - start, .ptr = s.ptr + start}); + OC_ASSERT(start <= end && start <= s.len && end <= s.len); + return ((oc_str8){ .len = end - start, .ptr = s.ptr + start }); } oc_str8 oc_str8_push_buffer(oc_arena* arena, u64 len, char* buffer) { - oc_str8 str = {0}; - str.len = len; - str.ptr = oc_arena_push_array(arena, char, len+1); - memcpy(str.ptr, buffer, len); - str.ptr[str.len] = '\0'; - return(str); + oc_str8 str = { 0 }; + str.len = len; + str.ptr = oc_arena_push_array(arena, char, len + 1); + memcpy(str.ptr, buffer, len); + str.ptr[str.len] = '\0'; + return (str); } oc_str8 oc_str8_push_cstring(oc_arena* arena, const char* str) { - int len = 0; - if(str) - { - len = strlen(str); - } - return(oc_str8_push_buffer(arena, strlen(str), (char*)str)); + int len = 0; + if(str) + { + len = strlen(str); + } + return (oc_str8_push_buffer(arena, strlen(str), (char*)str)); } oc_str8 oc_str8_push_copy(oc_arena* arena, oc_str8 s) { - return(oc_str8_push_buffer(arena, oc_str8_lp(s))); + return (oc_str8_push_buffer(arena, oc_str8_lp(s))); } char* oc_str8_to_cstring(oc_arena* arena, oc_str8 string) { - //NOTE: forward to push_copy, which null-terminates the copy - string = oc_str8_push_copy(arena, string); - return(string.ptr); + //NOTE: forward to push_copy, which null-terminates the copy + string = oc_str8_push_copy(arena, string); + return (string.ptr); } oc_str8 oc_str8_push_slice(oc_arena* arena, oc_str8 s, u64 start, u64 end) { - oc_str8 slice = oc_str8_slice(s, start, end); - return(oc_str8_push_copy(arena, slice)); + oc_str8 slice = oc_str8_slice(s, start, end); + return (oc_str8_push_copy(arena, slice)); } oc_str8 oc_str8_pushfv(oc_arena* arena, const char* format, va_list args) { - //NOTE(martin): - // We first compute the number of characters to write passing a size of 0. - // then we allocate len+1 (since vsnprint always terminates with a '\0'). + //NOTE(martin): + // We first compute the number of characters to write passing a size of 0. + // then we allocate len+1 (since vsnprint always terminates with a '\0'). - char dummy; - oc_str8 str = {0}; - va_list argCopy; - va_copy(argCopy, args); - str.len = vsnprintf(&dummy, 0, format, argCopy); - va_end(argCopy); + char dummy; + oc_str8 str = { 0 }; + va_list argCopy; + va_copy(argCopy, args); + str.len = vsnprintf(&dummy, 0, format, argCopy); + va_end(argCopy); - str.ptr = oc_arena_push_array(arena, char, str.len + 1); - vsnprintf((char*)str.ptr, str.len + 1, format, args); - return(str); + str.ptr = oc_arena_push_array(arena, char, str.len + 1); + vsnprintf((char*)str.ptr, str.len + 1, format, args); + return (str); } oc_str8 oc_str8_pushf(oc_arena* arena, const char* format, ...) { - va_list args; - va_start(args, format); - oc_str8 str = oc_str8_pushfv(arena, format, args); - va_end(args); - return(str); + va_list args; + va_start(args, format); + oc_str8 str = oc_str8_pushfv(arena, format, args); + va_end(args); + return (str); } int oc_str8_cmp(oc_str8 s1, oc_str8 s2) { - int res = strncmp(s1.ptr, s2.ptr, oc_min(s1.len, s2.len)); - if(!res) - { - res = (s1.len < s2.len)? -1 : ((s1.len == s2.len)? 0 : 1); - } - return(res); + int res = strncmp(s1.ptr, s2.ptr, oc_min(s1.len, s2.len)); + if(!res) + { + res = (s1.len < s2.len) ? -1 : ((s1.len == s2.len) ? 0 : 1); + } + return (res); } //---------------------------------------------------------------------------------- @@ -105,116 +105,116 @@ int oc_str8_cmp(oc_str8 s1, oc_str8 s2) void oc_str8_list_init(oc_str8_list* list) { - oc_list_init(&list->list); - list->eltCount = 0; - list->len = 0; + oc_list_init(&list->list); + list->eltCount = 0; + list->len = 0; } void oc_str8_list_push(oc_arena* arena, oc_str8_list* list, oc_str8 str) { - oc_str8_elt* elt = oc_arena_push_type(arena, oc_str8_elt); - elt->string = str; - oc_list_append(&list->list, &elt->listElt); - list->eltCount++; - list->len += str.len; + oc_str8_elt* elt = oc_arena_push_type(arena, oc_str8_elt); + elt->string = str; + oc_list_append(&list->list, &elt->listElt); + list->eltCount++; + list->len += str.len; } void oc_str8_list_pushf(oc_arena* arena, oc_str8_list* list, const char* format, ...) { - va_list args; - va_start(args, format); - oc_str8 str = oc_str8_pushfv(arena, format, args); - va_end(args); - oc_str8_list_push(arena, list, str); + va_list args; + va_start(args, format); + oc_str8 str = oc_str8_pushfv(arena, format, args); + va_end(args); + oc_str8_list_push(arena, list, str); } oc_str8 oc_str8_list_collate(oc_arena* arena, oc_str8_list list, oc_str8 prefix, oc_str8 separator, oc_str8 postfix) { - oc_str8 str = {0}; - str.len = prefix.len + list.len + list.eltCount*separator.len + postfix.len; - str.ptr = oc_arena_push_array(arena, char, str.len + 1); - char* dst = str.ptr; - memcpy(dst, prefix.ptr, prefix.len); - dst += prefix.len; + oc_str8 str = { 0 }; + str.len = prefix.len + list.len + list.eltCount * separator.len + postfix.len; + str.ptr = oc_arena_push_array(arena, char, str.len + 1); + char* dst = str.ptr; + memcpy(dst, prefix.ptr, prefix.len); + dst += prefix.len; - oc_str8_elt* elt = oc_list_first_entry(&list.list, oc_str8_elt, listElt); - if(elt) - { - memcpy(dst, elt->string.ptr, elt->string.len); - dst += elt->string.len; - elt = oc_list_next_entry(&list.list, elt, oc_str8_elt, listElt); - } + oc_str8_elt* elt = oc_list_first_entry(&list.list, oc_str8_elt, listElt); + if(elt) + { + memcpy(dst, elt->string.ptr, elt->string.len); + dst += elt->string.len; + elt = oc_list_next_entry(&list.list, elt, oc_str8_elt, listElt); + } - for( ; elt != 0; elt = oc_list_next_entry(&list.list, elt, oc_str8_elt, listElt)) - { - memcpy(dst, separator.ptr, separator.len); - dst += separator.len; - memcpy(dst, elt->string.ptr, elt->string.len); - dst += elt->string.len; - } - memcpy(dst, postfix.ptr, postfix.len); - str.ptr[str.len] = '\0'; - return(str); + for(; elt != 0; elt = oc_list_next_entry(&list.list, elt, oc_str8_elt, listElt)) + { + memcpy(dst, separator.ptr, separator.len); + dst += separator.len; + memcpy(dst, elt->string.ptr, elt->string.len); + dst += elt->string.len; + } + memcpy(dst, postfix.ptr, postfix.len); + str.ptr[str.len] = '\0'; + return (str); } oc_str8 oc_str8_list_join(oc_arena* arena, oc_str8_list list) { - oc_str8 empty = {.len = 0, .ptr = 0}; - return(oc_str8_list_collate(arena, list, empty, empty, empty)); + oc_str8 empty = { .len = 0, .ptr = 0 }; + return (oc_str8_list_collate(arena, list, empty, empty, empty)); } oc_str8_list oc_str8_split(oc_arena* arena, oc_str8 str, oc_str8_list separators) { - oc_str8_list list = {0}; - oc_list_init(&list.list); + oc_str8_list list = { 0 }; + oc_list_init(&list.list); - char* ptr = str.ptr; - char* end = str.ptr + str.len; - char* subStart = ptr; - for(; ptr < end; ptr++) - { - //NOTE(martin): search all separators and try to match them to the current ptr - oc_str8* foundSep = 0; - oc_list_for(&separators.list, elt, oc_str8_elt, listElt) - { - oc_str8* separator = &elt->string; - bool equal = true; - for(u64 offset = 0; - (offset < separator->len) && (ptr+offset < end); - offset++) - { - if(separator->ptr[offset] != ptr[offset]) - { - equal = false; - break; - } - } - if(equal) - { - foundSep = separator; - break; - } - } - if(foundSep) - { - //NOTE(martin): we found a separator. If the start of the current substring is != ptr, - // the current substring is not empty and we emit the substring - if(ptr != subStart) - { - oc_str8 sub = oc_str8_from_buffer(ptr-subStart, subStart); - oc_str8_list_push(arena, &list, sub); - } - ptr += foundSep->len - 1; //NOTE(martin): ptr is incremented at the end of the loop - subStart = ptr+1; - } - } - //NOTE(martin): emit the last substring - if(ptr != subStart) - { - oc_str8 sub = oc_str8_from_buffer(ptr-subStart, subStart); - oc_str8_list_push(arena, &list, sub); - } - return(list); + char* ptr = str.ptr; + char* end = str.ptr + str.len; + char* subStart = ptr; + for(; ptr < end; ptr++) + { + //NOTE(martin): search all separators and try to match them to the current ptr + oc_str8* foundSep = 0; + oc_list_for(&separators.list, elt, oc_str8_elt, listElt) + { + oc_str8* separator = &elt->string; + bool equal = true; + for(u64 offset = 0; + (offset < separator->len) && (ptr + offset < end); + offset++) + { + if(separator->ptr[offset] != ptr[offset]) + { + equal = false; + break; + } + } + if(equal) + { + foundSep = separator; + break; + } + } + if(foundSep) + { + //NOTE(martin): we found a separator. If the start of the current substring is != ptr, + // the current substring is not empty and we emit the substring + if(ptr != subStart) + { + oc_str8 sub = oc_str8_from_buffer(ptr - subStart, subStart); + oc_str8_list_push(arena, &list, sub); + } + ptr += foundSep->len - 1; //NOTE(martin): ptr is incremented at the end of the loop + subStart = ptr + 1; + } + } + //NOTE(martin): emit the last substring + if(ptr != subStart) + { + oc_str8 sub = oc_str8_from_buffer(ptr - subStart, subStart); + oc_str8_list_push(arena, &list, sub); + } + return (list); } //---------------------------------------------------------------------------------- @@ -222,85 +222,85 @@ oc_str8_list oc_str8_split(oc_arena* arena, oc_str8 str, oc_str8_list separators //---------------------------------------------------------------------------------- oc_str16 oc_str16_from_buffer(u64 len, u16* buffer) { - return((oc_str16){.len = len, .ptr = buffer}); + return ((oc_str16){ .len = len, .ptr = buffer }); } oc_str16 oc_str16_slice(oc_str16 s, u64 start, u64 end) { - OC_ASSERT(start <= end && start <= s.len && end <= s.len); - return((oc_str16){.len = end - start, .ptr = s.ptr + start}); + OC_ASSERT(start <= end && start <= s.len && end <= s.len); + return ((oc_str16){ .len = end - start, .ptr = s.ptr + start }); } oc_str16 oc_str16_push_buffer(oc_arena* arena, u64 len, u16* buffer) { - oc_str16 str = {0}; - str.len = len; - str.ptr = oc_arena_push_array(arena, u16, len+1); - memcpy(str.ptr, buffer, len*sizeof(u16)); - str.ptr[str.len] = (u16)0; - return(str); + oc_str16 str = { 0 }; + str.len = len; + str.ptr = oc_arena_push_array(arena, u16, len + 1); + memcpy(str.ptr, buffer, len * sizeof(u16)); + str.ptr[str.len] = (u16)0; + return (str); } oc_str16 oc_str16_push_copy(oc_arena* arena, oc_str16 s) { - return(oc_str16_push_buffer(arena, s.len, s.ptr)); + return (oc_str16_push_buffer(arena, s.len, s.ptr)); } oc_str16 oc_str16_push_slice(oc_arena* arena, oc_str16 s, u64 start, u64 end) { - oc_str16 slice = oc_str16_slice(s, start, end); - return(oc_str16_push_copy(arena, slice)); + oc_str16 slice = oc_str16_slice(s, start, end); + return (oc_str16_push_copy(arena, slice)); } void oc_str16_list_init(oc_str16_list* list) { - oc_list_init(&list->list); - list->eltCount = 0; - list->len = 0; + oc_list_init(&list->list); + list->eltCount = 0; + list->len = 0; } void oc_str16_list_push(oc_arena* arena, oc_str16_list* list, oc_str16 str) { - oc_str16_elt* elt = oc_arena_push_type(arena, oc_str16_elt); - elt->string = str; - oc_list_append(&list->list, &elt->listElt); - list->eltCount++; - list->len += str.len; + oc_str16_elt* elt = oc_arena_push_type(arena, oc_str16_elt); + elt->string = str; + oc_list_append(&list->list, &elt->listElt); + list->eltCount++; + list->len += str.len; } oc_str16 oc_str16_list_collate(oc_arena* arena, oc_str16_list list, oc_str16 prefix, oc_str16 separator, oc_str16 postfix) { - oc_str16 str = {0}; - str.len = prefix.len + list.len + list.eltCount*separator.len + postfix.len; - str.ptr = oc_arena_push_array(arena, u16, str.len + 1); - char* dst = (char*)str.ptr; - memcpy(dst, prefix.ptr, prefix.len*sizeof(u16)); - dst += prefix.len*sizeof(u16); + oc_str16 str = { 0 }; + str.len = prefix.len + list.len + list.eltCount * separator.len + postfix.len; + str.ptr = oc_arena_push_array(arena, u16, str.len + 1); + char* dst = (char*)str.ptr; + memcpy(dst, prefix.ptr, prefix.len * sizeof(u16)); + dst += prefix.len * sizeof(u16); - oc_str16_elt* elt = oc_list_first_entry(&list.list, oc_str16_elt, listElt); - if(elt) - { - memcpy(dst, elt->string.ptr, elt->string.len*sizeof(u16)); - dst += elt->string.len*sizeof(u16); - elt = oc_list_next_entry(&list.list, elt, oc_str16_elt, listElt); - } + oc_str16_elt* elt = oc_list_first_entry(&list.list, oc_str16_elt, listElt); + if(elt) + { + memcpy(dst, elt->string.ptr, elt->string.len * sizeof(u16)); + dst += elt->string.len * sizeof(u16); + elt = oc_list_next_entry(&list.list, elt, oc_str16_elt, listElt); + } - for( ; elt != 0; elt = oc_list_next_entry(&list.list, elt, oc_str16_elt, listElt)) - { - memcpy(dst, separator.ptr, separator.len*sizeof(u16)); - dst += separator.len*sizeof(u16); - memcpy(dst, elt->string.ptr, elt->string.len*sizeof(u16)); - dst += elt->string.len*sizeof(u16); - } - memcpy(dst, postfix.ptr, postfix.len*sizeof(u16)); - str.ptr[str.len] = (u16)0; - return(str); + for(; elt != 0; elt = oc_list_next_entry(&list.list, elt, oc_str16_elt, listElt)) + { + memcpy(dst, separator.ptr, separator.len * sizeof(u16)); + dst += separator.len * sizeof(u16); + memcpy(dst, elt->string.ptr, elt->string.len * sizeof(u16)); + dst += elt->string.len * sizeof(u16); + } + memcpy(dst, postfix.ptr, postfix.len * sizeof(u16)); + str.ptr[str.len] = (u16)0; + return (str); } oc_str16 oc_str16_list_join(oc_arena* arena, oc_str16_list list) { - oc_str16 empty = {.len = 0, .ptr = 0}; - return(oc_str16_list_collate(arena, list, empty, empty, empty)); + oc_str16 empty = { .len = 0, .ptr = 0 }; + return (oc_str16_list_collate(arena, list, empty, empty, empty)); } //---------------------------------------------------------------------------------- @@ -308,83 +308,83 @@ oc_str16 oc_str16_list_join(oc_arena* arena, oc_str16_list list) //---------------------------------------------------------------------------------- oc_str32 oc_str32_from_buffer(u64 len, u32* buffer) { - return((oc_str32){.len = len, .ptr = buffer}); + return ((oc_str32){ .len = len, .ptr = buffer }); } oc_str32 oc_str32_slice(oc_str32 s, u64 start, u64 end) { - OC_ASSERT(start <= end && start <= s.len && end <= s.len); - return((oc_str32){.len = end - start, .ptr = s.ptr + start}); + OC_ASSERT(start <= end && start <= s.len && end <= s.len); + return ((oc_str32){ .len = end - start, .ptr = s.ptr + start }); } oc_str32 oc_str32_push_buffer(oc_arena* arena, u64 len, u32* buffer) { - oc_str32 str = {0}; - str.len = len; - str.ptr = oc_arena_push_array(arena, u32, len+1); - memcpy(str.ptr, buffer, len*sizeof(u32)); - str.ptr[str.len] = 0; - return(str); + oc_str32 str = { 0 }; + str.len = len; + str.ptr = oc_arena_push_array(arena, u32, len + 1); + memcpy(str.ptr, buffer, len * sizeof(u32)); + str.ptr[str.len] = 0; + return (str); } oc_str32 oc_str32_push_copy(oc_arena* arena, oc_str32 s) { - return(oc_str32_push_buffer(arena, s.len, s.ptr)); + return (oc_str32_push_buffer(arena, s.len, s.ptr)); } oc_str32 oc_str32_push_slice(oc_arena* arena, oc_str32 s, u64 start, u64 end) { - oc_str32 slice = oc_str32_slice(s, start, end); - return(oc_str32_push_copy(arena, slice)); + oc_str32 slice = oc_str32_slice(s, start, end); + return (oc_str32_push_copy(arena, slice)); } void oc_str32_list_init(oc_str32_list* list) { - oc_list_init(&list->list); - list->eltCount = 0; - list->len = 0; + oc_list_init(&list->list); + list->eltCount = 0; + list->len = 0; } void oc_str32_list_push(oc_arena* arena, oc_str32_list* list, oc_str32 str) { - oc_str32_elt* elt = oc_arena_push_type(arena, oc_str32_elt); - elt->string = str; - oc_list_append(&list->list, &elt->listElt); - list->eltCount++; - list->len += str.len; + oc_str32_elt* elt = oc_arena_push_type(arena, oc_str32_elt); + elt->string = str; + oc_list_append(&list->list, &elt->listElt); + list->eltCount++; + list->len += str.len; } oc_str32 oc_str32_list_collate(oc_arena* arena, oc_str32_list list, oc_str32 prefix, oc_str32 separator, oc_str32 postfix) { - oc_str32 str = {0}; - str.len = prefix.len + list.len + list.eltCount*separator.len + postfix.len; - str.ptr = oc_arena_push_array(arena, u32, str.len+1); - char* dst = (char*)str.ptr; - memcpy(dst, prefix.ptr, prefix.len*sizeof(u32)); - dst += prefix.len*sizeof(u32); + oc_str32 str = { 0 }; + str.len = prefix.len + list.len + list.eltCount * separator.len + postfix.len; + str.ptr = oc_arena_push_array(arena, u32, str.len + 1); + char* dst = (char*)str.ptr; + memcpy(dst, prefix.ptr, prefix.len * sizeof(u32)); + dst += prefix.len * sizeof(u32); - oc_str32_elt* elt = oc_list_first_entry(&list.list, oc_str32_elt, listElt); - if(elt) - { - memcpy(dst, elt->string.ptr, elt->string.len*sizeof(u32)); - dst += elt->string.len*sizeof(u32); - elt = oc_list_next_entry(&list.list, elt, oc_str32_elt, listElt); - } + oc_str32_elt* elt = oc_list_first_entry(&list.list, oc_str32_elt, listElt); + if(elt) + { + memcpy(dst, elt->string.ptr, elt->string.len * sizeof(u32)); + dst += elt->string.len * sizeof(u32); + elt = oc_list_next_entry(&list.list, elt, oc_str32_elt, listElt); + } - for( ; elt != 0; elt = oc_list_next_entry(&list.list, elt, oc_str32_elt, listElt)) - { - memcpy(dst, separator.ptr, separator.len*sizeof(u32)); - dst += separator.len*sizeof(u32); - memcpy(dst, elt->string.ptr, elt->string.len*sizeof(u32)); - dst += elt->string.len*sizeof(u32); - } - memcpy(dst, postfix.ptr, postfix.len*sizeof(u32)); - str.ptr[str.len] = 0; - return(str); + for(; elt != 0; elt = oc_list_next_entry(&list.list, elt, oc_str32_elt, listElt)) + { + memcpy(dst, separator.ptr, separator.len * sizeof(u32)); + dst += separator.len * sizeof(u32); + memcpy(dst, elt->string.ptr, elt->string.len * sizeof(u32)); + dst += elt->string.len * sizeof(u32); + } + memcpy(dst, postfix.ptr, postfix.len * sizeof(u32)); + str.ptr[str.len] = 0; + return (str); } oc_str32 oc_str32_list_join(oc_arena* arena, oc_str32_list list) { - oc_str32 empty = {.len = 0, .ptr = 0}; - return(oc_str32_list_collate(arena, list, empty, empty, empty)); + oc_str32 empty = { .len = 0, .ptr = 0 }; + return (oc_str32_list_collate(arena, list, empty, empty, empty)); } diff --git a/src/util/strings.h b/src/util/strings.h index f3a45e7..4f574be 100644 --- a/src/util/strings.h +++ b/src/util/strings.h @@ -1,4 +1,4 @@ -/************************************************************//** +/************************************************************/ /** * * @file: strings.h * @author: Martin Fouilleul @@ -9,18 +9,19 @@ #ifndef __STRINGS_H_ #define __STRINGS_H_ -#include"typedefs.h" -#include"debug.h" -#include"lists.h" -#include"memory.h" -#include -#include +#include "debug.h" +#include "lists.h" +#include "memory.h" +#include "typedefs.h" +#include +#include #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -/*NOTE: + /*NOTE: By convention, functions that take an arena and return a string slice allocated on this arena, always allocate one more element and null-terminate the string. This is done so we can pass those strings directly to C APIs that requires C strings without @@ -30,129 +31,132 @@ extern "C" { into the original string. Only the _list nodes_ are allocated on the arena. */ -//---------------------------------------------------------------------------------- -// u8 strings -//---------------------------------------------------------------------------------- -typedef struct oc_str8 -{ - u64 len; - char* ptr; -} oc_str8; + //---------------------------------------------------------------------------------- + // u8 strings + //---------------------------------------------------------------------------------- + typedef struct oc_str8 + { + u64 len; + char* ptr; + } oc_str8; -#define OC_STR8(s) ((oc_str8){.len = (s) ? strlen(s) : 0, .ptr = (char*)s}) +#define OC_STR8(s) ((oc_str8){ .len = (s) ? strlen(s) : 0, .ptr = (char*)s }) //NOTE: this only works with string literals, but is sometimes necessary to generate compile-time constants -#define OC_STR8_LIT(s) {sizeof(s)-1, s} +#define OC_STR8_LIT(s) \ + { \ + sizeof(s) - 1, s \ + } #define oc_str8_lp(s) ((s).len), ((s).ptr) #define oc_str8_ip(s) (int)oc_str8_lp(s) -ORCA_API oc_str8 oc_str8_from_buffer(u64 len, char* buffer); -ORCA_API oc_str8 oc_str8_slice(oc_str8 s, u64 start, u64 end); + ORCA_API oc_str8 oc_str8_from_buffer(u64 len, char* buffer); + ORCA_API oc_str8 oc_str8_slice(oc_str8 s, u64 start, u64 end); -ORCA_API oc_str8 oc_str8_push_buffer(oc_arena* arena, u64 len, char* buffer); -ORCA_API oc_str8 oc_str8_push_cstring(oc_arena* arena, const char* str); -ORCA_API oc_str8 oc_str8_push_copy(oc_arena* arena, oc_str8 s); -ORCA_API oc_str8 oc_str8_push_slice(oc_arena* arena, oc_str8 s, u64 start, u64 end); + ORCA_API oc_str8 oc_str8_push_buffer(oc_arena* arena, u64 len, char* buffer); + ORCA_API oc_str8 oc_str8_push_cstring(oc_arena* arena, const char* str); + ORCA_API oc_str8 oc_str8_push_copy(oc_arena* arena, oc_str8 s); + ORCA_API oc_str8 oc_str8_push_slice(oc_arena* arena, oc_str8 s, u64 start, u64 end); -ORCA_API oc_str8 oc_str8_pushfv(oc_arena* arena, const char* format, va_list args); -ORCA_API oc_str8 oc_str8_pushf(oc_arena* arena, const char* format, ...); + ORCA_API oc_str8 oc_str8_pushfv(oc_arena* arena, const char* format, va_list args); + ORCA_API oc_str8 oc_str8_pushf(oc_arena* arena, const char* format, ...); -ORCA_API int oc_str8_cmp(oc_str8 s1, oc_str8 s2); + ORCA_API int oc_str8_cmp(oc_str8 s1, oc_str8 s2); -ORCA_API char* oc_str8_to_cstring(oc_arena* arena, oc_str8 string); -//---------------------------------------------------------------------------------- -// string lists -//---------------------------------------------------------------------------------- -typedef struct oc_str8_elt -{ - oc_list_elt listElt; - oc_str8 string; -} oc_str8_elt; + ORCA_API char* oc_str8_to_cstring(oc_arena* arena, oc_str8 string); -typedef struct oc_str8_list -{ - oc_list list; - u64 eltCount; - u64 len; -} oc_str8_list; + //---------------------------------------------------------------------------------- + // string lists + //---------------------------------------------------------------------------------- + typedef struct oc_str8_elt + { + oc_list_elt listElt; + oc_str8 string; + } oc_str8_elt; -ORCA_API void oc_str8_list_push(oc_arena* arena, oc_str8_list* list, oc_str8 str); -ORCA_API void oc_str8_list_pushf(oc_arena* arena, oc_str8_list* list, const char* format, ...); + typedef struct oc_str8_list + { + oc_list list; + u64 eltCount; + u64 len; + } oc_str8_list; -ORCA_API oc_str8 oc_str8_list_collate(oc_arena* arena, oc_str8_list list, oc_str8 prefix, oc_str8 separator, oc_str8 postfix); -ORCA_API oc_str8 oc_str8_list_join(oc_arena* arena, oc_str8_list list); -ORCA_API oc_str8_list oc_str8_split(oc_arena* arena, oc_str8 str, oc_str8_list separators); + ORCA_API void oc_str8_list_push(oc_arena* arena, oc_str8_list* list, oc_str8 str); + ORCA_API void oc_str8_list_pushf(oc_arena* arena, oc_str8_list* list, const char* format, ...); -//---------------------------------------------------------------------------------- -// u16 strings -//---------------------------------------------------------------------------------- -typedef struct oc_str16 -{ - u64 len; - u16* ptr; -} oc_str16; + ORCA_API oc_str8 oc_str8_list_collate(oc_arena* arena, oc_str8_list list, oc_str8 prefix, oc_str8 separator, oc_str8 postfix); + ORCA_API oc_str8 oc_str8_list_join(oc_arena* arena, oc_str8_list list); + ORCA_API oc_str8_list oc_str8_split(oc_arena* arena, oc_str8 str, oc_str8_list separators); -ORCA_API oc_str16 oc_str16_from_buffer(u64 len, u16* buffer); -ORCA_API oc_str16 oc_str16_slice(oc_str16 s, u64 start, u64 end); + //---------------------------------------------------------------------------------- + // u16 strings + //---------------------------------------------------------------------------------- + typedef struct oc_str16 + { + u64 len; + u16* ptr; + } oc_str16; -ORCA_API oc_str16 oc_str16_push_buffer(oc_arena* arena, u64 len, u16* buffer); -ORCA_API oc_str16 oc_str16_push_copy(oc_arena* arena, oc_str16 s); -ORCA_API oc_str16 oc_str16_push_slice(oc_arena* arena, oc_str16 s, u64 start, u64 end); + ORCA_API oc_str16 oc_str16_from_buffer(u64 len, u16* buffer); + ORCA_API oc_str16 oc_str16_slice(oc_str16 s, u64 start, u64 end); -typedef struct oc_str16_elt -{ - oc_list_elt listElt; - oc_str16 string; -} oc_str16_elt; + ORCA_API oc_str16 oc_str16_push_buffer(oc_arena* arena, u64 len, u16* buffer); + ORCA_API oc_str16 oc_str16_push_copy(oc_arena* arena, oc_str16 s); + ORCA_API oc_str16 oc_str16_push_slice(oc_arena* arena, oc_str16 s, u64 start, u64 end); -typedef struct oc_str16_list -{ - oc_list list; - u64 eltCount; - u64 len; -} oc_str16_list; + typedef struct oc_str16_elt + { + oc_list_elt listElt; + oc_str16 string; + } oc_str16_elt; -ORCA_API void oc_str16_list_push(oc_arena* arena, oc_str16_list* list, oc_str16 str); -ORCA_API oc_str16 oc_str16_list_join(oc_arena* arena, oc_str16_list list); -ORCA_API oc_str16_list oc_str16_split(oc_arena* arena, oc_str16 str, oc_str16_list separators); + typedef struct oc_str16_list + { + oc_list list; + u64 eltCount; + u64 len; + } oc_str16_list; -//---------------------------------------------------------------------------------- -// u32 strings -//---------------------------------------------------------------------------------- -typedef struct oc_str32 -{ - u64 len; - u32* ptr; -} oc_str32; + ORCA_API void oc_str16_list_push(oc_arena* arena, oc_str16_list* list, oc_str16 str); + ORCA_API oc_str16 oc_str16_list_join(oc_arena* arena, oc_str16_list list); + ORCA_API oc_str16_list oc_str16_split(oc_arena* arena, oc_str16 str, oc_str16_list separators); -ORCA_API oc_str32 oc_str32_from_buffer(u64 len, u32* buffer); -ORCA_API oc_str32 oc_str32_slice(oc_str32 s, u64 start, u64 end); + //---------------------------------------------------------------------------------- + // u32 strings + //---------------------------------------------------------------------------------- + typedef struct oc_str32 + { + u64 len; + u32* ptr; + } oc_str32; -ORCA_API oc_str32 oc_str32_push_buffer(oc_arena* arena, u64 len, u32* buffer); -ORCA_API oc_str32 oc_str32_push_copy(oc_arena* arena, oc_str32 s); -ORCA_API oc_str32 oc_str32_push_slice(oc_arena* arena, oc_str32 s, u64 start, u64 end); + ORCA_API oc_str32 oc_str32_from_buffer(u64 len, u32* buffer); + ORCA_API oc_str32 oc_str32_slice(oc_str32 s, u64 start, u64 end); -typedef struct oc_str32_elt -{ - oc_list_elt listElt; - oc_str32 string; -} oc_str32_elt; + ORCA_API oc_str32 oc_str32_push_buffer(oc_arena* arena, u64 len, u32* buffer); + ORCA_API oc_str32 oc_str32_push_copy(oc_arena* arena, oc_str32 s); + ORCA_API oc_str32 oc_str32_push_slice(oc_arena* arena, oc_str32 s, u64 start, u64 end); -typedef struct oc_str32_list -{ - oc_list list; - u64 eltCount; - u64 len; -} oc_str32_list; + typedef struct oc_str32_elt + { + oc_list_elt listElt; + oc_str32 string; + } oc_str32_elt; -ORCA_API void oc_str32_list_push(oc_arena* arena, oc_str32_list* list, oc_str32 str); -ORCA_API oc_str32 oc_str32_list_join(oc_arena* arena, oc_str32_list list); -ORCA_API oc_str32_list oc_str32_split(oc_arena* arena, oc_str32 str, oc_str32_list separators); + typedef struct oc_str32_list + { + oc_list list; + u64 eltCount; + u64 len; + } oc_str32_list; + + ORCA_API void oc_str32_list_push(oc_arena* arena, oc_str32_list* list, oc_str32 str); + ORCA_API oc_str32 oc_str32_list_join(oc_arena* arena, oc_str32_list list); + ORCA_API oc_str32_list oc_str32_split(oc_arena* arena, oc_str32 str, oc_str32_list separators); #ifdef __cplusplus } // extern "C" #endif - #endif //__STRINGS_H_ diff --git a/src/util/typedefs.h b/src/util/typedefs.h index 1522bae..81913b9 100644 --- a/src/util/typedefs.h +++ b/src/util/typedefs.h @@ -10,91 +10,97 @@ #ifndef __TYPEDEFS_H_ #define __TYPEDEFS_H_ -#include -#include -#include //FLT_MAX/MIN etc... +#include //FLT_MAX/MIN etc... +#include +#include #ifndef __cplusplus -#include + #include #endif //__cplusplus -typedef uint8_t byte; -typedef uint8_t u8; +typedef uint8_t byte; +typedef uint8_t u8; typedef uint16_t u16; typedef uint32_t u32; typedef uint64_t u64; -typedef int8_t i8; -typedef int16_t i16; -typedef int32_t i32; -typedef int64_t i64; +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; -typedef float f32; -typedef double f64; +typedef float f32; +typedef double f64; typedef union { - struct - { - f32 x; - f32 y; - }; - f32 c[2]; + struct + { + f32 x; + f32 y; + }; + + f32 c[2]; } oc_vec2; typedef union { - struct - { - f32 x; - f32 y; - f32 z; - }; - f32 c[3]; + struct + { + f32 x; + f32 y; + f32 z; + }; + + f32 c[3]; } oc_vec3; typedef union { - struct - { - i32 x; - i32 y; - }; - i32 c[2]; + struct + { + i32 x; + i32 y; + }; + + i32 c[2]; } oc_vec2i; typedef union { - struct - { - f32 x; - f32 y; - f32 z; - f32 w; - }; - f32 c[4]; + struct + { + f32 x; + f32 y; + f32 z; + f32 w; + }; + + f32 c[4]; } oc_vec4; typedef struct oc_mat2x3 { - f32 m[6]; + f32 m[6]; } oc_mat2x3; typedef union { - struct - { - f32 x; - f32 y; - f32 w; - f32 h; - }; - struct - { - oc_vec2 xy; - oc_vec2 wh; - }; - f32 c[4]; + struct + { + f32 x; + f32 y; + f32 w; + f32 h; + }; + + struct + { + oc_vec2 xy; + oc_vec2 wh; + }; + + f32 c[4]; } oc_rect; #endif //__TYPEDEFS_H_ diff --git a/src/util/utf8.c b/src/util/utf8.c index e49b319..482a458 100644 --- a/src/util/utf8.c +++ b/src/util/utf8.c @@ -7,27 +7,28 @@ // $note: (C) 2016 by Martin Fouilleul - all rights reserved $ // //***************************************************************** -#include"utf8.h" +#include "utf8.h" //----------------------------------------------------------------- // utf-8 gore //----------------------------------------------------------------- static const u32 offsetsFromUTF8[6] = { - 0x00000000UL, 0x00003080UL, 0x000E2080UL, - 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; - -static const char trailingBytesForUTF8[256] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 + 0x00000000UL, 0x00003080UL, 0x000E2080UL, + 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; -#define oc_utf8_is_start_byte(c) (((c)&0xc0)!=0x80) +static const char trailingBytesForUTF8[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5 +}; + +#define oc_utf8_is_start_byte(c) (((c)&0xc0) != 0x80) //----------------------------------------------------------------- //NOTE: getting sizes / offsets / indices @@ -35,89 +36,89 @@ static const char trailingBytesForUTF8[256] = { u32 oc_utf8_size_from_leading_char(char leadingChar) { - return(trailingBytesForUTF8[(unsigned int)(unsigned char)leadingChar] + 1); + return (trailingBytesForUTF8[(unsigned int)(unsigned char)leadingChar] + 1); } u32 oc_utf8_codepoint_size(oc_utf32 codePoint) { - if(codePoint < 0x80) - { - return(1); - } - if(codePoint < 0x800) - { - return(2); - } - if(codePoint < 0x10000) - { - return(3); - } - if(codePoint < 0x110000) - { - return(4); - } - return(0); + if(codePoint < 0x80) + { + return (1); + } + if(codePoint < 0x800) + { + return (2); + } + if(codePoint < 0x10000) + { + return (3); + } + if(codePoint < 0x110000) + { + return (4); + } + return (0); } u64 oc_utf8_codepoint_count_for_string(oc_str8 string) { - u64 byteOffset = 0; - u64 codePointIndex = 0; - for(; - (byteOffset < string.len) && (string.ptr[byteOffset] != 0); - codePointIndex++) - { - oc_utf8_dec decode = oc_utf8_decode_at(string, byteOffset); - byteOffset += decode.size; - } - return(codePointIndex); + u64 byteOffset = 0; + u64 codePointIndex = 0; + for(; + (byteOffset < string.len) && (string.ptr[byteOffset] != 0); + codePointIndex++) + { + oc_utf8_dec decode = oc_utf8_decode_at(string, byteOffset); + byteOffset += decode.size; + } + return (codePointIndex); } u64 oc_utf8_byte_count_for_codepoints(oc_str32 codePoints) { - //NOTE(martin): return the exact number of bytes taken by the encoded - // version of codePoints. (ie do not attempt to provision - // for a zero terminator). - u64 byteCount = 0; - for(u64 i=0; i= string.len) - { - res = string.len; - } - else - { - u64 nextOffset = byteOffset + oc_utf8_size_from_leading_char(string.ptr[byteOffset]); - res = oc_min(nextOffset, string.len); - } - return(res); + u64 res = 0; + if(byteOffset >= string.len) + { + res = string.len; + } + else + { + u64 nextOffset = byteOffset + oc_utf8_size_from_leading_char(string.ptr[byteOffset]); + res = oc_min(nextOffset, string.len); + } + return (res); } u64 oc_utf8_prev_offset(oc_str8 string, u64 byteOffset) { - u64 res = 0; - if(byteOffset > string.len) - { - res = string.len; - } - else if(byteOffset) - { - byteOffset--; - while(byteOffset > 0 && !oc_utf8_is_start_byte(string.ptr[byteOffset])) - { - byteOffset--; - } - res = byteOffset; - } - return(res); + u64 res = 0; + if(byteOffset > string.len) + { + res = string.len; + } + else if(byteOffset) + { + byteOffset--; + while(byteOffset > 0 && !oc_utf8_is_start_byte(string.ptr[byteOffset])) + { + byteOffset--; + } + res = byteOffset; + } + return (res); } //----------------------------------------------------------------- @@ -126,155 +127,155 @@ u64 oc_utf8_prev_offset(oc_str8 string, u64 byteOffset) oc_utf8_dec oc_utf8_decode_at(oc_str8 string, u64 offset) { - //NOTE(martin): get the first codepoint in str, and advance index to the - // next oc_utf8 character - //TODO(martin): check for utf-16 surrogate pairs - oc_utf32 cp = 0; - u64 sz = 0; + //NOTE(martin): get the first codepoint in str, and advance index to the + // next oc_utf8 character + //TODO(martin): check for utf-16 surrogate pairs + oc_utf32 cp = 0; + u64 sz = 0; - if(offset >= string.len || !string.ptr[offset]) - { - cp = 0; - sz = 1; - } - else if( !oc_utf8_is_start_byte(string.ptr[offset])) - { - //NOTE(martin): unexpected continuation or invalid character. - cp = 0xfffd; - sz = 1; - } - else - { - int expectedSize = oc_utf8_size_from_leading_char(string.ptr[offset]); - do - { - /*NOTE(martin): + if(offset >= string.len || !string.ptr[offset]) + { + cp = 0; + sz = 1; + } + else if(!oc_utf8_is_start_byte(string.ptr[offset])) + { + //NOTE(martin): unexpected continuation or invalid character. + cp = 0xfffd; + sz = 1; + } + else + { + int expectedSize = oc_utf8_size_from_leading_char(string.ptr[offset]); + do + { + /*NOTE(martin): we shift 6 bits and add the next byte at each round. at the end we have our oc_utf8 codepoint, added to the shifted versions of the oc_utf8 leading bits for each encoded byte. These values are precomputed in offsetsFromUTF8. */ - unsigned char b = string.ptr[offset]; - cp <<= 6; - cp += b; - offset += 1; - sz++; + unsigned char b = string.ptr[offset]; + cp <<= 6; + cp += b; + offset += 1; + sz++; - if(b == 0xc0 || b == 0xc1 || b >= 0xc5) - { - //NOTE(martin): invalid byte encountered - break; - } + if(b == 0xc0 || b == 0xc1 || b >= 0xc5) + { + //NOTE(martin): invalid byte encountered + break; + } - } while( offset < string.len - && string.ptr[offset] - && !oc_utf8_is_start_byte(string.ptr[offset]) - && sz < expectedSize); + } while(offset < string.len + && string.ptr[offset] + && !oc_utf8_is_start_byte(string.ptr[offset]) + && sz < expectedSize); - if(sz != expectedSize) - { - //NOTE(martin): if we encountered an error, we return the replacement codepoint U+FFFD - cp = 0xfffd; - } - else - { - cp -= offsetsFromUTF8[sz-1]; + if(sz != expectedSize) + { + //NOTE(martin): if we encountered an error, we return the replacement codepoint U+FFFD + cp = 0xfffd; + } + else + { + cp -= offsetsFromUTF8[sz - 1]; - //NOTE(martin): check for invalid codepoints - if(cp > 0x10ffff || (cp >= 0xd800 && cp <= 0xdfff)) - { - cp = 0xfffd; - } - } - } - oc_utf8_dec res = {.codepoint = cp, .size = sz}; - return(res); + //NOTE(martin): check for invalid codepoints + if(cp > 0x10ffff || (cp >= 0xd800 && cp <= 0xdfff)) + { + cp = 0xfffd; + } + } + } + oc_utf8_dec res = { .codepoint = cp, .size = sz }; + return (res); } oc_utf8_dec oc_utf8_decode(oc_str8 string) { - return(oc_utf8_decode_at(string, 0)); + return (oc_utf8_decode_at(string, 0)); } oc_str8 oc_utf8_encode(char* dest, oc_utf32 codePoint) { - u64 sz = 0; - if (codePoint < 0x80) - { - dest[0] = (char)codePoint; - sz = 1; - } - else if (codePoint < 0x800) - { - dest[0] = (codePoint>>6) | 0xC0; - dest[1] = (codePoint & 0x3F) | 0x80; - sz = 2; - } - else if (codePoint < 0x10000) - { - dest[0] = (codePoint>>12) | 0xE0; - dest[1] = ((codePoint>>6) & 0x3F) | 0x80; - dest[2] = (codePoint & 0x3F) | 0x80; - sz = 3; - } - else if (codePoint < 0x110000) - { - dest[0] = (codePoint>>18) | 0xF0; - dest[1] = ((codePoint>>12) & 0x3F) | 0x80; - dest[2] = ((codePoint>>6) & 0x3F) | 0x80; - dest[3] = (codePoint & 0x3F) | 0x80; - sz = 4; - } - oc_str8 res = {.len = sz, .ptr = dest}; - return(res); + u64 sz = 0; + if(codePoint < 0x80) + { + dest[0] = (char)codePoint; + sz = 1; + } + else if(codePoint < 0x800) + { + dest[0] = (codePoint >> 6) | 0xC0; + dest[1] = (codePoint & 0x3F) | 0x80; + sz = 2; + } + else if(codePoint < 0x10000) + { + dest[0] = (codePoint >> 12) | 0xE0; + dest[1] = ((codePoint >> 6) & 0x3F) | 0x80; + dest[2] = (codePoint & 0x3F) | 0x80; + sz = 3; + } + else if(codePoint < 0x110000) + { + dest[0] = (codePoint >> 18) | 0xF0; + dest[1] = ((codePoint >> 12) & 0x3F) | 0x80; + dest[2] = ((codePoint >> 6) & 0x3F) | 0x80; + dest[3] = (codePoint & 0x3F) | 0x80; + sz = 4; + } + oc_str8 res = { .len = sz, .ptr = dest }; + return (res); } oc_str32 oc_utf8_to_codepoints(u64 maxCount, oc_utf32* backing, oc_str8 string) { - u64 codePointIndex = 0; - u64 byteOffset = 0; - for(; codePointIndex < maxCount && byteOffset < string.len; codePointIndex++) - { - oc_utf8_dec decode = oc_utf8_decode_at(string, byteOffset); - backing[codePointIndex] = decode.codepoint; - byteOffset += decode.size; - } - oc_str32 res = {.len = codePointIndex, .ptr = backing}; - return(res); + u64 codePointIndex = 0; + u64 byteOffset = 0; + for(; codePointIndex < maxCount && byteOffset < string.len; codePointIndex++) + { + oc_utf8_dec decode = oc_utf8_decode_at(string, byteOffset); + backing[codePointIndex] = decode.codepoint; + byteOffset += decode.size; + } + oc_str32 res = { .len = codePointIndex, .ptr = backing }; + return (res); } oc_str8 oc_utf8_from_codepoints(u64 maxBytes, char* backing, oc_str32 codePoints) { - u64 byteOffset = 0; - for(u64 codePointIndex = 0; (codePointIndex < codePoints.len); codePointIndex++) - { - oc_utf32 codePoint = codePoints.ptr[codePointIndex]; - u32 byteCount = oc_utf8_codepoint_size(codePoint); - if(byteOffset + byteCount > maxBytes) - { - break; - } - oc_utf8_encode(backing+byteOffset, codePoint); - byteOffset += byteCount; - } - oc_str8 res = {.len = byteOffset, .ptr = backing}; - return(res); + u64 byteOffset = 0; + for(u64 codePointIndex = 0; (codePointIndex < codePoints.len); codePointIndex++) + { + oc_utf32 codePoint = codePoints.ptr[codePointIndex]; + u32 byteCount = oc_utf8_codepoint_size(codePoint); + if(byteOffset + byteCount > maxBytes) + { + break; + } + oc_utf8_encode(backing + byteOffset, codePoint); + byteOffset += byteCount; + } + oc_str8 res = { .len = byteOffset, .ptr = backing }; + return (res); } oc_str32 oc_utf8_push_to_codepoints(oc_arena* arena, oc_str8 string) { - u64 count = oc_utf8_codepoint_count_for_string(string); - oc_utf32* backing = oc_arena_push_array(arena, oc_utf32, count); - oc_str32 res = oc_utf8_to_codepoints(count, backing, string); - return(res); + u64 count = oc_utf8_codepoint_count_for_string(string); + oc_utf32* backing = oc_arena_push_array(arena, oc_utf32, count); + oc_str32 res = oc_utf8_to_codepoints(count, backing, string); + return (res); } oc_str8 oc_utf8_push_from_codepoints(oc_arena* arena, oc_str32 codePoints) { - u64 count = oc_utf8_byte_count_for_codepoints(codePoints); - char* backing = oc_arena_push_array(arena, char, count); - oc_str8 res = oc_utf8_from_codepoints(count, backing, codePoints); - return(res); + u64 count = oc_utf8_byte_count_for_codepoints(codePoints); + char* backing = oc_arena_push_array(arena, char, count); + oc_str8 res = oc_utf8_from_codepoints(count, backing, codePoints); + return (res); } #define OC_UNICODE_RANGE(start, cnt, name) ORCA_API const oc_unicode_range OC_CAT2(OC_UNICODE_, name) = { .firstCodePoint = start, .count = cnt }; diff --git a/src/util/utf8.h b/src/util/utf8.h index 61065cd..4176715 100644 --- a/src/util/utf8.h +++ b/src/util/utf8.h @@ -10,187 +10,188 @@ #ifndef __UTF8_H_ #define __UTF8_H_ -#include"typedefs.h" -#include"strings.h" +#include "strings.h" +#include "typedefs.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -typedef u32 oc_utf32; + typedef u32 oc_utf32; -//----------------------------------------------------------------- -//NOTE: getting sizes / offsets / indices -//----------------------------------------------------------------- -ORCA_API u32 oc_utf8_size_from_leading_char(char leadingChar); -ORCA_API u32 oc_utf8_codepoint_size(oc_utf32 codePoint); + //----------------------------------------------------------------- + //NOTE: getting sizes / offsets / indices + //----------------------------------------------------------------- + ORCA_API u32 oc_utf8_size_from_leading_char(char leadingChar); + ORCA_API u32 oc_utf8_codepoint_size(oc_utf32 codePoint); -ORCA_API u64 oc_utf8_codepoint_count_for_string(oc_str8 string); -ORCA_API u64 oc_utf8_byte_count_for_codepoints(oc_str32 codePoints); + ORCA_API u64 oc_utf8_codepoint_count_for_string(oc_str8 string); + ORCA_API u64 oc_utf8_byte_count_for_codepoints(oc_str32 codePoints); -ORCA_API u64 oc_utf8_next_offset(oc_str8 string, u64 byteOffset); -ORCA_API u64 oc_utf8_prev_offset(oc_str8 string, u64 byteOffset); + ORCA_API u64 oc_utf8_next_offset(oc_str8 string, u64 byteOffset); + ORCA_API u64 oc_utf8_prev_offset(oc_str8 string, u64 byteOffset); -//----------------------------------------------------------------- -//NOTE: encoding / decoding -//----------------------------------------------------------------- -typedef struct oc_utf8_dec -{ - oc_utf32 codepoint; //NOTE: decoded codepoint - u32 size; //NOTE: size of corresponding oc_utf8 sequence -} oc_utf8_dec; + //----------------------------------------------------------------- + //NOTE: encoding / decoding + //----------------------------------------------------------------- + typedef struct oc_utf8_dec + { + oc_utf32 codepoint; //NOTE: decoded codepoint + u32 size; //NOTE: size of corresponding oc_utf8 sequence + } oc_utf8_dec; -ORCA_API oc_utf8_dec oc_utf8_decode(oc_str8 string); //NOTE: decode a single oc_utf8 sequence at start of string -ORCA_API oc_utf8_dec oc_utf8_decode_at(oc_str8 string, u64 offset); //NOTE: decode a single oc_utf8 sequence starting at byte offset -ORCA_API oc_str8 oc_utf8_encode(char* dst, oc_utf32 codePoint); //NOTE: encode codepoint into backing buffer dst + ORCA_API oc_utf8_dec oc_utf8_decode(oc_str8 string); //NOTE: decode a single oc_utf8 sequence at start of string + ORCA_API oc_utf8_dec oc_utf8_decode_at(oc_str8 string, u64 offset); //NOTE: decode a single oc_utf8 sequence starting at byte offset + ORCA_API oc_str8 oc_utf8_encode(char* dst, oc_utf32 codePoint); //NOTE: encode codepoint into backing buffer dst -ORCA_API oc_str32 oc_utf8_to_codepoints(u64 maxCount, oc_utf32* backing, oc_str8 string); -ORCA_API oc_str8 oc_utf8_from_codepoints(u64 maxBytes, char* backing, oc_str32 codePoints); + ORCA_API oc_str32 oc_utf8_to_codepoints(u64 maxCount, oc_utf32* backing, oc_str8 string); + ORCA_API oc_str8 oc_utf8_from_codepoints(u64 maxBytes, char* backing, oc_str32 codePoints); -ORCA_API oc_str32 oc_utf8_push_to_codepoints(oc_arena* arena, oc_str8 string); -ORCA_API oc_str8 oc_utf8_push_from_codepoints(oc_arena* arena, oc_str32 codePoints); + ORCA_API oc_str32 oc_utf8_push_to_codepoints(oc_arena* arena, oc_str8 string); + ORCA_API oc_str8 oc_utf8_push_from_codepoints(oc_arena* arena, oc_str32 codePoints); -//----------------------------------------------------------------- -// oc_utf8 range struct and X-macros for defining oc_utf8 ranges -//----------------------------------------------------------------- + //----------------------------------------------------------------- + // oc_utf8 range struct and X-macros for defining oc_utf8 ranges + //----------------------------------------------------------------- -typedef struct oc_unicode_range -{ - oc_utf32 firstCodePoint; - u32 count; -} oc_unicode_range; + typedef struct oc_unicode_range + { + oc_utf32 firstCodePoint; + u32 count; + } oc_unicode_range; //NOTE(martin): range declared here are defined in utf8.cpp // they can be used by prefixing them with UTF8_RANGE_, as in 'UTF8_RANGE_BASIC_LATIN' -#define OC_UNICODE_RANGES \ -OC_UNICODE_RANGE(0x0000, 127, BASIC_LATIN) \ -OC_UNICODE_RANGE(0x0080, 127, C1_CONTROLS_AND_LATIN_1_SUPPLEMENT) \ -OC_UNICODE_RANGE(0x0100, 127, LATIN_EXTENDED_A) \ -OC_UNICODE_RANGE(0x0180, 207, LATIN_EXTENDED_B) \ -OC_UNICODE_RANGE(0x0250, 95, IPA_EXTENSIONS) \ -OC_UNICODE_RANGE(0x02b0, 79, SPACING_MODIFIER_LETTERS) \ -OC_UNICODE_RANGE(0x0300, 111, COMBINING_DIACRITICAL_MARKS) \ -OC_UNICODE_RANGE(0x0370, 143, GREEK_COPTIC) \ -OC_UNICODE_RANGE(0x0400, 255, CYRILLIC) \ -OC_UNICODE_RANGE(0x0500, 47, CYRILLIC_SUPPLEMENT) \ -OC_UNICODE_RANGE(0x0530, 95, ARMENIAN) \ -OC_UNICODE_RANGE(0x0590, 111, HEBREW) \ -OC_UNICODE_RANGE(0x0600, 255, ARABIC) \ -OC_UNICODE_RANGE(0x0700, 79, SYRIAC) \ -OC_UNICODE_RANGE(0x0780, 63, THAANA) \ -OC_UNICODE_RANGE(0x0900, 127, DEVANAGARI) \ -OC_UNICODE_RANGE(0x0980, 127, BENGALI_ASSAMESE) \ -OC_UNICODE_RANGE(0x0a00, 127, GURMUKHI) \ -OC_UNICODE_RANGE(0x0a80, 127, GUJARATI) \ -OC_UNICODE_RANGE(0x0b00, 127, ORIYA) \ -OC_UNICODE_RANGE(0x0b80, 127, TAMIL) \ -OC_UNICODE_RANGE(0x0c00, 127, TELUGU) \ -OC_UNICODE_RANGE(0x0c80, 127, KANNADA) \ -OC_UNICODE_RANGE(0x0d00, 255, MALAYALAM) \ -OC_UNICODE_RANGE(0x0d80, 127, SINHALA) \ -OC_UNICODE_RANGE(0x0e00, 127, THAI) \ -OC_UNICODE_RANGE(0x0e80, 127, LAO) \ -OC_UNICODE_RANGE(0x0f00, 255, TIBETAN) \ -OC_UNICODE_RANGE(0x1000, 159, MYANMAR) \ -OC_UNICODE_RANGE(0x10a0, 95, GEORGIAN) \ -OC_UNICODE_RANGE(0x1100, 255, HANGUL_JAMO) \ -OC_UNICODE_RANGE(0x1200, 383, ETHIOPIC) \ -OC_UNICODE_RANGE(0x13a0, 95, CHEROKEE) \ -OC_UNICODE_RANGE(0x1400, 639, UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS) \ -OC_UNICODE_RANGE(0x1680, 31, OGHAM) \ -OC_UNICODE_RANGE(0x16a0, 95, RUNIC) \ -OC_UNICODE_RANGE(0x1700, 31, TAGALOG) \ -OC_UNICODE_RANGE(0x1720, 31, HANUNOO) \ -OC_UNICODE_RANGE(0x1740, 31, BUHID) \ -OC_UNICODE_RANGE(0x1760, 31, TAGBANWA) \ -OC_UNICODE_RANGE(0x1780, 127, KHMER) \ -OC_UNICODE_RANGE(0x1800, 175, MONGOLIAN) \ -OC_UNICODE_RANGE(0x1900, 79, LIMBU) \ -OC_UNICODE_RANGE(0x1950, 47, TAI_LE) \ -OC_UNICODE_RANGE(0x19e0, 31, KHMER_SYMBOLS) \ -OC_UNICODE_RANGE(0x1d00, 127, PHONETIC_EXTENSIONS) \ -OC_UNICODE_RANGE(0x1e00, 255, LATIN_EXTENDED_ADDITIONAL) \ -OC_UNICODE_RANGE(0x1f00, 255, GREEK_EXTENDED) \ -OC_UNICODE_RANGE(0x2000, 111, GENERAL_PUNCTUATION) \ -OC_UNICODE_RANGE(0x2070, 47, SUPERSCRIPTS_AND_SUBSCRIPTS) \ -OC_UNICODE_RANGE(0x20a0, 47, CURRENCY_SYMBOLS) \ -OC_UNICODE_RANGE(0x20d0, 47, COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS) \ -OC_UNICODE_RANGE(0x2100, 79, LETTERLIKE_SYMBOLS) \ -OC_UNICODE_RANGE(0x2150, 63, NUMBER_FORMS) \ -OC_UNICODE_RANGE(0x2190, 111, ARROWS) \ -OC_UNICODE_RANGE(0x2200, 255, MATHEMATICAL_OPERATORS) \ -OC_UNICODE_RANGE(0x2300, 255, MISCELLANEOUS_TECHNICAL) \ -OC_UNICODE_RANGE(0x2400, 63, CONTROL_PICTURES) \ -OC_UNICODE_RANGE(0x2440, 31, OPTICAL_CHARACTER_RECOGNITION) \ -OC_UNICODE_RANGE(0x2460, 159, ENCLOSED_ALPHANUMERICS) \ -OC_UNICODE_RANGE(0x2500, 127, BOX_DRAWING) \ -OC_UNICODE_RANGE(0x2580, 31, BLOCK_ELEMENTS) \ -OC_UNICODE_RANGE(0x25a0, 95, GEOMETRIC_SHAPES) \ -OC_UNICODE_RANGE(0x2600, 255, MISCELLANEOUS_SYMBOLS) \ -OC_UNICODE_RANGE(0x2700, 191, DINGBATS) \ -OC_UNICODE_RANGE(0x27c0, 47, MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A) \ -OC_UNICODE_RANGE(0x27f0, 15, SUPPLEMENTAL_ARROWS_A) \ -OC_UNICODE_RANGE(0x2800, 255, BRAILLE_PATTERNS) \ -OC_UNICODE_RANGE(0x2900, 127, SUPPLEMENTAL_ARROWS_B) \ -OC_UNICODE_RANGE(0x2980, 127, MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B) \ -OC_UNICODE_RANGE(0x2a00, 255, SUPPLEMENTAL_MATHEMATICAL_OPERATORS) \ -OC_UNICODE_RANGE(0x2b00, 255, MISCELLANEOUS_SYMBOLS_AND_ARROWS) \ -OC_UNICODE_RANGE(0x2e80, 127, CJK_RADICALS_SUPPLEMENT) \ -OC_UNICODE_RANGE(0x2f00, 223, KANGXI_RADICALS) \ -OC_UNICODE_RANGE(0x2ff0, 15, IDEOGRAPHIC_DESCRIPTION_CHARACTERS) \ -OC_UNICODE_RANGE(0x3000, 63, CJK_SYMBOLS_AND_PUNCTUATION) \ -OC_UNICODE_RANGE(0x3040, 95, HIRAGANA) \ -OC_UNICODE_RANGE(0x30a0, 95, KATAKANA) \ -OC_UNICODE_RANGE(0x3100, 47, BOPOMOFO) \ -OC_UNICODE_RANGE(0x3130, 95, HANGUL_COMPATIBILITY_JAMO) \ -OC_UNICODE_RANGE(0x3190, 15, KANBUN_KUNTEN) \ -OC_UNICODE_RANGE(0x31a0, 31, BOPOMOFO_EXTENDED) \ -OC_UNICODE_RANGE(0x31f0, 15, KATAKANA_PHONETIC_EXTENSIONS) \ -OC_UNICODE_RANGE(0x3200, 255, ENCLOSED_CJK_LETTERS_AND_MONTHS) \ -OC_UNICODE_RANGE(0x3300, 255, CJK_COMPATIBILITY) \ -OC_UNICODE_RANGE(0x3400, 6591, CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A) \ -OC_UNICODE_RANGE(0x4dc0, 63, YIJING_HEXAGRAM_SYMBOLS) \ -OC_UNICODE_RANGE(0x4e00, 20911, CJK_UNIFIED_IDEOGRAPHS) \ -OC_UNICODE_RANGE(0xa000, 1167, YI_SYLLABLES) \ -OC_UNICODE_RANGE(0xa490, 63, YI_RADICALS) \ -OC_UNICODE_RANGE(0xac00, 11183, HANGUL_SYLLABLES) \ -OC_UNICODE_RANGE(0xd800, 1023, HIGH_SURROGATE_AREA) \ -OC_UNICODE_RANGE(0xdc00, 1023, LOW_SURROGATE_AREA) \ -OC_UNICODE_RANGE(0xe000, 6399, PRIVATE_USE_AREA) \ -OC_UNICODE_RANGE(0xf900, 511, CJK_COMPATIBILITY_IDEOGRAPHS) \ -OC_UNICODE_RANGE(0xfb00, 79, ALPHABETIC_PRESENTATION_FORMS) \ -OC_UNICODE_RANGE(0xfb50, 687, ARABIC_PRESENTATION_FORMS_A) \ -OC_UNICODE_RANGE(0xfe00, 15, VARIATION_SELECTORS) \ -OC_UNICODE_RANGE(0xfe20, 15, COMBINING_HALF_MARKS) \ -OC_UNICODE_RANGE(0xfe30, 31, CJK_COMPATIBILITY_FORMS) \ -OC_UNICODE_RANGE(0xfe50, 31, SMALL_FORM_VARIANTS) \ -OC_UNICODE_RANGE(0xfe70, 143, ARABIC_PRESENTATION_FORMS_B) \ -OC_UNICODE_RANGE(0xff00, 239, HALFWIDTH_AND_FULLWIDTH_FORMS) \ -OC_UNICODE_RANGE(0xfff0, 15, SPECIALS) \ -OC_UNICODE_RANGE(0x10000, 127, LINEAR_B_SYLLABARY) \ -OC_UNICODE_RANGE(0x10080, 127, LINEAR_B_IDEOGRAMS) \ -OC_UNICODE_RANGE(0x10100, 63, AEGEAN_NUMBERS) \ -OC_UNICODE_RANGE(0x10300, 47, OLD_ITALIC) \ -OC_UNICODE_RANGE(0x10330, 31, GOTHIC) \ -OC_UNICODE_RANGE(0x10380, 31, UGARITIC) \ -OC_UNICODE_RANGE(0x10400, 79, DESERET) \ -OC_UNICODE_RANGE(0x10450, 47, SHAVIAN) \ -OC_UNICODE_RANGE(0x10480, 47, OSMANYA) \ -OC_UNICODE_RANGE(0x10800, 63, CYPRIOT_SYLLABARY) \ -OC_UNICODE_RANGE(0x1d000, 255, BYZANTINE_MUSICAL_SYMBOLS) \ -OC_UNICODE_RANGE(0x1d100, 255, MUSICAL_SYMBOLS) \ -OC_UNICODE_RANGE(0x1d300, 95, TAI_XUAN_JING_SYMBOLS) \ -OC_UNICODE_RANGE(0x1d400, 1023, MATHEMATICAL_ALPHANUMERIC_SYMBOLS) \ -OC_UNICODE_RANGE(0x20000, 42719, CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B) \ -OC_UNICODE_RANGE(0x2f800, 543, CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT) \ -OC_UNICODE_RANGE(0xe0000, 127, TAGS) \ -OC_UNICODE_RANGE(0xe0100, 239, VARIATION_SELECTORS_SUPPLEMENT) \ -OC_UNICODE_RANGE(0xf0000, 65533, SUPPLEMENTARY_PRIVATE_USE_AREA_A) \ -OC_UNICODE_RANGE(0x100000, 65533, SUPPLEMENTARY_PRIVATE_USE_AREA_B) +#define OC_UNICODE_RANGES \ + OC_UNICODE_RANGE(0x0000, 127, BASIC_LATIN) \ + OC_UNICODE_RANGE(0x0080, 127, C1_CONTROLS_AND_LATIN_1_SUPPLEMENT) \ + OC_UNICODE_RANGE(0x0100, 127, LATIN_EXTENDED_A) \ + OC_UNICODE_RANGE(0x0180, 207, LATIN_EXTENDED_B) \ + OC_UNICODE_RANGE(0x0250, 95, IPA_EXTENSIONS) \ + OC_UNICODE_RANGE(0x02b0, 79, SPACING_MODIFIER_LETTERS) \ + OC_UNICODE_RANGE(0x0300, 111, COMBINING_DIACRITICAL_MARKS) \ + OC_UNICODE_RANGE(0x0370, 143, GREEK_COPTIC) \ + OC_UNICODE_RANGE(0x0400, 255, CYRILLIC) \ + OC_UNICODE_RANGE(0x0500, 47, CYRILLIC_SUPPLEMENT) \ + OC_UNICODE_RANGE(0x0530, 95, ARMENIAN) \ + OC_UNICODE_RANGE(0x0590, 111, HEBREW) \ + OC_UNICODE_RANGE(0x0600, 255, ARABIC) \ + OC_UNICODE_RANGE(0x0700, 79, SYRIAC) \ + OC_UNICODE_RANGE(0x0780, 63, THAANA) \ + OC_UNICODE_RANGE(0x0900, 127, DEVANAGARI) \ + OC_UNICODE_RANGE(0x0980, 127, BENGALI_ASSAMESE) \ + OC_UNICODE_RANGE(0x0a00, 127, GURMUKHI) \ + OC_UNICODE_RANGE(0x0a80, 127, GUJARATI) \ + OC_UNICODE_RANGE(0x0b00, 127, ORIYA) \ + OC_UNICODE_RANGE(0x0b80, 127, TAMIL) \ + OC_UNICODE_RANGE(0x0c00, 127, TELUGU) \ + OC_UNICODE_RANGE(0x0c80, 127, KANNADA) \ + OC_UNICODE_RANGE(0x0d00, 255, MALAYALAM) \ + OC_UNICODE_RANGE(0x0d80, 127, SINHALA) \ + OC_UNICODE_RANGE(0x0e00, 127, THAI) \ + OC_UNICODE_RANGE(0x0e80, 127, LAO) \ + OC_UNICODE_RANGE(0x0f00, 255, TIBETAN) \ + OC_UNICODE_RANGE(0x1000, 159, MYANMAR) \ + OC_UNICODE_RANGE(0x10a0, 95, GEORGIAN) \ + OC_UNICODE_RANGE(0x1100, 255, HANGUL_JAMO) \ + OC_UNICODE_RANGE(0x1200, 383, ETHIOPIC) \ + OC_UNICODE_RANGE(0x13a0, 95, CHEROKEE) \ + OC_UNICODE_RANGE(0x1400, 639, UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS) \ + OC_UNICODE_RANGE(0x1680, 31, OGHAM) \ + OC_UNICODE_RANGE(0x16a0, 95, RUNIC) \ + OC_UNICODE_RANGE(0x1700, 31, TAGALOG) \ + OC_UNICODE_RANGE(0x1720, 31, HANUNOO) \ + OC_UNICODE_RANGE(0x1740, 31, BUHID) \ + OC_UNICODE_RANGE(0x1760, 31, TAGBANWA) \ + OC_UNICODE_RANGE(0x1780, 127, KHMER) \ + OC_UNICODE_RANGE(0x1800, 175, MONGOLIAN) \ + OC_UNICODE_RANGE(0x1900, 79, LIMBU) \ + OC_UNICODE_RANGE(0x1950, 47, TAI_LE) \ + OC_UNICODE_RANGE(0x19e0, 31, KHMER_SYMBOLS) \ + OC_UNICODE_RANGE(0x1d00, 127, PHONETIC_EXTENSIONS) \ + OC_UNICODE_RANGE(0x1e00, 255, LATIN_EXTENDED_ADDITIONAL) \ + OC_UNICODE_RANGE(0x1f00, 255, GREEK_EXTENDED) \ + OC_UNICODE_RANGE(0x2000, 111, GENERAL_PUNCTUATION) \ + OC_UNICODE_RANGE(0x2070, 47, SUPERSCRIPTS_AND_SUBSCRIPTS) \ + OC_UNICODE_RANGE(0x20a0, 47, CURRENCY_SYMBOLS) \ + OC_UNICODE_RANGE(0x20d0, 47, COMBINING_DIACRITICAL_MARKS_FOR_SYMBOLS) \ + OC_UNICODE_RANGE(0x2100, 79, LETTERLIKE_SYMBOLS) \ + OC_UNICODE_RANGE(0x2150, 63, NUMBER_FORMS) \ + OC_UNICODE_RANGE(0x2190, 111, ARROWS) \ + OC_UNICODE_RANGE(0x2200, 255, MATHEMATICAL_OPERATORS) \ + OC_UNICODE_RANGE(0x2300, 255, MISCELLANEOUS_TECHNICAL) \ + OC_UNICODE_RANGE(0x2400, 63, CONTROL_PICTURES) \ + OC_UNICODE_RANGE(0x2440, 31, OPTICAL_CHARACTER_RECOGNITION) \ + OC_UNICODE_RANGE(0x2460, 159, ENCLOSED_ALPHANUMERICS) \ + OC_UNICODE_RANGE(0x2500, 127, BOX_DRAWING) \ + OC_UNICODE_RANGE(0x2580, 31, BLOCK_ELEMENTS) \ + OC_UNICODE_RANGE(0x25a0, 95, GEOMETRIC_SHAPES) \ + OC_UNICODE_RANGE(0x2600, 255, MISCELLANEOUS_SYMBOLS) \ + OC_UNICODE_RANGE(0x2700, 191, DINGBATS) \ + OC_UNICODE_RANGE(0x27c0, 47, MISCELLANEOUS_MATHEMATICAL_SYMBOLS_A) \ + OC_UNICODE_RANGE(0x27f0, 15, SUPPLEMENTAL_ARROWS_A) \ + OC_UNICODE_RANGE(0x2800, 255, BRAILLE_PATTERNS) \ + OC_UNICODE_RANGE(0x2900, 127, SUPPLEMENTAL_ARROWS_B) \ + OC_UNICODE_RANGE(0x2980, 127, MISCELLANEOUS_MATHEMATICAL_SYMBOLS_B) \ + OC_UNICODE_RANGE(0x2a00, 255, SUPPLEMENTAL_MATHEMATICAL_OPERATORS) \ + OC_UNICODE_RANGE(0x2b00, 255, MISCELLANEOUS_SYMBOLS_AND_ARROWS) \ + OC_UNICODE_RANGE(0x2e80, 127, CJK_RADICALS_SUPPLEMENT) \ + OC_UNICODE_RANGE(0x2f00, 223, KANGXI_RADICALS) \ + OC_UNICODE_RANGE(0x2ff0, 15, IDEOGRAPHIC_DESCRIPTION_CHARACTERS) \ + OC_UNICODE_RANGE(0x3000, 63, CJK_SYMBOLS_AND_PUNCTUATION) \ + OC_UNICODE_RANGE(0x3040, 95, HIRAGANA) \ + OC_UNICODE_RANGE(0x30a0, 95, KATAKANA) \ + OC_UNICODE_RANGE(0x3100, 47, BOPOMOFO) \ + OC_UNICODE_RANGE(0x3130, 95, HANGUL_COMPATIBILITY_JAMO) \ + OC_UNICODE_RANGE(0x3190, 15, KANBUN_KUNTEN) \ + OC_UNICODE_RANGE(0x31a0, 31, BOPOMOFO_EXTENDED) \ + OC_UNICODE_RANGE(0x31f0, 15, KATAKANA_PHONETIC_EXTENSIONS) \ + OC_UNICODE_RANGE(0x3200, 255, ENCLOSED_CJK_LETTERS_AND_MONTHS) \ + OC_UNICODE_RANGE(0x3300, 255, CJK_COMPATIBILITY) \ + OC_UNICODE_RANGE(0x3400, 6591, CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A) \ + OC_UNICODE_RANGE(0x4dc0, 63, YIJING_HEXAGRAM_SYMBOLS) \ + OC_UNICODE_RANGE(0x4e00, 20911, CJK_UNIFIED_IDEOGRAPHS) \ + OC_UNICODE_RANGE(0xa000, 1167, YI_SYLLABLES) \ + OC_UNICODE_RANGE(0xa490, 63, YI_RADICALS) \ + OC_UNICODE_RANGE(0xac00, 11183, HANGUL_SYLLABLES) \ + OC_UNICODE_RANGE(0xd800, 1023, HIGH_SURROGATE_AREA) \ + OC_UNICODE_RANGE(0xdc00, 1023, LOW_SURROGATE_AREA) \ + OC_UNICODE_RANGE(0xe000, 6399, PRIVATE_USE_AREA) \ + OC_UNICODE_RANGE(0xf900, 511, CJK_COMPATIBILITY_IDEOGRAPHS) \ + OC_UNICODE_RANGE(0xfb00, 79, ALPHABETIC_PRESENTATION_FORMS) \ + OC_UNICODE_RANGE(0xfb50, 687, ARABIC_PRESENTATION_FORMS_A) \ + OC_UNICODE_RANGE(0xfe00, 15, VARIATION_SELECTORS) \ + OC_UNICODE_RANGE(0xfe20, 15, COMBINING_HALF_MARKS) \ + OC_UNICODE_RANGE(0xfe30, 31, CJK_COMPATIBILITY_FORMS) \ + OC_UNICODE_RANGE(0xfe50, 31, SMALL_FORM_VARIANTS) \ + OC_UNICODE_RANGE(0xfe70, 143, ARABIC_PRESENTATION_FORMS_B) \ + OC_UNICODE_RANGE(0xff00, 239, HALFWIDTH_AND_FULLWIDTH_FORMS) \ + OC_UNICODE_RANGE(0xfff0, 15, SPECIALS) \ + OC_UNICODE_RANGE(0x10000, 127, LINEAR_B_SYLLABARY) \ + OC_UNICODE_RANGE(0x10080, 127, LINEAR_B_IDEOGRAMS) \ + OC_UNICODE_RANGE(0x10100, 63, AEGEAN_NUMBERS) \ + OC_UNICODE_RANGE(0x10300, 47, OLD_ITALIC) \ + OC_UNICODE_RANGE(0x10330, 31, GOTHIC) \ + OC_UNICODE_RANGE(0x10380, 31, UGARITIC) \ + OC_UNICODE_RANGE(0x10400, 79, DESERET) \ + OC_UNICODE_RANGE(0x10450, 47, SHAVIAN) \ + OC_UNICODE_RANGE(0x10480, 47, OSMANYA) \ + OC_UNICODE_RANGE(0x10800, 63, CYPRIOT_SYLLABARY) \ + OC_UNICODE_RANGE(0x1d000, 255, BYZANTINE_MUSICAL_SYMBOLS) \ + OC_UNICODE_RANGE(0x1d100, 255, MUSICAL_SYMBOLS) \ + OC_UNICODE_RANGE(0x1d300, 95, TAI_XUAN_JING_SYMBOLS) \ + OC_UNICODE_RANGE(0x1d400, 1023, MATHEMATICAL_ALPHANUMERIC_SYMBOLS) \ + OC_UNICODE_RANGE(0x20000, 42719, CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B) \ + OC_UNICODE_RANGE(0x2f800, 543, CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT) \ + OC_UNICODE_RANGE(0xe0000, 127, TAGS) \ + OC_UNICODE_RANGE(0xe0100, 239, VARIATION_SELECTORS_SUPPLEMENT) \ + OC_UNICODE_RANGE(0xf0000, 65533, SUPPLEMENTARY_PRIVATE_USE_AREA_A) \ + OC_UNICODE_RANGE(0x100000, 65533, SUPPLEMENTARY_PRIVATE_USE_AREA_B) #define OC_UNICODE_RANGE(start, count, name) \ - ORCA_API extern const oc_unicode_range OC_CAT2(OC_UNICODE_, name); -OC_UNICODE_RANGES + ORCA_API extern const oc_unicode_range OC_CAT2(OC_UNICODE_, name); + OC_UNICODE_RANGES #undef OC_UNICODE_RANGE #ifdef __cplusplus diff --git a/src/wasmbind/gles_api_bind_manual.c b/src/wasmbind/gles_api_bind_manual.c index 8d622ba..2edafd6 100644 --- a/src/wasmbind/gles_api_bind_manual.c +++ b/src/wasmbind/gles_api_bind_manual.c @@ -5,678 +5,709 @@ u64 orca_gles_check_cstring(IM3Runtime runtime, const char* ptr) { - uint32_t memorySize = 0; - char* memory = (char*)m3_GetMemory(runtime, &memorySize, 0); + uint32_t memorySize = 0; + char* memory = (char*)m3_GetMemory(runtime, &memorySize, 0); - //NOTE: Here we are guaranteed that ptr is in [ memory ; memory + memorySize [ - // hence (memory + memorySize) - ptr is representable by size_t and <= memorySize - size_t maxLen = (memory + memorySize) - ptr; + //NOTE: Here we are guaranteed that ptr is in [ memory ; memory + memorySize [ + // hence (memory + memorySize) - ptr is representable by size_t and <= memorySize + size_t maxLen = (memory + memorySize) - ptr; - u64 len = strnlen(ptr, maxLen); + u64 len = strnlen(ptr, maxLen); - if(len == maxLen) - { - //NOTE: string overflows wasm memory, return a length that will trigger the bounds check - len = maxLen + 1; - } - return(len+1); //include null-terminator + if(len == maxLen) + { + //NOTE: string overflows wasm memory, return a length that will trigger the bounds check + len = maxLen + 1; + } + return (len + 1); //include null-terminator } u64 orca_gl_type_size(GLenum type) { - u64 size = 8; - switch(type) - { - case GL_UNSIGNED_BYTE: - case GL_BYTE: - size = sizeof(GLbyte); - break; + u64 size = 8; + switch(type) + { + case GL_UNSIGNED_BYTE: + case GL_BYTE: + size = sizeof(GLbyte); + break; - case GL_UNSIGNED_SHORT: - case GL_SHORT: - case GL_HALF_FLOAT: - size = sizeof(GLshort); - break; + case GL_UNSIGNED_SHORT: + case GL_SHORT: + case GL_HALF_FLOAT: + size = sizeof(GLshort); + break; - case GL_UNSIGNED_INT: - case GL_INT: - case GL_FIXED: - case GL_INT_2_10_10_10_REV: - case GL_UNSIGNED_INT_2_10_10_10_REV: - size = sizeof(GLint); - break; + case GL_UNSIGNED_INT: + case GL_INT: + case GL_FIXED: + case GL_INT_2_10_10_10_REV: + case GL_UNSIGNED_INT_2_10_10_10_REV: + size = sizeof(GLint); + break; - case GL_FLOAT: - size = sizeof(GLfloat); - break; + case GL_FLOAT: + size = sizeof(GLfloat); + break; - case GL_DOUBLE: - size = sizeof(GLdouble); - break; + case GL_DOUBLE: + size = sizeof(GLdouble); + break; - default: - OC_ASSERT(0, "unknown GLenum type %i", type); - } + default: + OC_ASSERT(0, "unknown GLenum type %i", type); + } - return(size); + return (size); } u64 orca_gl_format_count(GLenum format) { - u64 count = 4; - switch(format) - { - case GL_RED: - case GL_RED_INTEGER: - case GL_DEPTH_COMPONENT: - case GL_STENCIL_INDEX: - case GL_LUMINANCE: - case GL_ALPHA: - count = 1; - break; + u64 count = 4; + switch(format) + { + case GL_RED: + case GL_RED_INTEGER: + case GL_DEPTH_COMPONENT: + case GL_STENCIL_INDEX: + case GL_LUMINANCE: + case GL_ALPHA: + count = 1; + break; - case GL_RG: - case GL_RG_INTEGER: - case GL_DEPTH_STENCIL: - case GL_LUMINANCE_ALPHA: - count = 2; - break; + case GL_RG: + case GL_RG_INTEGER: + case GL_DEPTH_STENCIL: + case GL_LUMINANCE_ALPHA: + count = 2; + break; - case GL_RGB: - case GL_RGB_INTEGER: - count = 3; - break; + case GL_RGB: + case GL_RGB_INTEGER: + count = 3; + break; - case GL_RGBA: - case GL_RGBA_INTEGER: - count = 4; - break; + case GL_RGBA: + case GL_RGBA_INTEGER: + count = 4; + break; - default: - OC_ASSERT(0, "unknow GLenum format %i", format); - } + default: + OC_ASSERT(0, "unknow GLenum format %i", format); + } - return(count); + return (count); } typedef struct orca_gles_impl_limits { - bool init; - int maxDrawBuffers; - int numCompressedTextureFormats; - int numProgramBinaryFormats; - int numShaderBinaryFormats; - //... + bool init; + int maxDrawBuffers; + int numCompressedTextureFormats; + int numProgramBinaryFormats; + int numShaderBinaryFormats; + //... } orca_gles_impl_limits; -orca_gles_impl_limits __orcaGLESImplLimits = {0}; +orca_gles_impl_limits __orcaGLESImplLimits = { 0 }; u64 orca_glGet_data_length(GLenum pname) { - if(!__orcaGLESImplLimits.init) - { - glGetIntegerv(GL_MAX_DRAW_BUFFERS, &__orcaGLESImplLimits.maxDrawBuffers); - glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &__orcaGLESImplLimits.numCompressedTextureFormats); - glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &__orcaGLESImplLimits.numProgramBinaryFormats); - glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &__orcaGLESImplLimits.numShaderBinaryFormats); - } - u64 count = 8; + if(!__orcaGLESImplLimits.init) + { + glGetIntegerv(GL_MAX_DRAW_BUFFERS, &__orcaGLESImplLimits.maxDrawBuffers); + glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &__orcaGLESImplLimits.numCompressedTextureFormats); + glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &__orcaGLESImplLimits.numProgramBinaryFormats); + glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &__orcaGLESImplLimits.numShaderBinaryFormats); + } + u64 count = 8; - if(pname >= GL_DRAW_BUFFER0 && pname < GL_DRAW_BUFFER0 + __orcaGLESImplLimits.maxDrawBuffers) - { - count = 1; - } - else - { - switch(pname) - { - case GL_ACTIVE_TEXTURE: - case GL_ALPHA_BITS: - case GL_ARRAY_BUFFER_BINDING: - case GL_BLEND: - case GL_BLEND_DST_ALPHA: - case GL_BLEND_DST_RGB: - case GL_BLEND_EQUATION_ALPHA: - case GL_BLEND_EQUATION_RGB: - case GL_BLEND_SRC_ALPHA: - case GL_BLEND_SRC_RGB: - case GL_BLUE_BITS: - case GL_CONTEXT_FLAGS: - case GL_CONTEXT_ROBUST_ACCESS: - case GL_COPY_READ_BUFFER_BINDING: - case GL_COPY_WRITE_BUFFER_BINDING: - case GL_CULL_FACE: - case GL_CULL_FACE_MODE: - case GL_CURRENT_PROGRAM: - case GL_DEBUG_GROUP_STACK_DEPTH: - case GL_DEBUG_LOGGED_MESSAGES: - case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH: - case GL_DEPTH_BITS: - case GL_DEPTH_CLEAR_VALUE: - case GL_DEPTH_FUNC: - case GL_DEPTH_TEST: - case GL_DEPTH_WRITEMASK: - case GL_DISPATCH_INDIRECT_BUFFER_BINDING: - case GL_DITHER: - case GL_DRAW_FRAMEBUFFER_BINDING: - case GL_ELEMENT_ARRAY_BUFFER_BINDING: - case GL_FRAGMENT_INTERPOLATION_OFFSET_BITS: - case GL_FRAGMENT_SHADER_DERIVATIVE_HINT: - case GL_FRONT_FACE: - case GL_GENERATE_MIPMAP_HINT: - case GL_GREEN_BITS: - case GL_IMAGE_BINDING_LAYERED: - case GL_IMPLEMENTATION_COLOR_READ_FORMAT: - case GL_IMPLEMENTATION_COLOR_READ_TYPE: - case GL_LAYER_PROVOKING_VERTEX: - case GL_LINE_WIDTH: - case GL_MAJOR_VERSION: - case GL_MAX_3D_TEXTURE_SIZE: - case GL_MAX_ARRAY_TEXTURE_LAYERS: - case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS: - case GL_MAX_COLOR_ATTACHMENTS: + if(pname >= GL_DRAW_BUFFER0 && pname < GL_DRAW_BUFFER0 + __orcaGLESImplLimits.maxDrawBuffers) + { + count = 1; + } + else + { + switch(pname) + { + case GL_ACTIVE_TEXTURE: + case GL_ALPHA_BITS: + case GL_ARRAY_BUFFER_BINDING: + case GL_BLEND: + case GL_BLEND_DST_ALPHA: + case GL_BLEND_DST_RGB: + case GL_BLEND_EQUATION_ALPHA: + case GL_BLEND_EQUATION_RGB: + case GL_BLEND_SRC_ALPHA: + case GL_BLEND_SRC_RGB: + case GL_BLUE_BITS: + case GL_CONTEXT_FLAGS: + case GL_CONTEXT_ROBUST_ACCESS: + case GL_COPY_READ_BUFFER_BINDING: + case GL_COPY_WRITE_BUFFER_BINDING: + case GL_CULL_FACE: + case GL_CULL_FACE_MODE: + case GL_CURRENT_PROGRAM: + case GL_DEBUG_GROUP_STACK_DEPTH: + case GL_DEBUG_LOGGED_MESSAGES: + case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH: + case GL_DEPTH_BITS: + case GL_DEPTH_CLEAR_VALUE: + case GL_DEPTH_FUNC: + case GL_DEPTH_TEST: + case GL_DEPTH_WRITEMASK: + case GL_DISPATCH_INDIRECT_BUFFER_BINDING: + case GL_DITHER: + case GL_DRAW_FRAMEBUFFER_BINDING: + case GL_ELEMENT_ARRAY_BUFFER_BINDING: + case GL_FRAGMENT_INTERPOLATION_OFFSET_BITS: + case GL_FRAGMENT_SHADER_DERIVATIVE_HINT: + case GL_FRONT_FACE: + case GL_GENERATE_MIPMAP_HINT: + case GL_GREEN_BITS: + case GL_IMAGE_BINDING_LAYERED: + case GL_IMPLEMENTATION_COLOR_READ_FORMAT: + case GL_IMPLEMENTATION_COLOR_READ_TYPE: + case GL_LAYER_PROVOKING_VERTEX: + case GL_LINE_WIDTH: + case GL_MAJOR_VERSION: + case GL_MAX_3D_TEXTURE_SIZE: + case GL_MAX_ARRAY_TEXTURE_LAYERS: + case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS: + case GL_MAX_COLOR_ATTACHMENTS: - case GL_MAX_COMBINED_ATOMIC_COUNTERS: - case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS: - case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS: - case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: - case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS: - case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: - case GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS: - case GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS: - case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: - case GL_MAX_COMBINED_UNIFORM_BLOCKS: - case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: - case GL_MAX_COMPUTE_ATOMIC_COUNTERS: - case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS: - case GL_MAX_COMPUTE_IMAGE_UNIFORMS: - case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS: - case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS: - case GL_MAX_COMPUTE_UNIFORM_BLOCKS: - case GL_MAX_COMPUTE_UNIFORM_COMPONENTS: - case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS: - case GL_MAX_COMPUTE_WORK_GROUP_COUNT: - case GL_MAX_COMPUTE_WORK_GROUP_SIZE: - case GL_MAX_CUBE_MAP_TEXTURE_SIZE: - case GL_MAX_DEBUG_GROUP_STACK_DEPTH: - case GL_MAX_DEBUG_LOGGED_MESSAGES: - case GL_MAX_DEBUG_MESSAGE_LENGTH: - case GL_MAX_DEPTH_TEXTURE_SAMPLES: - case GL_MAX_DRAW_BUFFERS: - case GL_MAX_ELEMENT_INDEX: - case GL_MAX_ELEMENTS_INDICES: - case GL_MAX_ELEMENTS_VERTICES: - case GL_MAX_FRAGMENT_ATOMIC_COUNTERS: - case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS: - case GL_MAX_FRAGMENT_IMAGE_UNIFORMS: - case GL_MAX_FRAGMENT_INPUT_COMPONENTS: - case GL_MAX_FRAGMENT_INTERPOLATION_OFFSET: - case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS: - case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: - case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: - case GL_MAX_FRAGMENT_UNIFORM_VECTORS: - case GL_MAX_FRAMEBUFFER_HEIGHT: - case GL_MAX_FRAMEBUFFER_LAYERS: - case GL_MAX_FRAMEBUFFER_SAMPLES: - case GL_MAX_FRAMEBUFFER_WIDTH: - case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS: - case GL_MAX_GEOMETRY_ATOMIC_COUNTERS: - case GL_MAX_GEOMETRY_IMAGE_UNIFORMS: - case GL_MAX_GEOMETRY_INPUT_COMPONENTS: - case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS: - case GL_MAX_GEOMETRY_OUTPUT_VERTICES: - case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS: - case GL_MAX_GEOMETRY_SHADER_INVOCATIONS: - case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS: - case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: - case GL_MAX_GEOMETRY_UNIFORM_BLOCKS: - case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS: - case GL_MAX_INTEGER_SAMPLES: - case GL_MAX_LABEL_LENGTH: - case GL_MAX_PROGRAM_TEXEL_OFFSET: - case GL_MAX_RENDERBUFFER_SIZE: - case GL_MAX_SAMPLE_MASK_WORDS: - case GL_MAX_SAMPLES: - case GL_MAX_SERVER_WAIT_TIMEOUT: - case GL_MAX_SHADER_STORAGE_BLOCK_SIZE: - case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS: - case GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS: - case GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS: - case GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS: - case GL_MAX_TESS_CONTROL_INPUT_COMPONENTS: - case GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS: - case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS: - case GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS: - case GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS: - case GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS: - case GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS: - case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS: - case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS: - case GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS: - case GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS: - case GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS: - case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS: - case GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS: - case GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS: - case GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS: - case GL_MAX_TESS_GEN_LEVEL: - case GL_MAX_TESS_PATCH_COMPONENTS: - case GL_MAX_TEXTURE_BUFFER_SIZE: - case GL_MAX_TEXTURE_IMAGE_UNITS: - case GL_MAX_TEXTURE_LOD_BIAS: - case GL_MAX_TEXTURE_SIZE: - case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: - case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: - case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: - case GL_MAX_UNIFORM_BLOCK_SIZE: - case GL_MAX_UNIFORM_BUFFER_BINDINGS: - case GL_MAX_UNIFORM_LOCATIONS: - case GL_MAX_VARYING_COMPONENTS: - case GL_MAX_VARYING_VECTORS: - case GL_MAX_VERTEX_ATOMIC_COUNTERS: - case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS: - case GL_MAX_VERTEX_ATTRIB_BINDINGS: - case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET: - case GL_MAX_VERTEX_ATTRIBS: - case GL_MAX_VERTEX_IMAGE_UNIFORMS: - case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS: - case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: - case GL_MAX_VERTEX_OUTPUT_COMPONENTS: - case GL_MAX_VERTEX_UNIFORM_BLOCKS: - case GL_MAX_VERTEX_UNIFORM_COMPONENTS: - case GL_MAX_VERTEX_UNIFORM_VECTORS: - case GL_MIN_FRAGMENT_INTERPOLATION_OFFSET: - case GL_MIN_PROGRAM_TEXEL_OFFSET: - case GL_MIN_SAMPLE_SHADING_VALUE: - case GL_MINOR_VERSION: - case GL_NUM_COMPRESSED_TEXTURE_FORMATS: - case GL_NUM_EXTENSIONS: - case GL_NUM_PROGRAM_BINARY_FORMATS: - case GL_NUM_SHADER_BINARY_FORMATS: - case GL_PACK_ALIGNMENT: - case GL_PACK_ROW_LENGTH: - case GL_PACK_SKIP_PIXELS: - case GL_PACK_SKIP_ROWS: - case GL_PATCH_VERTICES: - case GL_PIXEL_PACK_BUFFER_BINDING: - case GL_PIXEL_UNPACK_BUFFER_BINDING: - case GL_POLYGON_OFFSET_FACTOR: - case GL_POLYGON_OFFSET_FILL: - case GL_POLYGON_OFFSET_UNITS: - case GL_PRIMITIVE_RESTART_FIXED_INDEX: - case GL_PROGRAM_PIPELINE_BINDING: - case GL_RASTERIZER_DISCARD: - case GL_READ_BUFFER: - case GL_READ_FRAMEBUFFER_BINDING: - case GL_RED_BITS: - case GL_RENDERBUFFER_BINDING: - case GL_RESET_NOTIFICATION_STRATEGY: - case GL_SAMPLE_ALPHA_TO_COVERAGE: - case GL_SAMPLE_BUFFERS: - case GL_SAMPLE_COVERAGE: - case GL_SAMPLE_COVERAGE_INVERT: - case GL_SAMPLE_COVERAGE_VALUE: - case GL_SAMPLE_MASK_VALUE: - case GL_SAMPLE_SHADING: - case GL_SAMPLER_BINDING: - case GL_SAMPLES: - case GL_SCISSOR_TEST: - case GL_SHADER_COMPILER: - case GL_SHADER_STORAGE_BUFFER_BINDING: - case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT: - case GL_SHADER_STORAGE_BUFFER_SIZE: - case GL_SHADER_STORAGE_BUFFER_START: - case GL_STENCIL_BACK_FAIL: - case GL_STENCIL_BACK_FUNC: - case GL_STENCIL_BACK_PASS_DEPTH_FAIL: - case GL_STENCIL_BACK_PASS_DEPTH_PASS: - case GL_STENCIL_BACK_REF: - case GL_STENCIL_BACK_VALUE_MASK: - case GL_STENCIL_BACK_WRITEMASK: - case GL_STENCIL_BITS: - case GL_STENCIL_CLEAR_VALUE: - case GL_STENCIL_FAIL: - case GL_STENCIL_FUNC: - case GL_STENCIL_PASS_DEPTH_FAIL: - case GL_STENCIL_PASS_DEPTH_PASS: - case GL_STENCIL_REF: - case GL_STENCIL_TEST: - case GL_STENCIL_VALUE_MASK: - case GL_STENCIL_WRITEMASK: - case GL_SUBPIXEL_BITS: - case GL_TEXTURE_BINDING_2D: - case GL_TEXTURE_BINDING_2D_ARRAY: - case GL_TEXTURE_BINDING_3D: - case GL_TEXTURE_BINDING_BUFFER: - case GL_TEXTURE_BINDING_CUBE_MAP: - case GL_TEXTURE_BINDING_2D_MULTISAMPLE: - case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY: - case GL_TEXTURE_BINDING_CUBE_MAP_ARRAY: - case GL_TEXTURE_BUFFER_BINDING: - case GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT: - case GL_TRANSFORM_FEEDBACK_BINDING: - case GL_TRANSFORM_FEEDBACK_ACTIVE: - case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: - case GL_TRANSFORM_FEEDBACK_PAUSED: - case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: - case GL_TRANSFORM_FEEDBACK_BUFFER_START: - case GL_UNIFORM_BUFFER_BINDING: - case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: - case GL_UNIFORM_BUFFER_SIZE: - case GL_UNIFORM_BUFFER_START: - case GL_UNPACK_ALIGNMENT: - case GL_UNPACK_IMAGE_HEIGHT: - case GL_UNPACK_ROW_LENGTH: - case GL_UNPACK_SKIP_IMAGES: - case GL_UNPACK_SKIP_PIXELS: - case GL_UNPACK_SKIP_ROWS: - case GL_VERTEX_ARRAY_BINDING: - case GL_VERTEX_BINDING_DIVISOR: - case GL_VERTEX_BINDING_OFFSET: - case GL_VERTEX_BINDING_STRIDE: - case GL_TEXTURE_2D: - case GL_TEXTURE_3D: - count = 1; - break; + case GL_MAX_COMBINED_ATOMIC_COUNTERS: + case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS: + case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: + case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS: + case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS: + case GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS: + case GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS: + case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: + case GL_MAX_COMBINED_UNIFORM_BLOCKS: + case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: + case GL_MAX_COMPUTE_ATOMIC_COUNTERS: + case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_COMPUTE_IMAGE_UNIFORMS: + case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS: + case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS: + case GL_MAX_COMPUTE_UNIFORM_BLOCKS: + case GL_MAX_COMPUTE_UNIFORM_COMPONENTS: + case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS: + case GL_MAX_COMPUTE_WORK_GROUP_COUNT: + case GL_MAX_COMPUTE_WORK_GROUP_SIZE: + case GL_MAX_CUBE_MAP_TEXTURE_SIZE: + case GL_MAX_DEBUG_GROUP_STACK_DEPTH: + case GL_MAX_DEBUG_LOGGED_MESSAGES: + case GL_MAX_DEBUG_MESSAGE_LENGTH: + case GL_MAX_DEPTH_TEXTURE_SAMPLES: + case GL_MAX_DRAW_BUFFERS: + case GL_MAX_ELEMENT_INDEX: + case GL_MAX_ELEMENTS_INDICES: + case GL_MAX_ELEMENTS_VERTICES: + case GL_MAX_FRAGMENT_ATOMIC_COUNTERS: + case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_FRAGMENT_IMAGE_UNIFORMS: + case GL_MAX_FRAGMENT_INPUT_COMPONENTS: + case GL_MAX_FRAGMENT_INTERPOLATION_OFFSET: + case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS: + case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: + case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: + case GL_MAX_FRAGMENT_UNIFORM_VECTORS: + case GL_MAX_FRAMEBUFFER_HEIGHT: + case GL_MAX_FRAMEBUFFER_LAYERS: + case GL_MAX_FRAMEBUFFER_SAMPLES: + case GL_MAX_FRAMEBUFFER_WIDTH: + case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_GEOMETRY_ATOMIC_COUNTERS: + case GL_MAX_GEOMETRY_IMAGE_UNIFORMS: + case GL_MAX_GEOMETRY_INPUT_COMPONENTS: + case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS: + case GL_MAX_GEOMETRY_OUTPUT_VERTICES: + case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS: + case GL_MAX_GEOMETRY_SHADER_INVOCATIONS: + case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS: + case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS: + case GL_MAX_GEOMETRY_UNIFORM_BLOCKS: + case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS: + case GL_MAX_INTEGER_SAMPLES: + case GL_MAX_LABEL_LENGTH: + case GL_MAX_PROGRAM_TEXEL_OFFSET: + case GL_MAX_RENDERBUFFER_SIZE: + case GL_MAX_SAMPLE_MASK_WORDS: + case GL_MAX_SAMPLES: + case GL_MAX_SERVER_WAIT_TIMEOUT: + case GL_MAX_SHADER_STORAGE_BLOCK_SIZE: + case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS: + case GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS: + case GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS: + case GL_MAX_TESS_CONTROL_INPUT_COMPONENTS: + case GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS: + case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS: + case GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS: + case GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS: + case GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS: + case GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS: + case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS: + case GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS: + case GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS: + case GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS: + case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS: + case GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS: + case GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS: + case GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS: + case GL_MAX_TESS_GEN_LEVEL: + case GL_MAX_TESS_PATCH_COMPONENTS: + case GL_MAX_TEXTURE_BUFFER_SIZE: + case GL_MAX_TEXTURE_IMAGE_UNITS: + case GL_MAX_TEXTURE_LOD_BIAS: + case GL_MAX_TEXTURE_SIZE: + case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: + case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: + case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: + case GL_MAX_UNIFORM_BLOCK_SIZE: + case GL_MAX_UNIFORM_BUFFER_BINDINGS: + case GL_MAX_UNIFORM_LOCATIONS: + case GL_MAX_VARYING_COMPONENTS: + case GL_MAX_VARYING_VECTORS: + case GL_MAX_VERTEX_ATOMIC_COUNTERS: + case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS: + case GL_MAX_VERTEX_ATTRIB_BINDINGS: + case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET: + case GL_MAX_VERTEX_ATTRIBS: + case GL_MAX_VERTEX_IMAGE_UNIFORMS: + case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS: + case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS: + case GL_MAX_VERTEX_OUTPUT_COMPONENTS: + case GL_MAX_VERTEX_UNIFORM_BLOCKS: + case GL_MAX_VERTEX_UNIFORM_COMPONENTS: + case GL_MAX_VERTEX_UNIFORM_VECTORS: + case GL_MIN_FRAGMENT_INTERPOLATION_OFFSET: + case GL_MIN_PROGRAM_TEXEL_OFFSET: + case GL_MIN_SAMPLE_SHADING_VALUE: + case GL_MINOR_VERSION: + case GL_NUM_COMPRESSED_TEXTURE_FORMATS: + case GL_NUM_EXTENSIONS: + case GL_NUM_PROGRAM_BINARY_FORMATS: + case GL_NUM_SHADER_BINARY_FORMATS: + case GL_PACK_ALIGNMENT: + case GL_PACK_ROW_LENGTH: + case GL_PACK_SKIP_PIXELS: + case GL_PACK_SKIP_ROWS: + case GL_PATCH_VERTICES: + case GL_PIXEL_PACK_BUFFER_BINDING: + case GL_PIXEL_UNPACK_BUFFER_BINDING: + case GL_POLYGON_OFFSET_FACTOR: + case GL_POLYGON_OFFSET_FILL: + case GL_POLYGON_OFFSET_UNITS: + case GL_PRIMITIVE_RESTART_FIXED_INDEX: + case GL_PROGRAM_PIPELINE_BINDING: + case GL_RASTERIZER_DISCARD: + case GL_READ_BUFFER: + case GL_READ_FRAMEBUFFER_BINDING: + case GL_RED_BITS: + case GL_RENDERBUFFER_BINDING: + case GL_RESET_NOTIFICATION_STRATEGY: + case GL_SAMPLE_ALPHA_TO_COVERAGE: + case GL_SAMPLE_BUFFERS: + case GL_SAMPLE_COVERAGE: + case GL_SAMPLE_COVERAGE_INVERT: + case GL_SAMPLE_COVERAGE_VALUE: + case GL_SAMPLE_MASK_VALUE: + case GL_SAMPLE_SHADING: + case GL_SAMPLER_BINDING: + case GL_SAMPLES: + case GL_SCISSOR_TEST: + case GL_SHADER_COMPILER: + case GL_SHADER_STORAGE_BUFFER_BINDING: + case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT: + case GL_SHADER_STORAGE_BUFFER_SIZE: + case GL_SHADER_STORAGE_BUFFER_START: + case GL_STENCIL_BACK_FAIL: + case GL_STENCIL_BACK_FUNC: + case GL_STENCIL_BACK_PASS_DEPTH_FAIL: + case GL_STENCIL_BACK_PASS_DEPTH_PASS: + case GL_STENCIL_BACK_REF: + case GL_STENCIL_BACK_VALUE_MASK: + case GL_STENCIL_BACK_WRITEMASK: + case GL_STENCIL_BITS: + case GL_STENCIL_CLEAR_VALUE: + case GL_STENCIL_FAIL: + case GL_STENCIL_FUNC: + case GL_STENCIL_PASS_DEPTH_FAIL: + case GL_STENCIL_PASS_DEPTH_PASS: + case GL_STENCIL_REF: + case GL_STENCIL_TEST: + case GL_STENCIL_VALUE_MASK: + case GL_STENCIL_WRITEMASK: + case GL_SUBPIXEL_BITS: + case GL_TEXTURE_BINDING_2D: + case GL_TEXTURE_BINDING_2D_ARRAY: + case GL_TEXTURE_BINDING_3D: + case GL_TEXTURE_BINDING_BUFFER: + case GL_TEXTURE_BINDING_CUBE_MAP: + case GL_TEXTURE_BINDING_2D_MULTISAMPLE: + case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY: + case GL_TEXTURE_BINDING_CUBE_MAP_ARRAY: + case GL_TEXTURE_BUFFER_BINDING: + case GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT: + case GL_TRANSFORM_FEEDBACK_BINDING: + case GL_TRANSFORM_FEEDBACK_ACTIVE: + case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + case GL_TRANSFORM_FEEDBACK_PAUSED: + case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE: + case GL_TRANSFORM_FEEDBACK_BUFFER_START: + case GL_UNIFORM_BUFFER_BINDING: + case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: + case GL_UNIFORM_BUFFER_SIZE: + case GL_UNIFORM_BUFFER_START: + case GL_UNPACK_ALIGNMENT: + case GL_UNPACK_IMAGE_HEIGHT: + case GL_UNPACK_ROW_LENGTH: + case GL_UNPACK_SKIP_IMAGES: + case GL_UNPACK_SKIP_PIXELS: + case GL_UNPACK_SKIP_ROWS: + case GL_VERTEX_ARRAY_BINDING: + case GL_VERTEX_BINDING_DIVISOR: + case GL_VERTEX_BINDING_OFFSET: + case GL_VERTEX_BINDING_STRIDE: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + count = 1; + break; - case GL_ALIASED_LINE_WIDTH_RANGE: - case GL_ALIASED_POINT_SIZE_RANGE: - case GL_DEPTH_RANGE: - case GL_MAX_VIEWPORT_DIMS: - case GL_MULTISAMPLE_LINE_WIDTH_RANGE: - count = 2; - break; + case GL_ALIASED_LINE_WIDTH_RANGE: + case GL_ALIASED_POINT_SIZE_RANGE: + case GL_DEPTH_RANGE: + case GL_MAX_VIEWPORT_DIMS: + case GL_MULTISAMPLE_LINE_WIDTH_RANGE: + count = 2; + break; - case GL_BLEND_COLOR: - case GL_COLOR_CLEAR_VALUE: - case GL_COLOR_WRITEMASK: - case GL_SCISSOR_BOX: - case GL_VIEWPORT: - count = 4; - break; + case GL_BLEND_COLOR: + case GL_COLOR_CLEAR_VALUE: + case GL_COLOR_WRITEMASK: + case GL_SCISSOR_BOX: + case GL_VIEWPORT: + count = 4; + break; - case GL_PRIMITIVE_BOUNDING_BOX: - count = 8; - break; + case GL_PRIMITIVE_BOUNDING_BOX: + count = 8; + break; - case GL_COMPRESSED_TEXTURE_FORMATS: - count = __orcaGLESImplLimits.numCompressedTextureFormats; - break; + case GL_COMPRESSED_TEXTURE_FORMATS: + count = __orcaGLESImplLimits.numCompressedTextureFormats; + break; - case GL_PROGRAM_BINARY_FORMATS: - count = __orcaGLESImplLimits.numProgramBinaryFormats; - break; + case GL_PROGRAM_BINARY_FORMATS: + count = __orcaGLESImplLimits.numProgramBinaryFormats; + break; - case GL_SHADER_BINARY_FORMATS: - count = __orcaGLESImplLimits.numShaderBinaryFormats; - break; + case GL_SHADER_BINARY_FORMATS: + count = __orcaGLESImplLimits.numShaderBinaryFormats; + break; - default: - OC_ASSERT(0, "unknown GLenum pname %i", pname); - break; - } - } - return(count); + default: + OC_ASSERT(0, "unknown GLenum pname %i", pname); + break; + } + } + return (count); } u64 orca_glDrawElements_indices_length(IM3Runtime runtime, GLsizei count, GLenum type) { - return(orca_gl_type_size(type)*count); + return (orca_gl_type_size(type) * count); } u64 orca_glGetBooleanv_data_length(IM3Runtime runtime, GLenum pname) { - return(orca_glGet_data_length(pname)); + return (orca_glGet_data_length(pname)); } u64 orca_glGetBufferParameteriv_params_length(IM3Runtime runtime, GLenum pname) { - //NOTE: all pnames return a single value in 3.1 - return(1); + //NOTE: all pnames return a single value in 3.1 + return (1); } + u64 orca_glGetFloatv_data_length(IM3Runtime runtime, GLenum pname) { - return(orca_glGet_data_length(pname)); + return (orca_glGet_data_length(pname)); } + u64 orca_glGetFramebufferAttachmentParameteriv_params_length(IM3Runtime runtime, GLenum pname) { - //NOTE: all pnames return a single value in 3.1 - return(1); + //NOTE: all pnames return a single value in 3.1 + return (1); } + u64 orca_glGetIntegerv_data_length(IM3Runtime runtime, GLenum pname) { - return(orca_glGet_data_length(pname)); + return (orca_glGet_data_length(pname)); } + u64 orca_glGetProgramiv_params_length(IM3Runtime runtime, GLenum pname) { - //NOTE: all pnames return a single value in 3.1 - return(1); + //NOTE: all pnames return a single value in 3.1 + return (1); } + u64 orca_glGetRenderbufferParameteriv_params_length(IM3Runtime runtime, GLenum pname) { - //NOTE: all pnames return a single value in 3.1 - return(1); + //NOTE: all pnames return a single value in 3.1 + return (1); } + u64 orca_glGetShaderiv_params_length(IM3Runtime runtime, GLenum pname) { - //NOTE: all pnames return a single value in 3.1 - return(1); + //NOTE: all pnames return a single value in 3.1 + return (1); } u64 orca_glTexParameter_params_length_generic(GLenum pname) { - u64 count = 4; - if(pname == GL_TEXTURE_BORDER_COLOR) - { - count = 4; - } - else - { - count = 1; - } - return(count); + u64 count = 4; + if(pname == GL_TEXTURE_BORDER_COLOR) + { + count = 4; + } + else + { + count = 1; + } + return (count); } u64 orca_glGetTexParameterfv_params_length(IM3Runtime runtime, GLenum pname) { - return(orca_glTexParameter_params_length_generic(pname)); + return (orca_glTexParameter_params_length_generic(pname)); } u64 orca_glGetTexParameteriv_params_length(IM3Runtime runtime, GLenum pname) { - return(orca_glTexParameter_params_length_generic(pname)); + return (orca_glTexParameter_params_length_generic(pname)); } u64 orca_glReadPixels_pixels_length(IM3Runtime runtime, GLenum format, GLenum type, GLsizei width, GLsizei height) { - u64 count = width*height*orca_gl_type_size(type)*orca_gl_format_count(format); - return(count); + u64 count = width * height * orca_gl_type_size(type) * orca_gl_format_count(format); + return (count); } + u64 orca_glTexImage2D_pixels_length(IM3Runtime runtime, GLenum format, GLenum type, GLsizei width, GLsizei height) { - u64 count = width*height*orca_gl_type_size(type)*orca_gl_format_count(format); - return(count); + u64 count = width * height * orca_gl_type_size(type) * orca_gl_format_count(format); + return (count); } u64 orca_glTexParameterfv_params_length(IM3Runtime runtime, GLenum pname) { - return(orca_glTexParameter_params_length_generic(pname)); + return (orca_glTexParameter_params_length_generic(pname)); } + u64 orca_glTexParameteriv_params_length(IM3Runtime runtime, GLenum pname) { - return(orca_glTexParameter_params_length_generic(pname)); + return (orca_glTexParameter_params_length_generic(pname)); } + u64 orca_glTexSubImage2D_pixels_length(IM3Runtime runtime, GLenum format, GLenum type, GLsizei width, GLsizei height) { - u64 count = width*height*orca_gl_type_size(type)*orca_gl_format_count(format); - return(count); + u64 count = width * height * orca_gl_type_size(type) * orca_gl_format_count(format); + return (count); } u64 orca_glDrawRangeElements_indices_length(IM3Runtime runtime, GLsizei count, GLenum type) { - return(count*orca_gl_type_size(type)); + return (count * orca_gl_type_size(type)); } + u64 orca_glTexImage3D_pixels_length(IM3Runtime runtime, GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth) { - u64 count = width*height*depth*orca_gl_type_size(type)*orca_gl_format_count(format); - return(count); + u64 count = width * height * depth * orca_gl_type_size(type) * orca_gl_format_count(format); + return (count); } + u64 orca_glTexSubImage3D_pixels_length(IM3Runtime runtime, GLenum format, GLenum type, GLsizei width, GLsizei height, GLsizei depth) { - u64 count = width*height*depth*orca_gl_type_size(type)*orca_gl_format_count(format); - return(count); + u64 count = width * height * depth * orca_gl_type_size(type) * orca_gl_format_count(format); + return (count); } + u64 orca_glGetQueryiv_params_length(IM3Runtime runtime, GLenum pname) { - //NOTE: all pnames return a single value in 3.1 - return(1); + //NOTE: all pnames return a single value in 3.1 + return (1); } + u64 orca_glGetQueryObjectuiv_params_length(IM3Runtime runtime, GLenum pname) { - //NOTE: all pnames return a single value in 3.1 - return(1); + //NOTE: all pnames return a single value in 3.1 + return (1); } + u64 orca_glGetIntegeri_v_data_length(IM3Runtime runtime, GLenum target) { - return(orca_glGet_data_length(target)); + return (orca_glGet_data_length(target)); } + u64 orca_glVertexAttribIPointer_pointer_length(IM3Runtime runtime, GLint size, GLenum type, GLsizei stride) { - //WARN: pointer param of glVertexAttribPointer is actually treated as an offset, - // so, we don't need to check if this points to valid memory ?? - return(0); + //WARN: pointer param of glVertexAttribPointer is actually treated as an offset, + // so, we don't need to check if this points to valid memory ?? + return (0); } u64 orca_glClearBuffer_value_length_generic(GLenum buffer) { - u64 count = 4; - switch(buffer) - { - case GL_COLOR: - count = 4; - break; + u64 count = 4; + switch(buffer) + { + case GL_COLOR: + count = 4; + break; - case GL_DEPTH: - case GL_STENCIL: - count = 1; - break; + case GL_DEPTH: + case GL_STENCIL: + count = 1; + break; - default: - OC_ASSERT(0, "invalid buffer enum for glClearBuffer()"); - } - return(count); + default: + OC_ASSERT(0, "invalid buffer enum for glClearBuffer()"); + } + return (count); } u64 orca_glClearBufferiv_value_length(IM3Runtime runtime, GLenum buffer) { - return(orca_glClearBuffer_value_length_generic(buffer)); + return (orca_glClearBuffer_value_length_generic(buffer)); } + u64 orca_glClearBufferuiv_value_length(IM3Runtime runtime, GLenum buffer) { - return(orca_glClearBuffer_value_length_generic(buffer)); + return (orca_glClearBuffer_value_length_generic(buffer)); } + u64 orca_glClearBufferfv_value_length(IM3Runtime runtime, GLenum buffer) { - return(orca_glClearBuffer_value_length_generic(buffer)); + return (orca_glClearBuffer_value_length_generic(buffer)); } u64 orca_glGetUniformIndices_uniformIndices_length(IM3Runtime runtime, GLsizei uniformCount) { - return(uniformCount); + return (uniformCount); } + u64 orca_glGetActiveUniformsiv_params_length(IM3Runtime runtime, GLsizei uniformCount, GLenum pname) { - return(uniformCount); + return (uniformCount); } u64 orca_glGetActiveUniformBlockiv_params_length(IM3Runtime runtime, GLuint program, GLuint uniformBlockIndex, GLenum pname) { - u64 count; - if(pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) - { - GLint param; - glGetActiveUniformBlockiv(program, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, ¶m); - count = param; - } - else - { - count = 1; - } - return(count); + u64 count; + if(pname == GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES) + { + GLint param; + glGetActiveUniformBlockiv(program, uniformBlockIndex, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, ¶m); + count = param; + } + else + { + count = 1; + } + return (count); } + u64 orca_glDrawElementsInstanced_indices_length(IM3Runtime runtime, GLsizei count, GLenum type) { - return(count*orca_gl_type_size(type)); + return (count * orca_gl_type_size(type)); } + u64 orca_glGetInteger64v_data_length(IM3Runtime runtime, GLenum pname) { - return(orca_glGet_data_length(pname)); + return (orca_glGet_data_length(pname)); } + u64 orca_glGetInteger64i_v_data_length(IM3Runtime runtime, GLenum target) { - return(orca_glGet_data_length(target)); + return (orca_glGet_data_length(target)); } + u64 orca_glGetBufferParameteri64v_params_length(IM3Runtime runtime, GLenum pname) { - //NOTE: all pnames return a single value in 3.1 - return(1); + //NOTE: all pnames return a single value in 3.1 + return (1); } u64 orca_glSamplerParameter_param_length_generic(GLenum pname) { - //NOTE: same as texture parameter pnames - return(orca_glTexParameter_params_length_generic(pname)); + //NOTE: same as texture parameter pnames + return (orca_glTexParameter_params_length_generic(pname)); } u64 orca_glSamplerParameteriv_param_length(IM3Runtime runtime, GLenum pname) { - return(orca_glSamplerParameter_param_length_generic(pname)); + return (orca_glSamplerParameter_param_length_generic(pname)); } + u64 orca_glSamplerParameterfv_param_length(IM3Runtime runtime, GLenum pname) { - return(orca_glSamplerParameter_param_length_generic(pname)); + return (orca_glSamplerParameter_param_length_generic(pname)); } + u64 orca_glGetSamplerParameteriv_params_length(IM3Runtime runtime, GLenum pname) { - return(orca_glSamplerParameter_param_length_generic(pname)); + return (orca_glSamplerParameter_param_length_generic(pname)); } + u64 orca_glGetSamplerParameterfv_params_length(IM3Runtime runtime, GLenum pname) { - return(orca_glSamplerParameter_param_length_generic(pname)); + return (orca_glSamplerParameter_param_length_generic(pname)); } + u64 orca_glGetFramebufferParameteriv_params_length(IM3Runtime runtime, GLenum pname) { - //NOTE: all pnames return a single value in 3.1 - return(1); + //NOTE: all pnames return a single value in 3.1 + return (1); } + u64 orca_glGetProgramInterfaceiv_params_length(IM3Runtime runtime, GLenum pname) { - //NOTE: all pnames return a single value in 3.1 - return(1); + //NOTE: all pnames return a single value in 3.1 + return (1); } u64 orca_glGetProgramPipelineiv_params_length(IM3Runtime runtime, GLenum pname) { - //NOTE: all pnames return a single value in 3.1 - return(1); + //NOTE: all pnames return a single value in 3.1 + return (1); } + u64 orca_glGetBooleani_v_data_length(IM3Runtime runtime, GLenum target) { - return(orca_glSamplerParameter_param_length_generic(target)); + return (orca_glSamplerParameter_param_length_generic(target)); } + u64 orca_glGetMultisamplefv_val_length(IM3Runtime runtime, GLenum pname) { - return(2); + return (2); } + u64 orca_glGetTexLevelParameteriv_params_length(IM3Runtime runtime, GLenum pname) { - //NOTE: all pnames return a single value in 3.1 - return(1); + //NOTE: all pnames return a single value in 3.1 + return (1); } + u64 orca_glGetTexLevelParameterfv_params_length(IM3Runtime runtime, GLenum pname) { - //NOTE: all pnames return a single value in 3.1 - return(1); + //NOTE: all pnames return a single value in 3.1 + return (1); } //------------------------------------------------------------------------ @@ -685,54 +716,54 @@ u64 orca_glGetTexLevelParameterfv_params_length(IM3Runtime runtime, GLenum pname u64 orca_glGetUniform_params_length_generic(GLuint program, GLint location) { - //NOTE: This is super stupid but we can't get the size (or index) of a uniform directly from its location, - // so we have to iterate through all uniforms... - GLint maxUniformName = 0; - glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformName); + //NOTE: This is super stupid but we can't get the size (or index) of a uniform directly from its location, + // so we have to iterate through all uniforms... + GLint maxUniformName = 0; + glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxUniformName); - int uniformCount = 0; - glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniformCount); + int uniformCount = 0; + glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &uniformCount); - oc_arena_scope scratch = oc_scratch_begin(); - char* name = oc_arena_push(scratch.arena, maxUniformName+1); + oc_arena_scope scratch = oc_scratch_begin(); + char* name = oc_arena_push(scratch.arena, maxUniformName + 1); - u64 count = 0; - bool found = false; + u64 count = 0; + bool found = false; - for(int i=0; i= (char*)_mem) && (((char*)pointer - (char*)_mem) < m3_GetMemorySize(runtime)), - "parameter 'pointer' is out of bounds"); - OC_ASSERT((char*)pointer + sizeof(i32) <= ((char*)_mem + m3_GetMemorySize(runtime)), - "parameter 'pointer' overflows wasm memory"); - } - void* rawPointer = 0; - glGetVertexAttribPointerv(index, pname, &rawPointer); + GLuint index = *(i32*)&_sp[0]; + GLenum pname = *(i32*)&_sp[1]; + i32* pointer = (i32*)((char*)_mem + *(u32*)&_sp[2]); + { + OC_ASSERT(((char*)pointer >= (char*)_mem) && (((char*)pointer - (char*)_mem) < m3_GetMemorySize(runtime)), + "parameter 'pointer' is out of bounds"); + OC_ASSERT((char*)pointer + sizeof(i32) <= ((char*)_mem + m3_GetMemorySize(runtime)), + "parameter 'pointer' overflows wasm memory"); + } + void* rawPointer = 0; + glGetVertexAttribPointerv(index, pname, &rawPointer); - //NOTE: pointer is actually a _byte offset_ into a GPU buffer. So we do _not_ convert it to a wasm pointer, - // but we need to truncate it to u32 size... - //WARN: can OpenGL return a byte offset > UINT_MAX ? - *pointer = (i32)(intptr_t)rawPointer; - return(0); + //NOTE: pointer is actually a _byte offset_ into a GPU buffer. So we do _not_ convert it to a wasm pointer, + // but we need to truncate it to u32 size... + //WARN: can OpenGL return a byte offset > UINT_MAX ? + *pointer = (i32)(intptr_t)rawPointer; + return (0); } const void* glVertexAttribPointer_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t* _sp, void* _mem) { - GLuint index = *(u32*)&_sp[0]; - GLint size = *(i32*)&_sp[1]; - GLenum type = *(i32*)&_sp[2]; - GLboolean normalized = (GLboolean)*(i32*)&_sp[3]; - GLsizei stride = *(i32*)&_sp[4]; + GLuint index = *(u32*)&_sp[0]; + GLint size = *(i32*)&_sp[1]; + GLenum type = *(i32*)&_sp[2]; + GLboolean normalized = (GLboolean) * (i32*)&_sp[3]; + GLsizei stride = *(i32*)&_sp[4]; - //NOTE: pointer is interpreted as an offset if there's a non-null buffer bound to GL_ARRAY_BUFFER, - // or as a pointer otherwise. Since there's no way of checking the length of client vertex arrays, - // we just disable those. + //NOTE: pointer is interpreted as an offset if there's a non-null buffer bound to GL_ARRAY_BUFFER, + // or as a pointer otherwise. Since there's no way of checking the length of client vertex arrays, + // we just disable those. - GLint boundBuffer = 0; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &boundBuffer); + GLint boundBuffer = 0; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &boundBuffer); - if(boundBuffer != 0) - { - //NOTE: don't do bounds checking since pointer is really an offset in a GPU buffer - const void* pointer = (void*)(intptr_t)*(u32*)&_sp[5]; + if(boundBuffer != 0) + { + //NOTE: don't do bounds checking since pointer is really an offset in a GPU buffer + const void* pointer = (void*)(intptr_t) * (u32*)&_sp[5]; - glVertexAttribPointer(index, size, type, normalized, stride, pointer); - } - else - { - //NOTE: we crash here before letting ANGLE crash because vertex attrib pointer is not set - OC_ASSERT("Calling glVertexAttribPointer with a GL_ARRAY_BUFFER binding of 0 is unsafe and disabled in Orca."); - } - return(0); + glVertexAttribPointer(index, size, type, normalized, stride, pointer); + } + else + { + //NOTE: we crash here before letting ANGLE crash because vertex attrib pointer is not set + OC_ASSERT("Calling glVertexAttribPointer with a GL_ARRAY_BUFFER binding of 0 is unsafe and disabled in Orca."); + } + return (0); } const void* glVertexAttribIPointer_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t* _sp, void* _mem) { - GLuint index = *(u32*)&_sp[0]; - GLint size = *(i32*)&_sp[1]; - GLenum type = *(i32*)&_sp[2]; - GLsizei stride = *(i32*)&_sp[3]; + GLuint index = *(u32*)&_sp[0]; + GLint size = *(i32*)&_sp[1]; + GLenum type = *(i32*)&_sp[2]; + GLsizei stride = *(i32*)&_sp[3]; - //NOTE: pointer is interpreted as an offset if there's a non-null buffer bound to GL_ARRAY_BUFFER, - // or as a pointer otherwise. Since there's no way of checking the length of client vertex arrays, - // we just disable those. + //NOTE: pointer is interpreted as an offset if there's a non-null buffer bound to GL_ARRAY_BUFFER, + // or as a pointer otherwise. Since there's no way of checking the length of client vertex arrays, + // we just disable those. - GLint boundBuffer = 0; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &boundBuffer); + GLint boundBuffer = 0; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &boundBuffer); - if(boundBuffer != 0) - { - //NOTE: don't do bounds checking since pointer is really an offset in a GPU buffer - const void* pointer = (void*)(intptr_t)*(u32*)&_sp[4]; + if(boundBuffer != 0) + { + //NOTE: don't do bounds checking since pointer is really an offset in a GPU buffer + const void* pointer = (void*)(intptr_t) * (u32*)&_sp[4]; - glVertexAttribIPointer(index, size, type, stride, pointer); - } - else - { - OC_ASSERT(0, "Calling glVertexAttribIPointer with a GL_ARRAY_BUFFER binding of 0 is unsafe and disabled in Orca."); - } - return(0); + glVertexAttribIPointer(index, size, type, stride, pointer); + } + else + { + OC_ASSERT(0, "Calling glVertexAttribIPointer with a GL_ARRAY_BUFFER binding of 0 is unsafe and disabled in Orca."); + } + return (0); } const void* glGetUniformIndices_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t* _sp, void* _mem) { - GLuint program = (GLuint)*(i32*)&_sp[0]; - GLsizei uniformCount = (GLsizei)*(i32*)&_sp[1]; - u32* uniformNames = (u32*)((char*)_mem + *(u32*)&_sp[2]); - GLuint * uniformIndices = (GLuint *)((char*)_mem + *(u32*)&_sp[3]); + GLuint program = (GLuint) * (i32*)&_sp[0]; + GLsizei uniformCount = (GLsizei) * (i32*)&_sp[1]; + u32* uniformNames = (u32*)((char*)_mem + *(u32*)&_sp[2]); + GLuint* uniformIndices = (GLuint*)((char*)_mem + *(u32*)&_sp[3]); - u64 memorySize = m3_GetMemorySize(runtime); - //NOTE: check size of uniformNames - { - OC_ASSERT(((char*)uniformNames >= (char*)_mem) && (((char*)uniformNames - (char*)_mem) < memorySize), - "parameter 'uniformNames' is out of bounds"); - OC_ASSERT((char*)uniformNames + uniformCount * sizeof(u32) <= ((char*)_mem + memorySize), - "parameter 'uniformNames' overflows wasm memory"); - } - //NOTE: check each individual uniformNames - oc_arena_scope scratch = oc_scratch_begin(); + u64 memorySize = m3_GetMemorySize(runtime); + //NOTE: check size of uniformNames + { + OC_ASSERT(((char*)uniformNames >= (char*)_mem) && (((char*)uniformNames - (char*)_mem) < memorySize), + "parameter 'uniformNames' is out of bounds"); + OC_ASSERT((char*)uniformNames + uniformCount * sizeof(u32) <= ((char*)_mem + memorySize), + "parameter 'uniformNames' overflows wasm memory"); + } + //NOTE: check each individual uniformNames + oc_arena_scope scratch = oc_scratch_begin(); - char** uniformNamesRaw = oc_arena_push_array(scratch.arena, char*, uniformCount); - for(int i=0; i= (char*)_mem && (raw - (char*)_mem) < memorySize, "uniformName[%i] is out of bounds", i); + char** uniformNamesRaw = oc_arena_push_array(scratch.arena, char*, uniformCount); + for(int i = 0; i < uniformCount; i++) + { + char* raw = ((char*)_mem + uniformNames[i]); + OC_ASSERT(raw >= (char*)_mem && (raw - (char*)_mem) < memorySize, "uniformName[%i] is out of bounds", i); - u64 len = orca_gles_check_cstring(runtime, raw); + u64 len = orca_gles_check_cstring(runtime, raw); - OC_ASSERT(raw + len <= ((char*)_mem + memorySize), "uniformName[%i] overflows wasm memory", i); + OC_ASSERT(raw + len <= ((char*)_mem + memorySize), "uniformName[%i] overflows wasm memory", i); - uniformNamesRaw[i] = raw; - } + uniformNamesRaw[i] = raw; + } - //NOTE: check size of uniformIndices - { - OC_ASSERT(((char*)uniformIndices >= (char*)_mem) && (((char*)uniformIndices - (char*)_mem) < memorySize), - "parameter 'uniformIndices' is out of bounds"); - OC_ASSERT((char*)uniformIndices + uniformCount * sizeof(GLuint) <= ((char*)_mem + memorySize), - "parameter 'uniformIndices' overflows wasm memory"); - } + //NOTE: check size of uniformIndices + { + OC_ASSERT(((char*)uniformIndices >= (char*)_mem) && (((char*)uniformIndices - (char*)_mem) < memorySize), + "parameter 'uniformIndices' is out of bounds"); + OC_ASSERT((char*)uniformIndices + uniformCount * sizeof(GLuint) <= ((char*)_mem + memorySize), + "parameter 'uniformIndices' overflows wasm memory"); + } - glGetUniformIndices(program, uniformCount, (const GLchar* const*)uniformNamesRaw, uniformIndices); + glGetUniformIndices(program, uniformCount, (const GLchar* const*)uniformNamesRaw, uniformIndices); - oc_scratch_end(scratch); - return(0); + oc_scratch_end(scratch); + return (0); } typedef struct orca_gl_getstring_entry { - u32 offset; - u32 len; + u32 offset; + u32 len; } orca_gl_getstring_entry; GLenum ORCA_GL_GETSTRING_NAMES[] = { - GL_EXTENSIONS, - GL_VENDOR, - GL_RENDERER, - GL_VERSION, - GL_SHADING_LANGUAGE_VERSION + GL_EXTENSIONS, + GL_VENDOR, + GL_RENDERER, + GL_VERSION, + GL_SHADING_LANGUAGE_VERSION }; -enum { - ORCA_GL_GETSTRING_ENTRY_COUNT = sizeof(ORCA_GL_GETSTRING_NAMES)/sizeof(GLenum) +enum +{ + ORCA_GL_GETSTRING_ENTRY_COUNT = sizeof(ORCA_GL_GETSTRING_NAMES) / sizeof(GLenum) }; typedef struct orca_gl_getstring_info { - bool init; + bool init; - orca_gl_getstring_entry entries[ORCA_GL_GETSTRING_ENTRY_COUNT]; + orca_gl_getstring_entry entries[ORCA_GL_GETSTRING_ENTRY_COUNT]; - u32 indexedEntryCount; - orca_gl_getstring_entry* indexedEntries; + u32 indexedEntryCount; + orca_gl_getstring_entry* indexedEntries; } orca_gl_getstring_info; -orca_gl_getstring_info __orcaGLGetStringInfo = {0}; +orca_gl_getstring_info __orcaGLGetStringInfo = { 0 }; void orca_gl_getstring_init(orca_gl_getstring_info* info, char* memory) { - u32 totalSize = 0; - const char* strings[ORCA_GL_GETSTRING_ENTRY_COUNT] = {0}; + u32 totalSize = 0; + const char* strings[ORCA_GL_GETSTRING_ENTRY_COUNT] = { 0 }; - for(int i=0; ientries[i].len = strlen(strings[i]) + 1; - totalSize += info->entries[i].len; - } - } + for(int i = 0; i < ORCA_GL_GETSTRING_ENTRY_COUNT; i++) + { + strings[i] = (const char*)glGetString(ORCA_GL_GETSTRING_NAMES[i]); + if(strings[i]) + { + info->entries[i].len = strlen(strings[i]) + 1; + totalSize += info->entries[i].len; + } + } - glGetIntegerv(GL_NUM_EXTENSIONS, (GLint*)&info->indexedEntryCount); - oc_arena_scope scratch = oc_scratch_begin(); - const char** extensions = oc_arena_push(scratch.arena, info->indexedEntryCount); + glGetIntegerv(GL_NUM_EXTENSIONS, (GLint*)&info->indexedEntryCount); + oc_arena_scope scratch = oc_scratch_begin(); + const char** extensions = oc_arena_push(scratch.arena, info->indexedEntryCount); - //NOTE: we will hold this until program terminates - info->indexedEntries = oc_malloc_array(orca_gl_getstring_entry, info->indexedEntryCount); + //NOTE: we will hold this until program terminates + info->indexedEntries = oc_malloc_array(orca_gl_getstring_entry, info->indexedEntryCount); - for(int i=0; iindexedEntryCount; i++) - { - extensions[i] = (const char*)glGetStringi(GL_EXTENSIONS, i); - if(extensions[i]) - { - info->indexedEntries[i].len = strlen(extensions[i])+1; - totalSize += info->indexedEntries[i].len; - } - } + for(int i = 0; i < info->indexedEntryCount; i++) + { + extensions[i] = (const char*)glGetStringi(GL_EXTENSIONS, i); + if(extensions[i]) + { + info->indexedEntries[i].len = strlen(extensions[i]) + 1; + totalSize += info->indexedEntries[i].len; + } + } - u32 wasmIndex = oc_mem_grow(totalSize); + u32 wasmIndex = oc_mem_grow(totalSize); - for(int i=0; ientries[i].offset = wasmIndex; - memcpy(memory + wasmIndex, strings[i], info->entries[i].len); + for(int i = 0; i < ORCA_GL_GETSTRING_ENTRY_COUNT; i++) + { + if(strings[i]) + { + info->entries[i].offset = wasmIndex; + memcpy(memory + wasmIndex, strings[i], info->entries[i].len); - wasmIndex += info->entries[i].len; - } - } + wasmIndex += info->entries[i].len; + } + } - for(int i=0; iindexedEntryCount; i++) - { - if(extensions[i]) - { - info->indexedEntries[i].offset = wasmIndex; - memcpy(memory + wasmIndex, extensions[i], info->indexedEntries[i].len); - wasmIndex += info->indexedEntries[i].len; - } - } + for(int i = 0; i < info->indexedEntryCount; i++) + { + if(extensions[i]) + { + info->indexedEntries[i].offset = wasmIndex; + memcpy(memory + wasmIndex, extensions[i], info->indexedEntries[i].len); + wasmIndex += info->indexedEntries[i].len; + } + } - oc_scratch_end(scratch); + oc_scratch_end(scratch); - info->init = true; + info->init = true; } const void* glGetString_stub(IM3Runtime runtime, IM3ImportContext _ctx, uint64_t* _sp, void* _mem) { - if(!__orcaGLGetStringInfo.init) - { - uint32_t memorySize = 0; - char* memory = (char*)m3_GetMemory(runtime, &memorySize, 0); - orca_gl_getstring_init(&__orcaGLGetStringInfo, memory); - } + if(!__orcaGLGetStringInfo.init) + { + uint32_t memorySize = 0; + char* memory = (char*)m3_GetMemory(runtime, &memorySize, 0); + orca_gl_getstring_init(&__orcaGLGetStringInfo, memory); + } - GLenum name = (GLenum)*(i32*)&_sp[1]; - *(u32*)&_sp[0] = 0; + GLenum name = (GLenum) * (i32*)&_sp[1]; + *(u32*)&_sp[0] = 0; - for(int i=0; i