diff --git a/source/engine/2dphysics.c b/source/engine/2dphysics.c index 242d1a2..41b5a48 100644 --- a/source/engine/2dphysics.c +++ b/source/engine/2dphysics.c @@ -47,6 +47,7 @@ void phys2d_shape_apply(struct phys2d_shape *shape) void init_phys2dshape(struct phys2d_shape *shape, struct gameobject *go) { + YughInfo("Making shape with GO %p", go); shape->go = go; cpShapeSetCollisionType(shape->shape, go); phys2d_shape_apply(shape); @@ -462,8 +463,9 @@ static cpBool s7_phys_cb_begin(cpArbiter *arb, cpSpace *space, void *data) { struct gameobject *g2 = cpBodyGetUserData(body2); - script_call_sym_args(go->cbs->begin, s7_make_integer(s7, g2->editor.id)); - //script_call_sym(go->cbs->begin); + //script_call_sym_args(go->cbs->begin, s7_make_integer(s7, g2->editor.id)); + s7_call(s7, go->cbs->begin, s7_list(s7, 2, s7_make_integer(s7, g2->editor.id), cpvec2s7(cpArbiterGetNormal(arb)))); + return 1; } diff --git a/source/engine/anim.c b/source/engine/anim.c index dfb2fb8..4ca141d 100644 --- a/source/engine/anim.c +++ b/source/engine/anim.c @@ -9,6 +9,10 @@ struct anim make_anim() { return a; } +void free_anim(struct anim a) { + arrfree(a.frames); +} + struct anim anim_add_keyframe(struct anim a, struct keyframe key) { arrput(a.frames, key); @@ -27,6 +31,8 @@ double near_val(struct anim anim, double t) { return (interval(anim.frames[i], anim.frames[i+1], t) >= 0.5f ? anim.frames[i+1].val : anim.frames[i].val); } + + return arrlast(anim.frames).val; } double lerp_val(struct anim anim, double t) { diff --git a/source/engine/editor/editor.c b/source/engine/editor/editor.c index 16787f8..522782c 100644 --- a/source/engine/editor/editor.c +++ b/source/engine/editor/editor.c @@ -28,6 +28,7 @@ #include #include #include "nuke.h" +#include "texture.h" #include "log.h" diff --git a/source/engine/font.c b/source/engine/font.c index 6438568..e97aad4 100644 --- a/source/engine/font.c +++ b/source/engine/font.c @@ -13,6 +13,7 @@ #include "openglrender.h" #include +#include "stb_rect_pack.h" static uint32_t VBO = 0; static uint32_t VAO = 0; @@ -50,7 +51,6 @@ void font_frame(struct window *w) { shader_use(shader); } -// Height in pixels struct sFont *MakeFont(const char *fontfile, int height) { shader_use(shader); @@ -62,6 +62,18 @@ struct sFont *MakeFont(const char *fontfile, int height) snprintf(fontpath, 256, "fonts/%s", fontfile); fread(ttf_buffer, 1, 1<<25, fopen(fontpath, "rb")); + unsigned char *bitmap = malloc(1024*1024); + + stbtt_packedchar glyphs[95]; + + stbtt_pack_context pc; + + stbtt_PackBegin(&pc, bitmap, 1024, 1024, 0, 1, NULL); + stbtt_PackSetOversampling(&pc, 1, 1); + stbtt_PackFontRange(&pc, ttf_buffer, 0, height, 32, 95, glyphs); + stbtt_PackEnd(&pc); + + stbtt_fontinfo fontinfo; if (!stbtt_InitFont(&fontinfo, ttf_buffer, stbtt_GetFontOffsetForIndex(ttf_buffer,0))) { @@ -69,47 +81,45 @@ struct sFont *MakeFont(const char *fontfile, int height) } float scale = stbtt_ScaleForPixelHeight(&fontinfo, height); + //glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glGenTextures(1, &newfont->texID); + glBindTexture(GL_TEXTURE_2D, newfont->texID); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 1024, 1024, 0, GL_RED, GL_UNSIGNED_BYTE, bitmap); + glGenerateMipmap(GL_TEXTURE_2D); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - int ascent, descent, linegap; - - stbtt_GetFontVMetrics(&fontinfo, &ascent, &descent, &linegap); - - ascent = roundf(ascent*scale); - descent = roundf(descent*scale); - - - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); for (unsigned char c = 32; c < 127; c++) { - unsigned char *bitmap; + //unsigned char *bitmap; int advance, lsb, w, h, x0, y0; stbtt_GetCodepointHMetrics(&fontinfo, c, &advance, &lsb); + stbtt_packedchar glyph = glyphs[c-32]; - bitmap = stbtt_GetCodepointBitmap(&fontinfo, scale, scale, c, &w, &h, &x0, &y0); + YughInfo("Packed char is at %d, %d, %d, %d", glyphs[c-32].x0, glyphs[c-32].y0, glyphs[c-32].x1, glyphs[c-32].y1); - GLuint ftexture; - glGenTextures(1, &ftexture); - glBindTexture(GL_TEXTURE_2D, ftexture); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, w, h, 0, GL_RED, GL_UNSIGNED_BYTE, bitmap); - - glGenerateMipmap(GL_TEXTURE_2D); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - newfont->Characters[c].TextureID = ftexture; + struct glrect r; + r.s0 = glyph.x0 / (float)1024; + r.s1 = glyph.x1 / (float) 1024; + r.t0 = glyph.y0 / (float) 1024; + r.t1 = glyph.y1 / (float) 1024; + YughInfo("That is %f %f %f %f", r.s0, r.t0, r.s1, r.t1); newfont->Characters[c].Advance = advance * scale; - newfont->Characters[c].Size[0] = w; - newfont->Characters[c].Size[1] = h; + newfont->Characters[c].Size[0] = glyphs[c-32].x1 - glyphs[c-32].x0; + newfont->Characters[c].Size[1] = glyphs[c-32].y1 - glyphs[c-32].y0; newfont->Characters[c].Bearing[0] = x0; newfont->Characters[c].Bearing[1] = y0*-1; + newfont->Characters[c].rect = r; } return newfont; } +static int curchar = 0; + void sdrawCharacter(struct Character c, mfloat_t cursor[2], float scale, struct shader *shader, float color[3]) { float w = c.Size[0] * scale; @@ -119,58 +129,15 @@ void sdrawCharacter(struct Character c, mfloat_t cursor[2], float scale, struct float ypos = cursor[1] + (c.Bearing[1] * scale) - h; float verts[4 * 4] = { - xpos, ypos, 0.f, 0.f, - xpos+w, ypos, 1.f, 0.f, - xpos, ypos + h, 0.f, 1.f, - xpos + w, ypos + h, 1.f, 1.f + xpos, ypos, c.rect.s0, c.rect.t1, + xpos+w, ypos, c.rect.s1, c.rect.t1, + xpos, ypos + h, c.rect.s0, c.rect.t0, + xpos + w, ypos + h, c.rect.s1, c.rect.t0 }; - glBindTexture(GL_TEXTURE_2D, c.TextureID); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(verts), verts); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glBufferSubData(GL_ARRAY_BUFFER, curchar*sizeof(verts), sizeof(verts), verts); -////// Outline calculation - // float outlineWidth = 1.1; - - // float ow = c.Size[0] * scale * outlineWidth; - // float oh = c.Size[1] * scale * outlineWidth; - - // float oxpos = cursor[0] + c.Bearing[0] * scale * outlineWidth - ((ow-w)/2); - // float oypos = cursor[1] - (c.Size[1] - c.Bearing[1]) * scale * outlineWidth - ((oh-h)/2); - - // float overts[4*4] = { - // oxpos, oypos + oh, 0.f, 0.f, - // oxpos, oypos, 0.f, 1.f, - // oxpos + ow, oypos + oh, 1.f, 0.f, - // oxpos + ow, oypos, 1.f, 1.f - // }; - - -/////////// Shadow calculation - -/* - float shadowOffset = 6.f; - float sxpos = cursor[0] + c.Bearing[0] * scale + (scale * shadowOffset); - float sypos = cursor[1] - (c.Size[1] - c.Bearing[1]) * scale - (scale * shadowOffset); - - float sverts[4 * 4] = { - sxpos, sypos, 0.f, 0.f, - sxpos+w, sypos, 1.f, 0.f, - sxpos, sypos + h, 0.f, 1.f, - sxpos + w, sypos+h, 1.f, 1.f - }; - - - - - //// Shadow pass - - float black[3] = { 0, 0, 0 }; - shader_setvec3(shader, "textColor", black); - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(sverts), sverts); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - -*/ + curchar++; } void text_settype(struct sFont *mfont) @@ -183,17 +150,24 @@ void renderText(const char *text, mfloat_t pos[2], float scale, mfloat_t color[3 shader_use(shader); shader_setvec3(shader, "textColor", color); + int len = strlen(text); + mfloat_t cursor[2] = { 0.f }; cursor[0] = pos[0]; cursor[1] = pos[1]; glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, font->texID); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); + glBufferData(GL_ARRAY_BUFFER, len*16*sizeof(float), NULL, GL_STREAM_DRAW); const unsigned char *line, *wordstart; line = (unsigned char*)text; + curchar = 0; + + while (*line != '\0') { @@ -230,4 +204,6 @@ void renderText(const char *text, mfloat_t pos[2], float scale, mfloat_t color[3 } } } + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4*curchar); } diff --git a/source/engine/font.h b/source/engine/font.h index 6eac02b..bb98aeb 100644 --- a/source/engine/font.h +++ b/source/engine/font.h @@ -6,18 +6,26 @@ struct shader; struct window; +struct glrect { + float s0; + float s1; + float t0; + float t1; +}; + /// Holds all state information relevant to a character as loaded using FreeType struct Character { - uint32_t TextureID; // ID handle of the glyph texture mfloat_t Size[2]; // Size of glyph mfloat_t Bearing[2]; // Offset from baseline to left/top of glyph unsigned int Advance; // Horizontal offset to advance to next glyph + struct glrect rect; }; struct sFont { uint32_t fontTexture; uint32_t height; struct Character Characters[127]; + uint32_t texID; }; diff --git a/source/engine/gameobject.c b/source/engine/gameobject.c index c627e50..619cc83 100644 --- a/source/engine/gameobject.c +++ b/source/engine/gameobject.c @@ -131,7 +131,7 @@ int gameobject_makefromprefab(char *path) FILE *fprefab = fopen(path, "rb"); if (fprefab == NULL) { YughError("Could not find prefab %s.", path); - return; + return -1; } struct gameobject *new = get_gameobject_from_id(MakeGameobject()); @@ -142,6 +142,8 @@ int gameobject_makefromprefab(char *path) fclose(fprefab); + arrlast(gameobjects).editor.id = arrlen(gameobjects)-1; + return arrlen(gameobjects)-1; } diff --git a/source/engine/mrbffi.c b/source/engine/mrbffi.c index bb51e98..7e2d0c1 100644 --- a/source/engine/mrbffi.c +++ b/source/engine/mrbffi.c @@ -31,6 +31,8 @@ cpVect s7tovec2(s7_scheme *sc, s7_pointer s7vec) { return ret; } + + extern s7_scheme *s7; /* FFI */ @@ -330,6 +332,10 @@ s7_pointer s7_set_body(s7_scheme *sc, s7_pointer args) { case 3: gameobject_move(go, s7tovec2(sc, s7_caddr(args))); break; + + case 4: + cpBodyApplyImpulseAtWorldPoint(go->body, s7tovec2(sc, s7_caddr(args)), cpBodyGetPosition(go->body)); + break; } return args; @@ -456,7 +462,10 @@ s7_pointer s7_anim(s7_scheme *sc, s7_pointer args) { for (double i = 0; i < 3.0; i = i + 0.1) { YughInfo("Val is now %f at time %f", anim_val(a, i), i); + s7_symbol_set_value(sc, prop, s7_make_real(sc, anim_val(a, i))); } + + free_anim(a); } #define S7_FUNC(NAME, ARGS) s7_define_function(s7, #NAME, s7_ ##NAME, ARGS, 0, 0, "") diff --git a/source/engine/mrbffi.h b/source/engine/mrbffi.h index 8f5b584..21db301 100644 --- a/source/engine/mrbffi.h +++ b/source/engine/mrbffi.h @@ -3,4 +3,5 @@ void ffi_load(); + #endif diff --git a/source/engine/nuke.c b/source/engine/nuke.c index 5292a3f..ce6a483 100644 --- a/source/engine/nuke.c +++ b/source/engine/nuke.c @@ -117,6 +117,11 @@ void nuke_tree_pop() { } void nuke_labelf(const char *fmt, ...) { + char buf[512]; + va_list args; - nk_labelf(ctx, NK_TEXT_LEFT, fmt, args); + va_start(args, fmt); + vsnprintf(buf, 512, fmt, args); + nuke_label(buf); + va_end(args); } \ No newline at end of file diff --git a/source/engine/particle.c b/source/engine/particle.c new file mode 100644 index 0000000..f86cb84 --- /dev/null +++ b/source/engine/particle.c @@ -0,0 +1,55 @@ +#include "particle.h" + +struct emitter make_emitter() +{ + struct emitter e = { 0 }; + return e; +} + +struct emitter set_emitter(struct emitter e) +{ + arrsetlen(e.particles, e.max); + + e.first = &e.particles[0]; + + for (int i = 0; i < arrlen(e.particles)-1; i++) { + e.particles[i].next = &e.particles[i+1]; + } +} + +void free_emitter(struct emitter e) +{ + arrfree(e.particles); +} + +void start_emitter(struct emitter e) +{ + +} + +void pause_emitter(struct emitter e) +{ + +} + +void stop_emitter(struct emitter e) +{ + +} + +void emitter_step(struct emitter e, double dt) +{ + for (int i = 0; i < arrlen(e.particles); i++) { + if (e.particles[i].life <= 0) + continue; + + e.particles[i].pos = cpvadd(e.particles[i].pos, cpvmult(e.particles[i].v, dt)); + e.particles[i].angle += e.particles[i].av * dt; + e.particles[i].life -= dt; + + if (e.particles[i].life <= 0) { + e.particles[i].next = e.first; + e.first = &e.particles[i]; + } + } +} \ No newline at end of file diff --git a/source/engine/particle.h b/source/engine/particle.h new file mode 100644 index 0000000..de2c785 --- /dev/null +++ b/source/engine/particle.h @@ -0,0 +1,36 @@ +#ifndef PARTICLE_H +#define PARTICLE_H + +#include + +struct particle { + cpVect pos; + cpVect v; /* velocity */ + double angle; + double av; /* angular velocity */ + + + union { + double life; + struct particle *next; + }; +}; + +struct emitter { + struct particle *particles; + struct particle *first; + int max; + double life; + void (*seeder)(struct particle *p); /* Called to initialize each particle */ +}; + +struct emitter make_emitter(); +void free_emitter(struct emitter e); + +void start_emitter(struct emitter e); +void pause_emitter(struct emitter e); +void stop_emitter(struct emitter e); + +void emitter_step(struct emitter e, double dt); + +#endif \ No newline at end of file diff --git a/source/engine/script.c b/source/engine/script.c index 24c374f..d87c837 100644 --- a/source/engine/script.c +++ b/source/engine/script.c @@ -9,7 +9,13 @@ s7_scheme *s7 = NULL; +s7_pointer cpvec2s7(cpVect v) { + s7_pointer ret = s7_make_vector(s7, 2); + s7_vector_set(s7, ret, 0, s7_make_real(s7, v.x)); + s7_vector_set(s7, ret, 1, s7_make_real(s7, v.y)); + return ret; +} static void null_port(s7_scheme *sc, uint8_t c, s7_pointer port) { diff --git a/source/engine/script.h b/source/engine/script.h index 0a6a74e..a693cdc 100644 --- a/source/engine/script.h +++ b/source/engine/script.h @@ -2,6 +2,7 @@ #define SCRIPT_H #include "s7.h" +#include extern s7_scheme *s7; @@ -26,4 +27,6 @@ void call_gui(); void register_physics(s7_pointer sym); void call_physics(double dt); +s7_pointer cpvec2s7(cpVect v); + #endif diff --git a/source/engine/shader.c b/source/engine/shader.c index f7767a1..76768fb 100644 --- a/source/engine/shader.c +++ b/source/engine/shader.c @@ -168,5 +168,6 @@ void shader_setUBO(struct shader *shader, const char *name, unsigned int index) void shader_compile_all() { - arrwalk(shaders, shader_compile); + for (int i = 0; i < arrlen(shaders); i++) + shader_compile(&shaders[i]); } diff --git a/source/engine/sprite.c b/source/engine/sprite.c index d4e6e42..42937fa 100644 --- a/source/engine/sprite.c +++ b/source/engine/sprite.c @@ -115,8 +115,8 @@ void sprite_initialize() float vertices[] = { // pos 0.f, 0.f, - 1.0f, 0.0f, - 0.f, 1.f, + 0.0f, 1.0f, + 1.f, 0.f, 1.f, 1.f }; diff --git a/source/engine/texture.c b/source/engine/texture.c index c395c68..d06729f 100644 --- a/source/engine/texture.c +++ b/source/engine/texture.c @@ -29,7 +29,7 @@ struct Texture *texture_pullfromfile(const char *path) tex->anim.ms = 1; int n; - stbi_set_flip_vertically_on_load(1); + stbi_set_flip_vertically_on_load(0); unsigned char *data = stbi_load(path, &tex->width, &tex->height, &n, 4); while (data == NULL) { diff --git a/source/engine/timer.c b/source/engine/timer.c index 040daa9..5a3431e 100644 --- a/source/engine/timer.c +++ b/source/engine/timer.c @@ -3,20 +3,20 @@ #include -static double time; - struct timer *timers; -void check_timer(struct timer *t) +void check_timer(struct timer *t, double dt) { if (!t->on) return; - if (time >= t->fire_time) { + t->remain_time -= dt; + + if (t->remain_time <= 0) { t->cb(t->data); if (t->repeat) { - t->fire_time = time + t->interval; + t->remain_time = t->interval; return; } @@ -25,13 +25,9 @@ void check_timer(struct timer *t) } } -void timer_update(double s) { - time = s; - - +void timer_update(double dt) { for (int i = 0; i < arrlen(timers); i++) - check_timer(&timers[i]); - + check_timer(&timers[i], dt); } struct timer *timer_make(double interval, void (*callback)(void *param), void *param) { @@ -53,8 +49,6 @@ void timer_pause(struct timer *t) { if (!t->on) return; t->on = 0; - - t->remain_time = t->fire_time - time; } void timer_stop(struct timer *t) { @@ -68,7 +62,6 @@ void timer_start(struct timer *t) { if (t->on) return; t->on = 1; - t->fire_time = time + t->remain_time; } void timer_remove(struct timer *t) { @@ -78,25 +71,6 @@ void timer_remove(struct timer *t) { } void timerr_settime(struct timer *t, double interval) { - //double elapsed = time - (t->fire_time - t->interval); + t->remain_time += (interval - t->interval); t->interval = interval; - t->remain_time = t->interval; - - // TODO: timerr_settime reacts to elapsed time -} - -void *arrfind(void *arr, int (*valid)(void *arr, void *cmp), void *cmp) -{ - for (int i = 0; i < arrlen(arr); i++) { - if (valid(&arr[i], cmp)) - return &arr[i]; - } - - return NULL; -} - -void arrwalk(void *arr, void (*fn)(void *data)) -{ - for (int i = 0; i < arrlen(arr); i++) - fn(&arr[i]); -} +} \ No newline at end of file diff --git a/source/engine/timer.h b/source/engine/timer.h index 71364a1..4be7560 100644 --- a/source/engine/timer.h +++ b/source/engine/timer.h @@ -4,9 +4,7 @@ struct timer { int timerid; int on; - double fire_time; // Time the timer will fire double interval; // Time of timer - double start_time; // Time the timer started this loop int repeat; double remain_time; // How much time until the timer executes void (*cb)(void *data); @@ -18,13 +16,7 @@ void timer_remove(struct timer *t); void timer_start(struct timer *t); void timer_pause(struct timer *t); void timer_stop(struct timer *t); -void timer_update(double s); +void timer_update(double dt); void timerr_settime(struct timer *t, double interval); - - - -void *arrfind(void *arr, int (*valid)(void *arr, void *cmp), void *cmp); -void arrwalk(void *arr, void (*fn)(void *data)); - #endif diff --git a/source/engine/window.c b/source/engine/window.c index bdbe1fe..cb46412 100644 --- a/source/engine/window.c +++ b/source/engine/window.c @@ -213,7 +213,8 @@ void window_handle_event(struct window *w) void window_all_handle_events() { - arrwalk(windows, window_handle_event); + for (int i = 0; i < arrlen(windows); i++) + window_handle_event(&windows[i]); } void window_makefullscreen(struct window *w) diff --git a/source/engine/yugine.c b/source/engine/yugine.c index 11f9bd2..0575919 100644 --- a/source/engine/yugine.c +++ b/source/engine/yugine.c @@ -174,7 +174,7 @@ int main(int argc, char **args) { lastTick = glfwGetTime(); - timer_update(lastTick); + timer_update(elapsed); if (sim_play) { physlag += elapsed; diff --git a/source/scripts/engine.scm b/source/scripts/engine.scm index c0af8c5..be4da42 100644 --- a/source/scripts/engine.scm +++ b/source/scripts/engine.scm @@ -124,7 +124,7 @@ (define-macro (register-phys type . expr) (let ((f (gensym))) `(begin - (define (,f hit) (begin . ,expr)) + (define (,f hit norm) (begin . ,expr)) (phys_cmd body ,(case type ((collide) 0) ((separate) 3)) ,f)))) diff --git a/source/shaders/spritevert.glsl b/source/shaders/spritevert.glsl index ad9714b..064e57a 100644 --- a/source/shaders/spritevert.glsl +++ b/source/shaders/spritevert.glsl @@ -12,5 +12,6 @@ uniform mat4 model; void main() { texcoords = vertex.xy; + texcoords.y *= -1; gl_Position = projection * model * vec4(vertex.xy, 0.0, 1.0); } \ No newline at end of file diff --git a/source/shaders/textvert.glsl b/source/shaders/textvert.glsl index e242a9e..5593ff5 100644 --- a/source/shaders/textvert.glsl +++ b/source/shaders/textvert.glsl @@ -10,5 +10,5 @@ layout (std140) uniform Projection void main() { gl_Position = projection * vec4(vertex.xy, 0.0, 1.0); - TexCoords = vec2(vertex.z, 1.0 - vertex.w); + TexCoords = vertex.zw; } \ No newline at end of file