rename ase & sheet 'tag' -> 'span'. begin sheet testing.
This commit is contained in:
parent
26950f13e3
commit
d646d3434c
28
src/ase.c
28
src/ase.c
@ -828,8 +828,8 @@ struct ase_decode_sheet_result ase_decode_sheet(struct arena *arena, struct buff
|
||||
u64 image_height = frame_height * frames_y;
|
||||
make_image_dimensions_squareish(&ase_header, &frames_x, &frames_y, &image_width, &image_height);
|
||||
|
||||
u32 num_tags = 0;
|
||||
struct ase_tag *tag_head = NULL;
|
||||
u32 num_spans = 0;
|
||||
struct ase_span *span_head = NULL;
|
||||
|
||||
u32 num_frames = 0;
|
||||
struct ase_frame *frame_head = NULL;
|
||||
@ -877,27 +877,27 @@ struct ase_decode_sheet_result ase_decode_sheet(struct arena *arena, struct buff
|
||||
|
||||
switch (chunk_type) {
|
||||
case CHUNK_TYPE_TAGS: {
|
||||
u16 frame_tag_count = br_read_u16(&br);
|
||||
u16 frame_span_count = br_read_u16(&br);
|
||||
br_seek(&br, 8);
|
||||
|
||||
for (u16 k = 0; k < frame_tag_count; ++k) {
|
||||
struct ase_tag *tag = arena_push_zero(arena, struct ase_tag);
|
||||
tag->next = tag_head;
|
||||
tag_head = tag;
|
||||
for (u16 k = 0; k < frame_span_count; ++k) {
|
||||
struct ase_span *span = arena_push_zero(arena, struct ase_span);
|
||||
span->next = span_head;
|
||||
span_head = span;
|
||||
|
||||
tag->start = br_read_u16(&br);
|
||||
tag->end = br_read_u16(&br);
|
||||
span->start = br_read_u16(&br);
|
||||
span->end = br_read_u16(&br);
|
||||
br_seek(&br, 13);
|
||||
|
||||
/* TODO: Decode utf-8 */
|
||||
u16 str_len = br_read_u16(&br);
|
||||
u8 *str_bytes = br_read_raw(&br, str_len);
|
||||
tag->name = (struct string) {
|
||||
span->name = (struct string) {
|
||||
str_len,
|
||||
arena_push_array(arena, u8, str_len)
|
||||
};
|
||||
MEMCPY(tag->name.text, str_bytes, str_len);
|
||||
++num_tags;
|
||||
MEMCPY(span->name.text, str_bytes, str_len);
|
||||
++num_spans;
|
||||
}
|
||||
|
||||
} break;
|
||||
@ -920,9 +920,9 @@ struct ase_decode_sheet_result ase_decode_sheet(struct arena *arena, struct buff
|
||||
res.image_size = V2(image_width, image_height);
|
||||
res.frame_size = V2(frame_width, frame_height);
|
||||
res.num_frames = num_frames;
|
||||
res.num_tags = num_tags;
|
||||
res.num_spans = num_spans;
|
||||
res.frame_head = frame_head;
|
||||
res.tag_head = tag_head;
|
||||
res.span_head = span_head;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -12,11 +12,11 @@ struct ase_error_list {
|
||||
struct ase_error *last;
|
||||
};
|
||||
|
||||
struct ase_tag {
|
||||
struct ase_span {
|
||||
struct string name;
|
||||
u32 start;
|
||||
u32 end;
|
||||
struct ase_tag *next;
|
||||
struct ase_span *next;
|
||||
};
|
||||
|
||||
struct ase_frame {
|
||||
@ -35,9 +35,9 @@ struct ase_decode_sheet_result {
|
||||
struct v2 image_size;
|
||||
struct v2 frame_size;
|
||||
u32 num_frames;
|
||||
u32 num_tags;
|
||||
u32 num_spans;
|
||||
struct ase_frame *frame_head;
|
||||
struct ase_tag *tag_head;
|
||||
struct ase_span *span_head;
|
||||
struct ase_error_list errors;
|
||||
};
|
||||
|
||||
|
||||
@ -65,9 +65,9 @@ struct entity {
|
||||
/* ====================================================================== */
|
||||
/* Sprite */
|
||||
|
||||
struct xform sprite_quad_xform;
|
||||
struct string sprite_name;
|
||||
struct string sprite_tag_name;
|
||||
struct string sprite_span_name;
|
||||
struct xform sprite_quad_xform;
|
||||
u32 sprite_tint;
|
||||
|
||||
/* ====================================================================== */
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
#include "texture.h"
|
||||
#include "util.h"
|
||||
|
||||
|
||||
struct asset;
|
||||
struct work_startup_receipt;
|
||||
struct renderer_startup_receipt;
|
||||
|
||||
24
src/game.c
24
src/game.c
@ -134,7 +134,7 @@ INTERNAL void game_update(void)
|
||||
e->rel_xform = XFORM_TRS(.t = pos, .r = r, .s = size);
|
||||
|
||||
struct string sprite_name = STR("res/graphics/tim.ase");
|
||||
struct string sprite_tag_name = STR("UNARMED");
|
||||
struct string sprite_span_name = STR("UNARMED");
|
||||
struct sheet *sheet = sheet_load(sprite_name);
|
||||
f32 meters_width = sheet->frame_size.x / (f32)PIXELS_PER_UNIT;
|
||||
f32 meters_height = sheet->frame_size.y / (f32)PIXELS_PER_UNIT;
|
||||
@ -157,7 +157,7 @@ INTERNAL void game_update(void)
|
||||
e->sprite_quad_xform = sprite_xf;
|
||||
|
||||
e->sprite_name = sprite_name;
|
||||
e->sprite_tag_name = sprite_tag_name;
|
||||
e->sprite_span_name = sprite_span_name;
|
||||
e->sprite_tint = COLOR_WHITE;
|
||||
|
||||
entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
|
||||
@ -185,7 +185,7 @@ INTERNAL void game_update(void)
|
||||
e->rel_xform = XFORM_TRS(.t = pos, .r = r, .s = size);
|
||||
|
||||
struct string sprite_name = STR("res/graphics/tim.ase");
|
||||
struct string sprite_tag_name = STR("UNARMED");
|
||||
struct string sprite_span_name = STR("UNARMED");
|
||||
struct sheet *sheet = sheet_load(sprite_name);
|
||||
f32 meters_width = sheet->frame_size.x / (f32)PIXELS_PER_UNIT;
|
||||
f32 meters_height = sheet->frame_size.y / (f32)PIXELS_PER_UNIT;
|
||||
@ -208,7 +208,7 @@ INTERNAL void game_update(void)
|
||||
e->sprite_quad_xform = sprite_xf;
|
||||
|
||||
e->sprite_name = sprite_name;
|
||||
e->sprite_tag_name = sprite_tag_name;
|
||||
e->sprite_span_name = sprite_span_name;
|
||||
e->sprite_tint = RGBA_F(0.5, 0.5, 0, 1);
|
||||
|
||||
//entity_enable_prop(e, ENTITY_PROP_PLAYER_CONTROLLED);
|
||||
@ -339,31 +339,33 @@ INTERNAL void game_update(void)
|
||||
* Update animation
|
||||
* ========================== */
|
||||
|
||||
#if 0
|
||||
if (entity_has_prop(ent, ENTITY_PROP_ANIMATING)) {
|
||||
f64 time_in_frame = ent->animation_time_in_frame + G.world.dt;
|
||||
u64 tag_frame_offset = ent->animation_frame;
|
||||
u64 span_frame_offset = ent->animation_frame;
|
||||
|
||||
struct sheet *sheet = sheet_load(ent->sprite_name);
|
||||
if (sheet) {
|
||||
struct sheet_tag tag = sheet_get_tag(sheet, ent->sprite_tag_name);
|
||||
u64 frame_index = tag.start + tag_frame_offset;
|
||||
struct sheet_span span = sheet_get_span(sheet, ent->sprite_span_name);
|
||||
u64 frame_index = span.start + span_frame_offset;
|
||||
|
||||
struct sheet_frame frame = sheet_get_frame(sheet, frame_index);
|
||||
while (time_in_frame > frame.duration) {
|
||||
time_in_frame -= frame.duration;
|
||||
++frame_index;
|
||||
if (frame_index > tag.end) {
|
||||
if (frame_index > span.end) {
|
||||
/* Loop animation */
|
||||
frame_index = tag.start;
|
||||
frame_index = span.start;
|
||||
}
|
||||
frame = sheet_get_frame(sheet, frame_index);
|
||||
}
|
||||
tag_frame_offset = frame_index - tag.start;
|
||||
span_frame_offset = frame_index - span.start;
|
||||
}
|
||||
|
||||
ent->animation_time_in_frame = time_in_frame;
|
||||
ent->animation_frame = tag_frame_offset;
|
||||
ent->animation_frame = span_frame_offset;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* ========================== *
|
||||
* Test
|
||||
|
||||
@ -38,7 +38,7 @@ struct log_level_settings {
|
||||
|
||||
struct log_event {
|
||||
i32 level;
|
||||
struct string msg; /* Lifetime is only as long as the callback function call */
|
||||
struct string msg; /* Lifetime is only as long as the callback function call receiving the event */
|
||||
struct log_level_settings settings;
|
||||
|
||||
/* These will be nulled if LOG_INCLUDE_SOURCE_LOCATION is disabled */
|
||||
|
||||
340
src/sheet.c
340
src/sheet.c
@ -1,3 +1,5 @@
|
||||
#if 1
|
||||
|
||||
#include "sheet.h"
|
||||
#include "arena.h"
|
||||
#include "log.h"
|
||||
@ -31,7 +33,6 @@ GLOBAL struct {
|
||||
struct sheet_task_params_store params;
|
||||
} G = { 0 }, DEBUG_ALIAS(G, G_sheet);
|
||||
|
||||
|
||||
/* ========================== *
|
||||
* Startup
|
||||
* ========================== */
|
||||
@ -106,19 +107,19 @@ INTERNAL struct sheet sheet_from_ase(struct arena *arena, struct ase_decode_shee
|
||||
};
|
||||
}
|
||||
|
||||
/* Init tags */
|
||||
sheet.tags_count = ase.num_tags;
|
||||
if (ase.num_tags > 0) {
|
||||
sheet.tags_dict = fixed_dict_init(arena, (u64)(ase.num_tags * SHEET_LOOKUP_TABLE_CAPACITY_FACTOR));
|
||||
for (struct ase_tag *ase_tag = ase.tag_head; ase_tag; ase_tag = ase_tag->next) {
|
||||
struct string name = string_copy(arena, ase_tag->name);
|
||||
struct sheet_tag *tag = arena_push(arena, struct sheet_tag);
|
||||
*tag = (struct sheet_tag) {
|
||||
/* Init spans */
|
||||
sheet.spans_count = ase.num_spans;
|
||||
if (ase.num_spans > 0) {
|
||||
sheet.spans_dict = fixed_dict_init(arena, (u64)(ase.num_spans * SHEET_LOOKUP_TABLE_CAPACITY_FACTOR));
|
||||
for (struct ase_span *ase_span = ase.span_head; ase_span; ase_span = ase_span->next) {
|
||||
struct string name = string_copy(arena, ase_span->name);
|
||||
struct sheet_span *span = arena_push(arena, struct sheet_span);
|
||||
*span = (struct sheet_span) {
|
||||
.name = name,
|
||||
.start = ase_tag->start,
|
||||
.end = ase_tag->end
|
||||
.start = ase_span->start,
|
||||
.end = ase_span->end
|
||||
};
|
||||
fixed_dict_set(arena, &sheet.tags_dict, name, tag);
|
||||
fixed_dict_set(arena, &sheet.spans_dict, name, span);
|
||||
}
|
||||
|
||||
}
|
||||
@ -278,13 +279,11 @@ struct sheet *sheet_load(struct string path)
|
||||
* Sheet data
|
||||
* ========================== */
|
||||
|
||||
GLOBAL READONLY struct sheet_tag g_default_tag = { 0 };
|
||||
|
||||
struct sheet_tag sheet_get_tag(struct sheet *sheet, struct string name)
|
||||
struct sheet_span sheet_get_span(struct sheet *sheet, struct string name)
|
||||
{
|
||||
struct sheet_tag res = g_default_tag;
|
||||
if (sheet->tags_count > 0) {
|
||||
struct sheet_tag *entry = fixed_dict_get(&sheet->tags_dict, name);
|
||||
struct sheet_span res = { 0 };
|
||||
if (sheet->spans_count > 0) {
|
||||
struct sheet_span *entry = fixed_dict_get(&sheet->spans_dict, name);
|
||||
if (entry) {
|
||||
res = *entry;
|
||||
}
|
||||
@ -297,3 +296,308 @@ struct sheet_frame sheet_get_frame(struct sheet *sheet, u32 index)
|
||||
index = min_u32(sheet->frames_count - 1, index);
|
||||
return sheet->frames[index];
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include "sheet.h"
|
||||
#include "arena.h"
|
||||
#include "log.h"
|
||||
#include "sys.h"
|
||||
#include "scratch.h"
|
||||
#include "resource.h"
|
||||
#include "asset_cache.h"
|
||||
#include "ase.h"
|
||||
#include "util.h"
|
||||
#include "work.h"
|
||||
|
||||
#define SHEET_LOAD_THREAD_COUNT_MAX 4
|
||||
|
||||
struct sheet_task_params {
|
||||
struct sheet_task_params *next_free;
|
||||
|
||||
struct asset *asset;
|
||||
u64 path_len;
|
||||
char path_cstr[1024];
|
||||
};
|
||||
|
||||
struct sheet_task_params_store {
|
||||
struct sheet_task_params *head_free;
|
||||
struct arena arena;
|
||||
struct sys_mutex mutex;
|
||||
};
|
||||
|
||||
/* ========================== *
|
||||
* Global state
|
||||
* ========================== */
|
||||
|
||||
GLOBAL struct {
|
||||
struct sheet_task_params_store params;
|
||||
struct sys_thread load_threads[SHEET_LOAD_THREAD_COUNT_MAX];
|
||||
|
||||
} G = { 0 }, DEBUG_ALIAS(G, G_sheet);
|
||||
|
||||
/* ========================== *
|
||||
* Startup
|
||||
* ========================== */
|
||||
|
||||
struct sheet_startup_receipt sheet_startup(struct work_startup_receipt *work_sr,
|
||||
struct asset_cache_startup_receipt *asset_cache_sr,
|
||||
struct resource_startup_receipt *resource_sr)
|
||||
{
|
||||
(UNUSED)work_sr;
|
||||
(UNUSED)asset_cache_sr;
|
||||
(UNUSED)resource_sr;
|
||||
|
||||
G.params.arena = arena_alloc(GIGABYTE(64));
|
||||
G.params.mutex = sys_mutex_alloc();
|
||||
|
||||
return (struct sheet_startup_receipt) { 0 };
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Load task param store
|
||||
* ========================== */
|
||||
|
||||
INTERNAL struct sheet_task_params *sheet_task_params_alloc(void)
|
||||
{
|
||||
struct sheet_task_params *p = NULL;
|
||||
sys_mutex_lock(&G.params.mutex);
|
||||
{
|
||||
if (G.params.head_free) {
|
||||
p = G.params.head_free;
|
||||
G.params.head_free = p->next_free;
|
||||
} else {
|
||||
p = arena_push_zero(&G.params.arena, struct sheet_task_params);
|
||||
}
|
||||
}
|
||||
sys_mutex_unlock(&G.params.mutex);
|
||||
return p;
|
||||
}
|
||||
|
||||
INTERNAL void sheet_task_params_release(struct sheet_task_params *p)
|
||||
{
|
||||
sys_mutex_lock(&G.params.mutex);
|
||||
{
|
||||
p->next_free = G.params.head_free;
|
||||
G.params.head_free = p;
|
||||
}
|
||||
sys_mutex_unlock(&G.params.mutex);
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Init
|
||||
* ========================== */
|
||||
|
||||
#define SHEET_LOOKUP_TABLE_CAPACITY_FACTOR 2.0
|
||||
|
||||
INTERNAL struct sheet sheet_from_ase(struct arena *arena, struct ase_decode_sheet_result ase)
|
||||
{
|
||||
struct sheet sheet = { 0 };
|
||||
|
||||
ASSERT(ase.num_frames >= 1);
|
||||
|
||||
/* Init frames */
|
||||
sheet.image_size = ase.image_size;
|
||||
sheet.frame_size = ase.frame_size;
|
||||
sheet.frames = arena_push_array_zero(arena, struct sheet_frame, ase.num_frames);
|
||||
sheet.frames_count = ase.num_frames;
|
||||
for (struct ase_frame *ase_frame = ase.frame_head; ase_frame; ase_frame = ase_frame->next) {
|
||||
u32 index = ase_frame->index;
|
||||
sheet.frames[index] = (struct sheet_frame) {
|
||||
.index = index,
|
||||
.duration = ase_frame->duration,
|
||||
.clip = ase_frame->clip
|
||||
};
|
||||
}
|
||||
|
||||
/* Init spans */
|
||||
sheet.spans_count = ase.num_spans;
|
||||
if (ase.num_spans > 0) {
|
||||
sheet.spans_dict = fixed_dict_init(arena, (u64)(ase.num_spans * SHEET_LOOKUP_TABLE_CAPACITY_FACTOR));
|
||||
for (struct ase_span *ase_span = ase.span_head; ase_span; ase_span = ase_span->next) {
|
||||
struct string name = string_copy(arena, ase_span->name);
|
||||
struct sheet_span *span = arena_push(arena, struct sheet_span);
|
||||
*span = (struct sheet_span) {
|
||||
.name = name,
|
||||
.start = ase_span->start,
|
||||
.end = ase_span->end
|
||||
};
|
||||
fixed_dict_set(arena, &sheet.spans_dict, name, span);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return sheet;
|
||||
}
|
||||
|
||||
INTERNAL struct sheet sheet_default(struct arena *arena)
|
||||
{
|
||||
struct sheet sheet = { 0 };
|
||||
sheet.frames_count = 1;
|
||||
sheet.frames = arena_push(arena, struct sheet_frame);
|
||||
sheet.frames[0] = (struct sheet_frame) {
|
||||
.index = 0,
|
||||
.duration = 0,
|
||||
.clip = CLIP_ALL
|
||||
};
|
||||
return sheet;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Load
|
||||
* ========================== */
|
||||
|
||||
INTERNAL WORK_TASK_FUNC_DEF(sheet_load_asset_task, vparams)
|
||||
{
|
||||
__prof;
|
||||
struct sheet_task_params *params = (struct sheet_task_params *)vparams;
|
||||
struct temp_arena scratch = scratch_begin_no_conflict();
|
||||
struct string path = string_from_cstr_len(params->path_cstr, params->path_len);
|
||||
struct asset *asset = params->asset;
|
||||
|
||||
logf_info("Loading sheet \"%F\"", FMT_STR(path));
|
||||
sys_timestamp_t start_ts = sys_timestamp();
|
||||
|
||||
b32 success = false;
|
||||
struct string error_msg = STR("Unknown error");
|
||||
|
||||
ASSERT(string_ends_with(path, STR(".ase")));
|
||||
if (resource_exists(path)) {
|
||||
/* Decode */
|
||||
struct resource sheet_rs = resource_open(path);
|
||||
struct ase_decode_sheet_result decoded = ase_decode_sheet(scratch.arena, sheet_rs.bytes);
|
||||
resource_close(sheet_rs);
|
||||
|
||||
/* Failure paths */
|
||||
if (decoded.errors.count > 0) {
|
||||
/* FIXME: Read all errors from decode */
|
||||
struct string msg = decoded.errors.first->msg;
|
||||
if (msg.len > 0) {
|
||||
error_msg = msg;
|
||||
}
|
||||
goto abort;
|
||||
} else {
|
||||
success = true;
|
||||
}
|
||||
|
||||
/* Initialize sheet & its data into store */
|
||||
struct sheet *sheet = NULL;
|
||||
{
|
||||
struct asset_cache_store store = asset_cache_store_open();
|
||||
sheet = arena_push(store.arena, struct sheet);
|
||||
*sheet = sheet_from_ase(store.arena, decoded);
|
||||
asset_cache_store_close(&store);
|
||||
}
|
||||
|
||||
logf_info("Finished loading sheet \"%F\" in %F seconds",
|
||||
FMT_STR(path),
|
||||
FMT_FLOAT(sys_timestamp_seconds(sys_timestamp() - start_ts)));
|
||||
|
||||
asset_cache_mark_ready(asset, sheet);
|
||||
} else {
|
||||
success = false;
|
||||
error_msg = STR("Resource not found");
|
||||
goto abort;
|
||||
}
|
||||
|
||||
abort:
|
||||
|
||||
if (!success) {
|
||||
logf_error("Error loading sheet \"%F\": %F", FMT_STR(path), FMT_STR(error_msg));
|
||||
|
||||
/* Store */
|
||||
struct sheet *sheet = NULL;
|
||||
{
|
||||
struct asset_cache_store store = asset_cache_store_open();
|
||||
sheet = arena_push(store.arena, struct sheet);
|
||||
*sheet = sheet_default(store.arena);
|
||||
asset_cache_store_close(&store);
|
||||
}
|
||||
|
||||
asset_cache_mark_ready(asset, sheet);
|
||||
}
|
||||
|
||||
sheet_task_params_release(params);
|
||||
|
||||
/* Decommit decoded sheet data */
|
||||
scratch_end_and_decommit(scratch);
|
||||
}
|
||||
|
||||
struct asset *sheet_load_asset(struct string path, b32 help)
|
||||
{
|
||||
__prof;
|
||||
struct temp_arena scratch = scratch_begin_no_conflict();
|
||||
|
||||
struct string key = string_cat(scratch.arena, path, STR("_sheet"));
|
||||
u64 hash = asset_cache_hash(key);
|
||||
b32 is_first_touch;
|
||||
struct asset *asset = asset_cache_touch(key, hash, &is_first_touch);
|
||||
|
||||
if (is_first_touch) {
|
||||
/* Assemble task params */
|
||||
struct sheet_task_params *params = sheet_task_params_alloc();
|
||||
if (path.len > (sizeof(params->path_cstr) - 1)) {
|
||||
sys_panic(string_format(scratch.arena,
|
||||
STR("Sheet path \"%F\" too long!"),
|
||||
FMT_STR(path)));
|
||||
}
|
||||
cstr_buff_from_string(BUFFER_FROM_ARRAY(params->path_cstr), path);
|
||||
params->path_len = path.len;
|
||||
params->asset = asset;
|
||||
|
||||
/* Push task */
|
||||
asset_cache_mark_loading(asset);
|
||||
struct work_handle wh = { 0 };
|
||||
if (help) {
|
||||
wh = work_push_task_and_help(&sheet_load_asset_task, params, WORK_PRIORITY_NORMAL);
|
||||
} else {
|
||||
wh = work_push_task(&sheet_load_asset_task, params, WORK_PRIORITY_NORMAL);
|
||||
}
|
||||
asset_cache_set_work(asset, &wh);
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
return asset;
|
||||
}
|
||||
|
||||
struct sheet *sheet_load_async(struct string path)
|
||||
{
|
||||
__prof;
|
||||
struct asset *asset = sheet_load_asset(path, false);
|
||||
struct sheet *sheet = (struct sheet *)asset_cache_get_store_data(asset);
|
||||
return sheet;
|
||||
}
|
||||
|
||||
|
||||
struct sheet *sheet_load(struct string path)
|
||||
{
|
||||
__prof;
|
||||
struct asset *asset = sheet_load_asset(path, true);
|
||||
asset_cache_wait(asset);
|
||||
struct sheet *sheet = (struct sheet *)asset_cache_get_store_data(asset);
|
||||
return sheet;
|
||||
}
|
||||
|
||||
/* ========================== *
|
||||
* Sheet data
|
||||
* ========================== */
|
||||
|
||||
struct sheet_span sheet_get_span(struct sheet *sheet, struct string name)
|
||||
{
|
||||
struct sheet_span res = { 0 };
|
||||
if (sheet->spans_count > 0) {
|
||||
struct sheet_span *entry = fixed_dict_get(&sheet->spans_dict, name);
|
||||
if (entry) {
|
||||
res = *entry;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
struct sheet_frame sheet_get_frame(struct sheet *sheet, u32 index)
|
||||
{
|
||||
index = min_u32(sheet->frames_count - 1, index);
|
||||
return sheet->frames[index];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
10
src/sheet.h
10
src/sheet.h
@ -14,11 +14,15 @@ struct sheet {
|
||||
struct v2 frame_size;
|
||||
u32 frames_count;
|
||||
struct sheet_frame *frames;
|
||||
u32 tags_count;
|
||||
struct fixed_dict tags_dict;
|
||||
u32 spans_count;
|
||||
struct fixed_dict spans_dict;
|
||||
};
|
||||
|
||||
struct sheet_tag {
|
||||
struct string path;
|
||||
};
|
||||
|
||||
struct sheet_span {
|
||||
struct string name;
|
||||
u32 start;
|
||||
u32 end;
|
||||
@ -39,7 +43,7 @@ struct asset *sheet_load_asset(struct string path, b32 wait);
|
||||
struct sheet *sheet_load_async(struct string path);
|
||||
struct sheet *sheet_load(struct string path);
|
||||
|
||||
struct sheet_tag sheet_get_tag(struct sheet *sheet, struct string name);
|
||||
struct sheet_span sheet_get_span(struct sheet *sheet, struct string name);
|
||||
struct sheet_frame sheet_get_frame(struct sheet *sheet, u32 index);
|
||||
|
||||
#endif
|
||||
|
||||
@ -482,7 +482,11 @@ void sys_panic(struct string msg);
|
||||
* Sleep
|
||||
* ========================== */
|
||||
|
||||
/* Sleep for precisely the amount of time specified (more cpu intensive) */
|
||||
void sys_sleep_precise(f64 seconds);
|
||||
void sys_sleep_imprecise(f64 seconds);
|
||||
|
||||
/* Sleep for the amount of time specified rounded to the OS scheduler period
|
||||
* (less cpu intensive) */
|
||||
void sys_sleep(f64 seconds);
|
||||
|
||||
#endif
|
||||
|
||||
@ -1882,10 +1882,10 @@ void sys_sleep_precise(f64 seconds)
|
||||
}
|
||||
}
|
||||
|
||||
void sys_sleep_imprecise(f64 seconds)
|
||||
void sys_sleep(f64 seconds)
|
||||
{
|
||||
__prof;
|
||||
u32 ms = math_round((f32)seconds);
|
||||
u32 ms = max_u32(1, math_round((f32)(seconds * 1000.0)));
|
||||
Sleep(ms);
|
||||
}
|
||||
|
||||
|
||||
1107
src/user.c
1107
src/user.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user