Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/unstable' into gfx-rdp
Browse files Browse the repository at this point in the history
  • Loading branch information
rasky committed Jun 18, 2023
2 parents 2ceb039 + 50c1360 commit 1149832
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 23 deletions.
1 change: 1 addition & 0 deletions include/rdpq_font.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ struct rdpq_font_s;
typedef struct rdpq_font_s rdpq_font_t;

rdpq_font_t* rdpq_font_load(const char *fn);
rdpq_font_t* rdpq_font_load_buf(void *buf, int sz);
void rdpq_font_free(rdpq_font_t *fnt);

void rdpq_font_begin(color_t color);
Expand Down
23 changes: 21 additions & 2 deletions include/sprite.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ typedef struct sprite_s
uint32_t data[0];
} sprite_t;

#define SPRITE_FLAGS_TEXFORMAT 0x1F ///< Pixel format of the sprite
#define SPRITE_FLAGS_EXT 0x80 ///< Sprite contains extended information (new format)
#define SPRITE_FLAGS_TEXFORMAT 0x1F ///< Pixel format of the sprite
#define SPRITE_FLAGS_OWNEDBUFFER 0x20 ///< Flag specifying that the sprite buffer must be freed by sprite_free
#define SPRITE_FLAGS_EXT 0x80 ///< Sprite contains extended information (new format)

/**
* @brief Load a sprite from a filesystem (eg: ROM)
Expand All @@ -78,6 +79,24 @@ typedef struct sprite_s
*/
sprite_t *sprite_load(const char *fn);

/**
* @brief Load a sprite from a buffer
*
* This function loads a sprite from a buffer corresponding to sprite
* file data in memory. The function also performs any necessary processing
* to load the sprite file data.
*
* sprite_load_buf functions in-place which means it does not allocate another
* buffer for the loaded sprite. So, sprite_free will not remove the sprite data
* from memory. This means that the input buffer must be freed manually after
* sprite_free is called.
*
* @param buf Pointer to the sprite file data
* @param sz Size of the sprite file buffer
* @return sprite_t* The loaded sprite
*/
sprite_t *sprite_load_buf(void *buf, int sz);

/** @brief Deallocate a sprite */
void sprite_free(sprite_t *sprite);

Expand Down
49 changes: 38 additions & 11 deletions src/rdpq/rdpq_font.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ _Static_assert(sizeof(atlas_t) == 12, "atlas_t size is wrong");
_Static_assert(sizeof(kerning_t) == 3, "kerning_t size is wrong");

#define PTR_DECODE(font, ptr) ((void*)(((uint8_t*)(font)) + (uint32_t)(ptr)))
#define PTR_ENCODE(font, ptr) ((void*)(((uint8_t*)(ptr)) - (uint32_t)(font)))

/** @brief Drawing context */
static struct draw_ctx_s {
Expand All @@ -37,32 +38,58 @@ static rdpq_tile_t atlas_activate(atlas_t *atlas)
return draw_ctx.atlas_tile;
}

rdpq_font_t* rdpq_font_load(const char *fn)
rdpq_font_t* rdpq_font_load_buf(void *buf, int sz)
{
int sz;
rdpq_font_t *fnt = asset_load(fn, &sz);
assertf(fnt->magic == FONT_MAGIC_V0, "invalid font file (magic: %08lx)", fnt->magic);

rdpq_font_t *fnt = buf;
assertf(sz >= sizeof(rdpq_font_t), "Font buffer too small (sz=%d)", sz);
if(fnt->magic == FONT_MAGIC_LOADED) {
assertf(0, "Trying to load already loaded font data (buf=%p, sz=%08x)", buf, sz);
}
assertf(fnt->magic == FONT_MAGIC_V0, "invalid font data (magic: %08lx)", fnt->magic);
fnt->ranges = PTR_DECODE(fnt, fnt->ranges);
fnt->glyphs = PTR_DECODE(fnt, fnt->glyphs);
fnt->atlases = PTR_DECODE(fnt, fnt->atlases);
fnt->kerning = PTR_DECODE(fnt, fnt->kerning);
for (int i = 0; i < fnt->num_atlases; i++) {
fnt->atlases[i].buf = PTR_DECODE(fnt, fnt->atlases[i].buf);
}

fnt->magic = FONT_MAGIC_LOADED;
data_cache_hit_writeback(fnt, sz);
return fnt;
}

rdpq_font_t* rdpq_font_load(const char *fn)
{
int sz;
void *buf = asset_load(fn, &sz);
rdpq_font_t *fnt = rdpq_font_load_buf(buf, sz);
fnt->magic = FONT_MAGIC_OWNED;
return fnt;
}

static void font_unload(rdpq_font_t *fnt)
{
for (int i = 0; i < fnt->num_atlases; i++) {
fnt->atlases[i].buf = PTR_ENCODE(fnt, fnt->atlases[i].buf);
}
fnt->ranges = PTR_ENCODE(fnt, fnt->ranges);
fnt->glyphs = PTR_ENCODE(fnt, fnt->glyphs);
fnt->atlases = PTR_ENCODE(fnt, fnt->atlases);
fnt->kerning = PTR_ENCODE(fnt, fnt->kerning);
fnt->magic = FONT_MAGIC_V0;
}

void rdpq_font_free(rdpq_font_t *fnt)
{
#ifndef NDEBUG
// To help debugging, zero the font structure
memset(fnt, 0, sizeof(rdpq_font_t));
#endif
font_unload(fnt);
if(fnt->magic == FONT_MAGIC_OWNED) {
#ifndef NDEBUG
// To help debugging, zero the font structure
memset(fnt, 0, sizeof(rdpq_font_t));
#endif

free(fnt);
free(fnt);
}
}


Expand Down
8 changes: 7 additions & 1 deletion src/rdpq/rdpq_font_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@
#define __RDPQ_FONT_INTERNAL_H

/** @brief font64 file magic header */
#define FONT_MAGIC_V0 0x464E5448 // "FNT0"
#define FONT_MAGIC_V0 0x464E5448 // "FNTH"

/** @brief font64 loaded font buffer magic */
#define FONT_MAGIC_LOADED 0x464E544C // "FNTL"

/** @brief font64 owned font buffer magic */
#define FONT_MAGIC_OWNED 0x464E544F // "FNTO"

/** @brief A range of codepoint (part of #rdpq_font_t) */
typedef struct {
Expand Down
29 changes: 20 additions & 9 deletions src/sprite.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,34 @@ bool __sprite_upgrade(sprite_t *sprite)
return false;
}

sprite_t *sprite_load(const char *fn)
sprite_t *sprite_load_buf(void *buf, int sz)
{
int sz;
sprite_t *s = asset_load(fn, &sz);
sprite_t *s = buf;
assertf(sz >= sizeof(sprite_t), "Sprite buffer too small (sz=%d)", sz);
__sprite_upgrade(s);
data_cache_hit_writeback(s, sz);
return s;
}

void sprite_free(sprite_t *s)
sprite_t *sprite_load(const char *fn)
{
#ifndef NDEBUG
// To help debugging, zero the sprite structure as well
memset(s, 0, sizeof(sprite_t));
#endif
int sz;
void *buf = asset_load(fn, &sz);
sprite_t *s = sprite_load_buf(buf, sz);
s->flags |= SPRITE_FLAGS_OWNEDBUFFER;
return s;
}

free(s);
void sprite_free(sprite_t *s)
{
if(s->flags & SPRITE_FLAGS_OWNEDBUFFER) {
#ifndef NDEBUG
//To help debugging, zero the sprite structure as well
memset(s, 0, sizeof(sprite_t));
#endif
free(s);
}

if (last_spritemap == s)
last_spritemap = NULL;
}
Expand Down

0 comments on commit 1149832

Please sign in to comment.