Setup GTE quad rendering

This commit is contained in:
Lucas S. Vieira 2025-01-10 17:06:07 -03:00
parent 8ca69094ef
commit 4da14b45b4
6 changed files with 129 additions and 13 deletions

View file

@ -37,5 +37,8 @@ void free_chara(Chara *chara);
void chara_render_frame(Chara *chara, int16_t framenum,
int16_t vx, int16_t vy, uint8_t flipx);
void chara_draw_gte(Chara *chara, int16_t framenum,
int16_t vx, int16_t vy,
uint8_t flipx, int32_t angle);
#endif

View file

@ -32,6 +32,7 @@
#define OTZ_LAYER_LEVEL_FG_FRONT 2
#define OTZ_LAYER_OBJECTS 3
#define OTZ_LAYER_PLAYER 4
#define OTZ_LAYER_UNDER_PLAYER 5
#define OTZ_LAYER_LEVEL_FG_BACK (OT_LENGTH - 3)
#define OTZ_LAYER_LEVEL_BG (OT_LENGTH - 2)

View file

@ -162,3 +162,101 @@ chara_render_frame(Chara *chara, int16_t framenum, int16_t vx, int16_t vy, uint8
}
}
void
chara_draw_gte(Chara *chara, int16_t framenum,
int16_t vx, int16_t vy,
uint8_t flipx, int32_t angle)
{
// Prepare position
VECTOR pos = { .vx = vx, .vy = vy, .vz = 0 };
SVECTOR rotation = { 0, 0, angle, 0 };
/* VECTOR scale = { ONE, flipx ? -ONE : ONE, ONE }; */
MATRIX world = { 0 };
RotMatrix(&rotation, &world);
TransMatrix(&world, &pos);
/* ScaleMatrix(&world, &scale); */
gte_SetRotMatrix(&world);
gte_SetTransMatrix(&world);
CharaFrame *frame = &chara->frames[framenum];
// Render only one tile
uint16_t idx = frame->tiles[0];
if(idx == 0) {
printf("Bad choice, bro\n");
return;
}
// Get upper left UV from tile index on tileset
uint16_t v0idx = idx >> 5; // divide by 32
uint16_t u0idx = idx - (v0idx << 5);
uint8_t
u0 = (u0idx << 3),
v0 = (v0idx << 3);
/* SPRT_8 *sprite = (SPRT_8 *)get_next_prim(); */
/* increment_prim(sizeof(SPRT_8)); */
/* setSprt8(sprite); */
/* setUV0(sprite, u0, v0); */
/* TILE *sprite = (TILE *)get_next_prim(); */
/* increment_prim(sizeof(TILE)); */
/* setTile(sprite); */
/* setRGB0(sprite, level_fade, level_fade, level_fade); */
/* sprite->w = 8; */
/* sprite->h = 8; */
/* //setXY0 */
/* SVECTOR p = { 0, 0, 8 << 12, 0 }; */
/* RotTransPers(&p, (uint32_t *)&sprite->x0); */
/* sort_prim(sprite, OTZ_LAYER_PLAYER); */
POLY_G4 *poly = (POLY_G4 *)get_next_prim();
increment_prim(sizeof(POLY_G4));
setPolyG4(poly);
if(flipx) {
setRGB1(poly, 128, 0, 0);
setRGB0(poly, 0, 128, 0);
setRGB3(poly, 0, 0, 128);
setRGB2(poly, 128, 128, 0);
} else {
setRGB0(poly, 128, 0, 0);
setRGB1(poly, 0, 128, 0);
setRGB2(poly, 0, 0, 128);
setRGB3(poly, 128, 128, 0);
}
/* setRGB0(poly, level_fade, level_fade, level_fade); */
SVECTOR vertices[] = {
{ -4, -4, 0, 0 },
{ 4, -4, 0, 0 },
{ -4, 4, 0, 0 },
{ 4, 4, 0, 0 },
};
int otz;
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);
printf("Position: (%4d, %4d)\n", poly->x0, poly->y0);
/* DR_TPAGE *tpage = get_next_prim(); */
/* increment_prim(sizeof(DR_TPAGE)); */
/* setDrawTPage(tpage, 0, 1, getTPage(1, 1, chara->prectx, chara->precty)); */
/* sort_prim(tpage, OTZ_LAYER_PLAYER); */
}

View file

@ -72,7 +72,8 @@ main(void)
/* mdec_fmv_init(); */
// Set first scene
scene_change(SCREEN_DISCLAIMER);
//scene_change(SCREEN_DISCLAIMER);
scene_change(SCREEN_SPRITETEST);
while(1) {
// Update systems

View file

@ -298,7 +298,7 @@ begin_render_routine:
|| (state->id == OBJ_EXPLOSION)
|| (state->id == OBJ_BUBBLE))
? OTZ_LAYER_OBJECTS
: OTZ_LAYER_PLAYER;
: OTZ_LAYER_UNDER_PLAYER;
// NOTABLE EXCEPTION: if this is a bubble object which animation has gone
// beyond the first digit display, it should be rendered on text layer

View file

@ -16,6 +16,7 @@ typedef struct {
VECTOR pos;
int16_t frame;
uint8_t play_frames;
uint8_t flipx;
int32_t angle;
} screen_sprite_test_data;
@ -34,11 +35,13 @@ screen_sprite_test_load()
load_chara(&data->chara, "\\SPRITES\\SONIC.CHARA;1", &tim);
data->pos = (VECTOR){ .vx = CENTERX, .vy = CENTERY, .vz = 0 };
data->pos = (VECTOR){ .vx = 0, .vy = 0, .vz = 0 };
data->frame = 0;
data->play_frames = 0;
data->angle = 0;
data->flipx = 0;
level_fade = 0x7f;
set_clear_color(36, 0, 180);
}
void
@ -55,6 +58,7 @@ screen_sprite_test_update(void *d)
screen_sprite_test_data *data = (screen_sprite_test_data *) d;
const int32_t spd = 5;
const int32_t rotspd = 5;
if(pad_pressing(PAD_UP)) {
data->pos.vy -= spd;
@ -76,6 +80,10 @@ screen_sprite_test_update(void *d)
data->play_frames ^= 1;
}
if(pad_pressed(PAD_TRIANGLE)) {
data->flipx ^= 1;
}
if(pad_pressed(PAD_SELECT)) {
scene_change(SCREEN_LEVELSELECT);
}
@ -88,14 +96,14 @@ screen_sprite_test_update(void *d)
else if(pad_pressed(PAD_SQUARE)) data->frame--;
}
if(pad_pressing(PAD_R1)) data->angle += spd;
else if(pad_pressing(PAD_L1)) data->angle -= spd;
if(pad_pressing(PAD_R1)) data->angle += rotspd;
else if(pad_pressing(PAD_L1)) data->angle -= rotspd;
if(data->frame < 0) data->frame = data->chara.numframes - 1;
else if(data->frame >= data->chara.numframes) data->frame = 0;
if(data->angle < 0) data->angle = ONE - spd;
else if(data->angle >= ONE) data->angle = 0;
//if(data->angle < 0) data->angle = ONE - spd;
//else if(data->angle >= ONE) data->angle = 0;
}
void
@ -117,10 +125,15 @@ screen_sprite_test_draw(void *d)
font_set_color(128, 128, 128);
font_draw_sm(buffer, 10, 10);
chara_render_frame(&data->chara,
data->frame,
(int16_t)(data->pos.vx),
(int16_t)(data->pos.vy),
0 // flipx
);
/* chara_render_frame(&data->chara, */
/* data->frame, */
/* (int16_t)(data->pos.vx), */
/* (int16_t)(data->pos.vy), */
/* data->flipx); */
chara_draw_gte(&data->chara,
data->frame,
(int16_t)(data->pos.vx),
(int16_t)(data->pos.vy),
data->flipx,
data->angle);
}