Replace x_get functions with macros

The PS1 port relies on a heap for primitives since the GPU renders the
scene asynchronously. However, SDL-based platforms render primitives
synchronously, so structures can be allocated on the stack instead.
This commit is contained in:
Xavier Del Campo Romero 2022-02-08 15:39:56 +01:00
parent df2ecf50e0
commit 3d90015c62
17 changed files with 85 additions and 179 deletions

View File

@ -22,9 +22,9 @@ int building_render(const struct building *const b,
if (!b->instance.alive)
return 0;
struct sprite *const s = sprite_get();
sprite_get_or_ret(s, -1);
if (!s || sprite_clone(&building_sprites[b->type], s))
if (sprite_clone(&building_sprites[b->type], s))
return -1;
const struct instance_render_cfg cfg =

View File

@ -73,9 +73,9 @@ static void cursor_update(struct camera *const cam, const struct pad *const p)
int cursor_render(const struct cursor *const c)
{
struct sprite *const s = sprite_get();
sprite_get_or_ret(s, -1);
if (!s || sprite_clone(&cursor_sprite, s))
if (sprite_clone(&cursor_sprite, s))
return -1;
s->x = c->x;

View File

@ -40,9 +40,9 @@ static int renderstr(const enum font f, const short x, short y, const char *str)
continue;
}
struct sprite *const s = sprite_get();
sprite_get_or_ret(s, -1);
if (!s || sprite_clone(cfg->s, s))
if (sprite_clone(cfg->s, s))
return -1;
s->w = cfg->fw;

View File

@ -1,4 +1,3 @@
set(src "src/heap.c")
set(inc "inc")
set(privinc "privinc")
set(deps util)
@ -21,10 +20,8 @@ elseif(SDL1_2_BUILD)
set(privinc ${privinc} "sdl-1.2/privinc")
set(src ${src}
"sdl-1.2/src/env.c"
"sdl-1.2/src/heap.c"
"sdl-1.2/src/line.c"
"sdl-1.2/src/rect.c"
"sdl-1.2/src/sort.c"
"sdl-1.2/src/sprite.c"
"sdl-1.2/src/quad.c")
set(deps ${deps} SDL)

View File

@ -19,15 +19,16 @@ void quad_sort(struct quad *q);
void rect_sort(struct rect *r);
void stp_4line_sort(struct stp_4line *l);
int sprite_from_fp(struct sprite *s, FILE *f);
struct sprite *sprite_get(void);
struct quad *quad_get(void);
struct rect *rect_get(bool semitrans);
struct stp_4line *stp_4line_get(void);
int quad_from_sprite(const struct sprite *s, struct quad *q);
bool gfx_inside_drawenv(short x, short y, short w, short h);
void gfx_deinit(void);
void sprite_free(struct sprite *src);
#define sprite_get_or_ret(x, ret) common_get_or_ret(sprite, x, ret)
#define stp_4line_get_or_ret(x, ret) common_get_or_ret(stp_4line, x, ret)
#define rect_get_or_ret(x, ret) common_get_or_ret(rect, x, ret)
#define quad_get_or_ret(x, ret) common_get_or_ret(quad, x, ret)
extern int screen_w, screen_h;
#ifdef __cplusplus

View File

@ -11,10 +11,6 @@ extern "C"
void rect_init(struct rect *r);
void semitrans_rect_init(struct rect *r);
void stp_4line_init(struct stp_4line *l);
void *gfx_port_heap(size_t *n);
void gfx_reset_heap(void);
#ifdef __cplusplus
}
#endif

View File

