mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-09-28 09:57:59 +03:00
Fix various issues with SACT2
Ensure that sact_get_sprite always returns a sprite object if sprite number is not negative. SACT2 functions in general should work before pixel data is attached to a sprite. This also fixes the default for the 'show' property (true) and changes the logic for adding/removing sprites from the scene to be less error-prone (checked whenever a sprite is dirtied).
This commit is contained in:
+30
-7
@@ -28,9 +28,14 @@ union vm_value;
|
||||
|
||||
struct sact_sprite {
|
||||
TAILQ_ENTRY(sact_sprite) entry;
|
||||
// The sprite's texture (CG or solid color). Initialized lazily.
|
||||
struct texture texture;
|
||||
// If no CG is attached to the sprite, the solid color to fill with.
|
||||
SDL_Color color;
|
||||
// The position and dimensions of the sprite.
|
||||
Rectangle rect;
|
||||
// Arbitrary text can be attached to the sprite. This is rendered on a
|
||||
// separate texture and overlayed.
|
||||
struct {
|
||||
struct string *str;
|
||||
struct texture texture;
|
||||
@@ -39,18 +44,39 @@ struct sact_sprite {
|
||||
int char_space;
|
||||
int line_space;
|
||||
} text;
|
||||
// The Z-layer of the sprite within the scene.
|
||||
int z;
|
||||
bool show;
|
||||
// This flag indicates that pixel data has been attached to a sprite; it
|
||||
// does NOT guarantee that the texture is initialized.
|
||||
bool has_pixel;
|
||||
// This flag indicates whether or not the sprite is included in the
|
||||
// the current scene. A sprite should be in the scene if there is pixel
|
||||
// or text data attached to it and it is not hidden.
|
||||
bool in_scene;
|
||||
// When a sprite is hidden, it is removed from the scene. Attaching new
|
||||
// pixel data does not alter the state of this flag.
|
||||
bool hidden;
|
||||
// The sprite handle.
|
||||
int no;
|
||||
// The CG number attached to the sprite.
|
||||
int cg_no;
|
||||
};
|
||||
|
||||
extern bool sact_dirty;
|
||||
|
||||
void sprite_register(struct sact_sprite *sp);
|
||||
void sprite_unregister(struct sact_sprite *sp);
|
||||
|
||||
static inline void sprite_dirty(struct sact_sprite *sp)
|
||||
{
|
||||
if (sp && sp->show)
|
||||
sact_dirty = true;
|
||||
if (!sp)
|
||||
return;
|
||||
sact_dirty = true;
|
||||
if (sp->hidden) {
|
||||
sprite_unregister(sp);
|
||||
} else if (sp->has_pixel || sp->text.texture.handle) {
|
||||
sprite_register(sp);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void scene_dirty(void)
|
||||
@@ -58,9 +84,6 @@ static inline void scene_dirty(void)
|
||||
sact_dirty = true;
|
||||
}
|
||||
|
||||
|
||||
void sprite_register(struct sact_sprite *sp);
|
||||
void sprite_unregister(struct sact_sprite *sp);
|
||||
void sprite_free(struct sact_sprite *sp);
|
||||
void sprite_render_scene(void);
|
||||
void sprite_flip(void);
|
||||
@@ -85,7 +108,7 @@ static inline int sprite_get_pos_y(struct sact_sprite *sp) { return sp->rect.y;
|
||||
static inline int sprite_get_width(struct sact_sprite *sp) { return sp->rect.w; }
|
||||
static inline int sprite_get_height(struct sact_sprite *sp) { return sp->rect.h; }
|
||||
static inline int sprite_get_z(struct sact_sprite *sp) { return sp->z; }
|
||||
static inline int sprite_get_show(struct sact_sprite *sp) { return sp->show; }
|
||||
static inline int sprite_get_show(struct sact_sprite *sp) { return !sp->hidden; }
|
||||
void sprite_set_text_home(struct sact_sprite *sp, int x, int y);
|
||||
void sprite_set_text_line_space(struct sact_sprite *sp, int px);
|
||||
void sprite_set_text_char_space(struct sact_sprite *sp, int px);
|
||||
|
||||
+13
-8
@@ -35,14 +35,6 @@
|
||||
static struct sact_sprite **sprites = NULL;
|
||||
static int nr_sprites = 0;
|
||||
|
||||
// NOTE: Used externally by DrawGraph and SengokuRanceFont
|
||||
struct sact_sprite *sact_get_sprite(int sp)
|
||||
{
|
||||
if (sp < -1 || sp >= nr_sprites)
|
||||
return NULL;
|
||||
return sprites[sp];
|
||||
}
|
||||
|
||||
static struct sact_sprite *sact_alloc_sprite(int sp)
|
||||
{
|
||||
sprites[sp] = xcalloc(1, sizeof(struct sact_sprite));
|
||||
@@ -71,6 +63,19 @@ static void realloc_sprite_table(int n)
|
||||
memset(sprites + old_nr_sprites, 0, sizeof(struct sact_sprite*) * (nr_sprites - old_nr_sprites));
|
||||
}
|
||||
|
||||
// NOTE: Used externally by DrawGraph and SengokuRanceFont
|
||||
struct sact_sprite *sact_get_sprite(int sp)
|
||||
{
|
||||
if (sp < -1)
|
||||
return NULL;
|
||||
if (sp >= nr_sprites)
|
||||
realloc_sprite_table(sp+256);
|
||||
if (!sprites[sp]) {
|
||||
return sact_alloc_sprite(sp);
|
||||
}
|
||||
return sprites[sp];
|
||||
}
|
||||
|
||||
int sact_Init(possibly_unused void *_, possibly_unused int cg_cache_size)
|
||||
{
|
||||
// already initialized
|
||||
|
||||
+20
-18
@@ -39,29 +39,34 @@ TAILQ_HEAD(listhead, sact_sprite) sprite_list =
|
||||
|
||||
void sprite_register(struct sact_sprite *sp)
|
||||
{
|
||||
if (sp->in_scene)
|
||||
return;
|
||||
|
||||
struct sact_sprite *p;
|
||||
TAILQ_FOREACH(p, &sprite_list, entry) {
|
||||
if (p->z > sp->z) {
|
||||
TAILQ_INSERT_BEFORE(p, sp, entry);
|
||||
sp->in_scene = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
TAILQ_INSERT_TAIL(&sprite_list, sp, entry);
|
||||
if (sp->show)
|
||||
scene_dirty();
|
||||
sp->in_scene = true;
|
||||
scene_dirty();
|
||||
}
|
||||
|
||||
void sprite_unregister(struct sact_sprite *sp)
|
||||
{
|
||||
if (!sp->in_scene)
|
||||
return;
|
||||
TAILQ_REMOVE(&sprite_list, sp, entry);
|
||||
if (sp->show)
|
||||
scene_dirty();
|
||||
sp->in_scene = false;
|
||||
scene_dirty();
|
||||
}
|
||||
|
||||
void sprite_free(struct sact_sprite *sp)
|
||||
{
|
||||
if (sp->show)
|
||||
sprite_unregister(sp);
|
||||
sprite_unregister(sp);
|
||||
gfx_delete_texture(&sp->texture);
|
||||
gfx_delete_texture(&sp->text.texture);
|
||||
}
|
||||
@@ -135,20 +140,23 @@ int sprite_set_cg(struct sact_sprite *sp, int cg_no)
|
||||
sp->rect.h = cg->metrics.h;
|
||||
sp->cg_no = cg_no;
|
||||
cg_free(cg);
|
||||
|
||||
sp->has_pixel = true;
|
||||
sprite_dirty(sp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attach pixel data to a sprite. The texture is initialized lazily.
|
||||
*/
|
||||
void sprite_init(struct sact_sprite *sp, int w, int h, int r, int g, int b, int a)
|
||||
{
|
||||
sp->color = (SDL_Color) { .r = r, .g = g, .b = b, .a = (a >= 0 ? a : 255) };
|
||||
sp->rect.w = w;
|
||||
sp->rect.h = h;
|
||||
if (!sp->show) {
|
||||
sp->show = true;
|
||||
sprite_register(sp);
|
||||
}
|
||||
gfx_delete_texture(&sp->texture);
|
||||
|
||||
sp->has_pixel = true;
|
||||
sprite_dirty(sp);
|
||||
}
|
||||
|
||||
@@ -181,7 +189,7 @@ void sprite_set_y(struct sact_sprite *sp, int y)
|
||||
void sprite_set_z(struct sact_sprite *sp, int z)
|
||||
{
|
||||
sp->z = z;
|
||||
if (sp->show) {
|
||||
if (sp->in_scene) {
|
||||
sprite_unregister(sp);
|
||||
sprite_register(sp);
|
||||
}
|
||||
@@ -200,14 +208,8 @@ void sprite_set_blend_rate(struct sact_sprite *sp, int rate)
|
||||
|
||||
void sprite_set_show(struct sact_sprite *sp, bool show)
|
||||
{
|
||||
if (show == sp->show)
|
||||
return;
|
||||
sp->show = show;
|
||||
sp->hidden = !show;
|
||||
sprite_dirty(sp);
|
||||
if (show)
|
||||
sprite_register(sp);
|
||||
else
|
||||
sprite_unregister(sp);
|
||||
}
|
||||
|
||||
int sprite_set_draw_method(struct sact_sprite *sp, int method)
|
||||
|
||||
Reference in New Issue
Block a user