ase refactor wip
This commit is contained in:
parent
9c0c649365
commit
ff7e0b2167
1936
src/ase/ase.c
1936
src/ase/ase.c
File diff suppressed because it is too large
Load Diff
507
src/ase/ase.h
507
src/ase/ase.h
@ -1,241 +1,328 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Sheet types
|
//~ Meta types
|
||||||
|
|
||||||
Struct(ASE_Slice)
|
Struct (ASE_Cel)
|
||||||
{
|
{
|
||||||
u32 start;
|
i32 _;
|
||||||
Rng2I32 rect;
|
|
||||||
ASE_Slice *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
Struct(ASE_Span)
|
|
||||||
{
|
|
||||||
String name;
|
|
||||||
u32 start;
|
|
||||||
u32 end;
|
|
||||||
ASE_Span *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
Struct(ASE_Frame)
|
|
||||||
{
|
|
||||||
u32 index;
|
|
||||||
Rng2I32 rect;
|
|
||||||
f64 duration;
|
|
||||||
ASE_Frame *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
Struct(ASE_SliceKey)
|
|
||||||
{
|
|
||||||
String name;
|
|
||||||
u32 slices_count;
|
|
||||||
ASE_Slice *first_slice;
|
|
||||||
ASE_SliceKey *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Decoder result types
|
|
||||||
|
|
||||||
Struct(ASE_Error)
|
|
||||||
{
|
|
||||||
String msg;
|
|
||||||
ASE_Error *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
Struct(ASE_ErrorList)
|
|
||||||
{
|
|
||||||
u64 count;
|
|
||||||
ASE_Error *first;
|
|
||||||
ASE_Error *last;
|
|
||||||
};
|
|
||||||
|
|
||||||
Struct(ASE_DecodedImage)
|
|
||||||
{
|
|
||||||
u32 width;
|
|
||||||
u32 height;
|
|
||||||
u32 *pixels; // Array of [width * height] pixels
|
|
||||||
ASE_ErrorList errors;
|
|
||||||
b32 ok;
|
|
||||||
};
|
|
||||||
|
|
||||||
Struct(ASE_DecodedSheet)
|
|
||||||
{
|
|
||||||
Vec2 image_size;
|
|
||||||
Vec2 frame_size;
|
|
||||||
u32 frames_count;
|
|
||||||
u32 spans_count;
|
|
||||||
u32 slice_keys_count;
|
|
||||||
ASE_Frame *first_frame;
|
|
||||||
ASE_Span *first_span;
|
|
||||||
ASE_SliceKey *first_slice_key;
|
|
||||||
ASE_ErrorList errors;
|
|
||||||
b32 ok;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Inflator types
|
|
||||||
|
|
||||||
#define ASE_HuffBitCount 16
|
|
||||||
|
|
||||||
Struct(ASE_Bitbuff)
|
|
||||||
{
|
|
||||||
u8 *data;
|
|
||||||
u64 cur_bit;
|
|
||||||
};
|
|
||||||
|
|
||||||
Enum(ASE_BlockType)
|
|
||||||
{
|
|
||||||
ASE_BlockType_Uncompressed = 0,
|
|
||||||
ASE_BlockType_CompressedFixed = 1,
|
|
||||||
ASE_BlockType_CompressedDynamic = 2,
|
|
||||||
ASE_BlockType_Reserved = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
Struct(ASE_HuffEntry)
|
|
||||||
{
|
|
||||||
u16 symbol;
|
|
||||||
u16 bits_used;
|
|
||||||
};
|
|
||||||
|
|
||||||
Struct(ASE_HuffDict)
|
|
||||||
{
|
|
||||||
u32 max_code_bits;
|
|
||||||
u32 entries_count;
|
|
||||||
ASE_HuffEntry *entries;
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Header types
|
|
||||||
|
|
||||||
Packed(Struct(ASE_Header)
|
|
||||||
{
|
|
||||||
u32 file_size;
|
|
||||||
u16 magic;
|
|
||||||
u16 frames;
|
|
||||||
u16 width;
|
|
||||||
u16 height;
|
|
||||||
u16 color_depth;
|
|
||||||
u32 flags;
|
|
||||||
u16 speed;
|
|
||||||
u32 _1;
|
|
||||||
u32 _2;
|
|
||||||
u8 palette_entry;
|
|
||||||
u8 _3[3];
|
|
||||||
u16 colors_count;
|
|
||||||
u8 pixel_width;
|
|
||||||
u8 pixel_height;
|
|
||||||
i16 grid_x;
|
|
||||||
i16 grid_y;
|
|
||||||
u16 grid_width;
|
|
||||||
u16 grid_height;
|
|
||||||
u8 _4[84];
|
|
||||||
});
|
|
||||||
|
|
||||||
Packed(Struct(ASE_FrameHeader)
|
|
||||||
{
|
|
||||||
u32 bytes;
|
|
||||||
u16 magic;
|
|
||||||
u16 chunks_old;
|
|
||||||
u16 frame_duration_ms;
|
|
||||||
u8 _[2];
|
|
||||||
u32 chunks_new;
|
|
||||||
});
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Image decoder types
|
|
||||||
|
|
||||||
Enum(ASE_ChunkKind)
|
|
||||||
{
|
|
||||||
ASE_ChunkKind_OldPalette1 = 0x0004,
|
|
||||||
ASE_ChunkKind_OldPalette2 = 0x0011,
|
|
||||||
ASE_ChunkKind_Layer = 0x2004,
|
|
||||||
ASE_ChunkKind_Cel = 0x2005,
|
|
||||||
ASE_ChunkKind_CelExtra = 0x2006,
|
|
||||||
ASE_ChunkKind_ColorProfile = 0x2007,
|
|
||||||
ASE_ChunkKind_ExternalFiles = 0x2008,
|
|
||||||
ASE_ChunkKind_Mask = 0x2016,
|
|
||||||
ASE_ChunkKind_Path = 0x2017,
|
|
||||||
ASE_ChunkKind_Tags = 0x2018,
|
|
||||||
ASE_ChunkKind_Palette = 0x2019,
|
|
||||||
ASE_ChunkKind_Userdata = 0x2020,
|
|
||||||
ASE_ChunkKind_Slice = 0x2022,
|
|
||||||
ASE_ChunkKind_Tileset = 0x2023
|
|
||||||
};
|
|
||||||
|
|
||||||
Enum(ASE_CelKind)
|
|
||||||
{
|
|
||||||
ASE_CelKind_RawImage = 0,
|
|
||||||
ASE_CelKind_Linked = 1,
|
|
||||||
ASE_CelKind_CompressedImage = 2,
|
|
||||||
ASE_CelKind_CompressedTilemap = 3
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(ASE_Layer)
|
Struct(ASE_Layer)
|
||||||
{
|
{
|
||||||
u16 flags;
|
|
||||||
u16 type;
|
|
||||||
u16 child_level;
|
|
||||||
u16 blend_mode;
|
|
||||||
u8 opacity;
|
|
||||||
String name;
|
|
||||||
u32 tileset_index;
|
|
||||||
|
|
||||||
u32 index;
|
|
||||||
ASE_Layer *next;
|
ASE_Layer *next;
|
||||||
|
ASE_Layer *prev;
|
||||||
|
|
||||||
|
String name;
|
||||||
|
i64 cels_count;
|
||||||
|
ASE_Cel *cels;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(ASE_Cel)
|
Struct(ASE_Span)
|
||||||
{
|
{
|
||||||
u16 layer_index;
|
ASE_Span *next;
|
||||||
i16 x_pos;
|
ASE_Span *prev;
|
||||||
i16 y_pos;
|
|
||||||
u8 opacity;
|
|
||||||
ASE_CelKind type;
|
|
||||||
i16 z_index;
|
|
||||||
|
|
||||||
// Linked cel
|
String name;
|
||||||
u16 frame_pos;
|
i64 start;
|
||||||
|
i64 end;
|
||||||
|
};
|
||||||
|
|
||||||
// Compressed image
|
Struct(ASE_Meta)
|
||||||
u32 width;
|
{
|
||||||
u32 height;
|
i64 frames_count;
|
||||||
u32 *pixels;
|
|
||||||
|
|
||||||
u16 frame_index;
|
i64 spans_count;
|
||||||
ASE_Cel *next;
|
ASE_Span *first_span;
|
||||||
|
ASE_Span *last_span;
|
||||||
|
|
||||||
|
i64 layers_count;
|
||||||
|
ASE_Layer *first_layer;
|
||||||
|
ASE_Layer *last_layer;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Ase bitbuff helpers
|
//~ Query types
|
||||||
|
|
||||||
u32 ASE_PeekBits(ASE_Bitbuff *bb, u32 nbits);
|
Struct(ASE_SinglePixelResult)
|
||||||
u32 ASE_ConsumeBits(ASE_Bitbuff *bb, u32 nbits);
|
{
|
||||||
void ASE_SkipBits(ASE_Bitbuff *bb, u32 nbits);
|
Vec2 pos;
|
||||||
|
u32 v;
|
||||||
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Inflate
|
//~ Meta
|
||||||
|
|
||||||
u32 ASE_ReverseBits(u32 v, u32 bit_count);
|
ASE_Meta ASE_DecodeMeta(Arena *arena, String encoded);
|
||||||
ASE_HuffDict ASE_InitHuffDict(Arena *arena, u32 max_code_bits, u32 *bl_counts, u32 bl_counts_count);
|
|
||||||
u16 ASE_DecodeHuffDict(ASE_HuffDict *huffman, ASE_Bitbuff *bb);
|
|
||||||
void ASE_Inflate(u8 *dst, u8 *encoded);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Error helpers
|
//~ Query
|
||||||
|
|
||||||
void ASE_PushError(Arena *arena, ASE_ErrorList *list, String msg_src);
|
ASE_SinglePixelResult ASE_SinglePixelFromCel(ASE_Cel *cel);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Decode helpers
|
//~ Rasterize
|
||||||
|
|
||||||
u32 ASE_Blend(u32 src, u32 dst, u8 opacity);
|
void ASE_RasterizeCel(ASE_Cel *cel, u32 *dst_pixels, Vec2 dst_dims);
|
||||||
void ASE_MakeDimensionsSquareish(ASE_Header *header, u32 *frames_x, u32 *frames_y, u64 *image_width, u64 *image_height);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Decode image
|
|
||||||
|
|
||||||
ASE_DecodedImage ASE_DecodeImage(Arena *arena, String encoded);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
|
||||||
//~ Decode sheet
|
|
||||||
|
|
||||||
ASE_DecodedSheet ASE_DecodeSheet(Arena *arena, String encoded);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ////////////////////////////////////////////////////////////
|
||||||
|
// //~ Sheet types
|
||||||
|
|
||||||
|
// Struct(ASE_Slice)
|
||||||
|
// {
|
||||||
|
// u32 start;
|
||||||
|
// Rng2I32 rect;
|
||||||
|
// ASE_Slice *next;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// Struct(ASE_Span)
|
||||||
|
// {
|
||||||
|
// String name;
|
||||||
|
// u32 start;
|
||||||
|
// u32 end;
|
||||||
|
// ASE_Span *next;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// Struct(ASE_Frame)
|
||||||
|
// {
|
||||||
|
// u32 index;
|
||||||
|
// Rng2I32 rect;
|
||||||
|
// f64 duration;
|
||||||
|
// ASE_Frame *next;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// Struct(ASE_SliceKey)
|
||||||
|
// {
|
||||||
|
// String name;
|
||||||
|
// u32 slices_count;
|
||||||
|
// ASE_Slice *first_slice;
|
||||||
|
// ASE_SliceKey *next;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// ////////////////////////////////////////////////////////////
|
||||||
|
// //~ Decoder result types
|
||||||
|
|
||||||
|
// Struct(ASE_Error)
|
||||||
|
// {
|
||||||
|
// String msg;
|
||||||
|
// ASE_Error *next;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// Struct(ASE_ErrorList)
|
||||||
|
// {
|
||||||
|
// u64 count;
|
||||||
|
// ASE_Error *first;
|
||||||
|
// ASE_Error *last;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// Struct(ASE_DecodedImage)
|
||||||
|
// {
|
||||||
|
// u32 width;
|
||||||
|
// u32 height;
|
||||||
|
// u32 *pixels; // Array of [width * height] pixels
|
||||||
|
// ASE_ErrorList errors;
|
||||||
|
// b32 ok;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// Struct(ASE_DecodedSheet)
|
||||||
|
// {
|
||||||
|
// Vec2 image_size;
|
||||||
|
// Vec2 frame_size;
|
||||||
|
// u32 frames_count;
|
||||||
|
// u32 spans_count;
|
||||||
|
// u32 slice_keys_count;
|
||||||
|
// ASE_Frame *first_frame;
|
||||||
|
// ASE_Span *first_span;
|
||||||
|
// ASE_SliceKey *first_slice_key;
|
||||||
|
// ASE_ErrorList errors;
|
||||||
|
// b32 ok;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// ////////////////////////////////////////////////////////////
|
||||||
|
// //~ Inflator types
|
||||||
|
|
||||||
|
// #define ASE_HuffBitCount 16
|
||||||
|
|
||||||
|
// Struct(ASE_Bitbuff)
|
||||||
|
// {
|
||||||
|
// u8 *data;
|
||||||
|
// u64 cur_bit;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// Enum(ASE_BlockType)
|
||||||
|
// {
|
||||||
|
// ASE_BlockType_Uncompressed = 0,
|
||||||
|
// ASE_BlockType_CompressedFixed = 1,
|
||||||
|
// ASE_BlockType_CompressedDynamic = 2,
|
||||||
|
// ASE_BlockType_Reserved = 3
|
||||||
|
// };
|
||||||
|
|
||||||
|
// Struct(ASE_HuffEntry)
|
||||||
|
// {
|
||||||
|
// u16 symbol;
|
||||||
|
// u16 bits_used;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// Struct(ASE_HuffDict)
|
||||||
|
// {
|
||||||
|
// u32 max_code_bits;
|
||||||
|
// u32 entries_count;
|
||||||
|
// ASE_HuffEntry *entries;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// ////////////////////////////////////////////////////////////
|
||||||
|
// //~ Header types
|
||||||
|
|
||||||
|
// Packed(Struct(ASE_Header)
|
||||||
|
// {
|
||||||
|
// u32 file_size;
|
||||||
|
// u16 magic;
|
||||||
|
// u16 frames;
|
||||||
|
// u16 width;
|
||||||
|
// u16 height;
|
||||||
|
// u16 color_depth;
|
||||||
|
// u32 flags;
|
||||||
|
// u16 speed;
|
||||||
|
// u32 _1;
|
||||||
|
// u32 _2;
|
||||||
|
// u8 palette_entry;
|
||||||
|
// u8 _3[3];
|
||||||
|
// u16 colors_count;
|
||||||
|
// u8 pixel_width;
|
||||||
|
// u8 pixel_height;
|
||||||
|
// i16 grid_x;
|
||||||
|
// i16 grid_y;
|
||||||
|
// u16 grid_width;
|
||||||
|
// u16 grid_height;
|
||||||
|
// u8 _4[84];
|
||||||
|
// });
|
||||||
|
|
||||||
|
// Packed(Struct(ASE_FrameHeader)
|
||||||
|
// {
|
||||||
|
// u32 bytes;
|
||||||
|
// u16 magic;
|
||||||
|
// u16 chunks_old;
|
||||||
|
// u16 frame_duration_ms;
|
||||||
|
// u8 _[2];
|
||||||
|
// u32 chunks_new;
|
||||||
|
// });
|
||||||
|
|
||||||
|
// ////////////////////////////////////////////////////////////
|
||||||
|
// //~ Image decoder types
|
||||||
|
|
||||||
|
// Enum(ASE_ChunkKind)
|
||||||
|
// {
|
||||||
|
// ASE_ChunkKind_OldPalette1 = 0x0004,
|
||||||
|
// ASE_ChunkKind_OldPalette2 = 0x0011,
|
||||||
|
// ASE_ChunkKind_Layer = 0x2004,
|
||||||
|
// ASE_ChunkKind_Cel = 0x2005,
|
||||||
|
// ASE_ChunkKind_CelExtra = 0x2006,
|
||||||
|
// ASE_ChunkKind_ColorProfile = 0x2007,
|
||||||
|
// ASE_ChunkKind_ExternalFiles = 0x2008,
|
||||||
|
// ASE_ChunkKind_Mask = 0x2016,
|
||||||
|
// ASE_ChunkKind_Path = 0x2017,
|
||||||
|
// ASE_ChunkKind_Tags = 0x2018,
|
||||||
|
// ASE_ChunkKind_Palette = 0x2019,
|
||||||
|
// ASE_ChunkKind_Userdata = 0x2020,
|
||||||
|
// ASE_ChunkKind_Slice = 0x2022,
|
||||||
|
// ASE_ChunkKind_Tileset = 0x2023
|
||||||
|
// };
|
||||||
|
|
||||||
|
// Enum(ASE_CelKind)
|
||||||
|
// {
|
||||||
|
// ASE_CelKind_RawImage = 0,
|
||||||
|
// ASE_CelKind_Linked = 1,
|
||||||
|
// ASE_CelKind_CompressedImage = 2,
|
||||||
|
// ASE_CelKind_CompressedTilemap = 3
|
||||||
|
// };
|
||||||
|
|
||||||
|
// Struct(ASE_Layer)
|
||||||
|
// {
|
||||||
|
// u16 flags;
|
||||||
|
// u16 type;
|
||||||
|
// u16 child_level;
|
||||||
|
// u16 blend_mode;
|
||||||
|
// u8 opacity;
|
||||||
|
// String name;
|
||||||
|
// u32 tileset_index;
|
||||||
|
|
||||||
|
// u32 index;
|
||||||
|
// ASE_Layer *next;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// Struct(ASE_Cel)
|
||||||
|
// {
|
||||||
|
// u16 layer_index;
|
||||||
|
// i16 x_pos;
|
||||||
|
// i16 y_pos;
|
||||||
|
// u8 opacity;
|
||||||
|
// ASE_CelKind type;
|
||||||
|
// i16 z_index;
|
||||||
|
|
||||||
|
// // Linked cel
|
||||||
|
// u16 frame_pos;
|
||||||
|
|
||||||
|
// // Compressed image
|
||||||
|
// u32 width;
|
||||||
|
// u32 height;
|
||||||
|
// u32 *pixels;
|
||||||
|
|
||||||
|
// u16 frame_index;
|
||||||
|
// ASE_Cel *next;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// ////////////////////////////////////////////////////////////
|
||||||
|
// //~ Ase bitbuff helpers
|
||||||
|
|
||||||
|
// u32 ASE_PeekBits(ASE_Bitbuff *bb, u32 nbits);
|
||||||
|
// u32 ASE_ConsumeBits(ASE_Bitbuff *bb, u32 nbits);
|
||||||
|
// void ASE_SkipBits(ASE_Bitbuff *bb, u32 nbits);
|
||||||
|
|
||||||
|
// ////////////////////////////////////////////////////////////
|
||||||
|
// //~ Inflate
|
||||||
|
|
||||||
|
// u32 ASE_ReverseBits(u32 v, u32 bit_count);
|
||||||
|
// ASE_HuffDict ASE_InitHuffDict(Arena *arena, u32 max_code_bits, u32 *bl_counts, u32 bl_counts_count);
|
||||||
|
// u16 ASE_DecodeHuffDict(ASE_HuffDict *huffman, ASE_Bitbuff *bb);
|
||||||
|
// void ASE_Inflate(u8 *dst, u8 *encoded);
|
||||||
|
|
||||||
|
// ////////////////////////////////////////////////////////////
|
||||||
|
// //~ Error helpers
|
||||||
|
|
||||||
|
// void ASE_PushError(Arena *arena, ASE_ErrorList *list, String msg_src);
|
||||||
|
|
||||||
|
// ////////////////////////////////////////////////////////////
|
||||||
|
// //~ Decode helpers
|
||||||
|
|
||||||
|
// u32 ASE_Blend(u32 src, u32 dst, u8 opacity);
|
||||||
|
// void ASE_MakeDimensionsSquareish(ASE_Header *header, u32 *frames_x, u32 *frames_y, u64 *image_width, u64 *image_height);
|
||||||
|
|
||||||
|
// ////////////////////////////////////////////////////////////
|
||||||
|
// //~ Decode image
|
||||||
|
|
||||||
|
// ASE_DecodedImage ASE_DecodeImage(Arena *arena, String encoded);
|
||||||
|
|
||||||
|
// ////////////////////////////////////////////////////////////
|
||||||
|
// //~ Decode sheet
|
||||||
|
|
||||||
|
// ASE_DecodedSheet ASE_DecodeSheet(Arena *arena, String encoded);
|
||||||
|
|||||||
BIN
src/pp/pp_res/sprite/bla3.ase
(Stored with Git LFS)
BIN
src/pp/pp_res/sprite/bla3.ase
(Stored with Git LFS)
Binary file not shown.
@ -9,7 +9,7 @@ void SPR_Bootstrap(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Key helpers
|
//~ Helpers
|
||||||
|
|
||||||
SPR_SheetKey SPR_SheetKeyFromResource(ResourceKey resource)
|
SPR_SheetKey SPR_SheetKeyFromResource(ResourceKey resource)
|
||||||
{
|
{
|
||||||
@ -25,228 +25,255 @@ SPR_SpanKey SPR_SpanKeyFromName(String name)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
SPR_MarkKey SPR_MarkKeyFromName(String name)
|
String SPR_NameFromRayKind(SPR_RayKind kind)
|
||||||
{
|
{
|
||||||
SPR_MarkKey result = Zi;
|
PERSIST Readonly String names[SPR_RayKind_COUNT] = {
|
||||||
result.v = HashString(name);
|
#define X(kind_name, layer_name, ...) [SPR_RayKind_##kind_name] = CompLit(#layer_name),
|
||||||
|
SPR_RayKindXMacro(X)
|
||||||
|
#undef X
|
||||||
|
};
|
||||||
|
String result = Zi;
|
||||||
|
if (kind >= 0 && kind < countof(names))
|
||||||
|
{
|
||||||
|
result = names[kind];
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
SPR_LayerKind SPR_LayerKindFromName(String name)
|
||||||
|
{
|
||||||
|
SPR_LayerKind result = SPR_LayerKind_Visual;
|
||||||
|
if (StringBeginsWith(name, Lit(".")) || StringBeginsWith(name, Lit("#")))
|
||||||
|
{
|
||||||
|
result = SPR_LayerKind_Hidden;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Lookup
|
//~ Lookup
|
||||||
|
|
||||||
SPR_SheetEntry *SPR_SheetFromKey(SPR_SheetKey key)
|
|
||||||
{
|
|
||||||
SPR_SheetEntry *result = 0;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 frame_seq)
|
SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 frame_seq)
|
||||||
{
|
{
|
||||||
SPR_Slice result = Zi;
|
//////////////////////////////
|
||||||
|
//- Fetch sheet
|
||||||
|
|
||||||
// FIXME: Default nil result
|
SPR_SheetEntry *sheet = 0;
|
||||||
|
|
||||||
// i64 completion = G_CompletionValueFromQueue(G_QueueKind_AsyncCopy);
|
|
||||||
// if (completion < Atomic64Fetch(&sheet->atlas_copy_completion_target))
|
|
||||||
|
|
||||||
SPR_SpanEntry *span = SPR_SpanEntryFromSheet(sheet_key, span_key);
|
|
||||||
if (span && span->slices_count > 0)
|
|
||||||
{
|
{
|
||||||
SPR_SpanStatus status = Atomic32Fetch(&span->status);
|
SPR_SheetBin *sheet_bin = &SPR.sheet_bins[sheet_key.r.v % countof(SPR.sheet_bins)];
|
||||||
if (status >= SPR_SpanStatus_Rasterized)
|
Lock sheet_bin_lock = LockS(&sheet_bin->mutex);
|
||||||
{
|
{
|
||||||
i64 frame_idx = frame_seq % span->slices_count;
|
for (sheet = sheet_bin->first; sheet; sheet = sheet->next_in_bin)
|
||||||
SPR_SliceEntry *slice_entry = &span->slices[frame_idx];
|
|
||||||
result.tex = slice_entry->atlas->tex;
|
|
||||||
result.tex_rect_uv = slice_entry->atlas_rect_uv;
|
|
||||||
result.dims = slice_entry->dims;
|
|
||||||
result.ready = 1;
|
|
||||||
}
|
|
||||||
result.exists = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// SPR_SheetEntry *sheet = SPR_SheetFromKey(sheet_key, 1);
|
|
||||||
// {
|
|
||||||
// SPR_SpanEntry *span = 0;
|
|
||||||
// {
|
|
||||||
// SPR_SpanBin *span_bin = &sheet->span_bins[span_key.v % sheet->span_bins_count];
|
|
||||||
// span = span_bin->first;
|
|
||||||
// for (; span; span = span->next_in_bin)
|
|
||||||
// {
|
|
||||||
// if (span->key.v == span_key.v)
|
|
||||||
// {
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (span && span->slices_count > 0)
|
|
||||||
// {
|
|
||||||
// i64 completion = G_CompletionValueFromQueue(G_QueueKind_AsyncCopy);
|
|
||||||
// if (completion < Atomic64Fetch(&sheet->atlas_copy_completion_target))
|
|
||||||
// {
|
|
||||||
// i64 frame_idx = frame_seq % span->slices_count;
|
|
||||||
// SPR_SliceEntry *slice_entry = &span->slices[frame_idx];
|
|
||||||
// result.tex = slice_entry->atlas->tex;
|
|
||||||
// result.tex_rect_uv = slice_entry->atlas_rect_uv;
|
|
||||||
// result.dims = slice_entry->dims;
|
|
||||||
// result.ready = 1;
|
|
||||||
// }
|
|
||||||
// result.exists = 1;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
SPR_Mark SPR_MarkFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, SPR_MarkKey mark_key, i64 frame_seq)
|
|
||||||
{
|
{
|
||||||
SPR_Mark result = Zi;
|
if (sheet->key.r.v == sheet_key.r.v)
|
||||||
|
|
||||||
// SPR_SheetEntry *sheet = SPR_SheetFromKey(sheet_key, 0);
|
|
||||||
|
|
||||||
SPR_SpanEntry *span = SPR_SpanEntryFromSheet(sheet_key, span_key);
|
|
||||||
if (span && span->slices_count > 0)
|
|
||||||
{
|
|
||||||
SPR_SpanStatus status = Atomic32Fetch(&span->status);
|
|
||||||
if (status >= SPR_SpanStatus_Processed)
|
|
||||||
{
|
|
||||||
i64 frame_idx = frame_seq % span->slices_count;
|
|
||||||
|
|
||||||
SPR_MarkEntry *mark_entry = 0
|
|
||||||
{
|
|
||||||
SPR_MarkBin *mark_bin = &span->mark_bins[mark_key.v % span->mark_bins_count];
|
|
||||||
mark_entry = mark_bin->first;
|
|
||||||
for (; mark_entry; mark_entry = mark_entry->next_in_bin)
|
|
||||||
{
|
|
||||||
if (mark_entry->key.v == mark_key.v)
|
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mark_entry)
|
Unlock(&sheet_bin_lock);
|
||||||
{
|
|
||||||
SPR_SliceEntry *slice_entry = &span->slices[frame_idx];
|
|
||||||
result.tex = slice_entry->atlas->tex;
|
|
||||||
result.tex_rect_uv = slice_entry->atlas_rect_uv;
|
|
||||||
result.dims = slice_entry->dims;
|
|
||||||
result.ready = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Decode sheet
|
||||||
|
|
||||||
|
if (!sheet)
|
||||||
|
{
|
||||||
|
SPR_SheetBin *sheet_bin = &SPR.sheet_bins[sheet_key.r.v % countof(SPR.sheet_bins)];
|
||||||
|
Lock sheet_bin_lock = LockE(&sheet_bin->mutex);
|
||||||
|
{
|
||||||
|
for (sheet = sheet_bin->first; sheet; sheet = sheet->next_in_bin)
|
||||||
|
{
|
||||||
|
if (sheet->key.r.v == sheet_key.r.v)
|
||||||
|
{
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
result.exists = 1;
|
}
|
||||||
|
if (!sheet)
|
||||||
|
{
|
||||||
|
Arena *perm = PermArena();
|
||||||
|
sheet = PushStruct(perm, SPR_SheetEntry);
|
||||||
|
SllStackPushN(sheet_bin->first, sheet, next_in_bin);
|
||||||
|
sheet->key = sheet_key;
|
||||||
|
|
||||||
|
String sheet_data = DataFromResource(sheet->key.r);
|
||||||
|
String sheet_name = NameFromResource(sheet->key.r);
|
||||||
|
LogInfoF("Decoding sprite sheet %F \"%F\" (%F bytes)", FmtHandle(sheet->key.r.v), FmtString(sheet_name), FmtUint(sheet_data.len));
|
||||||
|
sheet->meta = ASE_DecodeMeta(perm, sheet_data);
|
||||||
|
|
||||||
|
//- Init slices
|
||||||
|
sheet->slices_count = MaxI64(sheet->meta.frames_count, 1);
|
||||||
|
sheet->slices = PushStructs(perm, SPR_SliceEntry, sheet->slices_count);
|
||||||
|
for (i64 slice_idx = 0; slice_idx < sheet->slices_count; ++slice_idx)
|
||||||
|
{
|
||||||
|
SPR_SliceEntry *slice = &sheet->slices[slice_idx];
|
||||||
|
for (SPR_RayKind ray_kind = 0; ray_kind < SPR_RayKind_COUNT; ++ray_kind)
|
||||||
|
{
|
||||||
|
slice->rays[ray_kind] = XformIdentity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Push async rasterization commands
|
||||||
|
if (sheet->meta.frames_count > 0)
|
||||||
|
{
|
||||||
|
Lock cmds_lock = LockE(&SPR.submit.mutex);
|
||||||
|
{
|
||||||
|
for (i64 slice_idx = 0; slice_idx < sheet->meta.frames_count; ++slice_idx)
|
||||||
|
{
|
||||||
|
SPR_CmdNode *cmd_node = SPR.submit.first_free;
|
||||||
|
if (cmd_node)
|
||||||
|
{
|
||||||
|
SllStackPop(SPR.submit.first_free);
|
||||||
|
ZeroStruct(cmd_node);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cmd_node = PushStruct(perm, SPR_CmdNode);
|
||||||
|
}
|
||||||
|
cmd_node->cmd.sheet = sheet;
|
||||||
|
cmd_node->cmd.slice_idx = slice_idx;
|
||||||
|
SllQueuePush(SPR.submit.first, SPR.submit.last, cmd_node);
|
||||||
|
++SPR.submit.count;
|
||||||
|
}
|
||||||
|
Atomic32FetchSet(&SPR.new_cmds_present, 1);
|
||||||
|
SignalAsyncTick();
|
||||||
|
}
|
||||||
|
Unlock(&cmds_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Compute rays
|
||||||
|
for (SPR_RayKind ray_kind = 0; ray_kind < SPR_RayKind_COUNT; ++ray_kind)
|
||||||
|
{
|
||||||
|
String ray_name = SPR_NameFromRayKind(ray_kind);
|
||||||
|
b32 match = 0;
|
||||||
|
for (ASE_Layer *ase_layer = sheet->meta.last_layer; ase_layer && !match; ase_layer = ase_layer->prev)
|
||||||
|
{
|
||||||
|
if (MatchString(ray_name, ase_layer->name))
|
||||||
|
{
|
||||||
|
match = 1;
|
||||||
|
for (i64 slice_idx = 0; slice_idx < sheet->meta.frames_count; ++slice_idx)
|
||||||
|
{
|
||||||
|
ASE_Cel *ase_cel = &ase_layer->cels[slice_idx];
|
||||||
|
SPR_SliceEntry *slice = &sheet->slices[slice_idx];
|
||||||
|
ASE_SinglePixelResult ray_pix = ASE_SinglePixelFromCel(ase_cel);
|
||||||
|
u32 alpha = (ray_pix.v >> 24) & 0xFF;
|
||||||
|
if (alpha > 0)
|
||||||
|
{
|
||||||
|
// TODO: Different quantization so that 128 equals 0, instead of approximately 0
|
||||||
|
f32 rot_x = (((f32)((ray_pix.v >> 0) & 0xFF) / 255.0) * 2.0) - 1;
|
||||||
|
f32 rot_y = (((f32)((ray_pix.v >> 8) & 0xFF) / 255.0) * 2.0) - 1;
|
||||||
|
Vec2 rot = NormVec2(VEC2(rot_x, rot_y));
|
||||||
|
slice->rays[ray_kind].r = rot;
|
||||||
|
slice->rays[ray_kind].t = ray_pix.pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Init spans
|
||||||
|
sheet->span_bins_count = 256;
|
||||||
|
sheet->span_bins = PushStructs(perm, SPR_SpanBin, sheet->span_bins_count);
|
||||||
|
for (ASE_Span *ase_span = sheet->meta.first_span; ase_span; ase_span = ase_span->next)
|
||||||
|
{
|
||||||
|
SPR_SpanKey new_span_key = { .v = HashString(ase_span->name) };
|
||||||
|
SPR_SpanBin *span_bin = &sheet->span_bins[new_span_key.v % sheet->span_bins_count];
|
||||||
|
SPR_SpanEntry *span = 0;
|
||||||
|
for (span = span_bin->first; span; span = span->next_in_bin)
|
||||||
|
{
|
||||||
|
if (span->key.v == new_span_key.v)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!span)
|
||||||
|
{
|
||||||
|
span = PushStruct(perm, SPR_SpanEntry);
|
||||||
|
SllQueuePush(sheet->first_span, sheet->last_span, span);
|
||||||
|
SllStackPushN(span_bin->first, span, next_in_bin);
|
||||||
|
span->key = new_span_key;
|
||||||
|
span->start = ase_span->start;
|
||||||
|
span->end = ase_span->end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Proper validation
|
||||||
|
sheet->ok = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Unlock(&sheet_bin_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Fetch span
|
||||||
|
|
||||||
|
SPR_SpanEntry *span = 0;
|
||||||
|
b32 span_matched = 0;
|
||||||
|
{
|
||||||
|
if (sheet->ok)
|
||||||
|
{
|
||||||
|
SPR_SpanBin *span_bin = &sheet->span_bins[span_key.v % sheet->span_bins_count];
|
||||||
|
for (span = span_bin->first; span; span = span->next_in_bin)
|
||||||
|
{
|
||||||
|
if (span->key.v == span_key.v)
|
||||||
|
{
|
||||||
|
span_matched = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!span)
|
||||||
|
{
|
||||||
|
// FIXME: Ensure first span always exists in sheet
|
||||||
|
span = sheet->first_span;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Fetch slice
|
||||||
|
|
||||||
|
SPR_SliceEntry *slice = 0;
|
||||||
|
{
|
||||||
|
// FIXME: Ensure span->end is never <= span->start
|
||||||
|
i64 slice_idx = span->start + (frame_seq % (span->end - span->start));
|
||||||
|
slice = &sheet->slices[slice_idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////
|
||||||
|
//- Compute result
|
||||||
|
|
||||||
|
SPR_Slice result = Zi;
|
||||||
|
{
|
||||||
|
result.exists = span_matched;
|
||||||
|
if (result.exists)
|
||||||
|
{
|
||||||
|
i64 completion = G_CompletionValueFromQueue(G_QueueKind_AsyncCopy);
|
||||||
|
if (completion >= Atomic64Fetch(&slice->atlas_copy_completion_target))
|
||||||
|
{
|
||||||
|
result.ready = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Fill tex info
|
||||||
|
if (result.ready)
|
||||||
|
{
|
||||||
|
result.tex = slice->atlas->tex_ref;
|
||||||
|
result.tex_rect_uv = slice->atlas_rect_uv;
|
||||||
|
result.dims = slice->dims;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result.tex = SPR.unready_tex;
|
||||||
|
result.tex_rect_uv = RNG2(VEC2(0, 0), VEC2(1, 1));
|
||||||
|
result.dims = SPR.unready_tex_dims;
|
||||||
|
}
|
||||||
|
// Fill rays
|
||||||
|
StaticAssert(countof(result.rays) == countof(slice->rays));
|
||||||
|
CopyStructs(result.rays, slice->rays, countof(result.rays));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// SPR_SliceEntry SPR_SliceFromSheet(SPR_SheetKey sheet, SPR_SpanKey span, i64 frame_seq)
|
|
||||||
// {
|
|
||||||
// // TODO: Ability to specify desired alpha modes (Straight, Premultiplied, Opaque)
|
|
||||||
// SPR_SliceEntry result = Zi;
|
|
||||||
|
|
||||||
// // FIXME
|
|
||||||
// u64 hash = sheet.r.v;
|
|
||||||
// hash = HashStringEx(hash, slice_name);
|
|
||||||
|
|
||||||
// i64 completion = G_CompletionValueFromQueue(G_QueueKind_AsyncCopy);
|
|
||||||
|
|
||||||
// // Search for existing entry
|
|
||||||
// b32 found = 0;
|
|
||||||
// SPR_SliceBin *bin = &SPR.slice_bins[hash % countof(SPR.slice_bins)];
|
|
||||||
// {
|
|
||||||
// Lock bin_lock = LockS(&bin->mutex);
|
|
||||||
// {
|
|
||||||
// SPR_SliceEntry *entry = bin->first;
|
|
||||||
// for (; entry; entry = entry->next)
|
|
||||||
// {
|
|
||||||
// if (entry->hash == hash)
|
|
||||||
// {
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (entry)
|
|
||||||
// {
|
|
||||||
// if (completion >= Atomic64Fetch(&entry->atlas_copy_completion_target))
|
|
||||||
// {
|
|
||||||
// result = entry->slice_entry;
|
|
||||||
// }
|
|
||||||
// found = 1;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// Unlock(&bin_lock);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Push new entry
|
|
||||||
// if (!found)
|
|
||||||
// {
|
|
||||||
// Lock submit_lock = LockE(&SPR.submit.mutex);
|
|
||||||
// Lock bin_lock = LockE(&bin->mutex);
|
|
||||||
// {
|
|
||||||
// SPR_SliceEntry *entry = bin->first;
|
|
||||||
// for (; entry; entry = entry->next)
|
|
||||||
// {
|
|
||||||
// if (entry->hash == hash)
|
|
||||||
// {
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (entry)
|
|
||||||
// {
|
|
||||||
// if (completion >= Atomic64Fetch(&entry->atlas_copy_completion_target))
|
|
||||||
// {
|
|
||||||
// result = entry->slice_entry;
|
|
||||||
// }
|
|
||||||
// found = 1;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// Arena *perm = PermArena();
|
|
||||||
|
|
||||||
// entry = PushStruct(perm, SPR_SliceEntry);
|
|
||||||
// entry->hash = hash;
|
|
||||||
// Atomic64FetchSet(&entry->atlas_copy_completion_target, I64Max);
|
|
||||||
// entry->sheet = sheet;
|
|
||||||
// entry->slice_name = PushString(perm, slice_name);
|
|
||||||
// SllStackPush(bin->first, entry);
|
|
||||||
|
|
||||||
// SPR_CmdNode *n = SPR.submit.first_free;
|
|
||||||
// if (n)
|
|
||||||
// {
|
|
||||||
// SllStackPop(SPR.submit.first_free);
|
|
||||||
// ZeroStruct(n);
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// n = PushStruct(perm, SPR_CmdNode);
|
|
||||||
// }
|
|
||||||
// n->cmd.entry = entry;
|
|
||||||
// SllQueuePush(SPR.submit.first, SPR.submit.last, n);
|
|
||||||
// ++SPR.submit.count;
|
|
||||||
// Atomic32FetchSet(&SPR.new_cmds_present, 1);
|
|
||||||
// SignalAsyncTick();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// Unlock(&bin_lock);
|
|
||||||
// Unlock(&submit_lock);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (G_IsRefNil(result.tex))
|
|
||||||
// {
|
|
||||||
// result.tex = G_BlankTexture2D();
|
|
||||||
// result.uv_rect.p0 = VEC2(0, 0);
|
|
||||||
// result.uv_rect.p1 = VEC2(1, 1);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return result;
|
|
||||||
// }
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Async
|
//~ Async
|
||||||
|
|
||||||
@ -291,56 +318,31 @@ void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
|
|||||||
{
|
{
|
||||||
SPR_Cmd *cmd = &cmds[cmd_idx];
|
SPR_Cmd *cmd = &cmds[cmd_idx];
|
||||||
SPR_SheetEntry *sheet = cmd->sheet;
|
SPR_SheetEntry *sheet = cmd->sheet;
|
||||||
ASE_Meta *meta = &sheet->meta;
|
ASE_Meta meta = sheet->meta;
|
||||||
|
|
||||||
String encoded = DataFromResource(sheet->key.r);
|
// String encoded = DataFromResource(sheet->key.r);
|
||||||
String name = NameFromResource(sheet->key.r);
|
// String name = NameFromResource(sheet->key.r);
|
||||||
LogInfoF("Rasterizing sprite sheet %F \"%F\" (%F bytes)", FmtHandle(sheet->key.r), FmtString(name), FmtUint(encoded.len));
|
// LogInfoF("Rasterizing sprite sheet %F \"%F\" (%F bytes)", FmtHandle(sheet->key.r), FmtString(name), FmtUint(encoded.len));
|
||||||
|
|
||||||
for (ASE_Span *ase_span = meta.first_span; ase_span; ase_span = ase_span->next)
|
SPR_SliceEntry *slice = &sheet->slices[cmd->slice_idx];
|
||||||
{
|
|
||||||
u64 span_hash = HashString(ase_span->name);
|
|
||||||
SPR_SpanBin *span_bin = &sheet->span_bins[span_hash % sheet->span_bins_count];
|
|
||||||
SPR_SpanEntry *span = span_bin->first;
|
|
||||||
for (; span; span = span->next_in_bin)
|
|
||||||
{
|
|
||||||
if (span->key.v == span_hash)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (span)
|
|
||||||
{
|
|
||||||
i64 slice_idx = 0;
|
|
||||||
for (ASE_Frame *ase_frame = span->first_frame; ase_frame && slice_idx < span->slices_count; ase_frame = ase_frame->next)
|
|
||||||
{
|
|
||||||
SPR_SliceEntry *slice_entry = &span->slice_entry[slice_idx];
|
|
||||||
|
|
||||||
// // Determine slice_entry bounds
|
//////////////////////////////
|
||||||
// Rng2 frame_bounds = Rng2Empty;
|
//- Rasterize
|
||||||
// for (ASE_Layer *ase_layer = ase_frame->first_layer; ase_layer; ase_layer = ase_layer->next)
|
|
||||||
// {
|
|
||||||
// if (!StringBeginsWith(ase_layer->name, Lit(".")))
|
|
||||||
// {
|
|
||||||
// frame_bounds = UnionRng2(frame_bounds);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// Vec2 dims = DimsFromRng2(frame_bounds);
|
|
||||||
|
|
||||||
if (!IsRng2Empty(frame_bounds))
|
u32 *pixels = PushStructs(frame_arena, u32, slice->dims.x * slice->dims.y);
|
||||||
{
|
for (ASE_Layer *ase_layer = sheet->meta.last_layer; ase_layer; ase_layer = ase_layer->prev)
|
||||||
// Rasterize slice_entry
|
|
||||||
u32 *pixels = PushStructs(frame_arena, u32, slice_entry->dims.x * slice_entry->dims.y);
|
|
||||||
for (ASE_Layer *ase_layer = ase_frame->first_layer; ase_layer; ase_layer = ase_layer->next)
|
|
||||||
{
|
{
|
||||||
SPR_LayerKind kind = SPR_LayerKindFromName(ase_layer->name);
|
SPR_LayerKind kind = SPR_LayerKindFromName(ase_layer->name);
|
||||||
if (kind == SPR_LayerKind_Standard)
|
if (kind == SPR_LayerKind_Visual)
|
||||||
{
|
{
|
||||||
ASE_RasterizeLayer(ase_layer, pixels, slice_entry->dims);
|
ASE_Cel *cel = &ase_layer->cels[cmd->slice_idx];
|
||||||
|
ASE_RasterizeCel(cel, pixels, slice->dims);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate atlas rect
|
//////////////////////////////
|
||||||
|
//- Write atlas
|
||||||
|
|
||||||
// TODO: Use a more efficient atlas packing algorithm for less wasted space
|
// TODO: Use a more efficient atlas packing algorithm for less wasted space
|
||||||
SPR_Atlas *atlas = SPR.first_atlas;
|
SPR_Atlas *atlas = SPR.first_atlas;
|
||||||
b32 can_use_atlas = 0;
|
b32 can_use_atlas = 0;
|
||||||
@ -350,9 +352,8 @@ void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
|
|||||||
// Create atlas
|
// Create atlas
|
||||||
if (!atlas)
|
if (!atlas)
|
||||||
{
|
{
|
||||||
Arena *perm = PermArena();
|
|
||||||
atlas = PushStruct(perm, SPR_Atlas);
|
atlas = PushStruct(perm, SPR_Atlas);
|
||||||
i32 atlas_size = MaxI32(1024, NextPow2U64(MaxI32(slice_entry->dims.x, slice_entry->dims.y)));
|
i32 atlas_size = MaxI32(1024, NextPow2U64(MaxI32(slice->dims.x, slice->dims.y)));
|
||||||
atlas->dims = VEC2I32(atlas_size, atlas_size);
|
atlas->dims = VEC2I32(atlas_size, atlas_size);
|
||||||
{
|
{
|
||||||
G_ArenaHandle gpu_perm = G_PermArena();
|
G_ArenaHandle gpu_perm = G_PermArena();
|
||||||
@ -369,14 +370,14 @@ void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
|
|||||||
}
|
}
|
||||||
// Determine pos in atlas
|
// Determine pos in atlas
|
||||||
pos_in_atlas = atlas->cur_pos;
|
pos_in_atlas = atlas->cur_pos;
|
||||||
atlas->cur_row_height = MaxI32(atlas->cur_row_height, slice_entry->dims.y);
|
atlas->cur_row_height = MaxI32(atlas->cur_row_height, slice->dims.y);
|
||||||
if (pos_in_atlas.x + slice_entry->dims.x > atlas->dims.x);
|
if (pos_in_atlas.x + slice->dims.x > atlas->dims.x);
|
||||||
{
|
{
|
||||||
atlas->cur_pos.x = 0;
|
atlas->cur_pos.x = 0;
|
||||||
atlas->cur_pos.y += atlas->cur_row_height;
|
atlas->cur_pos.y += atlas->cur_row_height;
|
||||||
atlas->cur_row_height = slice_entry->dims.y;
|
atlas->cur_row_height = slice->dims.y;
|
||||||
}
|
}
|
||||||
atlas->cur_pos.x += slice_entry->dims.x;
|
atlas->cur_pos.x += slice->dims.x;
|
||||||
if (atlas->cur_pos.x < atlas->dims.x && atlas->cur_pos.y < atlas->dims.y)
|
if (atlas->cur_pos.x < atlas->dims.x && atlas->cur_pos.y < atlas->dims.y)
|
||||||
{
|
{
|
||||||
can_use_atlas = 1;
|
can_use_atlas = 1;
|
||||||
@ -388,209 +389,38 @@ void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fill slice_entry atlas info
|
// Fill slice_entry atlas info
|
||||||
slice_entry->atlas = atlas;
|
{
|
||||||
slice_entry->atlas_rect = RNG2I32(pos_in_atlas, AddVec2I32(pos_in_atlas, slice_entry->dims));
|
Rng2I32 atlas_rect = RNG2I32(pos_in_atlas, AddVec2I32(pos_in_atlas, Vec2I32FromVec(slice->dims)));
|
||||||
slice_entry->atlas_rect_uv.p0.x = (f32)slice_entry->atlas_rect.p0.x / (f32)atlas->dims.x;
|
slice->atlas = atlas;
|
||||||
slice_entry->atlas_rect_uv.p0.y = (f32)slice_entry->atlas_rect.p0.y / (f32)atlas->dims.x;
|
slice->atlas_rect_uv.p0.x = (f32)atlas_rect.p0.x / (f32)atlas->dims.x;
|
||||||
slice_entry->atlas_rect_uv.p1.x = (f32)slice_entry->atlas_rect.p1.x / (f32)atlas->dims.x;
|
slice->atlas_rect_uv.p0.y = (f32)atlas_rect.p0.y / (f32)atlas->dims.x;
|
||||||
slice_entry->atlas_rect_uv.p1.y = (f32)slice_entry->atlas_rect.p1.y / (f32)atlas->dims.x;
|
slice->atlas_rect_uv.p1.x = (f32)atlas_rect.p1.x / (f32)atlas->dims.x;
|
||||||
|
slice->atlas_rect_uv.p1.y = (f32)atlas_rect.p1.y / (f32)atlas->dims.x;
|
||||||
|
}
|
||||||
|
|
||||||
// Copy to atlas
|
// Copy to atlas
|
||||||
G_CopyCpuToTexture(
|
G_CopyCpuToTexture(
|
||||||
cl,
|
cl,
|
||||||
atlas->tex, VEC3I32(pos_in_atlas.x, pos_in_atlas.y, 0),
|
atlas->tex, VEC3I32(pos_in_atlas.x, pos_in_atlas.y, 0),
|
||||||
pixels, VEC3I32(slice_entry->dims.x, slice_entry->dims.y, 1),
|
pixels, VEC3I32(slice->dims.x, slice->dims.y, 1),
|
||||||
RNG3I32(
|
RNG3I32(
|
||||||
VEC3I32(0, 0, 0),
|
VEC3I32(0, 0, 0),
|
||||||
VEC3I32(slice_entry->dims.x, slice_entry->dims.y, 1)
|
VEC3I32(slice->dims.x, slice->dims.y, 1)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
++slice_idx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i64 completion_target = G_CommitCommandList(cl);
|
i64 completion_target = G_CommitCommandList(cl);
|
||||||
|
|
||||||
// Update completion targets
|
//////////////////////////////
|
||||||
|
//- Update completion targets
|
||||||
|
|
||||||
for (i64 cmd_idx = 0; cmd_idx < cmds_count; ++cmd_idx)
|
for (i64 cmd_idx = 0; cmd_idx < cmds_count; ++cmd_idx)
|
||||||
{
|
{
|
||||||
SPR_Cmd *cmd = &cmds[cmd_idx];
|
SPR_Cmd *cmd = &cmds[cmd_idx];
|
||||||
SPR_SheetEntry *sheet = cmd->sheet;
|
SPR_SliceEntry *slice = &cmd->sheet->slices[cmd->slice_idx];
|
||||||
Atomic64Set(&sheet->atlas_copy_completion_target, completion_target);
|
Atomic64Set(&slice->atlas_copy_completion_target, completion_target);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// ASE_DecodedImage decoded_image = ASE_DecodeImage(frame_arena, encoded);
|
|
||||||
// ASE_DecodedSheet decoded_sheet = ASE_DecodeSheet(frame_arena, encoded);
|
|
||||||
|
|
||||||
// if (decoded_image.ok)
|
|
||||||
// {
|
|
||||||
// G_ResourceHandle gpu_resource = Zi;
|
|
||||||
// G_ArenaHandle gpu_perm = G_PermArena();
|
|
||||||
// G_CommandListHandle cl = G_PrepareCommandList(G_QueueKind_AsyncCopy);
|
|
||||||
// {
|
|
||||||
// Vec3I32 dims = Zi;
|
|
||||||
// dims.x = decoded_image.width;
|
|
||||||
// dims.y = decoded_image.height;
|
|
||||||
// dims.z = 1;
|
|
||||||
// gpu_resource = G_PushTexture2D(
|
|
||||||
// gpu_perm, cl,
|
|
||||||
// G_Format_R8G8B8A8_Unorm_Srgb,
|
|
||||||
// dims,
|
|
||||||
// G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present
|
|
||||||
// );
|
|
||||||
// G_CopyCpuToTexture(
|
|
||||||
// cl,
|
|
||||||
// gpu_resource, VEC3I32(0, 0, 0),
|
|
||||||
// decoded_image.pixels, dims,
|
|
||||||
// RNG3I32(
|
|
||||||
// VEC3I32(0, 0, 0),
|
|
||||||
// dims
|
|
||||||
// )
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// i64 completion_target = G_CommitCommandList(cl);
|
|
||||||
// sheet->atlas_copy_completion_target = completion_target;
|
|
||||||
// sheet->tex = G_PushTexture2DRef(gpu_perm, gpu_resource);
|
|
||||||
// // LogDebugF("Decoded with ref: %F", FmtUint(slice_entry->slice_entry.tex.v));
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// // TODO: Use 'missing' texture
|
|
||||||
// sheet->tex = G_BlankTexture2D();
|
|
||||||
// sheet->atlas_copy_completion_target = 0;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// slice_entry->slice_entry.tex = sheet->tex;
|
|
||||||
// // FIXME: Real uv
|
|
||||||
// slice_entry->slice_entry.uv_rect.p0 = VEC2(0, 0);
|
|
||||||
// slice_entry->slice_entry.uv_rect.p1= VEC2(1, 1);
|
|
||||||
// Atomic64Set(&slice_entry->atlas_copy_completion_target, sheet->atlas_copy_completion_target);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
|
|
||||||
// {
|
|
||||||
// Arena *perm = PermArena();
|
|
||||||
// SPR_AsyncCtx *async = &SPR.async;
|
|
||||||
// Arena *frame_arena = base_async_lane_frame->arena;
|
|
||||||
|
|
||||||
// // TODO: Go wide
|
|
||||||
// if (lane->idx == 0)
|
|
||||||
// {
|
|
||||||
// if (Atomic32Fetch(&SPR.new_cmds_present))
|
|
||||||
// {
|
|
||||||
// Atomic32Set(&SPR.new_cmds_present, 0);
|
|
||||||
// SPR_CmdNode *first_cmd_node = 0;
|
|
||||||
// SPR_CmdNode *last_cmd_node = 0;
|
|
||||||
// u64 cmds_count = 0;
|
|
||||||
// {
|
|
||||||
// Lock lock = LockE(&SPR.submit.mutex);
|
|
||||||
// {
|
|
||||||
// first_cmd_node = SPR.submit.first;
|
|
||||||
// last_cmd_node = SPR.submit.last;
|
|
||||||
// cmds_count = SPR.submit.count;
|
|
||||||
// SPR.submit.first = 0;
|
|
||||||
// SPR.submit.last = 0;
|
|
||||||
// SPR.submit.count = 0;
|
|
||||||
// }
|
|
||||||
// Unlock(&lock);
|
|
||||||
// }
|
|
||||||
// if (cmds_count > 0)
|
|
||||||
// {
|
|
||||||
// for (SPR_CmdNode *n = first_cmd_node; n; n = n->next)
|
|
||||||
// {
|
|
||||||
// SPR_Cmd cmd = n->cmd;
|
|
||||||
// SPR_SliceEntry *slice_entry = cmd.entry;
|
|
||||||
|
|
||||||
// SPR_SheetBin *sheet_bin = &async->sheet_bins[slice_entry->sheet.r.v % countof(async->sheet_bins)];
|
|
||||||
// SPR_SheetEntry *sheet = sheet_bin->first;
|
|
||||||
// for (; sheet; sheet = sheet->next)
|
|
||||||
// {
|
|
||||||
// if (sheet->key.r.v == slice_entry->sheet.r.v)
|
|
||||||
// {
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Decode sheet
|
|
||||||
// // TODO: Distribute chunk decoding accross wave
|
|
||||||
// // TODO: Use atlas allocator and separate slices into unique textures
|
|
||||||
// // TODO: Reuse command list for all uploads
|
|
||||||
// if (!sheet)
|
|
||||||
// {
|
|
||||||
// sheet = PushStruct(perm, SPR_SheetEntry);
|
|
||||||
// sheet->key = slice_entry->sheet;
|
|
||||||
// SllStackPush(sheet_bin->first, sheet);
|
|
||||||
|
|
||||||
// String encoded = DataFromResource(sheet->key.r);
|
|
||||||
// String name = NameFromResource(sheet->key.r);
|
|
||||||
// LogInfoF("Decoding sprite sheet \"%F\" (%F bytes)", FmtString(name), FmtUint(encoded.len));
|
|
||||||
|
|
||||||
// ASE_DecodedImage decoded_image = ASE_DecodeImage(frame_arena, encoded);
|
|
||||||
// ASE_DecodedSheet decoded_sheet = ASE_DecodeSheet(frame_arena, encoded);
|
|
||||||
|
|
||||||
// if (decoded_image.ok)
|
|
||||||
// {
|
|
||||||
// G_ResourceHandle gpu_resource = Zi;
|
|
||||||
// G_ArenaHandle gpu_perm = G_PermArena();
|
|
||||||
// G_CommandListHandle cl = G_PrepareCommandList(G_QueueKind_AsyncCopy);
|
|
||||||
// {
|
|
||||||
// Vec3I32 dims = Zi;
|
|
||||||
// dims.x = decoded_image.width;
|
|
||||||
// dims.y = decoded_image.height;
|
|
||||||
// dims.z = 1;
|
|
||||||
// gpu_resource = G_PushTexture2D(
|
|
||||||
// gpu_perm, cl,
|
|
||||||
// G_Format_R8G8B8A8_Unorm_Srgb,
|
|
||||||
// dims,
|
|
||||||
// G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present
|
|
||||||
// );
|
|
||||||
// G_CopyCpuToTexture(
|
|
||||||
// cl,
|
|
||||||
// gpu_resource, VEC3I32(0, 0, 0),
|
|
||||||
// decoded_image.pixels, dims,
|
|
||||||
// RNG3I32(
|
|
||||||
// VEC3I32(0, 0, 0),
|
|
||||||
// dims
|
|
||||||
// )
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// i64 completion_target = G_CommitCommandList(cl);
|
|
||||||
// sheet->atlas_copy_completion_target = completion_target;
|
|
||||||
// sheet->tex = G_PushTexture2DRef(gpu_perm, gpu_resource);
|
|
||||||
// // LogDebugF("Decoded with ref: %F", FmtUint(slice_entry->slice_entry.tex.v));
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// // TODO: Use 'missing' texture
|
|
||||||
// sheet->tex = G_BlankTexture2D();
|
|
||||||
// sheet->atlas_copy_completion_target = 0;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// slice_entry->slice_entry.tex = sheet->tex;
|
|
||||||
// // FIXME: Real uv
|
|
||||||
// slice_entry->slice_entry.uv_rect.p0 = VEC2(0, 0);
|
|
||||||
// slice_entry->slice_entry.uv_rect.p1= VEC2(1, 1);
|
|
||||||
// Atomic64Set(&slice_entry->atlas_copy_completion_target, sheet->atlas_copy_completion_target);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Free cmds
|
|
||||||
// Lock lock = LockE(&SPR.submit.mutex);
|
|
||||||
// {
|
|
||||||
// last_cmd_node->next = SPR.submit.first_free;
|
|
||||||
// SPR.submit.first_free = first_cmd_node;
|
|
||||||
// }
|
|
||||||
// Unlock(&lock);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|||||||
@ -3,56 +3,120 @@
|
|||||||
|
|
||||||
Struct(SPR_SheetKey) { ResourceKey r; };
|
Struct(SPR_SheetKey) { ResourceKey r; };
|
||||||
Struct(SPR_SpanKey) { u64 v; };
|
Struct(SPR_SpanKey) { u64 v; };
|
||||||
Struct(SPR_MarkKey) { u64 v; };
|
|
||||||
|
|
||||||
#define SPR_NilSheetKey ((SPR_SheetKey) { 0 })
|
#define SPR_NilSheetKey ((SPR_SheetKey) { 0 })
|
||||||
#define SPR_NilSpanKey ((SPR_SpanKey) { 0 })
|
#define SPR_NilSpanKey ((SPR_SpanKey) { 0 })
|
||||||
#define SPR_NilRayKey ((SPR_MarkKey) { 0 })
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Slice types
|
//~ Atlas types
|
||||||
|
|
||||||
|
Struct(SPR_Atlas)
|
||||||
|
{
|
||||||
|
SPR_Atlas *next;
|
||||||
|
|
||||||
|
Vec2I32 dims;
|
||||||
|
G_ResourceHandle tex;
|
||||||
|
G_Texture2DRef tex_ref;
|
||||||
|
Vec2I32 cur_pos;
|
||||||
|
i32 cur_row_height;
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Ray types
|
||||||
|
|
||||||
|
#define SPR_RayKindXMacro(X) \
|
||||||
|
X(Origin, .origin) \
|
||||||
|
X(Ap, .ap) \
|
||||||
|
/* ----------------------------- */
|
||||||
|
|
||||||
|
Enum(SPR_RayKind)
|
||||||
|
{
|
||||||
|
#define X(kind_name, ...) SPR_RayKind_##kind_name,
|
||||||
|
SPR_RayKindXMacro(X)
|
||||||
|
#undef X
|
||||||
|
SPR_RayKind_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Layer types
|
||||||
|
|
||||||
|
Enum(SPR_LayerKind)
|
||||||
|
{
|
||||||
|
SPR_LayerKind_Visual,
|
||||||
|
SPR_LayerKind_Hidden,
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//~ Lookup result types
|
||||||
|
|
||||||
Struct(SPR_Slice)
|
Struct(SPR_Slice)
|
||||||
{
|
{
|
||||||
|
Xform rays[SPR_RayKind_COUNT];
|
||||||
|
|
||||||
G_Texture2DRef tex;
|
G_Texture2DRef tex;
|
||||||
Rng2 uv_rect;
|
Rng2 tex_rect_uv;
|
||||||
Vec2 dims;
|
Vec2 dims;
|
||||||
|
|
||||||
|
b32 exists;
|
||||||
b32 ready;
|
b32 ready;
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Cache types
|
//~ Cache types
|
||||||
|
|
||||||
|
//- Slice
|
||||||
|
|
||||||
Struct(SPR_SliceEntry)
|
Struct(SPR_SliceEntry)
|
||||||
{
|
{
|
||||||
SPR_SliceEntry *next;
|
SPR_SliceEntry *next_in_bin;
|
||||||
|
|
||||||
SPR_SheetKey sheet;
|
Xform rays[SPR_RayKind_COUNT];
|
||||||
u64 hash;
|
|
||||||
|
SPR_Atlas *atlas;
|
||||||
|
Vec2 dims;
|
||||||
|
Rng2 atlas_rect_uv;
|
||||||
Atomic64 atlas_copy_completion_target;
|
Atomic64 atlas_copy_completion_target;
|
||||||
|
|
||||||
String slice_name;
|
|
||||||
|
|
||||||
SPR_Slice slice;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(SPR_SliceBin)
|
//- Span
|
||||||
|
|
||||||
|
Struct(SPR_SpanEntry)
|
||||||
{
|
{
|
||||||
Mutex mutex;
|
SPR_SpanEntry *next;
|
||||||
SPR_SliceEntry *first;
|
SPR_SpanEntry *next_in_bin;
|
||||||
|
SPR_SpanKey key;
|
||||||
|
|
||||||
|
i64 start;
|
||||||
|
i64 end;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Struct(SPR_SpanBin)
|
||||||
|
{
|
||||||
|
SPR_SpanEntry *first;
|
||||||
|
};
|
||||||
|
|
||||||
|
//- Sheet
|
||||||
|
|
||||||
Struct(SPR_SheetEntry)
|
Struct(SPR_SheetEntry)
|
||||||
{
|
{
|
||||||
SPR_SheetEntry *next;
|
SPR_SheetEntry *next_in_bin;
|
||||||
SPR_SheetKey key;
|
SPR_SheetKey key;
|
||||||
i64 atlas_copy_completion_target;
|
|
||||||
G_Texture2DRef tex;
|
i64 slices_count;
|
||||||
|
SPR_SliceEntry *slices;
|
||||||
|
|
||||||
|
i64 span_bins_count;
|
||||||
|
SPR_SpanBin *span_bins;
|
||||||
|
SPR_SpanEntry *first_span;
|
||||||
|
SPR_SpanEntry *last_span;
|
||||||
|
|
||||||
|
ASE_Meta meta;
|
||||||
|
b32 ok;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(SPR_SheetBin)
|
Struct(SPR_SheetBin)
|
||||||
{
|
{
|
||||||
|
Mutex mutex;
|
||||||
SPR_SheetEntry *first;
|
SPR_SheetEntry *first;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -61,7 +125,8 @@ Struct(SPR_SheetBin)
|
|||||||
|
|
||||||
Struct(SPR_Cmd)
|
Struct(SPR_Cmd)
|
||||||
{
|
{
|
||||||
SPR_SliceEntry *entry;
|
SPR_SheetEntry *sheet;
|
||||||
|
i64 slice_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(SPR_CmdNode)
|
Struct(SPR_CmdNode)
|
||||||
@ -75,12 +140,19 @@ Struct(SPR_CmdNode)
|
|||||||
|
|
||||||
Struct(SPR_AsyncCtx)
|
Struct(SPR_AsyncCtx)
|
||||||
{
|
{
|
||||||
SPR_SheetBin sheet_bins[Kibi(16)];
|
i32 _;
|
||||||
};
|
};
|
||||||
|
|
||||||
Struct(SPR_Ctx)
|
Struct(SPR_Ctx)
|
||||||
{
|
{
|
||||||
SPR_SliceBin slice_bins[Kibi(16)];
|
SPR_SheetBin sheet_bins[Kibi(16)];
|
||||||
|
|
||||||
|
// FIXME: Initialize this
|
||||||
|
G_Texture2DRef unready_tex;
|
||||||
|
Vec2 unready_tex_dims;
|
||||||
|
|
||||||
|
i64 atlases_count;
|
||||||
|
SPR_Atlas *first_atlas;
|
||||||
|
|
||||||
Atomic32 new_cmds_present;
|
Atomic32 new_cmds_present;
|
||||||
struct
|
struct
|
||||||
@ -103,18 +175,18 @@ extern SPR_Ctx SPR;
|
|||||||
void SPR_Bootstrap(void);
|
void SPR_Bootstrap(void);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Key helpers
|
//~ Helpers
|
||||||
|
|
||||||
SPR_SheetKey SPR_SheetKeyFromResource(ResourceKey resource);
|
SPR_SheetKey SPR_SheetKeyFromResource(ResourceKey resource);
|
||||||
SPR_SpanKey SPR_SpanKeyFromName(String name);
|
SPR_SpanKey SPR_SpanKeyFromName(String name);
|
||||||
SPR_MarkKey SPR_MarkKeyFromName(String name);
|
|
||||||
|
String SPR_NameFromRayKind(SPR_RayKind kind);
|
||||||
|
SPR_LayerKind SPR_LayerKindFromName(String name);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Lookup helpers
|
//~ Lookup
|
||||||
|
|
||||||
SPR_SpanEntry *SPR_SpanEntryFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key);
|
|
||||||
SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 frame_seq);
|
SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, i64 frame_seq);
|
||||||
SPR_Mark SPR_MarkFromSheet(SPR_SheetKey sheet_key, SPR_SpanKey span_key, SPR_MarkKey ray_key, i64 frame_seq);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
//~ Async
|
//~ Async
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user