diff options
-rw-r--r-- | CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/cglm_bindings.c | 814 | ||||
-rw-r--r-- | src/cglm_bindings.h | 543 | ||||
-rw-r--r-- | src/common.h | 81 | ||||
-rw-r--r-- | src/error/error.c | 126 | ||||
-rw-r--r-- | src/error/error.h | 7 | ||||
-rw-r--r-- | src/glm_bindings.c | 94 | ||||
-rw-r--r-- | src/glm_bindings.h | 33 | ||||
-rw-r--r-- | src/honey.c | 4 | ||||
-rw-r--r-- | src/honey.h | 2 | ||||
-rw-r--r-- | src/honey_lua.c | 489 |
11 files changed, 422 insertions, 1774 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f02dca..0d96e64 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,9 +15,8 @@ add_library(stb_image src/stb_image/stb_image.c) set(SOURCE_FILES src/main.c - src/cglm_bindings.c + src/glm_bindings.c src/camera/camera.c - src/error/error.c src/honey.c src/input/input.c src/honey_lua.c diff --git a/src/cglm_bindings.c b/src/cglm_bindings.c deleted file mode 100644 index 947c394..0000000 --- a/src/cglm_bindings.c +++ /dev/null @@ -1,814 +0,0 @@ -#include "cglm_bindings.h" - -void honey_setup_cglm(lua_State* L) -{ - honey_lua_element vec3_elements[] = { - { "dot", HONEY_FUNCTION, { .function = honey_cglm_vec3_dot } }, - { "norm2", HONEY_FUNCTION, { .function = honey_cglm_vec3_norm2 } }, - { "norm", HONEY_FUNCTION, { .function = honey_cglm_vec3_norm } }, - { "add", HONEY_FUNCTION, { .function = honey_cglm_vec3_add } }, - { "adds", HONEY_FUNCTION, { .function = honey_cglm_vec3_adds } }, - { "sub", HONEY_FUNCTION, { .function = honey_cglm_vec3_sub } }, - { "mul", HONEY_FUNCTION, { .function = honey_cglm_vec3_mul } }, - { "muls", HONEY_FUNCTION, { .function = honey_cglm_vec3_muls } }, - { "normalize", HONEY_FUNCTION, { .function = honey_cglm_vec3_normalize } }, - { "distance", HONEY_FUNCTION, { .function = honey_cglm_vec3_distance } }, - { "lerp", HONEY_FUNCTION, { .function = honey_cglm_vec3_lerp } }, - }; - - honey_lua_element vec4_elements[] = { - { "dot", HONEY_FUNCTION, { .function = honey_cglm_vec4_dot } }, - { "norm2", HONEY_FUNCTION, { .function = honey_cglm_vec4_norm2 } }, - { "norm", HONEY_FUNCTION, { .function = honey_cglm_vec4_norm } }, - { "add", HONEY_FUNCTION, { .function = honey_cglm_vec4_add } }, - { "adds", HONEY_FUNCTION, { .function = honey_cglm_vec4_adds } }, - { "sub", HONEY_FUNCTION, { .function = honey_cglm_vec4_sub } }, - { "mul", HONEY_FUNCTION, { .function = honey_cglm_vec4_mul } }, - { "muls", HONEY_FUNCTION, { .function = honey_cglm_vec4_muls } }, - { "normalize", HONEY_FUNCTION, { .function = honey_cglm_vec4_normalize } }, - { "distance", HONEY_FUNCTION, { .function = honey_cglm_vec4_distance } }, - { "lerp", HONEY_FUNCTION, { .function = honey_cglm_vec4_lerp } }, - }; - - honey_lua_element mat3_elements[] = { - { "identity", HONEY_FUNCTION, { .function = honey_cglm_mat3_identity } }, - { "mul", HONEY_FUNCTION, { .function = honey_cglm_mat3_mul } }, - { "muls", HONEY_FUNCTION, { .function = honey_cglm_mat3_muls } }, - { "mulv", HONEY_FUNCTION, { .function = honey_cglm_mat3_mulv } }, - { "trans", HONEY_FUNCTION, { .function = honey_cglm_mat3_trans } }, - { "det", HONEY_FUNCTION, { .function = honey_cglm_mat3_det } }, - { "trace", HONEY_FUNCTION, { .function = honey_cglm_mat3_trace } }, - { "inv", HONEY_FUNCTION, { .function = honey_cglm_mat3_inv } }, - }; - - honey_lua_element mat4_elements[] = { - { "identity", HONEY_FUNCTION, { .function = honey_cglm_mat4_identity } }, - { "pick3", HONEY_FUNCTION, { .function = honey_cglm_mat4_pick3 } }, - { "mul", HONEY_FUNCTION, { .function = honey_cglm_mat4_mul } }, - { "muls", HONEY_FUNCTION, { .function = honey_cglm_mat4_muls } }, - { "mulv", HONEY_FUNCTION, { .function = honey_cglm_mat4_mulv } }, - { "trans", HONEY_FUNCTION, { .function = honey_cglm_mat4_trans } }, - { "det", HONEY_FUNCTION, { .function = honey_cglm_mat4_det } }, - { "trace", HONEY_FUNCTION, { .function = honey_cglm_mat4_trace } }, - { "inv", HONEY_FUNCTION, { .function = honey_cglm_mat4_inv } }, - { "inv_fast", HONEY_FUNCTION, { .function = honey_cglm_mat4_inv_fast } }, - }; - - honey_lua_element affine_elements[] = { - { "translate", HONEY_FUNCTION, { .function = honey_cglm_translate } }, - { "scale", HONEY_FUNCTION, { .function = honey_cglm_scale } }, - { "rotate", HONEY_FUNCTION, { .function = honey_cglm_rotate } }, - }; - - honey_lua_element camera_elements[] = { - { "perspective", HONEY_FUNCTION, { .function = honey_cglm_perspective } }, - { "orthographic", HONEY_FUNCTION, { .function = honey_cglm_orthographic } }, - { "look", HONEY_FUNCTION, { .function = honey_cglm_look } }, - }; - - honey_lua_element cglm_elements[] = { - { "new_array_zero", HONEY_FUNCTION, { .function = honey_cglm_new_array_zero } }, - { "set_value", HONEY_FUNCTION, { .function = honey_cglm_array_set_value } }, - { "get_value", HONEY_FUNCTION, { .function = honey_cglm_array_get_value } }, - { "copy_array", HONEY_FUNCTION, { .function = honey_cglm_array_copy } }, - { "vec3", HONEY_TABLE, { .table = { 11, vec3_elements } } }, - { "vec4", HONEY_TABLE, { .table = { 11, vec4_elements } } }, - { "mat3", HONEY_TABLE, { .table = { 8, mat3_elements } } }, - { "mat4", HONEY_TABLE, { .table = { 10, mat4_elements } } }, - { "affine", HONEY_TABLE, { .table = { 3, affine_elements } } }, - { "camera", HONEY_TABLE, { .table = { 3, camera_elements } } }, - }; - - honey_lua_create_table(L, cglm_elements, 10); -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_new_array_zero(lua_State* L) -{ - if (!honey_lua_validate_types(L, 1, HONEY_INTEGER)) - lua_error(L); - - int size = lua_tointeger(L, 1); - - float* array = lua_newuserdata(L, size*sizeof(float)); - memset(array, 0, size*sizeof(float)); - return 1; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_array_set_value(lua_State* L) -{ - if (!honey_lua_validate_types(L, 3, HONEY_USERDATA, HONEY_INTEGER, HONEY_NUMBER)) - lua_error(L); - - float* array = lua_touserdata(L, 1); - int index = lua_tointeger(L, 2); - float value = lua_tonumber(L, 3); - - array[index] = value; - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_array_get_value(lua_State* L) -{ - if (!honey_lua_validate_types(L, 2, HONEY_USERDATA, HONEY_INTEGER)) - lua_error(L); - - float* array = lua_touserdata(L, 1); - int index = lua_tointeger(L, 2); - - lua_pushnumber(L, array[index]); - return 1; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_array_copy(lua_State* L) { - if (!honey_lua_validate_types(L, 2, HONEY_USERDATA, HONEY_INTEGER)) - lua_error(L); - - float* array = lua_touserdata(L, 1); - int n = lua_tointeger(L, 2); - - float* copy = lua_newuserdata(L, n*sizeof(float)); - memcpy(copy, array, n*sizeof(float)); - return 1; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * cglm vec3 functions - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -int honey_cglm_vec3_dot(lua_State* L) -{ - if (!honey_lua_validate_types(L, 2, HONEY_USERDATA, HONEY_USERDATA)) - lua_error(L); - - float* a = lua_touserdata(L, 1); - float* b = lua_touserdata(L, 2); - - float dot = glm_vec3_dot(a, b); - lua_pushnumber(L, dot); - return 1; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec3_norm2(lua_State* L) -{ - if (!honey_lua_validate_types(L, 1, HONEY_USERDATA)) - lua_error(L); - - float* v = lua_touserdata(L, 1); - - float norm2 = glm_vec3_norm2(v); - - lua_pushnumber(L, norm2); - return 1; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec3_norm(lua_State* L) -{ - if (!honey_lua_validate_types(L, 1, HONEY_USERDATA)) - lua_error(L); - - float* v = lua_touserdata(L, 1); - - float norm = glm_vec3_norm(v); - - lua_pushnumber(L, norm); - return 1; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec3_add(lua_State* L) -{ - float* a, *b, *dest; - honey_lua_parse_arguments(L, 3, - HONEY_USERDATA, &a, - HONEY_USERDATA, &b, - HONEY_USERDATA, &dest); - glm_vec3_add(a, b, dest); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec3_sub(lua_State* L) -{ - float* a, *b, *dest; - honey_lua_parse_arguments(L, 3, - HONEY_USERDATA, &a, - HONEY_USERDATA, &b, - HONEY_USERDATA, &dest); - glm_vec3_sub(a, b, dest); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec3_adds(lua_State* L) -{ - float a, *v, *dest; - honey_lua_parse_arguments(L, 3, - HONEY_NUMBER, &a, - HONEY_USERDATA, &v, - HONEY_USERDATA, &dest); - glm_vec3_adds(v, a, dest); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec3_mul(lua_State* L) -{ - float *a, *b, *dest; - honey_lua_parse_arguments(L, 3, - HONEY_USERDATA, &a, - HONEY_USERDATA, &b, - HONEY_USERDATA, &dest); - glm_vec3_mul(a, b, dest); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec3_muls(lua_State* L) -{ - float a, *v, *dest; - honey_lua_parse_arguments(L, 3, - HONEY_NUMBER, &a, - HONEY_USERDATA, &v, - HONEY_USERDATA, &dest); - glm_vec3_scale(v, a, dest); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec3_normalize(lua_State* L) -{ - float* a; - honey_lua_parse_arguments(L, 1, HONEY_USERDATA, &a); - - glm_vec3_normalize(a); - - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec3_distance(lua_State* L) -{ - float* a, *b; - honey_lua_parse_arguments(L, 2, - HONEY_USERDATA, &a, - HONEY_USERDATA, &b); - - float distance = glm_vec3_distance(a, b); - lua_pushnumber(L, distance); - - return 1; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec3_lerp(lua_State* L) -{ - float* a, *b, s, *dest; - honey_lua_parse_arguments(L, 4, - HONEY_USERDATA, &a, - HONEY_USERDATA, &b, - HONEY_NUMBER, &s, - HONEY_USERDATA, &dest); - glm_vec3_lerp(a, b, s, dest); - - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * cglm vec4 functions - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -int honey_cglm_vec4_dot(lua_State* L) -{ - if (!honey_lua_validate_types(L, 2, HONEY_USERDATA, HONEY_USERDATA)) - lua_error(L); - - float* a = lua_touserdata(L, 1); - float* b = lua_touserdata(L, 2); - - float dot = glm_vec4_dot(a, b); - lua_pushnumber(L, dot); - return 1; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec4_norm2(lua_State* L) -{ - if (!honey_lua_validate_types(L, 1, HONEY_USERDATA)) - lua_error(L); - - float* v = lua_touserdata(L, 1); - - float norm2 = glm_vec4_norm2(v); - - lua_pushnumber(L, norm2); - return 1; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec4_norm(lua_State* L) -{ - if (!honey_lua_validate_types(L, 1, HONEY_USERDATA)) - lua_error(L); - - float* v = lua_touserdata(L, 1); - - float norm = glm_vec4_norm(v); - - lua_pushnumber(L, norm); - return 1; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec4_add(lua_State* L) -{ - float* a, *b, *dest; - honey_lua_parse_arguments(L, 3, - HONEY_USERDATA, &a, - HONEY_USERDATA, &b, - HONEY_USERDATA, &dest); - glm_vec4_add(a, b, dest); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec4_adds(lua_State* L) -{ - float a, *v, *dest; - honey_lua_parse_arguments(L, 3, - HONEY_NUMBER, &a, - HONEY_USERDATA, &v, - HONEY_USERDATA, &dest); - glm_vec4_adds(v, a, dest); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec4_sub(lua_State* L) -{ - float* a, *b, *dest; - honey_lua_parse_arguments(L, 3, - HONEY_USERDATA, &a, - HONEY_USERDATA, &b, - HONEY_USERDATA, &dest); - glm_vec4_sub(a, b, dest); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec4_mul(lua_State* L) -{ - float *a, *b, *dest; - honey_lua_parse_arguments(L, 3, - HONEY_USERDATA, &a, - HONEY_USERDATA, &b, - HONEY_USERDATA, &dest); - glm_vec4_mul(a, b, dest); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec4_muls(lua_State* L) -{ - float a, *v, *dest; - honey_lua_parse_arguments(L, 3, - HONEY_NUMBER, &a, - HONEY_USERDATA, &v, - HONEY_USERDATA, &dest); - glm_vec4_scale(v, a, dest); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec4_normalize(lua_State* L) -{ - float* a; - honey_lua_parse_arguments(L, 1, HONEY_USERDATA, &a); - - glm_vec4_normalize(a); - - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec4_distance(lua_State* L) -{ - float* a, *b; - honey_lua_parse_arguments(L, 2, - HONEY_USERDATA, &a, - HONEY_USERDATA, &b); - - float distance = glm_vec4_distance(a, b); - lua_pushnumber(L, distance); - - return 1; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_vec4_lerp(lua_State* L) -{ - float* a, *b, s, *dest; - honey_lua_parse_arguments(L, 4, - HONEY_USERDATA, &a, - HONEY_USERDATA, &b, - HONEY_NUMBER, &s, - HONEY_USERDATA, &dest); - glm_vec4_lerp(a, b, s, dest); - - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * cglm mat3 functions - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -int honey_cglm_mat3_identity(lua_State* L) -{ - if (!honey_lua_validate_types(L, 1, HONEY_USERDATA)) - lua_error(L); - - float* matrix = lua_touserdata(L, 1); - glm_mat3_identity(matrix); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_mat3_mul(lua_State* L) -{ - float* A, *B, *dest; - honey_lua_parse_arguments(L, 3, - HONEY_USERDATA, &A, - HONEY_USERDATA, &B, - HONEY_USERDATA, &dest); - glm_mat3_mul(A, B, dest); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_mat3_muls(lua_State* L) -{ - float a; - float* M; - honey_lua_parse_arguments(L, 2, - HONEY_NUMBER, &a, - HONEY_USERDATA, &M); - glm_mat3_scale(M, a); - - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_mat3_mulv(lua_State* L) -{ - float* M, *v, *dest; - honey_lua_parse_arguments(L, 3, - HONEY_USERDATA, &M, - HONEY_USERDATA, &v, - HONEY_USERDATA, &dest); - glm_mat3_mulv(M, v, dest); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_mat3_trans(lua_State* L) -{ - if (!honey_lua_validate_types(L, 1, HONEY_USERDATA)) - lua_error(L); - - float* M = lua_touserdata(L, 1); - - glm_mat3_transpose(M); - - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_mat3_det(lua_State* L) -{ - if (!honey_lua_validate_types(L, 1, HONEY_USERDATA)) - lua_error(L); - - float* M = lua_touserdata(L, 1); - - float det = glm_mat3_det(M); - lua_pushnumber(L, det); - - return 1; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_mat3_trace(lua_State* L) -{ - if (!honey_lua_validate_types(L, 1, HONEY_USERDATA)) - lua_error(L); - - float* M = lua_touserdata(L, 1); - - float trace = glm_mat3_trace(M); - lua_pushnumber(L, trace); - - return 1; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_mat3_inv(lua_State* L) -{ - float* M, *dest; - honey_lua_parse_arguments(L, 2, - HONEY_USERDATA, &M, - HONEY_USERDATA, &dest); - glm_mat3_inv(M, dest); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * cglm mat4 functions - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -int honey_cglm_mat4_identity(lua_State* L) -{ - if (!honey_lua_validate_types(L, 1, HONEY_USERDATA)) - lua_error(L); - - float* matrix = lua_touserdata(L, 1); - glm_mat4_identity(matrix); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_mat4_pick3(lua_State* L) -{ - float* matrix, *dest; - honey_lua_parse_arguments(L, 2, - HONEY_USERDATA, &matrix, - HONEY_USERDATA, &dest); - glm_mat4_pick3(matrix, dest); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_mat4_mul(lua_State* L) -{ - float* A, *B, *dest; - honey_lua_parse_arguments(L, 3, - HONEY_USERDATA, &A, - HONEY_USERDATA, &B, - HONEY_USERDATA, &dest); - glm_mat4_mul(A, B, dest); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_mat4_muls(lua_State* L) -{ - float a; - float* M; - honey_lua_parse_arguments(L, 2, - HONEY_NUMBER, &a, - HONEY_USERDATA, &M); - glm_mat4_scale(M, a); - - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_mat4_mulv(lua_State* L) -{ - float* M, *v, *dest; - honey_lua_parse_arguments(L, 3, - HONEY_USERDATA, &M, - HONEY_USERDATA, &v, - HONEY_USERDATA, &dest); - glm_mat4_mulv(M, v, dest); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_mat4_trans(lua_State* L) -{ - if (!honey_lua_validate_types(L, 1, HONEY_USERDATA)) - lua_error(L); - - float* M = lua_touserdata(L, 1); - - glm_mat4_transpose(M); - - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_mat4_det(lua_State* L) -{ - if (!honey_lua_validate_types(L, 1, HONEY_USERDATA)) - lua_error(L); - - float* M = lua_touserdata(L, 1); - - float det = glm_mat4_det(M); - lua_pushnumber(L, det); - - return 1; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_mat4_trace(lua_State* L) -{ - if (!honey_lua_validate_types(L, 1, HONEY_USERDATA)) - lua_error(L); - - float* M = lua_touserdata(L, 1); - - float trace = glm_mat4_trace(M); - lua_pushnumber(L, trace); - - return 1; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_mat4_inv(lua_State* L) -{ - float* M, *dest; - honey_lua_parse_arguments(L, 2, - HONEY_USERDATA, &M, - HONEY_USERDATA, &dest); - glm_mat4_inv(M, dest); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_mat4_inv_fast(lua_State* L) -{ - float* M, *dest; - honey_lua_parse_arguments(L, 2, - HONEY_USERDATA, &M, - HONEY_USERDATA, &dest); - glm_mat4_inv_fast(M, dest); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * cglm 3d affine transforms - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -int honey_cglm_translate(lua_State* L) -{ - if (!honey_lua_validate_types(L, 2, HONEY_USERDATA, HONEY_USERDATA)) - lua_error(L); - - float* matrix = lua_touserdata(L, 1); - float* vector = lua_touserdata(L, 2); - - glm_translate(matrix, vector); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_scale(lua_State* L) -{ - if (!honey_lua_validate_types(L, 2, HONEY_USERDATA, HONEY_USERDATA)) - lua_error(L); - - float* matrix = lua_touserdata(L, 1); - float* vector = lua_touserdata(L, 2); - - glm_scale(matrix, vector); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_rotate(lua_State* L) { - if (!honey_lua_validate_types(L, 4, - HONEY_USERDATA, HONEY_USERDATA, - HONEY_USERDATA, HONEY_NUMBER)) - lua_error(L); - - float* matrix = lua_touserdata(L, 1); - float* center = lua_touserdata(L, 2); - float* axis = lua_touserdata(L, 3); - float angle = lua_tonumber(L, 4); - - glm_rotate_at(matrix, center, angle, axis); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * cglm camera matrix functions - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -int honey_cglm_perspective(lua_State* L) -{ - if (!honey_lua_validate_types(L, 5, - HONEY_USERDATA, - HONEY_NUMBER, HONEY_NUMBER, - HONEY_NUMBER, HONEY_NUMBER)) - lua_error(L); - - float* matrix = lua_touserdata(L, 1); - float fov = lua_tonumber(L, 2); - float aspect = lua_tonumber(L, 3); - float near = lua_tonumber(L, 4); - float far = lua_tonumber(L, 5); - - glm_perspective(fov, aspect, near, far, matrix); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_orthographic(lua_State* L) -{ - if (!honey_lua_validate_types(L, 5, - HONEY_USERDATA, - HONEY_USERDATA, - HONEY_USERDATA)) - - lua_error(L); - - float* matrix = lua_touserdata(L, 1); - float* a = lua_touserdata(L, 2); - float* b = lua_touserdata(L, 3); - - float* box[] = { a, b }; - - glm_ortho_aabb(box, matrix); - return 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -int honey_cglm_look(lua_State* L) -{ - float *position, *direction, *up, *dest; - honey_lua_parse_arguments(L, 4, - HONEY_USERDATA, &position, - HONEY_USERDATA, &direction, - HONEY_USERDATA, &up, - HONEY_USERDATA, &dest); - glm_look(position, direction, up, dest); - return 0; -} diff --git a/src/cglm_bindings.h b/src/cglm_bindings.h deleted file mode 100644 index 61554e3..0000000 --- a/src/cglm_bindings.h +++ /dev/null @@ -1,543 +0,0 @@ -#ifndef HONEY_CGLM_BINDINGS_H -#define HONEY_CGLM_BINDINGS_H - -/** @file cglm_bindings.h - * @brief Lua bindings for CGLM functions. - */ - -#include "common.h" - -/** @brief Push the honey cglm binding functions to the lua stack. - * - * @returns Nothing. - */ -void honey_setup_cglm(lua_State* L); - -/** @brief Push a new float array to the lua stack. - * - * This function initializes the array to all zeros. - * - * @param[in] n The size of the floating-point array to create. - * - * @returns The vector so generated. - */ -int honey_cglm_new_array_zero(lua_State* L); - -/** @brief Set an element of a float array. - * - * This function does NOT check if your index is out of bounds. - * Use caution! - * - * @param[in] array The array to modify. - * @param[in] index The index to set. - * @param[in] value The value to set array[index] to. - * - * @returns Nothing. - */ -int honey_cglm_array_set_value(lua_State* L); - -/** @brief Get an element of a vec3. - * - * This function does NOT check if your index is out of bounds. - * Use caution! - * - * @param[in] array The array to inspect. - * @param[in] index The index to get. - * - * @returns The value at array[index]. - */ -int honey_cglm_array_get_value(lua_State* L); - -/** @brief Create a copy of a floating point array. - * - * @param[in] array The array to copy. - * @param[in] n The size of the array. - * - * @returns A copy of the array. - */ -int honey_cglm_array_copy(lua_State* L); - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * cglm vec3 functions - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -/** @brief Compute the dot product of two vectors. - * - * @param[in] a Vector a. - * @param[in] b Vector b. - * - * @returns dot(a,b). - */ -int honey_cglm_vec3_dot(lua_State* L); - -/** @brief Compute the square of the norm of a vector. - * - * Use this if you are tempted to compute norm*norm; - * it avoids the two calls to sqrt. - * - * @param[in] v The vector to compute norm^2 for. - * - * @returns norm(v)^2. - */ -int honey_cglm_vec3_norm2(lua_State* L); - -/** @brief Compute the norm of a vector. - * - * @param[in] v The vector. - * - * @returns norm(v). - */ -int honey_cglm_vec3_norm(lua_State* L); - -/** @brief Add two vectors together. - * - * @param[in] a The first vector. - * @param[in] b The second vector. - * @param[out] dest vec3 to fill with a + b. - * - * @returns Nothing. - */ -int honey_cglm_vec3_add(lua_State* L); - -/** @brief Subtract one vector from another. - * - * @param[in] a The first vector. - * @param[in] b The second vector. - * @param[out] dest Vector to fill with a - b - * - * @returns Nothing. - */ -int honey_cglm_vec3_sub(lua_State* L); - -/** @brief Add a scalar to a vector. - * - * @param[in] a The scalar. - * @param[in] v The vector. - * @param[out] dest vec3 to fill with a + v - * - * @returns Nothing. - */ -int honey_cglm_vec3_adds(lua_State* L); - -/** @param Component-wise multiply two vectors together. - * - * @param[in] a The first vector. - * @param[in] b The second vector. - * @param[out] dest vec3 to fill with [ a.x*b.x, a.y*b.y, a.z*b.z, a.w*b.w ] - * - * @returns Nothing. - */ -int honey_cglm_vec3_mul(lua_State* L); - -/** @brief Multiply a vector by a scalar. - * - * @param[in] a The scalar. - * @param[in] v The vector. - * @param[out] dest vec3 to fill with a*v. - * - * @returns Nothing. - */ -int honey_cglm_vec3_muls(lua_State* L); - -/** @brief Normalize a vector. - * - * @param[in,out] v The vector. - * - * @returns Nothing. - */ -int honey_cglm_vec3_normalize(lua_State* L); - -/** @brief Compute the distance between two vectors. - * - * @param[in] a The first vector. - * @param[in] b The second vector. - * - * @returns norm(a-b). - */ -int honey_cglm_vec3_distance(lua_State* L); - -/** @brief Linearly interpolate between two values. - * - * @param[in] a The first vector. - * @param[in] b The second vector. - * @param[in] s A scalar. - * @param[out] dest vec3 to fill with a + s*(b-s). - * - * @returns Nothing. - */ -int honey_cglm_vec3_lerp(lua_State* L); - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * cglm vec4 functions - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -/** @brief Compute the dot product of two vectors. - * - * @param[in] a Vector a. - * @param[in] b Vector b. - * - * @returns dot(a,b). - */ -int honey_cglm_vec4_dot(lua_State* L); - -/** @brief Compute the square of the norm of a vector. - * - * Use this if you are tempted to compute norm*norm; - * it avoids the two calls to sqrt. - * - * @param[in] v The vector to compute norm^2 for. - * - * @returns norm(v)^2. - */ -int honey_cglm_vec4_norm2(lua_State* L); - -/** @brief Compute the norm of a vector. - * - * @param[in] v The vector. - * - * @returns norm(v). - */ -int honey_cglm_vec4_norm(lua_State* L); - -/** @brief Add two vectors together. - * - * @param[in] a The first vector. - * @param[in] b The second vector. - * @param[out] dest vec4 to fill with a + b. - * - * @returns Nothing. - */ -int honey_cglm_vec4_add(lua_State* L); - -/** @brief Add a scalar to a vector. - * - * @param[in] a The scalar. - * @param[in] v The vector. - * @param[out] dest vec4 to fill with a + v - * - * @returns Nothing. - */ -int honey_cglm_vec4_adds(lua_State* L); - -/** @brief Subtract one vector from another. - * - * @param[in] a The first vector. - * @param[in] b The second vector. - * @param[out] dest vec4 to fill with a - b. - * - * @returns Nothing. - */ -int honey_cglm_vec4_sub(lua_State* L); - -/** @param Component-wise multiply two vectors together. - * - * @param[in] a The first vector. - * @param[in] b The second vector. - * @param[out] dest vec4 to fill with [ a.x*b.x, a.y*b.y, a.z*b.z, a.w*b.w ] - * - * @returns Nothing. - */ -int honey_cglm_vec4_mul(lua_State* L); - -/** @brief Multiply a vector by a scalar. - * - * @param[in] a The scalar. - * @param[in] v The vector. - * @param[out] dest vec4 to fill with a*v. - * - * @returns Nothing. - */ -int honey_cglm_vec4_muls(lua_State* L); - -/** @brief Normalize a vector. - * - * @param[in,out] v The vector. - * - * @returns Nothing. - */ -int honey_cglm_vec4_normalize(lua_State* L); - -/** @brief Compute the distance between two vectors. - * - * @param[in] a The first vector. - * @param[in] b The second vector. - * - * @returns norm(a-b). - */ -int honey_cglm_vec4_distance(lua_State* L); - -/** @brief Linearly interpolate between two values. - * - * @param[in] a The first vector. - * @param[in] b The second vector. - * @param[in] s A scalar. - * @param[out] dest vec4 to fill with a + s*(b-s). - * - * @returns Nothing. - */ -int honey_cglm_vec4_lerp(lua_State* L); - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * cglm mat3 functions - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -/** @brief Set a matrix to be the identity matrix. - * - * @param[out] matrix The matrix to set to the identity. - * - * @returns Nothing. - */ -int honey_cglm_mat3_identity(lua_State* L); - -/** @brief Multiply two mat3s together. - * - * @param[in] A The first matrix. - * @param[in] B The second matrix. - * @param[out] dest mat3 to fill with A*B. - * - * @returns Nothing. - */ -int honey_cglm_mat3_mul(lua_State* L); - -/** @brief Multiply a matrix by a scalar. - * - * @param[in] a The scalar. - * @param[in,out] M The matrix. - * - * @returns Nothing. - */ -int honey_cglm_mat3_muls(lua_State* L); - -/** @brief Multiply a matrix by a column vector. - * - * @param[in] M The matrix. - * @param[in] v The column vector. - * @param[out] dest Matrix to fill with M*v. - * - * @returns Nothing. - */ -int honey_cglm_mat3_mulv(lua_State* L); - -/** @brief Transpose a matrix. - * - * @param[in,out] M The matrix to transpose. - * - * @returns Nothing. - */ -int honey_cglm_mat3_trans(lua_State* L); - -/** @brief Get the determinant of a matrix. - * - * @param[in] M The matrix. - * - * @returns det(M). - */ -int honey_cglm_mat3_det(lua_State* L); - -/** @brief Get the trace of a matrix. - * - * @param[in] M The matrix. - * - * @returns trace(M). - */ -int honey_cglm_mat3_trace(lua_State* L); - -/** @brief Get the inverse of a matrix. - * - * @param[in] M The matrix to invert. - * @param[out] dest Matrix to fill with inv(M). - * - * @returns Nothing. - */ -int honey_cglm_mat3_inv(lua_State* L); - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * cglm mat4 functions - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -/** @brief Set a matrix to be the identity matrix. - * - * @param[out] matrix The matrix to set to the identity. - * - * @returns Nothing. - */ -int honey_cglm_mat4_identity(lua_State* L); - -/** @brief Get the upper left of a matrix as a mat3. - * - * @param[in] matrix The matrix to extract. - * @param[out] dest The 3x3 matrix to fill. - * - * @returns Nothing. - */ -int honey_cglm_mat4_pick3(lua_State* L); - -/** @brief Multiply two mat4s together. - * - * @param[in] A The first matrix. - * @param[in] B The second matrix. - * @param[out] dest mat4 to fill with A*B. - * - * @returns Nothing. - */ -int honey_cglm_mat4_mul(lua_State* L); - -/** @brief Multiply a matrix by a scalar. - * - * @param[in] a The scalar. - * @param[in,out] M The matrix. - * - * @returns Nothing. - */ -int honey_cglm_mat4_muls(lua_State* L); - -/** @brief Multiply a matrix by a column vector. - * - * @param[in] M The matrix. - * @param[in] v The column vector. - * @param[out] dest Matrix to fill with M*v. - * - * @returns Nothing. - */ -int honey_cglm_mat4_mulv(lua_State* L); - -/** @brief Transpose a matrix. - * - * @param[in,out] M The matrix to transpose. - * - * @returns Nothing. - */ -int honey_cglm_mat4_trans(lua_State* L); - -/** @brief Get the determinant of a matrix. - * - * @param[in] M The matrix. - * - * @returns det(M). - */ -int honey_cglm_mat4_det(lua_State* L); - -/** @brief Get the trace of a matrix. - * - * @param[in] M The matrix. - * - * @returns trace(M). - */ -int honey_cglm_mat4_trace(lua_State* L); - -/** @brief Get the inverse of a matrix. - * - * This is the precise version; use honey_cglm_mat4_inv_fast - * for a faster but less precise version. - * - * @param[in] M The matrix to invert. - * @param[out] dest Matrix to fill with inv(M). - * - * @returns Nothing. - */ -int honey_cglm_mat4_inv(lua_State* L); - -/** @brief Get the inverse of a matrix. - * - * This is the fast version; use honey_cglm_mat4_inv - * for a slower but more precise version. - * - * @param[in] M The matrix to invert. - * @param[out] dest Matrix to fill with inv(M). - * - * @returns Nothing. - */ -int honey_cglm_mat4_inv_fast(lua_State* L); - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * cglm 3d affine transforms - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -/** @brief Translate a matrix by a vector. - * - * This function modifies the matrix in place. - * - * @param[in,out] matrix The mat4 to translate. - * @param[in] vector The vec3 to translate by. - * - * @returns Nothing. - */ -int honey_cglm_translate(lua_State* L); - -/** @brief Scale a matrix by a vector. - * - * @param[in,out] matrix The mat4 to scale. - * @param[in] vector The vec3 to scale by. - * - * @returns Nothing. - */ -int honey_cglm_scale(lua_State* L); - -/** @brief Rotate a matrix about a given axis. - * - * @param[in,out] matrix The mat4 to rotate. - * @param[in] center The vec3 center of rotation. - * @param[in] axis The vec3 axis of rotation. - * @param[in] angle The angle to rotate by. - * - * @returns Nothing. - */ -int honey_cglm_rotate(lua_State* L); - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * - * cglm camera matrix functions - * - * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - */ - -/** @brief Put perspective projection matrix into float array. - * - * @param[out] matrix The mat4 to populate. - * @param[in] fov The FOV for the camera. - * @param[in] aspect The aspect ratio to use with the camera. - * @param[in] near Distance to the near clipping plane. - * @param[in] far Distance to the far clipping plane. - * - * @returns Nothing. - */ -int honey_cglm_perspective(lua_State* L); - -/** @brief Put an orthographic projection matrix into float array. - * - * @param[out] matrix The mat4 to populate. - * @param[in] a The first vector of the AABB bounding box. - * @param[in] b The second vector of the AABB bounding box. - * - * @returns Nothing. - */ -int honey_cglm_orthographic(lua_State* L); - -/** @brief Compute the view matrix. - * - * @param[in] position The camera's vec3 position. - * @param[in] direction The vec3 direction the camera is facing. - * @param[in] up The camera's vec3 up vector. - * @param[out] dest The view matrix destination. - * - * @returns Nothing. - */ -int honey_cglm_look(lua_State* L); - - -#endif diff --git a/src/common.h b/src/common.h index 556304f..6ae1c40 100644 --- a/src/common.h +++ b/src/common.h @@ -72,40 +72,25 @@ typedef enum { HONEY_N_ERRORS } honey_result; -#define HONEY_ERROR_DATA_STRING_LENGTH 4096 - -static struct { - char string1[HONEY_ERROR_DATA_STRING_LENGTH]; - char string2[HONEY_ERROR_DATA_STRING_LENGTH]; -} honey_error_data; - -void honey_error_clear_strings(); -void honey_error_set_string1(char* string); -void honey_error_set_string2(char* string); - -/** @brief Generate a human-readable error message. - * - * @param[out] error_string A string with at least 3*HONEY_ERROR_DATA_STRING_LENGTH characters to store the result - * @param[in] error The error to generate a message for - */ -void honey_human_readable_error(char* error_string, honey_result error); +honey_result honey_format_string(char** string, + char* format_string, + ...); -/** @brief Generate a string from a format string. +/** @brief Throw an error with a string generated by a printf format string. * - * This function allocates memory for the destination; the user is - * responsible for deallocating it. As a side effect of this, the destination - * pointer cannot overlap with any of the varargs. + * This function attempts to create a string from the given format string; + * if an error should occur, it will instead throw a lua error with the appropriate + * message. * - * @param[out] string Pointer to the destination string. - * @param[in] format_string The format string used to generate the result. + * @param[in] L The Lua state to throw an error from. + * @param[in] format_string The format string used to generate the error message. * @param[in] ... The arguments for the format string. * - * @returns HONEY_OK on success; HONEY_MEMORY_ALLOCATION_ERROR on a - * memory allocation error. + * @returns Nothing. */ -honey_result honey_format_string(char** string, - char* format_string, - ...); +void honey_lua_throw_error(lua_State* L, + char* format_string, + ...); /* lua binding functions */ @@ -122,35 +107,37 @@ typedef enum { HONEY_ANY } honey_lua_type; +typedef struct { + honey_lua_type type; + void* ptr; +} honey_lua_argument_pair; + /** @brief Get arguments from a function, checking to ensure the types match. * - * If a function should accept a variable list of arguments, but you still wish to ensure - * correct types, use honey_lua_validate_types() and throw an error only if all of your - * possiblities fail to match. + * Each argument type should be specified as [# of args], type, ptr, type, ptr..., + * e.g. + * ``` + * honey_lua_parse_arguments(L, 3, + * // option 0 + * 2, HONEY_INTEGER, &a, HONEY_INTEGER, &b, + * // option 1 + * 1, HONEY_INTEGER, &a, + * // option 2 + * 0); + * ``` * * Note that this function will check for correct types of HONEY_TABLE, HONEY_NIL, and * HONEY_FUNCTION, but does not expect a pointer to them. It performs no check for * HONEY_ANY, and also does not expect a pointer. * * @param[in] L The lua state to parse arguments from. - * @param[in] n The number of arguments to parse. - * @param[in] ... Variadic list of alternating types and pointers to store the type. - * - * @returns Nothing, but throws a lua_error if a type mismatch is detected. - */ -void honey_lua_parse_arguments(lua_State* L, int n, ...); - - -/** @brief Check that a functions' arguments are of the correct type. - * - * @param[in] L The lua state to validate. - * @param[in] n_types The number of types to validate. - * @param[in] ... Variadic list of honey_lua_types to validate against the stack. + * @param[in] n The number of argument options to parse. + * @param[in] ... Variadic list of argument options. * - * @returns true if the validation was successful; false otherwise, pushing an error message - * to the lua stack. + * @returns The zero-indexed index of the actual argument option used. Throws an + * error if no options matched the provided arguments. */ -bool honey_lua_validate_types(lua_State* L, unsigned int n_types, ...); +int honey_lua_parse_arguments(lua_State* L, int n, ...); /** @brief Wrap C objects for lua. */ typedef struct honey_lua_element { diff --git a/src/error/error.c b/src/error/error.c deleted file mode 100644 index 671d34e..0000000 --- a/src/error/error.c +++ /dev/null @@ -1,126 +0,0 @@ -#include "../common.h" - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -void honey_error_clear_strings() { - memset(honey_error_data.string1, 0, HONEY_ERROR_DATA_STRING_LENGTH); - memset(honey_error_data.string2, 0, HONEY_ERROR_DATA_STRING_LENGTH); -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -void honey_error_set_string1(char* string) { - size_t n_bytes = strlen(string) + 1; - if (n_bytes > HONEY_ERROR_DATA_STRING_LENGTH) - n_bytes = HONEY_ERROR_DATA_STRING_LENGTH; - memcpy(honey_error_data.string1, string, n_bytes); - honey_error_data.string1[HONEY_ERROR_DATA_STRING_LENGTH-1] = 0; -} - -void honey_error_set_string2(char* string) { - size_t n_bytes = strlen(string) + 1; - if (n_bytes > HONEY_ERROR_DATA_STRING_LENGTH) - n_bytes = HONEY_ERROR_DATA_STRING_LENGTH; - memcpy(honey_error_data.string2, string, n_bytes); - honey_error_data.string2[HONEY_ERROR_DATA_STRING_LENGTH-1] = 0; -} - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -void honey_human_readable_error(char* error_string, honey_result error) { - size_t string_size = sizeof(char)*3*HONEY_ERROR_DATA_STRING_LENGTH; - - switch(error) { - case HONEY_OK: - snprintf(error_string, string_size, "[honey] OK"); - break; - - case HONEY_MEMORY_ALLOCATION_ERROR: - snprintf(error_string, string_size, "[honey] ERROR: failed to allocate memory"); - break; - - case HONEY_FILE_READ_ERROR: - if (honey_error_data.string1 != NULL) { - snprintf(error_string, - string_size, - "[honey] ERROR: failed to read file '%s'", - honey_error_data.string1); - } else { - snprintf(error_string, string_size, "[honey] ERROR: failed to read file"); - } - break; - - case HONEY_VERTEX_SHADER_COMPILATION_ERROR: - if (honey_error_data.string1 != NULL) { - if (honey_error_data.string2 != NULL) { - snprintf(error_string, - string_size, - "[honey] ERROR: failed to compile vertex shader '%s'\n" - "[honey] GLSL compiler output:\n%s\n", - honey_error_data.string2, - honey_error_data.string1); - } else { - snprintf(error_string, - string_size, - "[honey] ERROR: failed to compile vertex shader\n" - "[honey] GLSL compiler output:\n%s\n", - honey_error_data.string1); - } - } else { - snprintf(error_string, - string_size, - "[honey] ERROR: failed to compile vertex shader."); - } - break; - - - case HONEY_FRAGMENT_SHADER_COMPILATION_ERROR: - if (honey_error_data.string1 != NULL) { - if (honey_error_data.string2 != NULL) { - snprintf(error_string, - string_size, - "[honey] ERROR: failed to compile fragment shader '%s'\n" - "[honey] GLSL compiler output:\n%s\n", - honey_error_data.string2, - honey_error_data.string1); - } else { - snprintf(error_string, - string_size, - "[honey] ERROR: failed to compile fragment shader\n" - "[honey] GLSL compiler output:\n%s\n", - honey_error_data.string1); - } - } else { - snprintf(error_string, - string_size, - "[honey] ERROR: failed to compile fragment shader."); - } - break; - - case HONEY_SHADER_LINK_ERROR: - break; - - case HONEY_MESH_BAD_VERTEX_DATA: - break; - - case HONEY_MESH_BAD_INDEX_DATA: - break; - - case HONEY_MODEL_LOAD_ERROR: - snprintf(error_string, - string_size, - "[honey] ERROR: model '%s' contains errors", - honey_error_data.string1); - break; - - default: - break; - } -} - - - - - - - diff --git a/src/error/error.h b/src/error/error.h deleted file mode 100644 index e456c88..0000000 --- a/src/error/error.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef HONEY_ERROR_H -#define HONEY_ERROR_H - -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - - -#endif diff --git a/src/glm_bindings.c b/src/glm_bindings.c new file mode 100644 index 0000000..cfd85e5 --- /dev/null +++ b/src/glm_bindings.c @@ -0,0 +1,94 @@ +#include "glm_bindings.h" + +int honey_glm_vec3_mt_ref = LUA_NOREF; +int honey_glm_vec4_mt_ref = LUA_NOREF; +int honey_glm_mat3_mt_ref = LUA_NOREF; +int honey_glm_mat4_mt_ref = LUA_NOREF; + +void honey_setup_glm(lua_State* L) +{ + honey_lua_create_table(L, NULL, 0); +} + +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * GLM Array Setup Functions + * + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +static void setup_new_array(lua_State* L, + honey_glm_array* array, + honey_glm_array_type type) +{ + unsigned int size; + switch(type) { + case VEC3: + size = 3; + break; + + case VEC4: + size = 4; + break; + + case MAT3: + size = 9; + break; + + case MAT4: + size = 16; + break; + + default: + honey_lua_throw_error(L, + "unknown array type: %d", + type); + break; + } + + array->type = type; + array->size = size; + array->data = calloc(size, sizeof(float)); + if (array->data == NULL) + honey_lua_throw_error(L, + "failed to allocate memory for array of type %d", + type); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +static int honey_glm_new_vec3(lua_State* L) +{ + honey_glm_array* vec3 = lua_newuserdata(L, sizeof(honey_glm_array)); + setup_new_array(L, vec3, VEC3); + lua_rawgeti(L, LUA_REGISTRYINDEX, honey_glm_vec3_mt_ref); + lua_setmetatable(L, -2); + return 1; +} + +static int honey_glm_new_vec4(lua_State* L) +{ + honey_glm_array* vec4 = lua_newuserdata(L, sizeof(honey_glm_array)); + setup_new_array(L, vec4, VEC4); + lua_rawgeti(L, LUA_REGISTRYINDEX, honey_glm_vec4_mt_ref); + lua_setmetatable(L, -2); + return 1; +} + +static int honey_glm_new_mat3(lua_State* L) +{ + honey_glm_array* mat3 = lua_newuserdata(L, sizeof(honey_glm_array)); + setup_new_array(L, mat3, MAT3); + lua_rawgeti(L, LUA_REGISTRYINDEX, honey_glm_mat3_mt_ref); + lua_setmetatable(L, -2); + return 1; +} + +static int honey_glm_new_mat4(lua_State* L) +{ + honey_glm_array* mat4 = lua_newuserdata(L, sizeof(honey_glm_array)); + setup_new_array(L, mat4, MAT4); + lua_rawgeti(L, LUA_REGISTRYINDEX, honey_glm_mat4_mt_ref); + lua_setmetatable(L, -2); + return 1; +} diff --git a/src/glm_bindings.h b/src/glm_bindings.h new file mode 100644 index 0000000..d47f153 --- /dev/null +++ b/src/glm_bindings.h @@ -0,0 +1,33 @@ +#ifndef HONEY_GLM_BINDINGS_H +#define HONEY_GLM_BINDINGS_H + +/** @file glm_bindings.h + * @brief Lua bindings for GLM functions. + */ + +#include "common.h" + +extern int honey_glm_vec3_mt_ref; +extern int honey_glm_vec4_mt_ref; +extern int honey_glm_mat3_mt_ref; +extern int honey_glm_mat4_mt_ref; + +typedef enum { VEC3, + VEC4, + MAT3, + MAT4 +} honey_glm_array_type; + +typedef struct { + honey_glm_array_type type; + unsigned int size; + float* data; +} honey_glm_array; + +/** @brief Push the honey glm binding functions to the lua stack. + * + * @returns Nothing. + */ +void honey_setup_glm(lua_State* L); + +#endif diff --git a/src/honey.c b/src/honey.c index 4ffb83f..673cd49 100644 --- a/src/honey.c +++ b/src/honey.c @@ -122,8 +122,8 @@ bool honey_setup(lua_State** L) honey_setup_input(*L); lua_setfield(*L, -2, "input"); - honey_setup_cglm(*L); - lua_setfield(*L, -2, "cglm"); + honey_setup_glm(*L); + lua_setfield(*L, -2, "glm"); honey_setup_shader(*L); lua_setfield(*L, -2, "shader"); diff --git a/src/honey.h b/src/honey.h index 5a2e6c2..0ca3d52 100644 --- a/src/honey.h +++ b/src/honey.h @@ -9,7 +9,7 @@ #include "common.h" #include "camera/camera.h" -#include "cglm_bindings.h" +#include "glm_bindings.h" #include "input/input.h" #include "light/light.h" #include "mesh/mesh.h" diff --git a/src/honey_lua.c b/src/honey_lua.c index f427969..7730809 100644 --- a/src/honey_lua.c +++ b/src/honey_lua.c @@ -1,6 +1,31 @@ #include "common.h" -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Lua binding helper function definitions + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +/* string must be able to hold at least 16 characters. */ +static void type_to_string(char* string, + honey_lua_type type); + +static bool check_argument(lua_State* L, + honey_lua_type type, + int index); + +static void get_argument(lua_State* L, + void* destination, + honey_lua_type type, + int index); + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * String wrangling helpers + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ honey_result honey_format_string(char** string, char* format_string, @@ -28,13 +53,46 @@ honey_result honey_format_string(char** string, /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +void honey_lua_throw_error(lua_State* L, + char* format_string, + ...) +{ + honey_result result; + va_list args, args_; + va_start(args, format_string); + va_copy(args_, args); + + int string_size = vsnprintf(NULL, 0, format_string, args_); + va_end(args_); + + char* string = malloc((string_size + 1) * sizeof(char)); + if (string == NULL) + lua_pushstring(L, "there was an error allocating memory for an error message"); + else { + vsnprintf(string, string_size + 1, format_string, args); + lua_pushstring(L, string); + free(string); + } + lua_error(L); +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Argument parsing functions + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + static void honey_lua_arg_error(lua_State* L, - char* expected_type, + honey_lua_type type, int position) { + char expected_type[16]; + type_to_string(expected_type, type); + char* error_message; honey_result result; - char* got_type = lua_typename(L, lua_type(L, position)); + char* got_type = (char*) lua_typename(L, lua_type(L, position)); result = honey_format_string(&error_message, "bad argument in position %d: " "expected %s, but got %s instead.", @@ -53,245 +111,29 @@ static void honey_lua_arg_error(lua_State* L, /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ -void honey_lua_parse_arguments(lua_State* L, int n, ...) +int honey_lua_parse_arguments(lua_State* L, int n, ...) { va_list args; va_start(args, n); for (int i=1; i<=n; i++) { - honey_lua_type expected_type = va_arg(args, honey_lua_type); - - switch (expected_type) { - case HONEY_BOOLEAN: - if (!lua_isboolean(L, i)) - honey_lua_arg_error(L, "boolean", i); - { - bool* result = va_arg(args, bool*); - *result = lua_toboolean(L, i); - } - break; - - case HONEY_INTEGER: - if (!lua_isnumber(L, i)) - honey_lua_arg_error(L, "integer", i); - { - int* result = va_arg(args, int*); - *result = lua_tointeger(L, i); - } - break; - - case HONEY_NUMBER: - if (!lua_isnumber(L, i)) - honey_lua_arg_error(L, "number", i); - { - float* result = va_arg(args, float*); - *result = lua_tonumber(L, i); - } - break; - - case HONEY_STRING: - if (!lua_isstring(L, i)) - honey_lua_arg_error(L, "string", i); - { - char** result = va_arg(args, char**); - *result = lua_tostring(L, i); - } - break; - - case HONEY_TABLE: - if (!lua_istable(L, i)) - honey_lua_arg_error(L, "table", i); - break; - - case HONEY_FUNCTION: - if (!lua_isfunction(L, i)) - honey_lua_arg_error(L, "function", i); - break; - - case HONEY_NIL: - if (!lua_isnil(L, i)) - honey_lua_arg_error(L, "nil", i); - break; - - case HONEY_USERDATA: - if (!lua_isuserdata(L, i)) - honey_lua_arg_error(L, "userdata", i); - { - void** result = va_arg(args, void**); - *result = lua_touserdata(L, i); - } - break; - - case HONEY_LIGHTUSERDATA: - if (!lua_isuserdata(L, i)) - honey_lua_arg_error(L, "light userdata", i); - { - void** result = va_arg(args, void**); - *result = lua_touserdata(L, i); - } - break; - - case HONEY_ANY: - break; - - default: - /* should never get here! */ - break; - } - } - - va_end(args); -} + honey_lua_type type = va_arg(args, honey_lua_type); + void* destination = va_arg(args, void*); + if (!check_argument(L, type, i)) + honey_lua_arg_error(L, type, i); -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - -bool honey_lua_validate_types(lua_State* L, - unsigned int n_types, - ...) -{ - va_list args; - va_start(args, n_types); - - for (int i=0; i<n_types; i++) { - honey_lua_type expected_type = va_arg(args, honey_lua_type); - honey_result result; - char* error_message; - - switch(expected_type) { - case HONEY_BOOLEAN: - if (!lua_isboolean(L, i+1)) { - result = honey_format_string(&error_message, - "Expected boolean in position %d", - i); - if (result != HONEY_OK) - lua_pushstring(L, "Expected boolean; allocation error occurred for more detailed message."); - else { - lua_pushstring(L, error_message); - free(error_message); - } - return false; - } - break; - - case HONEY_INTEGER: - case HONEY_NUMBER: - if (!lua_isnumber(L, i+1)) { - result = honey_format_string(&error_message, - "Expected number in position %d", - i); - if (result != HONEY_OK) - lua_pushstring(L, "Expected number; allocation error occurred for more detailed message."); - else { - lua_pushstring(L, error_message); - free(error_message); - } - return false; - } - break; - - case HONEY_STRING: - if (!lua_isstring(L, i+1)) { - result = honey_format_string(&error_message, - "Expected string in position %d", - i); - if (result != HONEY_OK) - lua_pushstring(L, "Expected string; allocation error occurred for more detailed message."); - else { - lua_pushstring(L, error_message); - free(error_message); - } - return false; - } - break; - - case HONEY_FUNCTION: - if (!lua_isfunction(L, i+1)) { - result = honey_format_string(&error_message, - "Expected function in position %d", - i); - if (result != HONEY_OK) - lua_pushstring(L, "Expected function; allocation error occurred for more detailed message."); - else { - lua_pushstring(L, error_message); - free(error_message); - } - return false; - } - break; - - case HONEY_TABLE: - if (!lua_istable(L, i+1)) { - result = honey_format_string(&error_message, - "Expected table in position %d", - i); - if (result != HONEY_OK) - lua_pushstring(L, "Expected table; allocation error occurred for more detailed message."); - else { - lua_pushstring(L, error_message); - free(error_message); - } - return false; - } - break; - - case HONEY_NIL: - if (!lua_isnil(L, i+1)) { - result = honey_format_string(&error_message, - "Expected nil in position %d", - i); - if (result != HONEY_OK) - lua_pushstring(L, "Expected nil; allocation error occurred for more detailed message."); - else { - lua_pushstring(L, error_message); - free(error_message); - } - return false; - } - break; - - case HONEY_USERDATA: - if (!lua_isuserdata(L, i+1)) { - result = honey_format_string(&error_message, - "Expected userdata in position %d", - i); - if (result != HONEY_OK) - lua_pushstring(L, "Expected userdata; allocation error occurred for more detailed message."); - else { - lua_pushstring(L, error_message); - free(error_message); - } - return false; - } - break; - - case HONEY_LIGHTUSERDATA: - if (!lua_islightuserdata(L, i+1)) { - result = honey_format_string(&error_message, - "Expected C pointer in position %d", - i); - if (result != HONEY_OK) - lua_pushstring(L, "Expected C pointer; allocation error occurred for more detailed message."); - else { - lua_pushstring(L, error_message); - free(error_message); - } - return false; - } - break; - - case HONEY_ANY: - break; - - default: - break; - } + get_argument(L, destination, type, i); } - + va_end(args); - return true; } -/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Table creation functions + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ void honey_lua_create_table(lua_State* L, honey_lua_element* elements, @@ -407,3 +249,186 @@ int honey_exit(lua_State* L) glfwSetWindowShouldClose(info->window, true); return 0; } + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * Lua binding helper functions + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +/* string must be able to hold at least 16 characters. */ +static void type_to_string(char* string, + honey_lua_type type) +{ + switch(type) { + case HONEY_BOOLEAN: + memcpy(string, "boolean", 8); + break; + + case HONEY_INTEGER: + memcpy(string, "integer", 8); + break; + + case HONEY_NUMBER: + memcpy(string, "number", 7); + break; + + case HONEY_STRING: + memcpy(string, "string", 7); + break; + + case HONEY_FUNCTION: + memcpy(string, "function", 9); + break; + + case HONEY_TABLE: + memcpy(string, "table", 6); + break; + + case HONEY_NIL: + memcpy(string, "nil", 4); + break; + + case HONEY_USERDATA: + memcpy(string, "userdata", 9); + break; + + case HONEY_LIGHTUSERDATA: + memcpy(string, "light userdata", 16); + break; + + case HONEY_ANY: + memcpy(string, "any", 4); + break; + + default: + break; + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +static bool check_argument(lua_State* L, + honey_lua_type type, + int index) +{ + switch(type) { + case HONEY_BOOLEAN: + if (!lua_isboolean(L, index)) + return false; + break; + + case HONEY_INTEGER: + case HONEY_NUMBER: + if (!lua_isnumber(L, index)) + return false; + break; + + case HONEY_STRING: + if (!lua_isstring(L, index)) + return false; + break; + + case HONEY_FUNCTION: + if (!lua_isfunction(L, index)) + return false; + break; + + case HONEY_TABLE: + if (!lua_istable(L, index)) + return false; + break; + + case HONEY_NIL: + if (!lua_isnil(L, index)) + return false; + break; + + case HONEY_USERDATA: + if (!lua_isuserdata(L, index)) + return false; + break; + + case HONEY_LIGHTUSERDATA: + if (!lua_islightuserdata(L, index)) + return false; + break; + + default: + break; + } + + + return true; +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ + +static void get_argument(lua_State* L, + void* destination, + honey_lua_type type, + int index) +{ + switch (type) { + case HONEY_BOOLEAN: + { + bool* result = destination; + *result = lua_toboolean(L, index); + } + break; + + case HONEY_INTEGER: + { + int* result = destination; + *result = lua_tointeger(L, index); + } + break; + + case HONEY_NUMBER: + { + float* result = destination; + *result = lua_tonumber(L, index); + } + break; + + case HONEY_STRING: + { + char** result = destination; + *result = (char*) lua_tostring(L, index); + } + break; + + case HONEY_TABLE: + break; + + case HONEY_FUNCTION: + break; + + case HONEY_NIL: + break; + + case HONEY_USERDATA: + { + void** result = destination; + *result = lua_touserdata(L, index); + } + break; + + case HONEY_LIGHTUSERDATA: + { + void** result = destination; + *result = lua_touserdata(L, index); + } + break; + + case HONEY_ANY: + break; + + default: + /* should never get here! */ + break; + } +} + +/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ |