From a39aee66f5de8cbb90f63b5d5c25348979db6150 Mon Sep 17 00:00:00 2001 From: John Alanbrook Date: Mon, 24 Apr 2023 22:22:18 +0000 Subject: [PATCH] stack trace on error and critical logs; set logging level --- source/engine/3d/model.c | 386 +++++++++++++++++--------------------- source/engine/3d/model.h | 4 +- source/engine/debug/log.c | 31 ++- source/engine/debug/log.h | 2 + source/engine/ffi.c | 25 ++- source/engine/script.c | 20 +- source/engine/script.h | 1 + source/engine/texture.c | 14 +- source/engine/yugine.c | 40 ++-- source/engine/yugine.h | 1 + source/scripts/debug.js | 36 ---- source/scripts/engine.js | 62 ++++++ 12 files changed, 320 insertions(+), 302 deletions(-) diff --git a/source/engine/3d/model.c b/source/engine/3d/model.c index 5ed402f..c5eff0b 100644 --- a/source/engine/3d/model.c +++ b/source/engine/3d/model.c @@ -1,282 +1,232 @@ #include "model.h" +#include "log.h" #include "mesh.h" #include "resources.h" #include "shader.h" +#include "stb_ds.h" #include -#include #include -#include "log.h" +#include -static struct model *lastRendered; -static struct model *loadedModels[100]; -static struct model **lastModel = loadedModels; +static struct { + char *key; + struct Texture *value; +} *modelhash = NULL; static void processnode(); static void processmesh(); static void processtexture(); +struct model *GetExistingModel(const char *path) { + if (!path || path[0] == '\0') return NULL; -struct model *GetExistingModel(const char *path) -{ - struct model **model = loadedModels; + int index = shgeti(modelhash, path); + if (index != -1) return modelhash[index].value; - while (model++ != lastModel) { - if (!strcmp(path, (*model)->path)) - goto end; - - return MakeModel(path); - - } - - end: - return NULL; + return MakeModel(path); } /* TODO: Make this a hash compare for speedup */ -struct model *MakeModel(const char *path) -{ - char *modelPath = - (char *) malloc(sizeof(char) * - (strlen(DATA_PATH) + strlen(path) + 1)); - modelPath[0] = '\0'; - strcat(modelPath, DATA_PATH); - strcat(modelPath, path); - printf - ("Created new model with modelPath %s, from data_path %s and path %s\n", - modelPath, DATA_PATH, path); +struct model *MakeModel(const char *path) { + cgltf_options options = {0}; + cgltf_data *data = NULL; + cgltf_result result = cgltf_parse_file(&options, path, &data); - struct model *newmodel = - (struct model *) malloc(sizeof(struct model)); - newmodel->path = path; + if (!result == cgltf_result_success) { + YughError("Could not read file %s.", path); + return; + } - loadmodel(newmodel); - *lastModel++ = newmodel; - return newmodel; -} + result = cgltf_load_buffers(&options, data, path); -// TODO: Come back to this; simple optimization -void draw_model(struct model *model, struct shader *shader) -{ - if (lastRendered != model) { - lastRendered = model; - for (int i = 0; i < (model->mp - model->meshes); i++) - DrawMesh(&model->meshes[i], shader); - } else { - for (uint32_t i = 0; i < (model->mp - model->meshes); i++) - DrawMeshAgain(&model->meshes[i]); - } -} + if (!result == cgltf_result_success) { + YughError("Could not load buffers for file %s.", path); + return; + } -void loadmodel(struct model *model) -{ - YughInfo("Loading model at path %s", model->path); -/* - // Load model with cgltf - cgltf_options options = {0}; - cgltf_data *data = NULL; - cgltf_result result = cgltf_parse_file(&options, model->path, &data); + struct model *model = malloc(sizeof(struct model)); - meshes = (struct mesh*)malloc(sizeof(Mesh)*cgltf_data->meshes_count); + model->meshes = malloc(sizeof(struct mesh) * data->meshes_count); - directory = get_directory_from_path(model->path); + for (int i = 0; i < data->nodes_count; i++) { + + if (data->nodes[i].mesh) { + cgltf_mesh *mesh = data->nodes[i].mesh; + + for (int j = 0; j < mesh->primitives_count; j++) { + cgltf_primitive primitive = mesh->primitives[j]; + + for (int k = 0; k < primitive.attributes_count; k++) { + cgltf_attribute attribute = primitive.attributes[k]; + + switch (attribute.type) { + + case cgltf_attribute_type_position: +// float *vs = malloc(sizeof(float) * cgltf_accessor_unpack_floats(attribute.accessor, NULL, attribute.accessor.count); +// cgltf_accessor_unpack_floats(attribute.accessor, vs, attribute.accessor.count); + break; - for (int i = 0; i < data->nodes_count; i++) { - if (data->nodes[i]->mesh) { - for (int j = 0; j < data->nodes[i]->mesh->primatives_count; j++) { + case cgltf_attribute_type_normal: + break; - for (int k = 0; k < data->nodes[i]->mesh->primatives[j]->attributes_count; k++) { - switch(data->nodes[i]->mesh->primatives[j]->attributes[k]->type) { - case cgltf_attribute_type_position: - Vertex *vs = (Vertex*)malloc(sizeof(Vertex) * cgltf_accessor_unpack_floats(:::attributes[k]->accesor, NULL, attributes[k]->accessor.count); - cgltf_accessor_unpack_floats(:::attributes[k]->accessor, vs, attributes[k]->accessor.count); - break; + case cgltf_attribute_type_tangent: + break; - case cgltf_attribute_type_normal: - - break; - - case cgltf_attribute_type_tangent: - break; - - case cgltf_attribute_type_texcoord: - break; - - } - } - } - } + case cgltf_attribute_type_texcoord: + break; + } } + } } - */ - - /* TODO: DELETE - - - - // read file via ASSIMP - Assimp::Importer importer; - const aiScene *scene = importer.ReadFile(path, - aiProcess_Triangulate | - aiProcess_GenSmoothNormals | - aiProcess_FlipUVs | - aiProcess_CalcTangentSpace); - // check for errors - if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE - || !scene->mRootNode) { - YughLog(0, SDL_LOG_PRIORITY_ERROR, - "ASSIMP error: %s", - importer.GetErrorString()); - return; - } - - directory = get_directory_from_path(path); - - meshes = (Mesh *) malloc(sizeof(Mesh) * 100); - mp = meshes; - // process ASSIMP's root node recursively - processNode(scene->mRootNode, scene); */ + } } +/* TODO: DELETE +static void processnode() { -static void processnode() -{ -/* - for (uint32_t i = 0; i < node->mNumMeshes; i++) { - aiMesh *mesh = scene->mMeshes[node->mMeshes[i]]; - *mp = processMesh(mesh, scene); - mp++; - } + for (uint32_t i = 0; i < node->mNumMeshes; i++) { + aiMesh *mesh = scene->mMeshes[node->mMeshes[i]]; + *mp = processMesh(mesh, scene); + mp++; + } - for (uint32_t i = 0; i < node->mNumChildren; i++) { - processnode(node->mChildren[i], scene); - } + for (uint32_t i = 0; i < node->mNumChildren; i++) { + processnode(node->mChildren[i], scene); + } + +} */ -} - -static void processmesh() -{ -/* - Vertex *vertices = - (Vertex *) malloc(sizeof(Vertex) * mesh->mNumVertices); - Vertex *vp = vertices + mesh->mNumVertices; - Vertex *p = vertices; - for (int i = 0; i < mesh->mNumVertices; i++) { - // positions - (p + i)->Position.x = mesh->mVertices[i][0]; - (p + i)->Position.y = mesh->mVertices[i][1]; - (p + i)->Position.z = mesh->mVertices[i][2]; +static void processmesh() { + /* + Vertex *vertices = + (Vertex *) malloc(sizeof(Vertex) * mesh->mNumVertices); + Vertex *vp = vertices + mesh->mNumVertices; + Vertex *p = vertices; + for (int i = 0; i < mesh->mNumVertices; i++) { + // positions + (p + i)->Position.x = mesh->mVertices[i][0]; + (p + i)->Position.y = mesh->mVertices[i][1]; + (p + i)->Position.z = mesh->mVertices[i][2]; - // normals - if (mesh->HasNormals()) { - (p + i)->Normal.x = mesh->mNormals[i][0]; - (p + i)->Normal.y = mesh->mNormals[i].y; - (p + i)->Normal.z = mesh->mNormals[i].z; - } + // normals + if (mesh->HasNormals()) { + (p + i)->Normal.x = mesh->mNormals[i][0]; + (p + i)->Normal.y = mesh->mNormals[i].y; + (p + i)->Normal.z = mesh->mNormals[i].z; + } - // texture coordinates - if (mesh->mTextureCoords[0]) { - glm::vec2 vec; - // a vertex can contain up to 8 different texture coordinates. We thus make the assumption that we won't - // use models where a vertex can have multiple texture coordinates so we always take the first set (0). - (p + i)->TexCoords.x = mesh->mTextureCoords[0][i].x; - (p + i)->TexCoords.y = mesh->mTextureCoords[0][i].y; + // texture coordinates + if (mesh->mTextureCoords[0]) { + glm::vec2 vec; + // a vertex can contain up to 8 different texture coordinates. We thus make the assumption that we won't + // use models where a vertex can have multiple texture coordinates so we always take the first set (0). + (p + i)->TexCoords.x = mesh->mTextureCoords[0][i].x; + (p + i)->TexCoords.y = mesh->mTextureCoords[0][i].y; - // tangent - (p + i)->Tangent.x = mesh->mTangents[i].x; - (p + i)->Tangent.y = mesh->mTangents[i].y; - (p + i)->Tangent.z = mesh->mTangents[i].z; + // tangent + (p + i)->Tangent.x = mesh->mTangents[i].x; + (p + i)->Tangent.y = mesh->mTangents[i].y; + (p + i)->Tangent.z = mesh->mTangents[i].z; - // bitangent - (p + i)->Bitangent.x = mesh->mBitangents[i].x; - (p + i)->Bitangent.y = mesh->mBitangents[i].y; - (p + i)->Bitangent.z = mesh->mBitangents[i].z; + // bitangent + (p + i)->Bitangent.x = mesh->mBitangents[i].x; + (p + i)->Bitangent.y = mesh->mBitangents[i].y; + (p + i)->Bitangent.z = mesh->mBitangents[i].z; - } else - (p + i)->TexCoords = glm::vec2(0.0f, 0.0f); - } + } else + (p + i)->TexCoords = glm::vec2(0.0f, 0.0f); + } - // TODO: Done quickly, find better way. Go through for loop twice! - int numindices = 0; - // now walk through each of the mesh's faces (a face is a mesh its triangle) and retrieve the corresponding vertex indices. - for (uint32_t i = 0; i < mesh->mNumFaces; i++) { - numindices += mesh->mFaces[i].mNumIndices; - } + // TODO: Done quickly, find better way. Go through for loop twice! + int numindices = 0; + // now walk through each of the mesh's faces (a face is a mesh its triangle) and retrieve the corresponding vertex indices. + for (uint32_t i = 0; i < mesh->mNumFaces; i++) { + numindices += mesh->mFaces[i].mNumIndices; + } - uint32_t *indices = (uint32_t *) malloc(sizeof(uint32_t) * numindices); - uint32_t *ip = indices; + uint32_t *indices = (uint32_t *) malloc(sizeof(uint32_t) * numindices); + uint32_t *ip = indices; - for (uint32_t i = 0; i < mesh->mNumFaces; i++) { - for (uint32_t j = 0; j < mesh->mFaces[i].mNumIndices; j++) { - *ip = mesh->mFaces[i].mIndices[j]; - ip++; - } - } + for (uint32_t i = 0; i < mesh->mNumFaces; i++) { + for (uint32_t j = 0; j < mesh->mFaces[i].mNumIndices; j++) { + *ip = mesh->mFaces[i].mIndices[j]; + ip++; + } + } - // std::vector textures; - aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex]; + // std::vector textures; + aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex]; - // TODO: Allocating 100 to be safe, can probably be way less - textures_loaded = (Texture *) malloc(sizeof(Texture) * 100); - tp = textures_loaded; - // we assume a convention for sampler names in the shaders. Each diffuse texture should be named - // as 'texture_diffuseN' where N is a sequential number ranging from 1 to MAX_SAMPLER_NUMBER. - // Same applies to other texture as the following list summarizes: - // diffuse: texture_diffuseN - // specular: texture_specularN - // normal: texture_normalN + // TODO: Allocating 100 to be safe, can probably be way less + textures_loaded = (Texture *) malloc(sizeof(Texture) * 100); + tp = textures_loaded; + // we assume a convention for sampler names in the shaders. Each diffuse texture should be named + // as 'texture_diffuseN' where N is a sequential number ranging from 1 to MAX_SAMPLER_NUMBER. + // Same applies to other texture as the following list summarizes: + // diffuse: texture_diffuseN + // specular: texture_specularN + // normal: texture_normalN - // 1. diffuse maps - loadMaterialTextures(material, aiTextureType_DIFFUSE, - "texture_diffuse"); + // 1. diffuse maps + loadMaterialTextures(material, aiTextureType_DIFFUSE, + "texture_diffuse"); - // 2. specular maps - loadMaterialTextures(material, aiTextureType_SPECULAR, - "texture_specular"); + // 2. specular maps + loadMaterialTextures(material, aiTextureType_SPECULAR, + "texture_specular"); - // 3. normal maps - loadMaterialTextures(material, aiTextureType_NORMALS, - "texture_normal"); + // 3. normal maps + loadMaterialTextures(material, aiTextureType_NORMALS, + "texture_normal"); - // 4. height maps - loadMaterialTextures(material, aiTextureType_AMBIENT, - "texture_height"); + // 4. height maps + loadMaterialTextures(material, aiTextureType_AMBIENT, + "texture_height"); - // return a mesh object created from the extracted mesh data - return Mesh(vertices, vp, indices, ip, textures_loaded, tp); - - */ + // return a mesh object created from the extracted mesh data + return Mesh(vertices, vp, indices, ip, textures_loaded, tp); + */ } // TODO: This routine mallocs inside the function -static void processtexture() -{ -/* - for (uint32_t i = 0; i < mat->GetTextureCount(type); i++) { - aiString str; - mat->GetTexture(type, i, &str); - for (Texture * tpp = textures_loaded; tpp != tp; tpp++) { - if (strcmp(tpp->path, str.data) == 0) - goto next; // Check if we already have this texture - } +static void processtexture() { + /* + for (uint32_t i = 0; i < mat->GetTextureCount(type); i++) { + aiString str; + mat->GetTexture(type, i, &str); + for (Texture * tpp = textures_loaded; tpp != tp; tpp++) { + if (strcmp(tpp->path, str.data) == 0) + goto next; // Check if we already have this texture + } - tp->id = TextureFromFile(str.data, this->directory); - tp->type = (char *) malloc(sizeof(char) * strlen(typeName)); - strcpy(tp->type, typeName); - tp->path = (char *) malloc(sizeof(char) * strlen(str.data)); - strcpy(tp->path, str.data); + tp->id = TextureFromFile(str.data, this->directory); + tp->type = (char *) malloc(sizeof(char) * strlen(typeName)); + strcpy(tp->type, typeName); + tp->path = (char *) malloc(sizeof(char) * strlen(str.data)); + strcpy(tp->path, str.data); - tp++; + tp++; - next:; + next:; + + } + */ +} + +void draw_models(struct model *model, struct shader *shader) +{ + +} + +// TODO: Come back to this; simple optimization +void draw_model(struct model *model, struct shader *shader) { - } - */ } diff --git a/source/engine/3d/model.h b/source/engine/3d/model.h index aa395bf..8ca61da 100644 --- a/source/engine/3d/model.h +++ b/source/engine/3d/model.h @@ -7,9 +7,6 @@ struct shader; struct model { struct mesh *meshes; struct mesh *mp; - char *directory; - const char *path; - char *name; }; /* Get the model at a path, or create and return if it doesn't exist */ @@ -22,5 +19,6 @@ struct model *MakeModel(const char *path); void loadmodel(struct model *model); void draw_model(struct model *model, struct shader *shader); +void draw_models(struct model *model, struct shader *shader); #endif diff --git a/source/engine/debug/log.c b/source/engine/debug/log.c index 22f8764..29659b7 100644 --- a/source/engine/debug/log.c +++ b/source/engine/debug/log.c @@ -8,7 +8,14 @@ #include #include -#define logLevel 0 +int logLevel = 1; + +/* Four levels of log: + 0 info + 1 warn + 2 error + 3 critical +*/ //char *logstr[] = { "INFO", "WARN", "\x1b[1;31mERROR\x1b[0m", "CRITICAL" }; char *logstr[] = { "info", "warn", "error", "critical" }; @@ -37,19 +44,23 @@ void mYughLog(int category, int priority, int line, const char *file, const char char buffer[ERROR_BUFFER] = { '\0' }; snprintf(buffer, ERROR_BUFFER, "%s:%d: %s, %s: %s\n", file, line, logstr[priority], catstr[category], msgbuffer); - fprintf(stderr, "%s", buffer); - fflush(stderr); + log_print(buffer); + } +} - strncat(consolelog, buffer, CONSOLE_BUF); +void log_print(const char *str) +{ + fprintf(stderr, "%s", str); + fflush(stderr); - if (logfile) { - fprintf(logfile, "%s", buffer); - fflush(logfile); - } + strncat(consolelog, str, CONSOLE_BUF); - snprintf(lastlog, ERROR_BUFFER, "%s", buffer); + if (logfile) { + fprintf(logfile, "%s", str); + fflush(logfile); + } - } + snprintf(lastlog, ERROR_BUFFER, "%s", str); } void log_setfile(char *file) { diff --git a/source/engine/debug/log.h b/source/engine/debug/log.h index 7c989fb..35b8192 100644 --- a/source/engine/debug/log.h +++ b/source/engine/debug/log.h @@ -14,6 +14,7 @@ extern char lastlog[]; extern char consolelog[]; +extern int logLevel; #if DBG #define YughLog(cat, pri, msg, ...) mYughLog(cat, pri, __LINE__, __FILE__, msg, ##__VA_ARGS__) @@ -35,5 +36,6 @@ void FlushGLErrors(); void log_setfile(char *file); void log_cat(FILE *f); +void log_print(const char *str); #endif diff --git a/source/engine/ffi.c b/source/engine/ffi.c index ebc0644..e111473 100644 --- a/source/engine/ffi.c +++ b/source/engine/ffi.c @@ -608,14 +608,12 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) case 11: str = JS_ToCString(js, argv[1]); ret = JS_NewInt64(js, file_mod_secs(str)); - JS_FreeCString(js,str); - return ret; + break; case 12: str = JS_ToCString(js,argv[2]); sprite_loadtex(id2sprite(js2int(argv[1])), str, js2glrect(argv[3])); - JS_FreeCString(js,str); - break; + break; case 13: str = JS_ToCString(js,argv[1]); @@ -722,16 +720,13 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) case 38: str = JS_ToCString(js,argv[1]); ret = JS_NewString(js, slurp_text(str)); - JS_FreeCString(js,str); - return ret; + break; case 39: str = JS_ToCString(js,argv[1]); str2 = JS_ToCString(js,argv[2]); ret = JS_NewInt64(js, slurp_write(str, str2)); - JS_FreeCString(js,str); - JS_FreeCString(js,str2); - return ret; + break; case 40: id2go(js2int(argv[1]))->filter.categories = js2bitmask(argv[2]); @@ -923,6 +918,18 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv) str = JS_ToCString(js, argv[1]); window_set_icon(str); break; + + case 91: + str = JS_ToCString(js,argv[1]); + log_print(str); + break; + + case 92: + logLevel = js2int(argv[1]); + break; + + case 93: + ret = int2js(logLevel); } if (str) diff --git a/source/engine/script.c b/source/engine/script.c index 6268859..00d6fbf 100644 --- a/source/engine/script.c +++ b/source/engine/script.c @@ -50,6 +50,24 @@ time_t file_mod_secs(const char *file) { return attr.st_mtime; } +void js_dump_stack() +{ + JSValue exception = JS_GetException(js); + JSValue val = JS_GetPropertyStr(js, exception, "stack"); + if (!JS_IsUndefined(val)) { + const char *name = JS_ToCString(js, JS_GetPropertyStr(js, exception, "name")); + const char *msg = JS_ToCString(js, JS_GetPropertyStr(js, exception, "message")); + const char *stack = JS_ToCString(js, val); + YughError("%s :: %s\n%s", name, msg, stack); + + JS_FreeCString(js, name); + JS_FreeCString(js, msg); + JS_FreeCString(js, stack); + } + +} + + int js_print_exception(JSValue v) { if (JS_IsException(v)) { @@ -73,7 +91,7 @@ int script_dofile(const char *file) { const char *script = slurp_text(file); if (!script) { YughError("Can't find file %s.", file); - return 1; + return 0; } JSValue obj = JS_Eval(js, script, strlen(script), file, 0); js_print_exception(obj); diff --git a/source/engine/script.h b/source/engine/script.h index 14e9316..80e2b45 100644 --- a/source/engine/script.h +++ b/source/engine/script.h @@ -20,6 +20,7 @@ void script_update(double dt); void script_draw(); void duk_run_err(); +void js_dump_stack(); void script_editor(); void script_call(const char *f); diff --git a/source/engine/texture.c b/source/engine/texture.c index 5f56a78..f275dd4 100644 --- a/source/engine/texture.c +++ b/source/engine/texture.c @@ -20,8 +20,6 @@ struct Texture *tex_default; /* If an empty string or null is put for path, loads default texture */ struct Texture *texture_pullfromfile(const char *path) { - if (!path || path[0] == '\0') { return NULL; } - int index = shgeti(texhash, path); if (index != -1) return texhash[index].value; @@ -49,8 +47,9 @@ struct Texture *texture_pullfromfile(const char *path) unsigned char *data = stbi_load(path, &tex->width, &tex->height, &n, 4); if (data == NULL) { - YughError("STBI failed to load file %s with message: %s", path, stbi_failure_reason()); - return NULL; + YughError("STBI failed to load file %s with message: %s\nOpening default instead.", path, stbi_failure_reason()); + print_stacktrace(); + return texture_pullfromfile("./icons/no_tex.png"); } tex->data = data; @@ -94,11 +93,6 @@ struct Texture *texture_pullfromfile(const char *path) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - - - -// stbi_image_free(data); - if (shlen(texhash) == 0) sh_new_arena(texhash); @@ -122,8 +116,6 @@ struct Texture *texture_loadfromfile(const char *path) { struct Texture *new = texture_pullfromfile(path); - if (new == NULL) { new = texture_pullfromfile("./icons/no_tex.png"); } - if (new->id == 0) { glGenTextures(1, &new->id); diff --git a/source/engine/yugine.c b/source/engine/yugine.c index 528e70b..249d246 100644 --- a/source/engine/yugine.c +++ b/source/engine/yugine.c @@ -58,19 +58,12 @@ int fps; #define SIM_PAUSE 2 #define SIM_STEP 3 -void seghandle(int sig) { -/* -#ifdef __linux__ +void print_stacktrace() +{ void *ents[512]; size_t size; size = backtrace(ents, 512); - if (strsignal(sig)) { - YughCritical("CRASH! Signal: %s.", strsignal(sig)); - } - else { - YughCritical("CRASH! Signal: %d.", sig); - } YughCritical("====================BACKTRACE===================="); char **stackstr = backtrace_symbols(ents, size); @@ -81,11 +74,23 @@ void seghandle(int sig) { YughCritical(stackstr[i]); } - duk_dump_stack(duk); + js_dump_stack(); + +} + +void seghandle(int sig) { +#ifdef __linux__ + if (strsignal(sig)) { + YughCritical("CRASH! Signal: %s.", strsignal(sig)); + } + else { + YughCritical("CRASH! Signal: %d.", sig); + } + + print_stacktrace(); exit(1); #endif -*/ } void compile_script(const char *file) @@ -135,6 +140,10 @@ int main(int argc, char **args) { compile_script(args[2]); exit(0); + case 'm': + logLevel = atoi(args[2]); + break; + case 'h': printf("-l Set log file\n"); printf("-p Launch engine in play mode instead of editor mode\n"); @@ -172,6 +181,8 @@ int main(int argc, char **args) { signal(SIGSEGV, seghandle); signal(SIGABRT, seghandle); signal(SIGFPE, seghandle); + signal(SIGBUS, seghandle); + #endif FILE *gameinfo = NULL; @@ -185,14 +196,15 @@ int main(int argc, char **args) { YughInfo("Refresh rate is %d", vidmode->refreshRate); renderMS = 1.0/vidmode->refreshRate; + + input_init(); + openglInit(); if (ed) script_dofile("scripts/editor.js"); else - script_dofile("game.js"); + script_dofile("scripts/play.js"); - input_init(); - openglInit(); while (!want_quit()) { double elapsed = glfwGetTime() - lastTick; deltaT = elapsed; diff --git a/source/engine/yugine.h b/source/engine/yugine.h index a16cc3b..7352b25 100644 --- a/source/engine/yugine.h +++ b/source/engine/yugine.h @@ -9,6 +9,7 @@ void sim_stop(); void sim_step(); int phys_stepping(); void set_timescale(float val); +void print_stacktrace(); int frame_fps(); diff --git a/source/scripts/debug.js b/source/scripts/debug.js index 79ff674..a47fcad 100644 --- a/source/scripts/debug.js +++ b/source/scripts/debug.js @@ -169,39 +169,3 @@ var Nuke = { Object.defineProperty(Nuke, "curwin", {enumerable:false}); Object.defineProperty(Nuke, "defaultrect", {enumerable:false}); - -var Log = { - print(msg, lvl) { - var lg; - if (typeof msg === 'object') { - lg = JSON.stringify(msg, null, 2); - } else { - lg = msg; - } - - var stack = (new Error()).stack; - var n = stack.next('\n',0)+1; - n = stack.next('\n', n)+1; - var nnn = stack.slice(n); - var fmatch = nnn.match(/\(.*\:/); - var file = fmatch ? fmatch[0].shift(1).shift(-1) : "nofile"; - var lmatch = nnn.match(/\:\d*\)/); - var line = lmatch ? lmatch[0].shift(1).shift(-1) : "0"; - - yughlog(lvl, lg, file, line); - }, - - info(msg) { - this.print(msg, 0); - }, - - warn(msg) { - this.print(msg, 1); - }, - - error(msg) { - this.print(msg, 2); - }, - -}; - diff --git a/source/scripts/engine.js b/source/scripts/engine.js index f4acab2..f2764c3 100644 --- a/source/scripts/engine.js +++ b/source/scripts/engine.js @@ -1,6 +1,68 @@ + +var Log = { + set level(x) { cmd(92,x); }, + get level() { return cmd(93); }, + print(msg, lvl) { + var lg; + if (typeof msg === 'object') { + lg = JSON.stringify(msg, null, 2); + } else { + lg = msg; + } + + var stack = (new Error()).stack; + var n = stack.next('\n',0)+1; + n = stack.next('\n', n)+1; + var nnn = stack.slice(n); + var fmatch = nnn.match(/\(.*\:/); + var file = fmatch ? fmatch[0].shift(1).shift(-1) : "nofile"; + var lmatch = nnn.match(/\:\d*\)/); + var line = lmatch ? lmatch[0].shift(1).shift(-1) : "0"; + + yughlog(lvl, lg, file, line); + }, + + info(msg) { + this.print(msg, 0); + }, + + warn(msg) { + this.print(msg, 1); + }, + + error(msg) { + this.print(msg, 2); + this.stack(1); + }, + + critical(msg) { + this.print(msg,3); + this.stack(1); + }, + + write(msg) { + cmd(91,msg); + }, + + stack(skip) { + var stack = (new Error()).stack; + var n = stack.next('\n',0)+1; + for (var i = 0; i < skip; i++) + n = stack.next('\n', n)+1; + + this.write(stack.slice(n)); + }, + +}; + var files = {}; function load(file) { var modtime = cmd(0, file); + + if (modtime === 0) { + Log.stack(); + return false; + } files[file] = modtime; }