add cartridge system
This commit is contained in:
parent
ff698730f1
commit
98ca54e920
25 changed files with 968 additions and 315 deletions
|
|
@ -10,6 +10,7 @@ pxl8_result pxl8_tilesheet_init(pxl8_tilesheet* tilesheet, u32 tile_size) {
|
|||
|
||||
memset(tilesheet, 0, sizeof(pxl8_tilesheet));
|
||||
tilesheet->tile_size = tile_size ? tile_size : PXL8_TILE_SIZE;
|
||||
tilesheet->ref_count = 1;
|
||||
|
||||
return PXL8_OK;
|
||||
}
|
||||
|
|
@ -26,6 +27,33 @@ void pxl8_tilesheet_free(pxl8_tilesheet* tilesheet) {
|
|||
free(tilesheet->tile_valid);
|
||||
tilesheet->tile_valid = NULL;
|
||||
}
|
||||
|
||||
if (tilesheet->animations) {
|
||||
for (u32 i = 0; i < tilesheet->animation_count; i++) {
|
||||
if (tilesheet->animations[i].frames) {
|
||||
free(tilesheet->animations[i].frames);
|
||||
}
|
||||
}
|
||||
free(tilesheet->animations);
|
||||
tilesheet->animations = NULL;
|
||||
}
|
||||
|
||||
if (tilesheet->properties) {
|
||||
free(tilesheet->properties);
|
||||
tilesheet->properties = NULL;
|
||||
}
|
||||
|
||||
if (tilesheet->autotile_rules) {
|
||||
for (u32 i = 0; i <= tilesheet->total_tiles; i++) {
|
||||
if (tilesheet->autotile_rules[i]) {
|
||||
free(tilesheet->autotile_rules[i]);
|
||||
}
|
||||
}
|
||||
free(tilesheet->autotile_rules);
|
||||
free(tilesheet->autotile_rule_counts);
|
||||
tilesheet->autotile_rules = NULL;
|
||||
tilesheet->autotile_rule_counts = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
pxl8_result pxl8_tilesheet_load(pxl8_tilesheet* tilesheet, const char* filepath, pxl8_gfx_ctx* gfx) {
|
||||
|
|
@ -177,6 +205,136 @@ pxl8_tilesheet* pxl8_tilesheet_new(u32 tile_size) {
|
|||
|
||||
void pxl8_tilesheet_destroy(pxl8_tilesheet* tilesheet) {
|
||||
if (!tilesheet) return;
|
||||
pxl8_tilesheet_free(tilesheet);
|
||||
free(tilesheet);
|
||||
}
|
||||
pxl8_tilesheet_unref(tilesheet);
|
||||
}
|
||||
|
||||
void pxl8_tilesheet_ref(pxl8_tilesheet* tilesheet) {
|
||||
if (!tilesheet) return;
|
||||
tilesheet->ref_count++;
|
||||
}
|
||||
|
||||
void pxl8_tilesheet_unref(pxl8_tilesheet* tilesheet) {
|
||||
if (!tilesheet) return;
|
||||
|
||||
if (--tilesheet->ref_count == 0) {
|
||||
pxl8_tilesheet_free(tilesheet);
|
||||
free(tilesheet);
|
||||
}
|
||||
}
|
||||
|
||||
pxl8_result pxl8_tilesheet_add_animation(pxl8_tilesheet* tilesheet, u16 base_tile_id,
|
||||
const u16* frames, u16 frame_count, f32 frame_duration) {
|
||||
if (!tilesheet || !frames || frame_count == 0) return PXL8_ERROR_INVALID_ARGUMENT;
|
||||
if (base_tile_id == 0 || base_tile_id > tilesheet->total_tiles) return PXL8_ERROR_INVALID_ARGUMENT;
|
||||
|
||||
if (!tilesheet->animations) {
|
||||
tilesheet->animations = calloc(tilesheet->total_tiles + 1, sizeof(pxl8_tile_animation));
|
||||
if (!tilesheet->animations) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pxl8_tile_animation* anim = &tilesheet->animations[base_tile_id];
|
||||
if (anim->frames) free(anim->frames);
|
||||
|
||||
anim->frames = malloc(frame_count * sizeof(u16));
|
||||
if (!anim->frames) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
memcpy(anim->frames, frames, frame_count * sizeof(u16));
|
||||
anim->frame_count = frame_count;
|
||||
anim->current_frame = 0;
|
||||
anim->frame_duration = frame_duration;
|
||||
anim->time_accumulator = 0;
|
||||
|
||||
tilesheet->animation_count++;
|
||||
return PXL8_OK;
|
||||
}
|
||||
|
||||
void pxl8_tilesheet_update_animations(pxl8_tilesheet* tilesheet, f32 delta_time) {
|
||||
if (!tilesheet || !tilesheet->animations) return;
|
||||
|
||||
for (u32 i = 1; i <= tilesheet->total_tiles; i++) {
|
||||
pxl8_tile_animation* anim = &tilesheet->animations[i];
|
||||
if (!anim->frames || anim->frame_count == 0) continue;
|
||||
|
||||
anim->time_accumulator += delta_time;
|
||||
while (anim->time_accumulator >= anim->frame_duration) {
|
||||
anim->time_accumulator -= anim->frame_duration;
|
||||
anim->current_frame = (anim->current_frame + 1) % anim->frame_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u16 pxl8_tilesheet_get_animated_frame(const pxl8_tilesheet* tilesheet, u16 tile_id) {
|
||||
if (!tilesheet || !tilesheet->animations || tile_id == 0 || tile_id > tilesheet->total_tiles) {
|
||||
return tile_id;
|
||||
}
|
||||
|
||||
const pxl8_tile_animation* anim = &tilesheet->animations[tile_id];
|
||||
if (!anim->frames || anim->frame_count == 0) return tile_id;
|
||||
|
||||
return anim->frames[anim->current_frame];
|
||||
}
|
||||
|
||||
void pxl8_tilesheet_set_tile_property(pxl8_tilesheet* tilesheet, u16 tile_id,
|
||||
const pxl8_tile_properties* props) {
|
||||
if (!tilesheet || !props || tile_id == 0 || tile_id > tilesheet->total_tiles) return;
|
||||
|
||||
if (!tilesheet->properties) {
|
||||
tilesheet->properties = calloc(tilesheet->total_tiles + 1, sizeof(pxl8_tile_properties));
|
||||
if (!tilesheet->properties) return;
|
||||
}
|
||||
|
||||
tilesheet->properties[tile_id] = *props;
|
||||
}
|
||||
|
||||
const pxl8_tile_properties* pxl8_tilesheet_get_tile_property(const pxl8_tilesheet* tilesheet, u16 tile_id) {
|
||||
if (!tilesheet || !tilesheet->properties || tile_id == 0 || tile_id > tilesheet->total_tiles) {
|
||||
return NULL;
|
||||
}
|
||||
return &tilesheet->properties[tile_id];
|
||||
}
|
||||
|
||||
pxl8_result pxl8_tilesheet_add_autotile_rule(pxl8_tilesheet* tilesheet, u16 base_tile_id,
|
||||
u8 neighbor_mask, u16 result_tile_id) {
|
||||
if (!tilesheet || base_tile_id == 0 || base_tile_id > tilesheet->total_tiles) {
|
||||
return PXL8_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (!tilesheet->autotile_rules) {
|
||||
tilesheet->autotile_rules = calloc(tilesheet->total_tiles + 1, sizeof(pxl8_autotile_rule*));
|
||||
tilesheet->autotile_rule_counts = calloc(tilesheet->total_tiles + 1, sizeof(u32));
|
||||
if (!tilesheet->autotile_rules || !tilesheet->autotile_rule_counts) {
|
||||
return PXL8_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
u32 count = tilesheet->autotile_rule_counts[base_tile_id];
|
||||
pxl8_autotile_rule* new_rules = realloc(tilesheet->autotile_rules[base_tile_id],
|
||||
(count + 1) * sizeof(pxl8_autotile_rule));
|
||||
if (!new_rules) return PXL8_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
new_rules[count].neighbor_mask = neighbor_mask;
|
||||
new_rules[count].tile_id = result_tile_id;
|
||||
|
||||
tilesheet->autotile_rules[base_tile_id] = new_rules;
|
||||
tilesheet->autotile_rule_counts[base_tile_id]++;
|
||||
|
||||
return PXL8_OK;
|
||||
}
|
||||
|
||||
u16 pxl8_tilesheet_apply_autotile(const pxl8_tilesheet* tilesheet, u16 base_tile_id, u8 neighbors) {
|
||||
if (!tilesheet || !tilesheet->autotile_rules || base_tile_id == 0 ||
|
||||
base_tile_id > tilesheet->total_tiles) {
|
||||
return base_tile_id;
|
||||
}
|
||||
|
||||
pxl8_autotile_rule* rules = tilesheet->autotile_rules[base_tile_id];
|
||||
u32 rule_count = tilesheet->autotile_rule_counts[base_tile_id];
|
||||
|
||||
for (u32 i = 0; i < rule_count; i++) {
|
||||
if (rules[i].neighbor_mask == neighbors) {
|
||||
return rules[i].tile_id;
|
||||
}
|
||||
}
|
||||
|
||||
return base_tile_id;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue