summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common.h1
-rw-r--r--src/honey.c173
-rw-r--r--src/honey.h50
-rw-r--r--src/input/input.c3
-rw-r--r--src/main.c186
5 files changed, 195 insertions, 218 deletions
diff --git a/src/common.h b/src/common.h
index 66500eb..47b7ee4 100644
--- a/src/common.h
+++ b/src/common.h
@@ -152,4 +152,5 @@ void honey_lua_push_element(lua_State* L,
void honey_lua_create_table(lua_State* L,
honey_lua_element* elements,
unsigned int n_elements);
+
#endif
diff --git a/src/honey.c b/src/honey.c
index 79ff970..0bd5b25 100644
--- a/src/honey.c
+++ b/src/honey.c
@@ -1,71 +1,138 @@
#include "honey.h"
-static void default_honey_update_callback(float dt) {}
-static void default_honey_draw_callback() {}
-
-honey_window honey_setup(int screen_width, int screen_height, char* window_title) {
- honey_update_callback = &default_honey_update_callback;
- honey_draw_callback = &default_honey_draw_callback;
-
- glfwInit();
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
-
- honey_window window = glfwCreateWindow(screen_width, screen_height, window_title, NULL, NULL);
- if (window == NULL) {
- fprintf(stderr, "ERROR: failed to create window!\n");
- glfwTerminate();
- return NULL;
- }
-
- glfwMakeContextCurrent(window);
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
-
- if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) {
- fprintf(stderr, "ERROR: failed to initialize GLAD!\n");
- glfwTerminate();
- return NULL;
- }
-
- honey_setup_keyboard();
- glfwSetKeyCallback(window, default_honey_keyboard_callback);
-
- // Enable blending
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- return window;
+void honey_print_help()
+{
+ printf("usage: honey [OPTIONS] SCRIPT_DIR\n"
+ " -v Enable verbose logging\n"
+ " -h Show this help message and exit\n"
+ " -l LOG Log to LOG instead of stdout\n");
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
-void honey_set_update_callback(void (*update_callback)(float)) {
- honey_update_callback = update_callback;
+bool honey_parse_options(honey_options* options, int argc, char** argv)
+{
+ honey_options opts;
+ opts.verbose = false;
+ opts.script_directory = NULL;
+ opts.logfile = NULL;
+
+ opterr = 0;
+ int c;
+
+ while ((c = getopt(argc, argv, "vhl:")) != -1) {
+ switch (c) {
+ case 'v':
+ opts.verbose = true;
+ break;
+
+ case 'h':
+ honey_print_help();
+ return false;
+
+ case 'l':
+ opts.logfile = optarg;
+ break;
+
+ case '?':
+ fprintf(stderr, "unknown option: '%c'\n", optopt);
+ honey_print_help();
+ return false;
+
+ default:
+ return false;
+ }
+ }
+
+ if (optind < argc) {
+ opts.script_directory = argv[optind];
+ }
+
+ *options = opts;
+
+ return true;
}
-void honey_set_draw_callback(void (*draw_callback)()) {
- honey_draw_callback = draw_callback;
+/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+
+bool honey_setup(lua_State** L, honey_window* window)
+{
+ /* set up glfw */
+ glfwInit();
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
+ glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
+ glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
+
+ *window = glfwCreateWindow(640, 480, "honey", NULL, NULL);
+ if (*window == NULL) {
+ fprintf(stderr, "[honey] ERROR: failed to create window!\n");
+ glfwTerminate();
+ return false;
+ }
+
+ glfwMakeContextCurrent(*window);
+
+ if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) {
+ fprintf(stderr, "[honey] ERROR: failed to initialize GLAD!\n");
+ glfwTerminate();
+ return false;
+ }
+
+ honey_setup_keyboard();
+ glfwSetKeyCallback(*window, default_honey_keyboard_callback);
+
+ // Enable blending
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+
+ /* set up lua and honey lua bindings */
+ *L = luaL_newstate();
+ luaL_openlibs(*L);
+ glfwSetWindowUserPointer(*window, *L);
+
+ lua_createtable(*L, 0, 1);
+
+ honey_setup_input(*L);
+ lua_setfield(*L, -2, "input");
+
+ lua_setglobal(*L, "honey");
+
+ return true;
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void honey_run(honey_window window) {
- float prevTime = 0;
- float currentTime = 0;
- float dt;
- float draw_dt = 0;
-
- while(!glfwWindowShouldClose(window)) {
- currentTime = (float) glfwGetTime();
- dt = currentTime - prevTime;
- prevTime = currentTime;
-
- honey_update_callback(dt);
- honey_draw_callback();
- }
+ /*float prevTime = 0;
+ float currentTime = 0;
+ float dt;
+ float draw_dt = 0;
+
+ while(!glfwWindowShouldClose(window)) {
+ currentTime = (float) glfwGetTime();
+ dt = currentTime - prevTime;
+ prevTime = currentTime;
+
+ honey_update_callback(dt);
+ honey_draw_callback();
+ }*/
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+int honey_get_callback(lua_State* L, char* callback)
+{
+ lua_getglobal(L, "honey");
+ lua_getfield(L, -1, callback);
+ int ref = LUA_NOREF;
+
+ if (lua_isfunction(L, -1))
+ ref = luaL_ref(L, LUA_REGISTRYINDEX);
+ else
+ lua_pop(L, 1);
+ lua_pop(L, 1);
+
+ return ref;
+}
diff --git a/src/honey.h b/src/honey.h
index c134894..b349475 100644
--- a/src/honey.h
+++ b/src/honey.h
@@ -17,28 +17,38 @@
#include "shader/shader.h"
#include "texture/texture.h"
-/** @brief Initialize Honey.
- *
- * @param[in] screen_width The desired width of the screen in pixels
- * @param[in] screen_height The desired height of the screen in pixels
- * @param[in] window_title Title to use for the window.
- */
-honey_window honey_setup(int screen_width, int screen_height, char* window_title);
+/** @struct Helper struct to wrap command-line options. */
+typedef struct {
+ bool verbose;
+ char* script_directory;
+ char* logfile;
+} honey_options;
-static void (*honey_update_callback)(float dt);
-static void (*honey_draw_callback)();
+/** @brief Print usage help for honey. */
+void honey_print_help();
-/** @brief Set the main update function.
+/** @brief Parse command-line options for honey.
+ *
+ * This function returns false if the -h option was passed, for simplicity's sake.
*
- * @param[in] update_callback The function to call every loop
+ * @param[in] argc The number of arguments passed to honey.
+ * @param[in] argv Argument string array.
+ * @param[out] options Pointer to the honey_options struct to populate.
+ *
+ * @returns true if parsing was successful and execution should continue;
+ * false otherwise.
*/
-void honey_set_update_callback(void (*update_callback)(float));
+bool honey_parse_options(honey_options* options, int argc, char** argv);
-/** @brief Set the main draw function
+/** @brief Initialize Honey and set up lua bindings.
+ *
+ * @param[out] L The lua state with honey configured.
+ * @param[out] window The GLFW window configured by honey.
+ * Also accessible from lua as honey.window.glfw_window.
*
- * @param[in] draw_callback The function to call every draw cycle
+ * @returns true on a success; false otherwise.
*/
-void honey_set_draw_callback(void (*draw_callback)());
+bool honey_setup(lua_State** L, honey_window* window);
/** @brief The main game loop.
*
@@ -46,6 +56,16 @@ void honey_set_draw_callback(void (*draw_callback)());
*/
void honey_run(honey_window window);
+/** @brief Get a registry reference to a given honey callback.
+ *
+ * @param[in] L The lua state to find the reference in.
+ * @param[in] callback Name of the callback to find.
+ *
+ * @returns Registry reference to the function if it exists;
+ * LUA_NOREF otherwise.
+ */
+int honey_get_callback(lua_State* L, char* callback);
+
#define honey_set_resize_callback glfwSetFramebufferSizeCallback
#define honey_set_mouse_move_callback glfwSetCursorPosCallback
diff --git a/src/input/input.c b/src/input/input.c
index ec28695..c231157 100644
--- a/src/input/input.c
+++ b/src/input/input.c
@@ -182,7 +182,8 @@ int honey_key_bind(lua_State* L)
}
else {
char* error_message;
- honey_format_string(error_message, "expected 2 or 3 arguments; received %d instead", n_args);
+ honey_format_string(&error_message, "expected 2 or 3 arguments; received %d instead", n_args);
+ lua_pushstring(L, error_message);
free(error_message);
lua_error(L);
}
diff --git a/src/main.c b/src/main.c
index 465e746..14037fb 100644
--- a/src/main.c
+++ b/src/main.c
@@ -1,144 +1,42 @@
#include "honey.h"
-struct options {
- bool verbose;
- bool run;
- bool has_update;
- bool has_draw;
- char* scriptdir;
-};
-
-bool has_function(lua_State* L, char* field)
-{
- lua_getglobal(L, "honey");
- lua_getfield(L, -1, field);
- if (lua_isfunction(L, -1))
- return true;
- return false;
-}
-
-bool parse_options(struct options* opt, int argc, char** argv)
-{
- opt->verbose = false;
- opt->run = false;
-
- opterr = 0;
- int c;
-
- while ((c = getopt(argc, argv, "vh")) != -1) {
- switch (c) {
- case 'v':
- opt->verbose = true;
- break;
-
- case 'h':
- // print help
- break;
-
- case '?':
- if (isprint (optopt))
- fprintf (stderr, "Unknown option `-%c'.\n", optopt);
- else
- fprintf (stderr,
- "Unknown option character `\\x%x'.\n",
- optopt);
- return false;
-
- default:
- return false;
- }
- }
-
- if (optind < argc) {
- opt->run = true;
- opt->scriptdir = argv[optind];
- }
-
- return true;
-}
-
-GLFWwindow* setup_window(int width, int height, char* title)
-{
- glfwInit();
- glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
- glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
- glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
-
- GLFWwindow* window = glfwCreateWindow(width, height, title, NULL, NULL);
- if (window == NULL) {
- fprintf(stderr, "ERROR: failed to create window!\n");
- glfwTerminate();
- return NULL;
- }
-
- glfwMakeContextCurrent(window);
- glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
-
- if (!gladLoadGLLoader((GLADloadproc) glfwGetProcAddress)) {
- fprintf(stderr, "ERROR: failed to initialize GLAD!\n");
- glfwTerminate();
- return NULL;
- }
-
- honey_setup_keyboard();
- glfwSetKeyCallback(window, default_honey_keyboard_callback);
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- return window;
-}
-
-// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
int main(int argc, char** argv)
{
- struct options opt;
- if (!parse_options(&opt, argc, argv)) {
- fprintf(stderr, "ERROR: failed to parse command line options!\n");
- return 1;
- }
-
- if (!opt.run)
+ honey_options opts;
+ if (!honey_parse_options(&opts, argc, argv)) {
return 0;
+ }
- printf("%d\n", LUA_NOREF);
-
- GLFWwindow* window = setup_window(480, 320, "honey-engine");
-
- lua_State* L = luaL_newstate();
- glfwSetWindowUserPointer(window, L);
- luaL_openlibs(L);
+ honey_window window;
+ lua_State* L;
- lua_createtable(L, 0, 1);
-
- honey_setup_input(L);
- lua_setfield(L, -2, "input");
+ if (!honey_setup(&L, &window))
+ return 1;
- lua_setglobal(L, "honey");
-
- size_t dirlen = strlen(opt.scriptdir) + 10;
- char* scriptfile = malloc(sizeof(char) * dirlen);
- if (scriptfile == NULL) {
- fprintf(stderr, "ERROR: failed to allocate memory for script file string!\n");
+ char* script;
+ honey_result res = honey_format_string(&script,
+ "%s/main.lua",
+ opts.script_directory);
+ if (res != HONEY_OK) {
+ fprintf(stderr, "[honey] FATAL: could not allocate space for script filename!");
return 1;
}
-
- snprintf(scriptfile, dirlen, "%s/main.lua", opt.scriptdir);
- if (luaL_loadfile(L, scriptfile) == 0) {
- if (lua_pcall(L, 0, 1, 0) == 0) {
- lua_pop(L, lua_gettop(L));
+ if (luaL_loadfile(L, script) == 0) {
+ if (!lua_pcall(L, 0, 1, 0) == 0) {
+ const char* error = lua_tostring(L, -1);
+ fprintf(stderr, "[honey] ERROR: %s\n", error);
+ return 1;
}
}
else {
- fprintf(stderr, "ERROR: failed to open %s!\n", scriptfile);
+ fprintf(stderr, "ERROR: failed to open %s!\n", script);
return 1;
}
- opt.has_update = has_function(L, "update");
- opt.has_draw = has_function(L, "draw");
-
+ int update_callback = honey_get_callback(L, "update");
+ int draw_callback = honey_get_callback(L, "draw");
+
float prevTime = 0;
float currentTime = 0;
float dt;
@@ -149,36 +47,26 @@ int main(int argc, char** argv)
prevTime = currentTime;
glfwPollEvents();
- lua_getglobal(L, "honey");
-
- if (opt.has_update) {
- lua_getfield(L, -1, "update");
- if (lua_isfunction(L, -1)) {
- lua_pushnumber(L, dt);
- int result = lua_pcall(L, 1, 0, 0);
- if (result != 0) {
- glfwSetWindowShouldClose(window, true);
- }
- }
- else {
- lua_pop(L, 1);
+ if (update_callback != LUA_NOREF) {
+ lua_rawgeti(L, LUA_REGISTRYINDEX, update_callback);
+ lua_pushnumber(L, dt);
+ int result = lua_pcall(L, 1, 0, 0);
+ if (result != 0) {
+ const char* error = lua_tostring(L, -1);
+ fprintf(stderr, "[honey] ERROR: %s\n", error);
+ glfwSetWindowShouldClose(window, true);
}
}
- if (opt.has_draw) {
- lua_getfield(L, -1, "draw");
- if (lua_isfunction(L, -1)) {
- int result = lua_pcall(L, 0, 0, 0);
- if (result != 0) {
- glfwSetWindowShouldClose(window, true);
- }
- }
- else {
- lua_pop(L, 1);
+ if (draw_callback != LUA_NOREF) {
+ lua_rawgeti(L, LUA_REGISTRYINDEX, draw_callback);
+ int result = lua_pcall(L, 0, 0, 0);
+ if (result != 0) {
+ const char* error = lua_tostring(L, -1);
+ fprintf(stderr, "[honey] ERROR: %s\n", error);
+ glfwSetWindowShouldClose(window, true);
}
}
-
- lua_pop(L, 1);
}
lua_close(L);