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
scene_man
En Yi 2024-05-06 21:18:03 +08:00
parent 0f09a7b2bd
commit 501a599336
5 changed files with 44 additions and 35 deletions

View File

@ -22,6 +22,7 @@ int main(void)
add_sprite(&assets, "testspr2", tex); add_sprite(&assets, "testspr2", tex);
Sprite_t* spr2 = get_sprite(&assets, "testspr2"); Sprite_t* spr2 = get_sprite(&assets, "testspr2");
spr2->frame_count = 4; spr2->frame_count = 4;
spr2->frame_per_row = 4;
spr2->origin = (Vector2){0, 0}; spr2->origin = (Vector2){0, 0};
spr2->frame_size = (Vector2){32, 32}; spr2->frame_size = (Vector2){32, 32};
spr2->speed = 15; spr2->speed = 15;

View File

@ -183,8 +183,9 @@ typedef struct _CWaterRunner {
typedef struct Sprite { typedef struct Sprite {
Texture2D* texture; Texture2D* texture;
Vector2 frame_size; Vector2 frame_size;
Vector2 origin; Vector2 origin; // TL of the frame
Vector2 anchor; Vector2 anchor; // Where transformation anchors on
uint8_t frame_per_row;
int frame_count; int frame_count;
int speed; int speed;
char* name; char* name;

View File

@ -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) 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; // Rollover behaviour
if (frame_num < 0) frame_num = 0; 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 = { Rectangle rec = {
spr->origin.x + spr->frame_size.x * frame_num, spr->origin.x + spr->frame_size.x * c,
spr->origin.y, spr->origin.y + spr->frame_size.y * r,
spr->frame_size.x * ((flip & 1) ? -1 : 1), spr->frame_size.x * ((flip & 1) ? -1 : 1),
spr->frame_size.y * ((flip & 2) ? -1 : 1), spr->frame_size.y * ((flip & 2) ? -1 : 1),
}; };

View File

@ -62,7 +62,8 @@ int main(void)
.frame_size = (Vector2){tex.width, tex.height}, .frame_size = (Vector2){tex.width, tex.height},
.origin = (Vector2){0, 0}, .origin = (Vector2){0, 0},
.anchor = (Vector2){tex.width / 2, tex.height / 2}, .anchor = (Vector2){tex.width / 2, tex.height / 2},
.frame_count = 0, .frame_count = 1,
.frame_per_row = 1,
.speed = 0, .speed = 0,
.name = "test_spr" .name = "test_spr"
}; };

View File

@ -19,6 +19,7 @@ typedef struct SpriteInfo
Vector2 frame_size; Vector2 frame_size;
int speed; int speed;
int frame_count; int frame_count;
int frame_per_row;
}SpriteInfo_t; }SpriteInfo_t;
static bool parse_sprite_info(char* sprite_info_str, SpriteInfo_t* spr_info) 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; spr_info->tex = tex_name;
char* spr_data = tex_name + strlen(tex_name) + 1; char* spr_data = tex_name + strlen(tex_name) + 1;
int data_count = sscanf( 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->origin.x, &spr_info->origin.y,
&spr_info->frame_size.x, &spr_info->frame_size.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) 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; 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) bool load_from_rres(const char* file, Assets_t* assets)
{ {
RresFileInfo_t rres_file; 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); printf("Unable to parse info for sprite at line %lu\n", line_num);
break; break;
} }
//printf("Compare %s,%s = %d\n", tmp2, spr_info.tex, strcmp(tmp2, spr_info.tex)); add_a_sprite(assets, &spr_info, 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);
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;
} }
break; break;
case EMITTER_INFO: case EMITTER_INFO:
@ -286,18 +298,7 @@ bool load_from_infofile(const char* file, Assets_t* assets)
break; break;
} }
//printf("Compare %s,%s = %d\n", tmp2, spr_info.tex, strcmp(tmp2, spr_info.tex)); //printf("Compare %s,%s = %d\n", tmp2, spr_info.tex, strcmp(tmp2, spr_info.tex));
Texture2D* tex = get_texture(assets, spr_info.tex); add_a_sprite(assets, &spr_info, name);
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;
} }
break; break;
case EMITTER_INFO: case EMITTER_INFO: