Dismember rendering function into smaller parts

This commit is contained in:
Lucas Vieira 2025-04-26 04:32:49 -03:00
parent 69abd4664c
commit 5495e7de66
4 changed files with 183 additions and 35 deletions

View file

@ -37,9 +37,16 @@ void free_chara(Chara *chara);
void chara_draw_gte(Chara *chara, int16_t framenum,
int16_t vx, int16_t vy,
uint8_t flipx, int32_t angle);
void chara_draw_fb(Chara *chara, int16_t framenum,
RECT *render_area,
int16_t vx, int16_t vy,
uint8_t flipx, int32_t angle);
void chara_draw_prepare(RECT *render_area, int otz);
void chara_draw_offscreen(Chara *chara, int16_t framenum, int otz);
void chara_draw_blit(RECT *render_area,
int16_t vx, int16_t vy,
uint8_t flipx, int32_t angle);
/* void chara_draw_fb(Chara *chara, int16_t framenum, */
/* RECT *render_area, */
/* int16_t vx, int16_t vy, */
/* uint8_t flipx, int32_t angle); */
void chara_draw_end(int otz);
#endif

View file

@ -102,22 +102,12 @@ free_chara(Chara *chara)
uint8_t frame_debug = 0;
void
chara_draw_fb(Chara *chara, int16_t framenum,
RECT *render_area,
int16_t vx, int16_t vy,
uint8_t flipx, int32_t angle)
chara_draw_prepare(RECT *render_area, int otz)
{
CharaFrame *frame = &chara->frames[framenum];
int16_t left = frame->x >> 3;
int16_t right = 7 - (frame->width >> 3) - left;
/* DR_TPAGE *tpage_a, *tpage_b; */
FILL *pfill;
DR_AREA *parea;
DR_OFFSET *poffs;
RECT *clip = render_get_buffer_clip();
sort_sub_ot();
// Clear offscreen area.
// This is put at the end because this is the very first thing to be done.
@ -126,32 +116,169 @@ chara_draw_fb(Chara *chara, int16_t framenum,
setXY0(pfill, render_area->x, render_area->y);
setWH(pfill, render_area->w, render_area->h);
setRGB0(pfill, 0, 0, 0);
sort_sub_prim(pfill, SUB_OT_LENGTH-1);
sort_sub_prim(pfill, otz);
increment_prim(sizeof(FILL));
// Sort draw area primitive.
parea = (DR_AREA *)get_next_prim();
setDrawArea(parea, render_area);
sort_sub_prim(parea, SUB_OT_LENGTH-1);
increment_prim(sizeof(DR_AREA));
// Revert to original draw area at end.
parea = (DR_AREA *)get_next_prim();
setDrawArea(parea, clip);
sort_sub_prim(parea, 1);
sort_sub_prim(parea, otz);
increment_prim(sizeof(DR_AREA));
// Sort draw offset primitive.
poffs = (DR_OFFSET *)get_next_prim();
setDrawOffset(poffs, render_area->x, render_area->y);
sort_sub_prim(poffs, SUB_OT_LENGTH-1);
sort_sub_prim(poffs, otz);
increment_prim(sizeof(DR_OFFSET));
}
void
chara_draw_end(int otz)
{
DR_AREA *parea;
DR_OFFSET *poffs;
RECT *clip = render_get_buffer_clip();
// Revert to original draw area at end.
parea = (DR_AREA *)get_next_prim();
setDrawArea(parea, clip);
sort_sub_prim(parea, otz);
increment_prim(sizeof(DR_AREA));
// Revert to original draw offset at end.
poffs = (DR_OFFSET *)get_next_prim();
setDrawOffset(poffs, clip->x, clip->y);
sort_sub_prim(poffs, 1);
sort_sub_prim(poffs, otz);
increment_prim(sizeof(DR_OFFSET));
}
void
chara_draw_offscreen(Chara *chara, int16_t framenum, int otz)
{
CharaFrame *frame = &chara->frames[framenum];
/* int16_t left = frame->x >> 3; */
/* int16_t right = 7 - (frame->width >> 3) - left; */
// Start drawing before sub_ot[2] and sub_ot[SUB_OT_LENGTH-2].
for(uint16_t row = 0; row < frame->rows; row++) {
for(uint16_t col = 0; col < frame->cols; col++) {
uint16_t idx = (row * frame->cols) + col;
idx = frame->tiles[idx];
if(idx == 0) continue;
uint16_t precty = chara->precty;
uint16_t v0idx = idx / 28;
uint16_t u0idx = idx - (v0idx * 28);
uint16_t
u0 = u0idx * 9,
v0 = v0idx * 9;
if((v0 + 9) >= 256) {
// Go to TPAGE right below
v0idx -= 28;
v0 = v0idx * 9;
precty = 256;
}
int16_t tilex = (col << 3) + frame->x + 5;
int16_t tiley = (row << 3) + frame->y - 5 + 8;
POLY_FT4 *poly = (POLY_FT4 *)get_next_prim();
increment_prim(sizeof(POLY_FT4));
setPolyFT4(poly);
setRGB0(poly, 128, 128, 128);
setTPage(poly, 1, 1, chara->prectx, precty);
setClut(poly, chara->crectx, chara->crecty);
setUV4(poly,
u0, v0,
u0 + 8, v0,
u0, v0 + 8,
u0 + 8, v0 + 8);
setXYWH(poly, tilex, tiley, 8, 8);
sort_sub_prim(poly, otz);
}
}
}
void
chara_draw_blit(RECT *render_area,
int16_t vx, int16_t vy,
uint8_t flipx, int32_t angle)
{
// Prepare position
VECTOR pos = {
.vx = vx - CENTERX,
.vy = vy - CENTERY,
.vz = frame_debug ? 0 : SCREEN_Z,
};
SVECTOR rotation = { 0, 0, angle, 0 };
int otz;
MATRIX world = { 0 };
TransMatrix(&world, &pos);
RotMatrix(&rotation, &world);
gte_SetTransMatrix(&world);
gte_SetRotMatrix(&world);
// Now draw the actual character, where it is supposed to be!
POLY_FT4 *poly = (POLY_FT4 *)get_next_prim();
increment_prim(sizeof(POLY_FT4));
setPolyFT4(poly);
setRGB0(poly, level_fade, level_fade, level_fade);
setTPage(poly, 2, 0, render_area->x, render_area->y);
// Not CLUT! We use 16-bit depth.
uint8_t umax = render_area->w - 1;
uint8_t vmax = render_area->h - 1;
uint8_t vmin = render_area->y;
poly->clut = 0;
if(flipx) {
setUV4(poly,
umax, vmin,
0, vmin,
umax, vmin + vmax,
0, vmin + vmax);
} else {
setUV4(poly,
0, vmin,
umax, vmin,
0, vmin + vmax,
umax, vmin + vmax);
}
int16_t hw = (render_area->w >> 1);
int16_t hh = (render_area->h >> 1);
SVECTOR vertices[] = {
{ -hw - 4, -hh - 4, 0, 0 },
{ hw - 4, -hh - 4, 0, 0 },
{ -hw - 4, hh - 4, 0, 0 },
{ hw - 4, hh - 4, 0, 0 },
};
RotAverageNclip4(
&vertices[0],
&vertices[1],
&vertices[2],
&vertices[3],
(uint32_t *)&poly->x0,
(uint32_t *)&poly->x1,
(uint32_t *)&poly->x2,
(uint32_t *)&poly->x3,
&otz);
sort_prim(poly, OTZ_LAYER_PLAYER);
}
void
chara_draw_fb(Chara *chara, int16_t framenum,
RECT *render_area,
int16_t vx, int16_t vy,
uint8_t flipx, int32_t angle)
{
CharaFrame *frame = &chara->frames[framenum];
int16_t left = frame->x >> 3;
int16_t right = 7 - (frame->width >> 3) - left;
// Start drawing before sub_ot[2] and sub_ot[SUB_OT_LENGTH-2].

View file

@ -84,6 +84,7 @@ main(void)
// Draw scene
scene_draw();
sort_sub_ot();
font_flush();
swap_buffers();
}

View file

@ -13,7 +13,7 @@
extern uint8_t level_fade;
extern uint8_t frame_debug;
static PlayerCharacter spritetest_character = CHARA_SONIC;
static PlayerCharacter spritetest_character = CHARA_MILES;
typedef struct {
Chara chara;
@ -58,14 +58,14 @@ screen_sprite_test_load()
load_chara(&data->chara, chara_file, &tim);
data->frame = 0;
data->play_frames = 1;
data->play_frames = 0;
data->angle = 0;
data->flipx = 0;
level_fade = 0x7f;
set_clear_color(0x64, 0x95, 0xed);
setRECT(&data->render_area, 960, 0, 64, 64);
setRECT(&data->render_sub_area, 960, data->render_area.y + data->render_area.h, 64, 64);
setRECT(&data->render_sub_area, 960, 64, 64, 64);
}
void
@ -155,13 +155,26 @@ screen_sprite_test_draw(void *d)
/* (int16_t)CENTERY, */
/* data->flipx, */
/* data->angle); */
chara_draw_fb(&data->chara,
data->frame,
&data->render_area,
(int16_t)CENTERX,
(int16_t)CENTERY,
data->flipx,
data->angle);
chara_draw_prepare(&data->render_area, SUB_OT_LENGTH - 1);
chara_draw_offscreen(&data->chara, data->frame, SUB_OT_LENGTH - 2);
chara_draw_blit(&data->render_area,
(int16_t)CENTERX,
(int16_t)CENTERY,
data->flipx,
data->angle);
if(spritetest_character == CHARA_MILES) {
chara_draw_prepare(&data->render_sub_area, SUB_OT_LENGTH - 3);
chara_draw_offscreen(&data->chara, 73, SUB_OT_LENGTH - 4);
chara_draw_blit(&data->render_sub_area,
(int16_t)CENTERX,
(int16_t)CENTERY,
data->flipx,
data->angle);
}
chara_draw_end(1);
}
void