From 07b70f93df5b60dd00121753602cae7aca72a376 Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: Mar 14 2020 13:31:45 +0000 Subject: another one --- diff --git a/SConstruct b/SConstruct index cf81332..cdb88f5 100644 --- a/SConstruct +++ b/SConstruct @@ -1,3 +1,3 @@ build_dir = ARGUMENTS.get('build_dir', 'build') -VariantDir(build_dir, 'src', duplicate = 0) +VariantDir(build_dir, 'heliantus', duplicate = 0) SConscript(build_dir + '/SConstruct') diff --git a/heliantus/SConstruct b/heliantus/SConstruct index 51fc8ab..dd00490 100644 --- a/heliantus/SConstruct +++ b/heliantus/SConstruct @@ -4,19 +4,27 @@ env = Environment() # config -libs = [] +libs = ['gtk+-3.0', 'glib-2.0', 'cairo'] # compute build options -flags = ' -O0 -g -Wall -fmessage-length=0 ' +flags = ' -O0 -g -lm -Wall -fmessage-length=0 ' # files lists -target = 'cblocks' +target = 'heliantus' sources = [ + 'animation.c', + 'array.c', + 'collider.c', + 'common.c', + 'drawing.c', + 'group.c', + 'sprite.c', + 'world.c', 'main.c' ] diff --git a/heliantus/animation.c b/heliantus/animation.c index 3f897d4..acccf36 100644 --- a/heliantus/animation.c +++ b/heliantus/animation.c @@ -15,7 +15,7 @@ static cairo_status_t read(void *closure, unsigned char *data, unsigned int leng static cairo_surface_t* loadFrame(const char *path) { if (!heliStringEndsWithLowcase(path, ".png")) return NULL; - FILE *f = g_fopen(path); + FILE *f = fopen(path, "rb"); if (f) { cairo_surface_t *frame = cairo_image_surface_create_from_png_stream(&read, f); fclose(f); @@ -71,3 +71,6 @@ HeliAnimation *heliCreateAnimation(const char *path) { void heliAnimationUnref(HeliAnimation *a) { if (--a->refcount <= 0) heliStringmapRemove(&cache, a->path); } +void heliAnimationFinish() + { heliArrayDestroy(&cache); } + diff --git a/heliantus/animation.o b/heliantus/animation.o new file mode 100644 index 0000000..7dc4094 Binary files /dev/null and b/heliantus/animation.o differ diff --git a/heliantus/array.c b/heliantus/array.c index b15c1b7..707e313 100644 --- a/heliantus/array.c +++ b/heliantus/array.c @@ -13,12 +13,12 @@ void heliPairDestroy(HeliPair *p) { heliPairInit(p); } -int heliArrayInit(HeliArray *a) { +void heliArrayInit(HeliArray *a) { a->items = NULL; a->count = a->allocated = 0; } -int heliArrayDestroy(HeliArray *a) { +void heliArrayDestroy(HeliArray *a) { heliArrayClear(a); free(a->items); heliArrayInit(a); @@ -42,7 +42,7 @@ HeliPair* heliArrayInsertPair(HeliArray *a, int i, void *k, void *v, HeliFreeCal i = a->count; if (a->allocated < a->count + 1) { a->allocated += a->allocated/4 + 32; - a->items = realloc(a->items, a->allocated); + a->items = realloc(a->items, a->allocated*sizeof(a->items[0])); memset(&a->items[a->count], 0, (a->allocated - a->count)*sizeof(a->items[0])); } if (i < a->count) { diff --git a/heliantus/array.o b/heliantus/array.o new file mode 100644 index 0000000..e83e4bc Binary files /dev/null and b/heliantus/array.o differ diff --git a/heliantus/collider.o b/heliantus/collider.o new file mode 100644 index 0000000..ed4d15b Binary files /dev/null and b/heliantus/collider.o differ diff --git a/heliantus/common.c b/heliantus/common.c index fbbb68d..7020b40 100644 --- a/heliantus/common.c +++ b/heliantus/common.c @@ -45,6 +45,6 @@ void heliLowercase(char *x) { while(*x) *x = tolower(*x); } void heliParseColor(const char *x, double *color) { - #error + #warning "TODO: heliParseColor: not implemented yet" } diff --git a/heliantus/drawing.c b/heliantus/drawing.c new file mode 100644 index 0000000..89cf385 --- /dev/null +++ b/heliantus/drawing.c @@ -0,0 +1,195 @@ + +#include + +#include "private.h" +#include "drawing.h" + +static double colorBack[4] = {1, 1, 1, 1}; +static double colorFill[4] = {0.5, 0.5, 0.5, 1}; +static double colorStroke[4] = {0, 0, 0, 1}; +static double lineWidth = 1; +static double *path; +static size_t pathSize; +static size_t pathAllocated; + +static HAlign horAlign = HALIGN_LEFT; +static VAlign vertAlign = VALIGN_TOP; +static char *font; +static double fontSize = 24; + + +void background(const char *color) + { heliParseColor(color, colorBack); } +void fill(const char *color) + { heliParseColor(color, colorFill); } +void noFill() + { fill("transparent"); } +void stroke(const char *color) + { heliParseColor(color, colorStroke); } +void noStroke() + { stroke("transparent"); } + +void strokeWeight(double weight) + { lineWidth = weight; } + +char* rgba(double r, double g, double b, double a) { + static char buf[1024]; + snprintf(buf, sizeof(buf) - 1, "%f %f %f %f", r, g, b, a); + return buf; +} + +char* rgb(double r, double g, double b) + { return rgba(r, g, b, 1); } + +void rect(double x, double y, double width, double height) { + resetPath(); + moveTo(x, y); + lineTo(x + width, y); + lineTo(x + width, y + height); + lineTo(x, y + height); + closePath(); +} + +void line(double x1, double y1, double x2, double y2) { + resetPath(); + moveTo(x1, y1); + lineTo(x2, y2); + strokePath(); +} + +void ellipse(double x, double y, double width, double height) { + resetPath(); + arcPath(x, y, width, height, 0, 360); + closePath(); +} + +void point(double x, double y) + { ellipse(x - lineWidth*0.25, y - lineWidth*0.25, lineWidth*0.5, lineWidth*0.5); } + +void arcPath(double x, double y, double w, double h, double start, double stop) { + double step = PI/180; + start *= PI/180; + stop *= PI/180; + if (start < stop) { double s = start; stop = start; start = s; } + for(double a = start; a < stop; a += step) { + double lx = x + cos(a)*w; + double ly = y + sin(a)*h; + lineTo(lx, ly); + } +} + +void arc(double x, double y, double w, double h, double start, double stop) { + resetPath(); + arcPath(x, y, w, h, start, stop); + strokePath(); +} + +void regularPolygon(double x, double y, int sides, double size) { + resetPath(); + size *= 0.5; + moveTo(x + size, y); + for(int i = 1; i < sides; ++i) { + double a = i*PI/sides; + lineTo(x + size*cos(a), y + size*sin(a)); + } + closePath(); +} + + +void resetPath() + { pathSize = 0; } + +static void endPath(int close, int stroke, int fill) { + cairo_t *cr = heliCairo; + if (cr && pathSize >= 8) { + cairo_save(cr); + cairo_move_to(cr, path[0], path[1]); + for(int i = 2; i < pathSize; i += 2) + cairo_line_to(cr, path[i], path[i+1]); + if (close) + cairo_close_path(cr); + if (fill) { + cairo_set_source_rgba(cr, colorFill[0], colorFill[1], colorFill[2], colorFill[3]); + if (stroke) cairo_fill_preserve(cr); else cairo_fill(cr); + } + if (stroke) { + cairo_set_line_width(cr, lineWidth); + cairo_set_source_rgba(cr, colorStroke[0], colorStroke[1], colorStroke[2], colorStroke[3]); + cairo_stroke(cr); + } + cairo_restore(cr); + } + resetPath(); +} + +static void pushPathPoint(double x, double y) { + if (pathAllocated < pathSize + 2) { + pathAllocated += pathAllocated/4 + 32; + path = realloc(path, pathAllocated); + memset(&path[pathSize], 0, (pathAllocated - pathSize)*sizeof(*path)); + } + path[pathSize++] = x; + path[pathSize++] = y; +} + +void closePath() + { endPath(TRUE, TRUE, TRUE); } +void strokePath() + { endPath(FALSE, TRUE, FALSE); } +void lineTo(double x, double y) + { pushPathPoint(x, y); } +void moveTo(double x, double y) + { resetPath(); lineTo(x, y); } + + +void textAlign(HAlign hor, VAlign vert) + { horAlign = hor; vertAlign = vert; } +void textFont(const char *f) + { free(font); font = heliStringCopy(f); } +void textSize(double size) + { fontSize = size; } + +void text(const char *text, double x, double y) { + resetPath(); + + cairo_t *cr = heliCairo; + if (!cr) return; + cairo_save(cr); + + if (font) cairo_select_font_face(cr, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); + cairo_set_font_size(cr, fontSize); + + cairo_text_extents_t extents; + cairo_text_extents(cr, text, &extents); + double w = extents.x_bearing + extents.width; + double h = extents.y_bearing + extents.height; + if (horAlign == HALIGN_CENTER) x -= w*0.5; + if (horAlign == HALIGN_RIGHT ) x -= w; + if (vertAlign == VALIGN_CENTER) y -= h*0.5; + if (vertAlign == VALIGN_BOTTOM) y -= h; + + cairo_set_source_rgba(cr, colorStroke[0], colorStroke[1], colorStroke[2], colorStroke[3]); + cairo_move_to(cr, x, y); + cairo_show_text(cr, text); + + cairo_restore(cr); +} + +void heliDrawingPrepareFrame() { + resetPath(); + cairo_t *cr = heliCairo; + if (!cr) return; + cairo_save(cr); + cairo_set_source_rgba(cr, colorBack[0], colorBack[1], colorBack[2], 1); + cairo_paint(cr); + cairo_restore(cr); +} + +void heliDrawingFinish() { + resetPath(); + free(path); + path = NULL; + pathAllocated = 0; + free(font); + font = NULL; +} diff --git a/heliantus/drawing.h b/heliantus/drawing.h index 9f493f8..3fa6f4a 100644 --- a/heliantus/drawing.h +++ b/heliantus/drawing.h @@ -28,16 +28,20 @@ char* rgba(double r, double g, double b, double a); void rect(double x, double y, double width, double height); void ellipse(double x, double y, double width, double height); void text(const char *text, double x, double y); -void textEx(const char *text, double x, double y, double x2, double y2); void textAlign(HAlign hor, VAlign vert); void textFont(const char *font); void textSize(double size); void arc(double x, double y, double w, double h, double start, double stop); -void line(double x1, double y1, double x1, double y1); +void arcPath(double x, double y, double w, double h, double start, double stop); +void line(double x1, double y1, double x2, double y2); void point(double x, double y); void regularPolygon(double x, double y, int sides, double size); + void moveTo(double x, double y); void lineTo(double x, double y); +void resetPath(); +void closePath(); +void strokePath(); #endif diff --git a/heliantus/group.c b/heliantus/group.c index b55f676..400bffd 100644 --- a/heliantus/group.c +++ b/heliantus/group.c @@ -85,7 +85,7 @@ int groupContains(Group group, Sprite sprite) { int groupGetCount(Group group) { return group->sprites.count; } Sprite groupGet(Group group, int i) - { return (Sprite)heliArrayGetValue(group, i); } + { return (Sprite)heliArrayGetValue(&group->sprites, i); } int groupOverlap(Group group, Sprite sprite) { return groupCollideEx(group, sprite, TRUE, TRUE, 0); } @@ -93,24 +93,30 @@ int groupCollide(Group group, Sprite sprite, double bounciness) { return groupCollideEx(group, sprite, FALSE, FALSE, bounciness); } int groupBounceOff(Group group, Sprite sprite, double bounciness) { return groupCollideEx(group, sprite, FALSE, TRUE, bounciness); } -int groupPush(Group group, Sprite sprite, double bounciness); +int groupPush(Group group, Sprite sprite, double bounciness) { return groupCollideEx(group, sprite, TRUE, FALSE, bounciness); } int groupCollideEx(Group group, Sprite sprite, int keepVelocityGroup, int keepVelocitySprite, double bounciness) { + int result = FALSE; for(int i = 0; i < groupGetCount(group); ++i) - spriteCollideEx(groupGet(group, i), sprite, keepVelocityGroup, keepVelocitySprite, bounciness); + if (spriteCollideEx(groupGet(group, i), sprite, keepVelocityGroup, keepVelocitySprite, bounciness)) + result = TRUE; + return result; } -int groupOverlapGroup(Group a, Group b); +int groupOverlapGroup(Group a, Group b) { return groupCollideGroupEx(a, b, TRUE, TRUE, 0); } -int groupCollideGroup(Group a, Group b, double bounciness); +int groupCollideGroup(Group a, Group b, double bounciness) { return groupCollideGroupEx(a, b, FALSE, FALSE, bounciness); } -int groupBounceOffGroup(Group group, Group other, double bounciness); - { return groupCollideGroupEx(a, b, FALSE, TRUE, bounciness); } -int groupPushGroup(Group group, Group other, double bounciness); - { return groupCollideGroupEx(a, b, TRUE, FALSE, bounciness); } +int groupBounceOffGroup(Group group, Group other, double bounciness) + { return groupCollideGroupEx(group, other, FALSE, TRUE, bounciness); } +int groupPushGroup(Group group, Group other, double bounciness) + { return groupCollideGroupEx(group, other, TRUE, FALSE, bounciness); } int groupCollideGroupEx(Group a, Group b, int keepVelocityA, int keepVelocityB, double bounciness) { + int result = FALSE; for(int i = 0; i < groupGetCount(b); ++i) - groupCollideEx(a, groupGet(b, i), keepVelocityA, keepVelocityB, bounciness); + if (groupCollideEx(a, groupGet(b, i), keepVelocityA, keepVelocityB, bounciness)) + result = TRUE; + return result; } double groupGetMinDepth(Group group) { @@ -134,11 +140,11 @@ double groupGetMaxDepth(Group group) { } -static void foreachInt(Group group, int value, void(*func)(Sprite, int)) +static void foreachInt(Group group, int value, HeliSpriteEashInt func) { for(int i = 0; i < groupGetCount(group); ++i) func(groupGet(group, i), value); } -static void foreachDouble(Group group, double value, void(*func)(Sprite, double)) +static void foreachDouble(Group group, double value, HeliSpriteEashDouble func) { for(int i = 0; i < groupGetCount(group); ++i) func(groupGet(group, i), value); } -static void foreachString(Group group, const char *value, void(*func)(Sprite, const char*)) +static void foreachString(Group group, const char *value, HeliSpriteEashString func) { for(int i = 0; i < groupGetCount(group); ++i) func(groupGet(group, i), value); } @@ -177,24 +183,24 @@ void groupSetTintColorEach(Group group, const char *color) { foreachString(group, color, &spriteSetTintColor); } void groupPointToEach(Group group, double x, double y) { - for(int i = 0; i < groupGetCount(b); ++i) + for(int i = 0; i < groupGetCount(group); ++i) spritePointTo(groupGet(group, i), x, y); } void groupSetSpeedAndDirectionEach(Group group, double speed, double angle) { - for(int i = 0; i < groupGetCount(b); ++i) + for(int i = 0; i < groupGetCount(group); ++i) spriteSetSpeedAndDirection(groupGet(group, i), speed, angle); } void groupSetVelocityEach(Group group, double x, double y) { - for(int i = 0; i < groupGetCount(b); ++i) + for(int i = 0; i < groupGetCount(group); ++i) spriteSetVelocityXY(groupGet(group, i), x, y); } void groupSetColliderEachEx(Group group, Collider type, double xOffset, double yOffset, double widthOrRadius, double height, double rotationOffset) { - for(int i = 0; i < groupGetCount(b); ++i) + for(int i = 0; i < groupGetCount(group); ++i) spriteSetColliderEx(groupGet(group, i), type, xOffset, yOffset, widthOrRadius, height, rotationOffset); } diff --git a/heliantus/heliantus.h b/heliantus/heliantus.h new file mode 100644 index 0000000..9288436 --- /dev/null +++ b/heliantus/heliantus.h @@ -0,0 +1,12 @@ +#ifndef HELI_HELIANTUS_H +#define HELI_HELIANTUS_H + + +#include "common.h" +#include "world.h" +#include "sprite.h" +#include "group.h" +#include "drawing.h" + + +#endif diff --git a/heliantus/main.c b/heliantus/main.c index 1a77d87..5a34848 100644 --- a/heliantus/main.c +++ b/heliantus/main.c @@ -1,5 +1,5 @@ -#include +#include "heliantus.h" void init() { } diff --git a/heliantus/private.h b/heliantus/private.h index 4e98887..9949c2d 100644 --- a/heliantus/private.h +++ b/heliantus/private.h @@ -45,9 +45,9 @@ typedef struct _HeliArray { void heliPairInit(HeliPair *p); void heliPairDestroy(HeliPair *p); -int heliArrayInit(HeliArray *a); +void heliArrayInit(HeliArray *a); void heliArrayClear(HeliArray *a); -int heliArrayDestroy(HeliArray *a); +void heliArrayDestroy(HeliArray *a); HeliPair* heliArrayGet(HeliArray *a, int i); void* heliArrayGetKey(HeliArray *a, int i); void* heliArrayGetValue(HeliArray *a, int i); @@ -71,6 +71,7 @@ typedef struct _HeliAnimation { HeliAnimation *heliCreateAnimation(const char *path); void heliAnimationUnref(HeliAnimation *a); +void heliAnimationFinish(); // collider @@ -91,6 +92,15 @@ int heliPointCollision(HeliCollider *c, double x, double y); // sprite -void heliUpdateSprites(double dt); +typedef void (*HeliSpriteEashInt)(Sprite, int); +typedef void (*HeliSpriteEashDouble)(Sprite, double); +typedef void (*HeliSpriteEashString)(Sprite, const char*); HeliArray* heliSpriteGetGroups(Sprite sprite); +void heliSpriteUpdate(double dt); +void heliSpriteFinish(); + +// drawing + +void heliDrawingPrepareFrame(); +void heliDrawingFinish(); diff --git a/heliantus/sprite.c b/heliantus/sprite.c index af8a7fa..69c579a 100644 --- a/heliantus/sprite.c +++ b/heliantus/sprite.c @@ -79,6 +79,8 @@ Sprite createSpriteEx(double x, double y, double width, double height) { heliArrayInsert(&sprites, -1, s, NULL); heliArrayInsert(&spritesSorted, -1, s, NULL); + + return s; } Sprite createSprite(double x, double y) @@ -151,7 +153,7 @@ void spriteSetMirrorX(Sprite sprite, int mirrorX) { sprite->mirrorX = mirrorX < 0 ? -1 : 1; } int spriteGetMirrorY(Sprite sprite) { return sprite->mirrorY; } -void spriteSetMirrorY(Sprite sprite, int mirrorY); +void spriteSetMirrorY(Sprite sprite, int mirrorY) { sprite->mirrorY = mirrorY < 0 ? -1 : 1; } double spriteGetDepth(Sprite sprite) { return sprite->depth; } @@ -251,7 +253,7 @@ double spriteGetScaledHeight(Sprite sprite) int worldGetSpriteCount() { return sprites.count; } -Sprite worldGetSprite(int i) { +Sprite worldGetSprite(int i) { return (Sprite)heliArrayGetValue(&sprites, i); } @@ -269,13 +271,13 @@ static void drawSpriteDebug(cairo_t *cr, Sprite s) { cairo_line_to(cr, hw, hh); cairo_line_to(cr, -hw, hh); cairo_close_path(cr); - cairo_stroke(); + cairo_stroke(cr); cairo_move_to(cr, -hw*0.25, 0); cairo_line_to(cr, hw*0.25, 0); cairo_move_to(cr, 0, -hh*0.25); cairo_line_to(cr, 0, hh*0.25); - cairo_stroke(); + cairo_stroke(cr); char buf[1024]; snprintf(buf, sizeof(buf)-1, "%f", s->depth); @@ -320,7 +322,7 @@ static void drawSprite(cairo_t *cr, Sprite s) { cairo_line_to(cr, hw, hh); cairo_line_to(cr, -hw, hh); cairo_close_path(cr); - cairo_fill(); + cairo_fill(cr); } // tint @@ -332,11 +334,11 @@ static void drawSprite(cairo_t *cr, Sprite s) { cairo_line_to(cr, hw, hh); cairo_line_to(cr, -hw, hh); cairo_close_path(cr); - cairo_fill(); + cairo_fill(cr); cairo_restore(cr); cairo_pop_group_to_source(cr); - cairo_paint(); + cairo_paint(cr); cairo_restore(cr); } @@ -347,35 +349,39 @@ void drawSprites() { while(found) { found = FALSE; // forward - for(int i = 1; i < sortedSprites.count; ++i) { - if (((Sprite)sortedSprites.items[i-1])->depth < ((Sprite)sortedSprites.items[i])->depth) { - void *x = sortedSprites.items[i]; - sortedSprites.items[i] = sortedSprites.items[i-1]; - sortedSprites.items[i-1] = x; + for(int i = 1; i < spritesSorted.count; ++i) { + if ( ((Sprite)spritesSorted.items[i-1].value)->depth + < ((Sprite)spritesSorted.items[i ].value)->depth ) + { + void *x = spritesSorted.items[i].value; + spritesSorted.items[i].value = spritesSorted.items[i-1].value; + spritesSorted.items[i-1].value = x; found = TRUE; } } if (!found) break; // backward found = FALSE; - for(int i = sortedSprites.count - 1; i > 0; --i) { - if (((Sprite)sortedSprites.items[i-1])->depth < ((Sprite)sortedSprites.items[i])->depth) { - void *x = sortedSprites.items[i]; - sortedSprites.items[i] = sortedSprites.items[i-1]; - sortedSprites.items[i-1] = x; + for(int i = spritesSorted.count - 1; i > 0; --i) { + if ( ((Sprite)spritesSorted.items[i-1].value)->depth + < ((Sprite)spritesSorted.items[i ].value)->depth ) + { + void *x = spritesSorted.items[i].value; + spritesSorted.items[i].value = spritesSorted.items[i-1].value; + spritesSorted.items[i-1].value = x; + found = TRUE; } - found = TRUE; } } // draw if (heliCairo) { - for(int i = 0; i < sortedSprites.count; ++i) { - Sprite s = (Sprite)(sortedSprites.items[i]); + for(int i = 0; i < spritesSorted.count; ++i) { + Sprite s = (Sprite)(spritesSorted.items[i].value); if (s->visible) drawSprite(heliCairo, s); } - for(int i = 0; i < sortedSprites.count; ++i) { - Sprite s = (Sprite)(sortedSprites.items[i]); + for(int i = 0; i < spritesSorted.count; ++i) { + Sprite s = (Sprite)(spritesSorted.items[i].value); if (s->debug) drawSpriteDebug(heliCairo, s); } } @@ -384,12 +390,13 @@ void drawSprites() { int mouseIsOver(Sprite sprite) { HeliCollider collider; prepareCollider(sprite, &collider); - heliPointCollision(&collider, mouseX(), mouseY()); + return heliPointCollision(&collider, mouseX(), mouseY()); } -void heliUpdateSprites(double dt) { +void heliSpriteUpdate(double dt) { // auto-remove for(int i = sprites.count - 1; i > 0; --i) { + Sprite s = (Sprite)sprites.items[i].value; if (s->lifeTime >= 0) { s->lifeTime -= dt; if (s->lifeTime <= 1e-5) @@ -410,3 +417,12 @@ void heliUpdateSprites(double dt) { HeliArray* heliSpriteGetGroups(Sprite sprite) { return &sprite->groups; } + +void heliSpriteFinish() { + while(worldGetSpriteCount()) + { spriteDestroy(worldGetSprite(0)); } + heliArrayDestroy(&sprites); + heliArrayDestroy(&spritesSorted); +} + + diff --git a/heliantus/world.c b/heliantus/world.c index 14b766c..2bbc96a 100644 --- a/heliantus/world.c +++ b/heliantus/world.c @@ -58,9 +58,9 @@ void stopSound(const char *path) { int keyDown(const char *code) { return heliStringmapGet(&keysPressed, code) != NULL; } -int keyWentDown(const char *code); +int keyWentDown(const char *code) { return heliStringmapGet(&keysPressedInFrame, code) != NULL; } -int keyWentUp(const char *code); +int keyWentUp(const char *code) { return heliStringmapGet(&keysReleasedInFrame, code) != NULL; } int mouseDidMove() @@ -86,7 +86,7 @@ void worldSetWidth(int w) { if (started) gtk_widget_set_size_request(window, width, height); } -int worldGetHeight(); +int worldGetHeight() { return height; } void worldSetHeight(int h) { height = h; @@ -163,6 +163,7 @@ static gboolean draw(GtkWidget *widget G_GNUC_UNUSED, cairo_t *cr, gpointer data if (!frameCount) { startTime = currentTime = newTime; if (initCallback) initCallback(); + heliDrawingPrepareFrame(); if (drawCallback) drawCallback(); heliArrayClear(&keysPressedInFrame); heliArrayClear(&keysReleasedInFrame); @@ -175,7 +176,8 @@ static gboolean draw(GtkWidget *widget G_GNUC_UNUSED, cairo_t *cr, gpointer data while(currentTime < newTime) { currentTime += timeStep; ++frameCount; - heliUpdateSprites(dt); + heliSpriteUpdate(dt); + heliDrawingPrepareFrame(); if (drawCallback) drawCallback(); heliArrayClear(&keysPressedInFrame); heliArrayClear(&keysReleasedInFrame); @@ -265,8 +267,9 @@ void worldRun() { g_application_run(G_APPLICATION(application), 0, NULL); g_object_unref(application); - while(worldGetSpriteCount()) - { spriteDestroy(worldGetSprite(0)); } + heliSpriteFinish(); + heliDrawingFinish(); + heliAnimationFinish(); heliArrayDestroy(&keysPressed); heliArrayDestroy(&keysPressed);