@ -3,17 +3,52 @@
#include <stddef.h>
static unsigned int sel;
static size_t heap_i;
void gfx_swapheap(void)
{
sel ^= 1;
heap_i = 0;
}
void *gfx_port_heap(size_t *const n)
static void *get_element(const size_t sz)
{
enum {HEAP_SZ = 5120, N_HEAPS = 2};
static char heaps[N_HEAPS][HEAP_SZ];
const size_t new_sz = heap_i + sz;
void *ret = NULL;
*n = sizeof *heaps / sizeof **heaps;
return heaps[sel];
if (new_sz < sizeof *heaps / sizeof **heaps)
{
ret = &heaps[sel][heap_i];
heap_i += sz;
}
else
{
fprintf(stderr, "%s: exceeded heap size (%zu/%zu)\n",
__func__, new_sz, sizeof *heaps / sizeof **heaps);
return NULL;
}
return ret;
}
struct sprite *sprite_get(void)
{
return get_element(sizeof (struct sprite));
}
struct quad *quad_get(void)
{
return get_element(sizeof (struct quad));
}
struct rect *rect_get(void)
{
return get_element(sizeof (struct rect));
}
struct stp_4line *stp_4line_get(void)
{
return get_element(sizeof (struct stp_4line));
}

View File

@ -55,7 +55,6 @@ void gfx_draw(void)
D2_BCR = 0;
D2_CHCR = (1 << 0xa) | 1 | (1 << 0x18);
first = NULL;
gfx_reset_heap();
}
void gfx_sync(void)

View File

@ -43,7 +43,8 @@ struct stp_4line
} vertices[4];
};
SDL_Surface *gfx_port_screen(void);
#define common_get_or_ret(t, x, ret) \
struct t x##__, *const x = &x##__
#ifdef __cplusplus
}

View File

@ -1,11 +0,0 @@
#include <gfx.h>
#include <gfx_private.h>
#include <stddef.h>
void *gfx_port_heap(size_t *const n)
{
static char heap[5120];
*n = sizeof heap / sizeof *heap;
return heap;
}

View File

@ -1,22 +0,0 @@
#include <gfx.h>
#include <gfx_private.h>
#include <gfx/port.h>
#include <SDL/SDL.h>
#include <stdio.h>
void gfx_draw(void)
{
enum {FPS = 50, REFRESH_MS = 1000 / FPS};
static Uint32 prev;
const Uint32 cur = SDL_GetTicks();
if (cur - prev < REFRESH_MS)
SDL_Delay(REFRESH_MS - (cur - prev));
prev = SDL_GetTicks();
if (SDL_Flip(gfx_port_screen()))
fprintf(stderr, "SDL_Flip: %s\n", SDL_GetError());
gfx_reset_heap();
}

View File

@ -1,56 +0,0 @@
#include <gfx.h>
#include <gfx_private.h>
#include <stddef.h>
static size_t heap_i;
void gfx_reset_heap(void)
{
heap_i = 0;
}
static void *get_element(const size_t sz)
{
size_t n;
char *ret = gfx_port_heap(&n);
if (ret && heap_i + sz < n)
{
ret += heap_i;
heap_i += sz;
}
else
return NULL;
return ret;
}
struct sprite *sprite_get(void)
{
return get_element(sizeof (struct sprite));
}
struct quad *quad_get(void)
{
return get_element(sizeof (struct quad));
}
struct rect *rect_get(const bool semitrans)
{
struct rect *const r = get_element(sizeof (struct rect));
if (r)
semitrans ? semitrans_rect_init(r) : rect_init(r);
return r;
}
struct stp_4line *stp_4line_get(void)
{
struct stp_4line *const l = get_element(sizeof (struct stp_4line));
if (l)
stp_4line_init(l);
return l;
}

View File

@ -12,10 +12,9 @@ struct sprite gui_sprites[MAX_GUI_SPRITES];
static int render_topleft(void)
{
struct sprite *const s = sprite_get();
sprite_get_or_ret(s, -1);
if (!s
|| sprite_clone(&gui_sprites[GUI_BAR_LEFT], s))
if (sprite_clone(&gui_sprites[GUI_BAR_LEFT], s))
return -1;
sprite_sort(s);
@ -24,9 +23,9 @@ static int render_topleft(void)
static int render_topright(void)
{
struct sprite *const s = sprite_get();
sprite_get_or_ret(s, -1);
if (!s || sprite_clone(&gui_sprites[GUI_BAR_RIGHT], s))
if (sprite_clone(&gui_sprites[GUI_BAR_RIGHT], s))
return -1;
s->x = screen_w - s->w;
@ -51,10 +50,9 @@ static int render_topmid(void)
a.i < n_mid;
a.i++, a.x += mid_w)
{
struct sprite *const m = sprite_get();
sprite_get_or_ret(m, -1);
if (!m
|| sprite_clone(&gui_sprites[GUI_BAR_MID], m))
if (sprite_clone(&gui_sprites[GUI_BAR_MID], m))
return -1;
m->x = a.x;
@ -91,10 +89,9 @@ static int render_seltop(struct sprite *const up)
up->x = 16;
sprite_sort(up);
struct sprite *const right = sprite_get();
sprite_get_or_ret(right, -1);
if (!right
|| sprite_clone(&gui_sprites[GUI_SELECTION_UP_RIGHT], right))
if (sprite_clone(&gui_sprites[GUI_SELECTION_UP_RIGHT], right))
return -1;
right->x = screen_w - right->w - up->x;
@ -119,12 +116,11 @@ static int render_selvert(const struct sprite *const up, const short x)
a.i < n_vert;
a.i++, a.y += vert_h)
{
struct sprite *const v = sprite_get();
sprite_get_or_ret(v, -1);
if (!v)
if (sprite_clone(&gui_sprites[GUI_SELECTION_MID_VERT], v))
return -1;
*v = gui_sprites[GUI_SELECTION_MID_VERT];
v->y = a.y;
v->x = x;
@ -152,24 +148,22 @@ static int render_selvertright(const struct sprite *const up)
static int render_seldown(const struct sprite *const up)
{
{
struct sprite *const left = sprite_get();
sprite_get_or_ret(left, -1);
if (!left)
if (sprite_clone(&gui_sprites[GUI_SELECTION_DOWN_LEFT], left))
return -1;
*left = gui_sprites[GUI_SELECTION_DOWN_LEFT];
left->x = up->x;
left->y = screen_h - left->h;
sprite_sort(left);
}
{
struct sprite *const right = sprite_get();
sprite_get_or_ret(right, -1);
if (!right)
if (sprite_clone(&gui_sprites[GUI_SELECTION_DOWN_RIGHT], right))
return -1;
*right = gui_sprites[GUI_SELECTION_DOWN_RIGHT];
right->x = screen_w - right->w - up->x;
right->y = screen_h - right->h;
sprite_sort(right);
@ -180,10 +174,8 @@ static int render_seldown(const struct sprite *const up)
static int render_selrect(const struct sprite *const up)
{
struct rect *const sel = rect_get(true);
if (!sel)
return -1;
rect_get_or_ret(sel, -1);
semitrans_rect_init(sel);
const struct sprite *const mid = &gui_sprites[GUI_SELECTION_MID],
*const vert = &gui_sprites[GUI_SELECTION_MID_VERT];
@ -214,11 +206,7 @@ static int render_selmid(const struct sprite *const up, const short y)
a.i < n_mid;
a.i++, a.x += mid_w)
{
struct sprite *const m = sprite_get();
if (!m)
return -1;
sprite_get_or_ret(m, -1);
*m = gui_sprites[GUI_SELECTION_MID];
m->x = a.x;
m->y = y;
@ -272,11 +260,8 @@ static int draw_hp(const struct instance *const i, const short x, const short y,
const short gw = (WIDTH * i->hp) / max_hp;
{
struct rect *const gr = rect_get(true);
if (!gr)
return -1;
rect_get_or_ret(gr, -1);
semitrans_rect_init(gr);
gr->x = x;
gr->y = ry;
gr->w = gw;
@ -286,11 +271,8 @@ static int draw_hp(const struct instance *const i, const short x, const short y,
}
{
struct rect *const rr = rect_get(true);
if (!rr)
return -1;
rect_get_or_ret(rr, -1);
semitrans_rect_init(rr);
rr->x = x + gw;
rr->y = ry;
rr->w = WIDTH - gw;
@ -314,11 +296,9 @@ static int draw_miners(const struct resource *const r)
if (g->miners[i])
{
enum {OFFSET = 112, SZ = 16, GAP = 4};
struct rect *const r = rect_get(true);
if (!r)
return -1;
rect_get_or_ret(r, -1);
semitrans_rect_init(r);
r->x = OFFSET + n * (SZ + GAP);
r->y = screen_h - 40;
r->r = r->g = r->b = 127;
@ -434,10 +414,9 @@ static int render_selinfo(const struct sprite *const up,
static int render_sel(const struct human_player *const h)
{
struct sprite *const up = sprite_get();
sprite_get_or_ret(up, -1);
if (!up
|| render_seltop(up)
if (render_seltop(up)
|| render_selrect(up)
|| render_selmidtop(up)
|| render_selmiddown(up)

View File

@ -34,13 +34,10 @@ void instance_cyclic(void)
static int draw_sel(const struct instance *const i, const short x, const short y)
{
struct stp_4line *const l = stp_4line_get();
if (!l)
return -1;
enum {R = 0, G = 255, B = 0};
stp_4line_get_or_ret(l, -1);
stp_4line_init(l);
l->x = l->vertices[2].x = l->vertices[3].x = x;
l->y = l->vertices[0].y = l->vertices[3].y = y;
l->vertices[0].x = l->vertices[1].x = x + i->r.w;
@ -60,12 +57,7 @@ static int draw_sel(const struct instance *const i, const short x, const short y
l->vertices[0].g = l->vertices[2].g = UCHAR_MAX - line_g;
l->vertices[1].g = l->vertices[3].g = line_g;
stp_4line_sort(l);
struct stp_4line *const ll = stp_4line_get();
if (!ll)
return -1;
stp_4line_get_or_ret(ll, -1);
*ll = *l;
ll->x = ll->vertices[2].x = ll->vertices[3].x = l->x ? l->x - 1 : 0;
ll->y = ll->vertices[0].y = ll->vertices[3].y = l->y ? l->y - 1 : 0;

View File

@ -61,9 +61,9 @@ int resource_render(const struct resource *const res,
if (!in->alive)
return 0;
struct sprite *const s = sprite_get();
sprite_get_or_ret(s, -1);
if (!s || sprite_clone(&resource_sprites[res->type], s))
if (sprite_clone(&resource_sprites[res->type], s))
return -1;
if (res->type == RESOURCE_TYPE_GOLD)

View File

@ -54,10 +54,7 @@ int terrain_render(const struct terrain_map *const map,
for (struct m y = {.i = start_y, .p = remy};
y.i < ny + start_y; y.i++, y.p += TERRAIN_SZ)
{
struct sprite *const s = sprite_get();
if (!s)
return -1;
sprite_get_or_ret(s, -1);
switch (map->m[y.i][x.i])
{

View File

@ -561,11 +561,6 @@ static int unit_quad(const struct unit *const u, struct render_cfg *const rcfg)
{
struct instance_render_quad *const qcfg = &rcfg->qcfg;
qcfg->q = quad_get();
if (!qcfg->q)
return -1;
static anim_dim *(*const f[])(const struct unit *) =
{
[UNIT_TYPE_PEASANT] = peasant_quad
@ -594,6 +589,9 @@ int unit_render(const struct unit *const u, const struct camera *const cam,
struct render_cfg rcfg;
quad_get_or_ret(q, -1);
rcfg.qcfg.q = q;
if (unit_quad(u, &rcfg))
return -1;