diff --git a/include/sact.h b/include/sact.h index b4267f9..cb40c9a 100644 --- a/include/sact.h +++ b/include/sact.h @@ -47,8 +47,18 @@ struct sact_sprite { int cg_no; }; +extern bool sact_dirty; + +static inline void sprite_dirty(struct sact_sprite *sp) +{ + if (sp && sp->show) + sact_dirty = true; +} + struct sact_sprite *sact_get_sprite(int sp); +struct sact_sprite *sact_get_sprite_dirty(int sp); struct texture *sact_get_texture(int sp_no); +struct texture *sact_get_texture_dirty(int sp_no); void sact_render_scene(void); diff --git a/src/hll/DrawGraph.c b/src/hll/DrawGraph.c index d87d7da..f44bd44 100644 --- a/src/hll/DrawGraph.c +++ b/src/hll/DrawGraph.c @@ -19,101 +19,102 @@ #include "gfx/types.h" #include "system4/string.h" -#define TEX(sp_no) sact_get_texture(sp_no) +#define STEX(sp_no) sact_get_texture(sp_no) +#define DTEX(sp_no) sact_get_texture_dirty(sp_no) static void DrawGraph_Copy(int dst, int dx, int dy, int src, int sx, int sy, int w, int h) { - gfx_copy(TEX(dst), dx, dy, TEX(src), sx, sy, w, h); + gfx_copy(DTEX(dst), dx, dy, STEX(src), sx, sy, w, h); } static void DrawGraph_CopyBright(int dst, int dx, int dy, int src, int sx, int sy, int w, int h, int rate) { - gfx_copy_bright(TEX(dst), dx, dy, TEX(src), sx, sy, w, h, rate); + gfx_copy_bright(DTEX(dst), dx, dy, STEX(src), sx, sy, w, h, rate); } static void DrawGraph_CopyAMap(int dst, int dx, int dy, int src, int sx, int sy, int w, int h) { - gfx_copy_amap(TEX(dst), dx, dy, TEX(src), sx, sy, w, h); + gfx_copy_amap(STEX(dst), dx, dy, STEX(src), sx, sy, w, h); } static void DrawGraph_CopySprite(int dst, int dx, int dy, int src, int sx, int sy, int w, int h, int r, int g, int b) { - gfx_copy_sprite(TEX(dst), dx, dy, TEX(src), sx, sy, w, h, COLOR(r, g, b, 0)); + gfx_copy_sprite(DTEX(dst), dx, dy, STEX(src), sx, sy, w, h, COLOR(r, g, b, 0)); } static void DrawGraph_CopyUseAMapUnder(int dst, int dx, int dy, int src, int sx, int sy, int w, int h, int alpha) { - gfx_copy_use_amap_under(TEX(dst), dx, dy, TEX(src), sx, sy, w, h, alpha); + gfx_copy_use_amap_under(DTEX(dst), dx, dy, STEX(src), sx, sy, w, h, alpha); } static void DrawGraph_CopyUseAMapBorder(int dst, int dx, int dy, int src, int sx, int sy, int w, int h, int alpha) { - gfx_copy_use_amap_border(TEX(dst), dx, dy, TEX(src), sx, sy, w, h, alpha); + gfx_copy_use_amap_border(DTEX(dst), dx, dy, STEX(src), sx, sy, w, h, alpha); } static void DrawGraph_CopyAMapMax(int dst, int dx, int dy, int src, int sx, int sy, int w, int h) { - gfx_copy_amap_max(TEX(dst), dx, dy, TEX(src), sx, sy, w, h); + gfx_copy_amap_max(DTEX(dst), dx, dy, STEX(src), sx, sy, w, h); } static void DrawGraph_CopyAMapMin(int dst, int dx, int dy, int src, int sx, int sy, int w, int h) { - gfx_copy_amap_min(TEX(dst), dx, dy, TEX(src), sx, sy, w, h); + gfx_copy_amap_min(DTEX(dst), dx, dy, STEX(src), sx, sy, w, h); } static void DrawGraph_Blend(int dst, int dx, int dy, int src, int sx, int sy, int w, int h, int alpha) { - gfx_blend(TEX(dst), dx, dy, TEX(src), sx, sy, w, h, alpha); + gfx_blend(DTEX(dst), dx, dy, STEX(src), sx, sy, w, h, alpha); } static void DrawGraph_BlendAMap(int dst, int dx, int dy, int src, int sx, int sy, int w, int h) { - gfx_blend_amap(TEX(dst), dx, dy, TEX(src), sx, sy, w, h); + gfx_blend_amap(DTEX(dst), dx, dy, STEX(src), sx, sy, w, h); } static void DrawGraph_BlendAMapAlpha(int dst, int dx, int dy, int src, int sx, int sy, int w, int h, int alpha) { - gfx_blend_amap_alpha(TEX(dst), dx, dy, TEX(src), sx, sy, w, h, alpha); + gfx_blend_amap_alpha(DTEX(dst), dx, dy, STEX(src), sx, sy, w, h, alpha); } static void DrawGraph_Fill(int dst, int x, int y, int w, int h, int r, int g, int b) { - gfx_fill(TEX(dst), x, y, w, h, r, g, b); + gfx_fill(DTEX(dst), x, y, w, h, r, g, b); } static void DrawGraph_FillAlphaColor(int dst, int x, int y, int w, int h, int r, int g, int b, int rate) { - gfx_fill_alpha_color(TEX(dst), x, y, w, h, r, g, b, rate); + gfx_fill_alpha_color(DTEX(dst), x, y, w, h, r, g, b, rate); } static void DrawGraph_FillAMap(int dst, int x, int y, int w, int h, int alpha) { - gfx_fill_amap(TEX(dst), x, y, w, h, alpha); + gfx_fill_amap(DTEX(dst), x, y, w, h, alpha); } static void DrawGraph_AddDA_DAxSA(int dst, int dx, int dy, int src, int sx, int sy, int w, int h) { - gfx_add_da_daxsa(TEX(dst), dx, dy, TEX(src), sx, sy, w, h); + gfx_add_da_daxsa(DTEX(dst), dx, dy, STEX(src), sx, sy, w, h); } static void DrawGraph_CopyStretch(int dst, int dx, int dy, int dw, int dh, int src, int sx, int sy, int sw, int sh) { - gfx_copy_stretch(TEX(dst), dx, dy, dw, dh, TEX(src), sx, sy, sw, sh); + gfx_copy_stretch(DTEX(dst), dx, dy, dw, dh, STEX(src), sx, sy, sw, sh); } static void DrawGraph_CopyStretchAMap(int dst, int dx, int dy, int dw, int dh, int src, int sx, int sy, int sw, int sh) { - gfx_copy_stretch_amap(TEX(dst), dx, dy, dw, dh, TEX(src), sx, sy, sw, sh); + gfx_copy_stretch_amap(DTEX(dst), dx, dy, dw, dh, STEX(src), sx, sy, sw, sh); } static void DrawGraph_DrawTextToPMap(int dst, int x, int y, struct string *s) { - gfx_draw_text_to_pmap(TEX(dst), x, y, s->text); + gfx_draw_text_to_pmap(DTEX(dst), x, y, s->text); } static void DrawGraph_DrawTextToAMap(int dst, int x, int y, struct string *s) { - gfx_draw_text_to_amap(TEX(dst), x, y, s->text); + gfx_draw_text_to_amap(DTEX(dst), x, y, s->text); } static void DrawGraph_SetFontColor(int r, int g, int b) @@ -131,27 +132,27 @@ static void DrawGraph_GetFontColor(int *r, int *g, int *b) static void DrawGraph_CopyRotZoom(int dst, int src, int sx, int sy, int w, int h, float rotate, float mag) { - gfx_copy_rot_zoom(TEX(dst), TEX(src), sx, sy, w, h, rotate, mag); + gfx_copy_rot_zoom(DTEX(dst), STEX(src), sx, sy, w, h, rotate, mag); } static void DrawGraph_CopyRotZoomAMap(int dst, int src, int sx, int sy, int w, int h, float rotate, float mag) { - gfx_copy_rot_zoom_amap(TEX(dst), TEX(src), sx, sy, w, h, rotate, mag); + gfx_copy_rot_zoom_amap(DTEX(dst), STEX(src), sx, sy, w, h, rotate, mag); } static void DrawGraph_CopyRotZoomUseAMap(int dst, int src, int sx, int sy, int w, int h, float rotate, float mag) { - gfx_copy_rot_zoom_use_amap(TEX(dst), TEX(src), sx, sy, w, h, rotate, mag); + gfx_copy_rot_zoom_use_amap(DTEX(dst), STEX(src), sx, sy, w, h, rotate, mag); } static void DrawGraph_CopyReverseLR(int dst, int dx, int dy, int src, int sx, int sy, int w, int h) { - gfx_copy_reverse_LR(TEX(dst), dx, dy, TEX(src), sx, sy, w, h); + gfx_copy_reverse_LR(DTEX(dst), dx, dy, STEX(src), sx, sy, w, h); } static void DrawGraph_CopyReverseAMapLR(int dst, int dx, int dy, int src, int sx, int sy, int w, int h) { - gfx_copy_reverse_amap_LR(TEX(dst), dx, dy, TEX(src), sx, sy, w, h); + gfx_copy_reverse_amap_LR(DTEX(dst), dx, dy, STEX(src), sx, sy, w, h); } static bool DrawGraph_GetAlphaColor(int surface, int x, int y, int *a) diff --git a/src/hll/SACT2.c b/src/hll/SACT2.c index 5d35fb4..2909730 100644 --- a/src/hll/SACT2.c +++ b/src/hll/SACT2.c @@ -236,7 +236,7 @@ static void sact_System_GetTime(int *hour, int *min, int *sec, int *ms) static void sact_CG_BlendAMapBin(int dst, int dx, int dy, int src, int sx, int sy, int w, int h, int border) { - gfx_copy_use_amap_border(sact_get_texture(dst), dx, dy, sact_get_texture(src), sx, sy, w, h, border); + gfx_copy_use_amap_border(sact_get_texture_dirty(dst), dx, dy, sact_get_texture(src), sx, sy, w, h, border); } //int SACT2_Error(struct string *err); diff --git a/src/sact_graphics.c b/src/sact_graphics.c index 292c440..b80ac83 100644 --- a/src/sact_graphics.c +++ b/src/sact_graphics.c @@ -32,6 +32,8 @@ static struct sact_sprite *create_sprite(int sp_no, int width, int height, int r, int g, int b, int a); +bool sact_dirty = true; + static struct sact_sprite **sprites = NULL; static int nr_sprites = 0; @@ -65,6 +67,14 @@ struct sact_sprite *sact_get_sprite(int sp) return sprites[sp]; } +struct sact_sprite *sact_get_sprite_dirty(int sp) +{ + if (sp < -1 || sp >= nr_sprites) + return NULL; + sprite_dirty(sprites[sp]); + return sprites[sp]; +} + struct texture *sact_get_texture(int sp_no) { struct sact_sprite *sp = sact_get_sprite(sp_no); @@ -76,10 +86,23 @@ struct texture *sact_get_texture(int sp_no) return &sp->texture; } +struct texture *sact_get_texture_dirty(int sp_no) +{ + struct sact_sprite *sp = sact_get_sprite_dirty(sp_no); + if (!sp) + return NULL; + if (!sp->texture.handle) { + gfx_init_texture_with_color(&sp->texture, sp->rect.w, sp->rect.h, sp->color); + } + return &sp->texture; + +} + static struct sact_sprite *alloc_sprite(int sp) { sprites[sp] = xcalloc(1, sizeof(struct sact_sprite)); sprites[sp]->no = sp; + sprite_dirty(sprites[sp]); return sprites[sp]; } @@ -152,6 +175,7 @@ int sact_SetWP(int cg_no) gfx_delete_texture(&wp.texture); gfx_init_texture_with_cg(&wp.texture, cg); cg_free(cg); + sact_dirty = true; return 1; } @@ -198,8 +222,11 @@ void sact_render_scene(void) int sact_Update(void) { handle_events(); - sact_render_scene(); - gfx_swap(); + if (sact_dirty) { + sact_render_scene(); + gfx_swap(); + sact_dirty = false; + } return 1; } @@ -246,7 +273,7 @@ int sact_SP_GetMaxZ(void) int sact_SP_SetCG(int sp_no, int cg_no) { - struct sact_sprite *sp = sact_get_sprite(sp_no); + struct sact_sprite *sp = sact_get_sprite_dirty(sp_no); if (!sp) sact_SP_Create(sp_no, 1, 1, 0, 0, 0, 255); if (!(sp = sact_get_sprite(sp_no))) { @@ -272,7 +299,7 @@ static struct sact_sprite *create_sprite(int sp_no, int width, int height, int r if (sp_no >= nr_sprites) { realloc_sprite_table(sp_no+256); } - if (!(sp = sact_get_sprite(sp_no))) + if (!(sp = sact_get_sprite_dirty(sp_no))) sp = alloc_sprite(sp_no); sp->color = (SDL_Color) { .r = r, .g = g, .b = b, .a = (a >= 0 ? a : 255) }; sp->rect.w = width; @@ -302,12 +329,13 @@ int sact_SP_Delete(int sp_no) struct sact_sprite *sp = sact_get_sprite(sp_no); if (!sp) return 0; free_sprite(sp); + sact_dirty = true; return 1; } int sact_SP_SetPos(int sp_no, int x, int y) { - struct sact_sprite *sp = sact_get_sprite(sp_no); + struct sact_sprite *sp = sact_get_sprite_dirty(sp_no); if (!sp) return 1; sp->rect.x = x; sp->rect.y = y; @@ -316,7 +344,7 @@ int sact_SP_SetPos(int sp_no, int x, int y) int sact_SP_SetX(int sp_no, int x) { - struct sact_sprite *sp = sact_get_sprite(sp_no); + struct sact_sprite *sp = sact_get_sprite_dirty(sp_no); if (!sp) return 0; sp->rect.x = x; return 1; @@ -324,7 +352,7 @@ int sact_SP_SetX(int sp_no, int x) int sact_SP_SetY(int sp_no, int y) { - struct sact_sprite *sp = sact_get_sprite(sp_no); + struct sact_sprite *sp = sact_get_sprite_dirty(sp_no); if (!sp) return 0; sp->rect.y = y; return 1; @@ -332,7 +360,7 @@ int sact_SP_SetY(int sp_no, int y) int sact_SP_SetZ(int sp_no, int z) { - struct sact_sprite *sp = sact_get_sprite(sp_no); + struct sact_sprite *sp = sact_get_sprite_dirty(sp_no); if (!sp) return 0; sp->z = z; if (sp->show) { @@ -351,7 +379,7 @@ int sact_SP_GetBlendRate(int sp_no) int sact_SP_SetBlendRate(int sp_no, int rate) { - struct texture *t = sact_get_texture(sp_no); + struct texture *t = sact_get_texture_dirty(sp_no); if (!t) return 0; t->alpha_mod = max(0, min(255, rate)); return 1; @@ -364,6 +392,7 @@ int sact_SP_SetShow(int sp_no, bool show) if (show == sp->show) return 1; sp->show = show; + sprite_dirty(sp); if (show) sprite_register(sp); else @@ -373,7 +402,7 @@ int sact_SP_SetShow(int sp_no, bool show) int sact_SP_SetDrawMethod(int sp_no, int method) { - struct texture *t = sact_get_texture(sp_no); + struct texture *t = sact_get_texture_dirty(sp_no); if (!t) return 0; if (method < 0 || method >= NR_DRAW_METHODS) { WARNING("unknown draw method: %d", method); @@ -446,7 +475,7 @@ int sact_SP_GetShow(int sp_no) int sact_SP_SetTextHome(int sp_no, int x, int y) { - struct sact_sprite *sp = sact_get_sprite(sp_no); + struct sact_sprite *sp = sact_get_sprite_dirty(sp_no); if (!sp) return 0; sp->text.home = (Point) { .x = x, .y = y }; return 1; @@ -454,7 +483,7 @@ int sact_SP_SetTextHome(int sp_no, int x, int y) int sact_SP_SetTextLineSpace(int sp_no, int px) { - struct sact_sprite *sp = sact_get_sprite(sp_no); + struct sact_sprite *sp = sact_get_sprite_dirty(sp_no); if (!sp) return 1; sp->text.line_space = px; return 1; @@ -462,7 +491,7 @@ int sact_SP_SetTextLineSpace(int sp_no, int px) int sact_SP_SetTextCharSpace(int sp_no, int px) { - struct sact_sprite *sp = sact_get_sprite(sp_no); + struct sact_sprite *sp = sact_get_sprite_dirty(sp_no); if (!sp) return 1; sp->text.char_space = px; return 1; @@ -470,7 +499,7 @@ int sact_SP_SetTextCharSpace(int sp_no, int px) int sact_SP_SetTextPos(int sp_no, int x, int y) { - struct sact_sprite *sp = sact_get_sprite(sp_no); + struct sact_sprite *sp = sact_get_sprite_dirty(sp_no); if (!sp) return 0; sp->text.pos = (Point) { .x = x, .y = y }; return 1; @@ -503,7 +532,7 @@ static void init_text_metrics(struct text_metrics *tm, union vm_value *_tm) int _sact_SP_TextDraw(int sp_no, struct string *text, struct text_metrics *tm) { - struct sact_sprite *sp = sact_get_sprite(sp_no); + struct sact_sprite *sp = sact_get_sprite_dirty(sp_no); if (!sp) return 0; if (!sp->text.texture.handle) { @@ -536,7 +565,7 @@ static void clear_text(struct sact_sprite *sp) int sact_SP_TextClear(int sp_no) { - struct sact_sprite *sp = sact_get_sprite(sp_no); + struct sact_sprite *sp = sact_get_sprite_dirty(sp_no); if (!sp) return 0; clear_text(sp); return 1; @@ -544,7 +573,7 @@ int sact_SP_TextClear(int sp_no) int sact_SP_TextHome(int sp_no, possibly_unused int size) { - struct sact_sprite *sp = sact_get_sprite(sp_no); + struct sact_sprite *sp = sact_get_sprite_dirty(sp_no); if (!sp) return 0; // FIXME: do something with nTextSize sp->text.pos = sp->text.home; @@ -553,7 +582,7 @@ int sact_SP_TextHome(int sp_no, possibly_unused int size) int sact_SP_TextNewLine(int sp_no, int size) { - struct sact_sprite *sp = sact_get_sprite(sp_no); + struct sact_sprite *sp = sact_get_sprite_dirty(sp_no); if (!sp) return 0; sp->text.pos = POINT(sp->text.home.x, sp->text.pos.y + size + sp->text.line_space); return 1; @@ -561,7 +590,7 @@ int sact_SP_TextNewLine(int sp_no, int size) int sact_SP_TextCopy(int dno, int sno) { - struct sact_sprite *dsp = sact_get_sprite(dno); + struct sact_sprite *dsp = sact_get_sprite_dirty(dno); struct sact_sprite *ssp = sact_get_sprite(sno); if (!ssp) return 0;