stack trace on error and critical logs; set logging level
This commit is contained in:
parent
2ab0f33d3f
commit
a39aee66f5
|
@ -1,282 +1,232 @@
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
#include "mesh.h"
|
#include "mesh.h"
|
||||||
#include "resources.h"
|
#include "resources.h"
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
|
#include "stb_ds.h"
|
||||||
#include <cgltf.h>
|
#include <cgltf.h>
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "log.h"
|
#include <string.h>
|
||||||
|
|
||||||
static struct model *lastRendered;
|
static struct {
|
||||||
static struct model *loadedModels[100];
|
char *key;
|
||||||
static struct model **lastModel = loadedModels;
|
struct Texture *value;
|
||||||
|
} *modelhash = NULL;
|
||||||
|
|
||||||
static void processnode();
|
static void processnode();
|
||||||
static void processmesh();
|
static void processmesh();
|
||||||
static void processtexture();
|
static void processtexture();
|
||||||
|
|
||||||
|
struct model *GetExistingModel(const char *path) {
|
||||||
|
if (!path || path[0] == '\0') return NULL;
|
||||||
|
|
||||||
struct model *GetExistingModel(const char *path)
|
int index = shgeti(modelhash, path);
|
||||||
{
|
if (index != -1) return modelhash[index].value;
|
||||||
struct model **model = loadedModels;
|
|
||||||
|
|
||||||
while (model++ != lastModel) {
|
return MakeModel(path);
|
||||||
if (!strcmp(path, (*model)->path))
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
return MakeModel(path);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Make this a hash compare for speedup */
|
/* TODO: Make this a hash compare for speedup */
|
||||||
struct model *MakeModel(const char *path)
|
struct model *MakeModel(const char *path) {
|
||||||
{
|
cgltf_options options = {0};
|
||||||
char *modelPath =
|
cgltf_data *data = NULL;
|
||||||
(char *) malloc(sizeof(char) *
|
cgltf_result result = cgltf_parse_file(&options, path, &data);
|
||||||
(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 *newmodel =
|
if (!result == cgltf_result_success) {
|
||||||
(struct model *) malloc(sizeof(struct model));
|
YughError("Could not read file %s.", path);
|
||||||
newmodel->path = path;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
loadmodel(newmodel);
|
result = cgltf_load_buffers(&options, data, path);
|
||||||
*lastModel++ = newmodel;
|
|
||||||
return newmodel;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Come back to this; simple optimization
|
if (!result == cgltf_result_success) {
|
||||||
void draw_model(struct model *model, struct shader *shader)
|
YughError("Could not load buffers for file %s.", path);
|
||||||
{
|
return;
|
||||||
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]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void loadmodel(struct model *model)
|
struct model *model = malloc(sizeof(struct 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);
|
|
||||||
|
|
||||||
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++) {
|
case cgltf_attribute_type_normal:
|
||||||
if (data->nodes[i]->mesh) {
|
break;
|
||||||
for (int j = 0; j < data->nodes[i]->mesh->primatives_count; j++) {
|
|
||||||
|
|
||||||
|
|
||||||
for (int k = 0; k < data->nodes[i]->mesh->primatives[j]->attributes_count; k++) {
|
case cgltf_attribute_type_tangent:
|
||||||
switch(data->nodes[i]->mesh->primatives[j]->attributes[k]->type) {
|
break;
|
||||||
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_normal:
|
case cgltf_attribute_type_texcoord:
|
||||||
|
break;
|
||||||
break;
|
}
|
||||||
|
|
||||||
case cgltf_attribute_type_tangent:
|
|
||||||
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);
|
||||||
for (uint32_t i = 0; i < node->mNumMeshes; i++) {
|
mp++;
|
||||||
aiMesh *mesh = scene->mMeshes[node->mMeshes[i]];
|
}
|
||||||
*mp = processMesh(mesh, scene);
|
|
||||||
mp++;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < node->mNumChildren; i++) {
|
for (uint32_t i = 0; i < node->mNumChildren; i++) {
|
||||||
processnode(node->mChildren[i], scene);
|
processnode(node->mChildren[i], scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
*/
|
*/
|
||||||
}
|
static void processmesh() {
|
||||||
|
/*
|
||||||
static void processmesh()
|
Vertex *vertices =
|
||||||
{
|
(Vertex *) malloc(sizeof(Vertex) * mesh->mNumVertices);
|
||||||
/*
|
Vertex *vp = vertices + mesh->mNumVertices;
|
||||||
Vertex *vertices =
|
Vertex *p = vertices;
|
||||||
(Vertex *) malloc(sizeof(Vertex) * mesh->mNumVertices);
|
for (int i = 0; i < mesh->mNumVertices; i++) {
|
||||||
Vertex *vp = vertices + mesh->mNumVertices;
|
// positions
|
||||||
Vertex *p = vertices;
|
(p + i)->Position.x = mesh->mVertices[i][0];
|
||||||
for (int i = 0; i < mesh->mNumVertices; i++) {
|
(p + i)->Position.y = mesh->mVertices[i][1];
|
||||||
// positions
|
(p + i)->Position.z = mesh->mVertices[i][2];
|
||||||
(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
|
// normals
|
||||||
if (mesh->HasNormals()) {
|
if (mesh->HasNormals()) {
|
||||||
(p + i)->Normal.x = mesh->mNormals[i][0];
|
(p + i)->Normal.x = mesh->mNormals[i][0];
|
||||||
(p + i)->Normal.y = mesh->mNormals[i].y;
|
(p + i)->Normal.y = mesh->mNormals[i].y;
|
||||||
(p + i)->Normal.z = mesh->mNormals[i].z;
|
(p + i)->Normal.z = mesh->mNormals[i].z;
|
||||||
}
|
}
|
||||||
|
|
||||||
// texture coordinates
|
// texture coordinates
|
||||||
if (mesh->mTextureCoords[0]) {
|
if (mesh->mTextureCoords[0]) {
|
||||||
glm::vec2 vec;
|
glm::vec2 vec;
|
||||||
// a vertex can contain up to 8 different texture coordinates. We thus make the assumption that we won't
|
// 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).
|
// 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.x = mesh->mTextureCoords[0][i].x;
|
||||||
(p + i)->TexCoords.y = mesh->mTextureCoords[0][i].y;
|
(p + i)->TexCoords.y = mesh->mTextureCoords[0][i].y;
|
||||||
|
|
||||||
// tangent
|
// tangent
|
||||||
(p + i)->Tangent.x = mesh->mTangents[i].x;
|
(p + i)->Tangent.x = mesh->mTangents[i].x;
|
||||||
(p + i)->Tangent.y = mesh->mTangents[i].y;
|
(p + i)->Tangent.y = mesh->mTangents[i].y;
|
||||||
(p + i)->Tangent.z = mesh->mTangents[i].z;
|
(p + i)->Tangent.z = mesh->mTangents[i].z;
|
||||||
|
|
||||||
// bitangent
|
// bitangent
|
||||||
(p + i)->Bitangent.x = mesh->mBitangents[i].x;
|
(p + i)->Bitangent.x = mesh->mBitangents[i].x;
|
||||||
(p + i)->Bitangent.y = mesh->mBitangents[i].y;
|
(p + i)->Bitangent.y = mesh->mBitangents[i].y;
|
||||||
(p + i)->Bitangent.z = mesh->mBitangents[i].z;
|
(p + i)->Bitangent.z = mesh->mBitangents[i].z;
|
||||||
|
|
||||||
} else
|
} else
|
||||||
(p + i)->TexCoords = glm::vec2(0.0f, 0.0f);
|
(p + i)->TexCoords = glm::vec2(0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: Done quickly, find better way. Go through for loop twice!
|
// TODO: Done quickly, find better way. Go through for loop twice!
|
||||||
int numindices = 0;
|
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.
|
// 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++) {
|
for (uint32_t i = 0; i < mesh->mNumFaces; i++) {
|
||||||
numindices += mesh->mFaces[i].mNumIndices;
|
numindices += mesh->mFaces[i].mNumIndices;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t *indices = (uint32_t *) malloc(sizeof(uint32_t) * numindices);
|
uint32_t *indices = (uint32_t *) malloc(sizeof(uint32_t) * numindices);
|
||||||
uint32_t *ip = indices;
|
uint32_t *ip = indices;
|
||||||
|
|
||||||
for (uint32_t i = 0; i < mesh->mNumFaces; i++) {
|
for (uint32_t i = 0; i < mesh->mNumFaces; i++) {
|
||||||
for (uint32_t j = 0; j < mesh->mFaces[i].mNumIndices; j++) {
|
for (uint32_t j = 0; j < mesh->mFaces[i].mNumIndices; j++) {
|
||||||
*ip = mesh->mFaces[i].mIndices[j];
|
*ip = mesh->mFaces[i].mIndices[j];
|
||||||
ip++;
|
ip++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// std::vector<Texture> textures;
|
// std::vector<Texture> textures;
|
||||||
aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex];
|
aiMaterial *material = scene->mMaterials[mesh->mMaterialIndex];
|
||||||
|
|
||||||
// TODO: Allocating 100 to be safe, can probably be way less
|
// TODO: Allocating 100 to be safe, can probably be way less
|
||||||
textures_loaded = (Texture *) malloc(sizeof(Texture) * 100);
|
textures_loaded = (Texture *) malloc(sizeof(Texture) * 100);
|
||||||
tp = textures_loaded;
|
tp = textures_loaded;
|
||||||
// we assume a convention for sampler names in the shaders. Each diffuse texture should be named
|
// 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.
|
// 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:
|
// Same applies to other texture as the following list summarizes:
|
||||||
// diffuse: texture_diffuseN
|
// diffuse: texture_diffuseN
|
||||||
// specular: texture_specularN
|
// specular: texture_specularN
|
||||||
// normal: texture_normalN
|
// normal: texture_normalN
|
||||||
|
|
||||||
// 1. diffuse maps
|
// 1. diffuse maps
|
||||||
loadMaterialTextures(material, aiTextureType_DIFFUSE,
|
loadMaterialTextures(material, aiTextureType_DIFFUSE,
|
||||||
"texture_diffuse");
|
"texture_diffuse");
|
||||||
|
|
||||||
// 2. specular maps
|
// 2. specular maps
|
||||||
loadMaterialTextures(material, aiTextureType_SPECULAR,
|
loadMaterialTextures(material, aiTextureType_SPECULAR,
|
||||||
"texture_specular");
|
"texture_specular");
|
||||||
|
|
||||||
// 3. normal maps
|
// 3. normal maps
|
||||||
loadMaterialTextures(material, aiTextureType_NORMALS,
|
loadMaterialTextures(material, aiTextureType_NORMALS,
|
||||||
"texture_normal");
|
"texture_normal");
|
||||||
|
|
||||||
// 4. height maps
|
// 4. height maps
|
||||||
loadMaterialTextures(material, aiTextureType_AMBIENT,
|
loadMaterialTextures(material, aiTextureType_AMBIENT,
|
||||||
"texture_height");
|
"texture_height");
|
||||||
|
|
||||||
|
|
||||||
// return a mesh object created from the extracted mesh data
|
// return a mesh object created from the extracted mesh data
|
||||||
return Mesh(vertices, vp, indices, ip, textures_loaded, tp);
|
return Mesh(vertices, vp, indices, ip, textures_loaded, tp);
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This routine mallocs inside the function
|
// TODO: This routine mallocs inside the function
|
||||||
static void processtexture()
|
static void processtexture() {
|
||||||
{
|
/*
|
||||||
/*
|
for (uint32_t i = 0; i < mat->GetTextureCount(type); i++) {
|
||||||
for (uint32_t i = 0; i < mat->GetTextureCount(type); i++) {
|
aiString str;
|
||||||
aiString str;
|
mat->GetTexture(type, i, &str);
|
||||||
mat->GetTexture(type, i, &str);
|
for (Texture * tpp = textures_loaded; tpp != tp; tpp++) {
|
||||||
for (Texture * tpp = textures_loaded; tpp != tp; tpp++) {
|
if (strcmp(tpp->path, str.data) == 0)
|
||||||
if (strcmp(tpp->path, str.data) == 0)
|
goto next; // Check if we already have this texture
|
||||||
goto next; // Check if we already have this texture
|
}
|
||||||
}
|
|
||||||
|
|
||||||
tp->id = TextureFromFile(str.data, this->directory);
|
tp->id = TextureFromFile(str.data, this->directory);
|
||||||
tp->type = (char *) malloc(sizeof(char) * strlen(typeName));
|
tp->type = (char *) malloc(sizeof(char) * strlen(typeName));
|
||||||
strcpy(tp->type, typeName);
|
strcpy(tp->type, typeName);
|
||||||
tp->path = (char *) malloc(sizeof(char) * strlen(str.data));
|
tp->path = (char *) malloc(sizeof(char) * strlen(str.data));
|
||||||
strcpy(tp->path, 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) {
|
||||||
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,9 +7,6 @@ struct shader;
|
||||||
struct model {
|
struct model {
|
||||||
struct mesh *meshes;
|
struct mesh *meshes;
|
||||||
struct mesh *mp;
|
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 */
|
/* 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 loadmodel(struct model *model);
|
||||||
|
|
||||||
void draw_model(struct model *model, struct shader *shader);
|
void draw_model(struct model *model, struct shader *shader);
|
||||||
|
void draw_models(struct model *model, struct shader *shader);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,7 +8,14 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#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", "\x1b[1;31mERROR\x1b[0m", "CRITICAL" };
|
||||||
char *logstr[] = { "info", "warn", "error", "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' };
|
char buffer[ERROR_BUFFER] = { '\0' };
|
||||||
snprintf(buffer, ERROR_BUFFER, "%s:%d: %s, %s: %s\n", file, line, logstr[priority], catstr[category], msgbuffer);
|
snprintf(buffer, ERROR_BUFFER, "%s:%d: %s, %s: %s\n", file, line, logstr[priority], catstr[category], msgbuffer);
|
||||||
|
|
||||||
fprintf(stderr, "%s", buffer);
|
log_print(buffer);
|
||||||
fflush(stderr);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
strncat(consolelog, buffer, CONSOLE_BUF);
|
void log_print(const char *str)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "%s", str);
|
||||||
|
fflush(stderr);
|
||||||
|
|
||||||
if (logfile) {
|
strncat(consolelog, str, CONSOLE_BUF);
|
||||||
fprintf(logfile, "%s", buffer);
|
|
||||||
fflush(logfile);
|
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
void log_setfile(char *file) {
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
extern char lastlog[];
|
extern char lastlog[];
|
||||||
extern char consolelog[];
|
extern char consolelog[];
|
||||||
|
extern int logLevel;
|
||||||
|
|
||||||
#if DBG
|
#if DBG
|
||||||
#define YughLog(cat, pri, msg, ...) mYughLog(cat, pri, __LINE__, __FILE__, msg, ##__VA_ARGS__)
|
#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_setfile(char *file);
|
||||||
void log_cat(FILE *f);
|
void log_cat(FILE *f);
|
||||||
|
void log_print(const char *str);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -608,14 +608,12 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
||||||
case 11:
|
case 11:
|
||||||
str = JS_ToCString(js, argv[1]);
|
str = JS_ToCString(js, argv[1]);
|
||||||
ret = JS_NewInt64(js, file_mod_secs(str));
|
ret = JS_NewInt64(js, file_mod_secs(str));
|
||||||
JS_FreeCString(js,str);
|
break;
|
||||||
return ret;
|
|
||||||
|
|
||||||
case 12:
|
case 12:
|
||||||
str = JS_ToCString(js,argv[2]);
|
str = JS_ToCString(js,argv[2]);
|
||||||
sprite_loadtex(id2sprite(js2int(argv[1])), str, js2glrect(argv[3]));
|
sprite_loadtex(id2sprite(js2int(argv[1])), str, js2glrect(argv[3]));
|
||||||
JS_FreeCString(js,str);
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case 13:
|
case 13:
|
||||||
str = JS_ToCString(js,argv[1]);
|
str = JS_ToCString(js,argv[1]);
|
||||||
|
@ -722,16 +720,13 @@ JSValue duk_cmd(JSContext *js, JSValueConst this, int argc, JSValueConst *argv)
|
||||||
case 38:
|
case 38:
|
||||||
str = JS_ToCString(js,argv[1]);
|
str = JS_ToCString(js,argv[1]);
|
||||||
ret = JS_NewString(js, slurp_text(str));
|
ret = JS_NewString(js, slurp_text(str));
|
||||||
JS_FreeCString(js,str);
|
break;
|
||||||
return ret;
|
|
||||||
|
|
||||||
case 39:
|
case 39:
|
||||||
str = JS_ToCString(js,argv[1]);
|
str = JS_ToCString(js,argv[1]);
|
||||||
str2 = JS_ToCString(js,argv[2]);
|
str2 = JS_ToCString(js,argv[2]);
|
||||||
ret = JS_NewInt64(js, slurp_write(str, str2));
|
ret = JS_NewInt64(js, slurp_write(str, str2));
|
||||||
JS_FreeCString(js,str);
|
break;
|
||||||
JS_FreeCString(js,str2);
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
case 40:
|
case 40:
|
||||||
id2go(js2int(argv[1]))->filter.categories = js2bitmask(argv[2]);
|
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]);
|
str = JS_ToCString(js, argv[1]);
|
||||||
window_set_icon(str);
|
window_set_icon(str);
|
||||||
break;
|
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)
|
if (str)
|
||||||
|
|
|
@ -50,6 +50,24 @@ time_t file_mod_secs(const char *file) {
|
||||||
return attr.st_mtime;
|
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)
|
int js_print_exception(JSValue v)
|
||||||
{
|
{
|
||||||
if (JS_IsException(v)) {
|
if (JS_IsException(v)) {
|
||||||
|
@ -73,7 +91,7 @@ int script_dofile(const char *file) {
|
||||||
const char *script = slurp_text(file);
|
const char *script = slurp_text(file);
|
||||||
if (!script) {
|
if (!script) {
|
||||||
YughError("Can't find file %s.", file);
|
YughError("Can't find file %s.", file);
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
JSValue obj = JS_Eval(js, script, strlen(script), file, 0);
|
JSValue obj = JS_Eval(js, script, strlen(script), file, 0);
|
||||||
js_print_exception(obj);
|
js_print_exception(obj);
|
||||||
|
|
|
@ -20,6 +20,7 @@ void script_update(double dt);
|
||||||
void script_draw();
|
void script_draw();
|
||||||
|
|
||||||
void duk_run_err();
|
void duk_run_err();
|
||||||
|
void js_dump_stack();
|
||||||
|
|
||||||
void script_editor();
|
void script_editor();
|
||||||
void script_call(const char *f);
|
void script_call(const char *f);
|
||||||
|
|
|
@ -20,8 +20,6 @@ struct Texture *tex_default;
|
||||||
/* If an empty string or null is put for path, loads default texture */
|
/* If an empty string or null is put for path, loads default texture */
|
||||||
struct Texture *texture_pullfromfile(const char *path)
|
struct Texture *texture_pullfromfile(const char *path)
|
||||||
{
|
{
|
||||||
if (!path || path[0] == '\0') { return NULL; }
|
|
||||||
|
|
||||||
int index = shgeti(texhash, path);
|
int index = shgeti(texhash, path);
|
||||||
if (index != -1)
|
if (index != -1)
|
||||||
return texhash[index].value;
|
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);
|
unsigned char *data = stbi_load(path, &tex->width, &tex->height, &n, 4);
|
||||||
|
|
||||||
if (data == NULL) {
|
if (data == NULL) {
|
||||||
YughError("STBI failed to load file %s with message: %s", path, stbi_failure_reason());
|
YughError("STBI failed to load file %s with message: %s\nOpening default instead.", path, stbi_failure_reason());
|
||||||
return NULL;
|
print_stacktrace();
|
||||||
|
return texture_pullfromfile("./icons/no_tex.png");
|
||||||
}
|
}
|
||||||
tex->data = data;
|
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_S, GL_REPEAT);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// stbi_image_free(data);
|
|
||||||
|
|
||||||
if (shlen(texhash) == 0)
|
if (shlen(texhash) == 0)
|
||||||
sh_new_arena(texhash);
|
sh_new_arena(texhash);
|
||||||
|
|
||||||
|
@ -122,8 +116,6 @@ struct Texture *texture_loadfromfile(const char *path)
|
||||||
{
|
{
|
||||||
struct Texture *new = texture_pullfromfile(path);
|
struct Texture *new = texture_pullfromfile(path);
|
||||||
|
|
||||||
if (new == NULL) { new = texture_pullfromfile("./icons/no_tex.png"); }
|
|
||||||
|
|
||||||
if (new->id == 0) {
|
if (new->id == 0) {
|
||||||
glGenTextures(1, &new->id);
|
glGenTextures(1, &new->id);
|
||||||
|
|
||||||
|
|
|
@ -58,19 +58,12 @@ int fps;
|
||||||
#define SIM_PAUSE 2
|
#define SIM_PAUSE 2
|
||||||
#define SIM_STEP 3
|
#define SIM_STEP 3
|
||||||
|
|
||||||
void seghandle(int sig) {
|
void print_stacktrace()
|
||||||
/*
|
{
|
||||||
#ifdef __linux__
|
|
||||||
void *ents[512];
|
void *ents[512];
|
||||||
size_t size;
|
size_t size;
|
||||||
|
|
||||||
size = backtrace(ents, 512);
|
size = backtrace(ents, 512);
|
||||||
if (strsignal(sig)) {
|
|
||||||
YughCritical("CRASH! Signal: %s.", strsignal(sig));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
YughCritical("CRASH! Signal: %d.", sig);
|
|
||||||
}
|
|
||||||
|
|
||||||
YughCritical("====================BACKTRACE====================");
|
YughCritical("====================BACKTRACE====================");
|
||||||
char **stackstr = backtrace_symbols(ents, size);
|
char **stackstr = backtrace_symbols(ents, size);
|
||||||
|
@ -81,11 +74,23 @@ void seghandle(int sig) {
|
||||||
YughCritical(stackstr[i]);
|
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);
|
exit(1);
|
||||||
#endif
|
#endif
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void compile_script(const char *file)
|
void compile_script(const char *file)
|
||||||
|
@ -135,6 +140,10 @@ int main(int argc, char **args) {
|
||||||
compile_script(args[2]);
|
compile_script(args[2]);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
|
case 'm':
|
||||||
|
logLevel = atoi(args[2]);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'h':
|
case 'h':
|
||||||
printf("-l Set log file\n");
|
printf("-l Set log file\n");
|
||||||
printf("-p Launch engine in play mode instead of editor mode\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(SIGSEGV, seghandle);
|
||||||
signal(SIGABRT, seghandle);
|
signal(SIGABRT, seghandle);
|
||||||
signal(SIGFPE, seghandle);
|
signal(SIGFPE, seghandle);
|
||||||
|
signal(SIGBUS, seghandle);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FILE *gameinfo = NULL;
|
FILE *gameinfo = NULL;
|
||||||
|
@ -185,14 +196,15 @@ int main(int argc, char **args) {
|
||||||
YughInfo("Refresh rate is %d", vidmode->refreshRate);
|
YughInfo("Refresh rate is %d", vidmode->refreshRate);
|
||||||
|
|
||||||
renderMS = 1.0/vidmode->refreshRate;
|
renderMS = 1.0/vidmode->refreshRate;
|
||||||
|
|
||||||
|
input_init();
|
||||||
|
openglInit();
|
||||||
|
|
||||||
if (ed)
|
if (ed)
|
||||||
script_dofile("scripts/editor.js");
|
script_dofile("scripts/editor.js");
|
||||||
else
|
else
|
||||||
script_dofile("game.js");
|
script_dofile("scripts/play.js");
|
||||||
|
|
||||||
input_init();
|
|
||||||
openglInit();
|
|
||||||
while (!want_quit()) {
|
while (!want_quit()) {
|
||||||
double elapsed = glfwGetTime() - lastTick;
|
double elapsed = glfwGetTime() - lastTick;
|
||||||
deltaT = elapsed;
|
deltaT = elapsed;
|
||||||
|
|
|
@ -9,6 +9,7 @@ void sim_stop();
|
||||||
void sim_step();
|
void sim_step();
|
||||||
int phys_stepping();
|
int phys_stepping();
|
||||||
void set_timescale(float val);
|
void set_timescale(float val);
|
||||||
|
void print_stacktrace();
|
||||||
|
|
||||||
int frame_fps();
|
int frame_fps();
|
||||||
|
|
||||||
|
|
|
@ -169,39 +169,3 @@ var Nuke = {
|
||||||
Object.defineProperty(Nuke, "curwin", {enumerable:false});
|
Object.defineProperty(Nuke, "curwin", {enumerable:false});
|
||||||
Object.defineProperty(Nuke, "defaultrect", {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);
|
|
||||||
},
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
|
@ -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 = {};
|
var files = {};
|
||||||
function load(file) {
|
function load(file) {
|
||||||
var modtime = cmd(0, file);
|
var modtime = cmd(0, file);
|
||||||
|
|
||||||
|
if (modtime === 0) {
|
||||||
|
Log.stack();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
files[file] = modtime;
|
files[file] = modtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue