From 501a59933635ff1fbf9ede03c00e4118df1335e6 Mon Sep 17 00:00:00 2001 From: En Yi Date: Mon, 6 May 2024 21:18:03 +0800 Subject: [PATCH] Allow multi-rows sprites framing Internal Changelog: - Add a new field to store frames per row for a sprite - Update sprite drawing function to bound check - Update assets loader to look for the new field - Refactor adding a sprite function to reduce repetition - Update all main programs --- assets_test.c | 1 + engine/EC.h | 5 ++-- engine/assets.c | 13 +++++++--- particle_test.c | 3 ++- scenes/assets_loader.c | 57 +++++++++++++++++++++--------------------- 5 files changed, 44 insertions(+), 35 deletions(-) diff --git a/assets_test.c b/assets_test.c index 4ddfacf..0cb15dc 100644 --- a/assets_test.c +++ b/assets_test.c @@ -22,6 +22,7 @@ int main(void) add_sprite(&assets, "testspr2", tex); Sprite_t* spr2 = get_sprite(&assets, "testspr2"); spr2->frame_count = 4; + spr2->frame_per_row = 4; spr2->origin = (Vector2){0, 0}; spr2->frame_size = (Vector2){32, 32}; spr2->speed = 15; diff --git a/engine/EC.h b/engine/EC.h index 3339ee0..ca966e2 100644 --- a/engine/EC.h +++ b/engine/EC.h @@ -183,8 +183,9 @@ typedef struct _CWaterRunner { typedef struct Sprite { Texture2D* texture; Vector2 frame_size; - Vector2 origin; - Vector2 anchor; + Vector2 origin; // TL of the frame + Vector2 anchor; // Where transformation anchors on + uint8_t frame_per_row; int frame_count; int speed; char* name; diff --git a/engine/assets.c b/engine/assets.c index a06d754..a8eb624 100644 --- a/engine/assets.c +++ b/engine/assets.c @@ -538,11 +538,16 @@ void draw_sprite(Sprite_t* spr, int frame_num, Vector2 pos, float rotation, bool void draw_sprite_pro(Sprite_t* spr, int frame_num, Vector2 pos, float rotation, uint8_t flip, Vector2 scale, Color colour) { - if (frame_num >= spr->frame_count) frame_num = spr->frame_count - 1; - if (frame_num < 0) frame_num = 0; + // Rollover behaviour + if (frame_num >= spr->frame_count) frame_num %= spr->frame_count; + + if (frame_num < 0) frame_num += spr->frame_count; + + int r = frame_num / spr->frame_per_row; + int c = frame_num % spr->frame_per_row; Rectangle rec = { - spr->origin.x + spr->frame_size.x * frame_num, - spr->origin.y, + spr->origin.x + spr->frame_size.x * c, + spr->origin.y + spr->frame_size.y * r, spr->frame_size.x * ((flip & 1) ? -1 : 1), spr->frame_size.y * ((flip & 2) ? -1 : 1), }; diff --git a/particle_test.c b/particle_test.c index d72a8b2..bd9b1dd 100644 --- a/particle_test.c +++ b/particle_test.c @@ -62,7 +62,8 @@ int main(void) .frame_size = (Vector2){tex.width, tex.height}, .origin = (Vector2){0, 0}, .anchor = (Vector2){tex.width / 2, tex.height / 2}, - .frame_count = 0, + .frame_count = 1, + .frame_per_row = 1, .speed = 0, .name = "test_spr" }; diff --git a/scenes/assets_loader.c b/scenes/assets_loader.c index cc57211..b63f6f0 100644 --- a/scenes/assets_loader.c +++ b/scenes/assets_loader.c @@ -19,6 +19,7 @@ typedef struct SpriteInfo Vector2 frame_size; int speed; int frame_count; + int frame_per_row; }SpriteInfo_t; static bool parse_sprite_info(char* sprite_info_str, SpriteInfo_t* spr_info) @@ -28,12 +29,12 @@ static bool parse_sprite_info(char* sprite_info_str, SpriteInfo_t* spr_info) spr_info->tex = tex_name; char* spr_data = tex_name + strlen(tex_name) + 1; int data_count = sscanf( - spr_data, "%f,%f,%f,%f,%d,%d", + spr_data, "%f,%f,%f,%f,%d,%d,%d", &spr_info->origin.x, &spr_info->origin.y, &spr_info->frame_size.x, &spr_info->frame_size.y, - &spr_info->frame_count, &spr_info->speed + &spr_info->frame_count, &spr_info->frame_per_row, &spr_info->speed ); - return data_count == 6; + return data_count == 7; } static bool parse_emitter_info(char* emitter_info_str, EmitterConfig_t* conf) @@ -82,6 +83,29 @@ static inline AssetInfoType_t get_asset_type(const char* str) return INVALID_INFO; } +static inline bool add_a_sprite(Assets_t* assets, const SpriteInfo_t* spr_info, char* name) +{ + Texture2D* tex = get_texture(assets, spr_info->tex); + if (tex == NULL) + { + printf("Unable to get texture info %s for sprite %s\n", spr_info->tex, name); + return false; + } + printf("Added Sprite %s from texture %s\n", name, spr_info->tex); + Sprite_t* spr = add_sprite(assets, name, tex); + spr->origin = spr_info->origin; + spr->frame_size = spr_info->frame_size; + spr->frame_count = spr_info->frame_count; + if (spr->frame_count == 0) + { + // Cannot be zero + spr->frame_count = 1; + } + spr->frame_per_row = spr_info->frame_count; + spr->speed = spr_info->speed; + return true; +} + bool load_from_rres(const char* file, Assets_t* assets) { RresFileInfo_t rres_file; @@ -169,19 +193,7 @@ bool load_from_rres(const char* file, Assets_t* assets) printf("Unable to parse info for sprite at line %lu\n", line_num); break; } - //printf("Compare %s,%s = %d\n", tmp2, spr_info.tex, strcmp(tmp2, spr_info.tex)); - Texture2D* tex = get_texture(assets, spr_info.tex); - if (tex == NULL) - { - printf("Unable to get texture info %s for sprite %s\n", spr_info.tex, name); - break; - } - printf("Added Sprite %s from texture %s\n", name, spr_info.tex); - Sprite_t* spr = add_sprite(assets, name, tex); - spr->origin = spr_info.origin; - spr->frame_size = spr_info.frame_size; - spr->frame_count = spr_info.frame_count; - spr->speed = spr_info.speed; + add_a_sprite(assets, &spr_info, name); } break; case EMITTER_INFO: @@ -286,18 +298,7 @@ bool load_from_infofile(const char* file, Assets_t* assets) break; } //printf("Compare %s,%s = %d\n", tmp2, spr_info.tex, strcmp(tmp2, spr_info.tex)); - Texture2D* tex = get_texture(assets, spr_info.tex); - if (tex == NULL) - { - printf("Unable to get texture info %s for sprite %s\n", spr_info.tex, name); - break; - } - printf("Added Sprite %s from texture %s\n", name, spr_info.tex); - Sprite_t* spr = add_sprite(assets, name, tex); - spr->origin = spr_info.origin; - spr->frame_size = spr_info.frame_size; - spr->frame_count = spr_info.frame_count; - spr->speed = spr_info.speed; + add_a_sprite(assets, &spr_info, name); } break; case EMITTER_INFO: