nolibgs_hello_worlds/hello_poly_fun/hello_poly_fun.c

618 lines
18 KiB
C

// Having fun with polygons, matrices and vectors
// Credits : Schnappy
//With great help from Jaby smoll Seamonstah, Nicolas Noble, NDR008, paul, sickle on https://discord.com/invite/Zd82yXvs
// 11/2020
#include <sys/types.h>
#include <stdio.h>
#include <libgte.h>
#include <libetc.h>
#include <libgpu.h>
#include <kernel.h>
#define VMODE 0 // Video Mode : 0 : NTSC, 1: PAL
#define SPIN 16 // Rotation speed increment
#define SCREENXRES 320
#define SCREENYRES 240
#define CENTERX SCREENXRES/2
#define CENTERY SCREENYRES/2
#define MARGINX 10 // margins for text display
#define MARGINY 4
#define FONTSIZE 8 * 7 // Text Field Height
#define OTLEN 16 // Ordering Table Length
DISPENV disp[2]; // Double buffered DISPENV and DRAWENV
DRAWENV draw[2];
u_long ot[2][OTLEN]; // double ordering table of length 8 * 32 = 256 bits / 32 bytes
char primbuff[2][32768] = {}; // double primitive buffer of length 32768 * 8 = 262.144 bits / 32,768 Kbytes
char *nextpri = primbuff[0]; // pointer to the next primitive in primbuff. Initially, points to the first bit of primbuff[0]
short db = 0; // index of which buffer is used, values 0, 1
CVECTOR BgColor[3] = {20, 20, 20};
struct polygon
{
POLY_F4 * poly_f4;
CVECTOR color;
short width;
short height;
//~ VECTOR PosV_L; // Not used anymore
SVECTOR RotV_L;
VECTOR TransV_L;
VECTOR ScaleV_L;
SVECTOR PivotV_L;
SVECTOR Verts[4];
MATRIX Matrix;
long depth;
long flag;
short rotSpeed;
int otz;
};
void init(void)
{
ResetGraph(0);
// Initialize and setup the GTE : Not needed ?
InitGeom();
SetGeomOffset(CENTERX,CENTERY);
SetGeomScreen(CENTERX);
PadInit(0);
SetDefDispEnv(&disp[0], 0, 0, SCREENXRES, SCREENYRES);
SetDefDispEnv(&disp[1], 0, SCREENYRES, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw[0], 0, SCREENYRES, SCREENXRES, SCREENYRES);
SetDefDrawEnv(&draw[1], 0, 0, SCREENXRES, SCREENYRES);
if (VMODE)
{
SetVideoMode(MODE_PAL);
disp[0].screen.y += 8;
disp[1].screen.y += 8;
}
SetDispMask(1); // Display on screen
setRGB0(&draw[0], BgColor->r, BgColor->g, BgColor->b);
setRGB0(&draw[1], BgColor->r, BgColor->g, BgColor->b);
draw[0].isbg = 1;
draw[1].isbg = 1;
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
FntLoad(960, 0);
FntOpen(MARGINX, SCREENYRES - MARGINY - FONTSIZE, SCREENXRES - MARGINX * 2, FONTSIZE, 0, 280 );
}
void display(void)
{
DrawSync(0);
VSync(0);
PutDispEnv(&disp[db]);
PutDrawEnv(&draw[db]);
DrawOTag(&ot[db][OTLEN - 1]);
db = !db;
nextpri = primbuff[db];
}
void pivotPoint(SVECTOR VertPos[3],short width,short height, SVECTOR pivot){
// Not very efficient I think
VertPos[0].vx = -pivot.vx;
VertPos[0].vy = -pivot.vy;
VertPos[0].vz = 1;
VertPos[1].vx = width - pivot.vx;
VertPos[1].vy = -pivot.vy;
VertPos[1].vz = 1;
VertPos[2].vx = -pivot.vx;
VertPos[2].vy = height-pivot.vy;
VertPos[2].vz = 1;
VertPos[3].vx = width - pivot.vx;
VertPos[3].vy = height - pivot.vy;
VertPos[3].vz = 1;
}
MATRIX identity(int num)
{
int row, col;
MATRIX matrix;
for (row = 0; row < num; row++)
{
for (col = 0; col < num; col++)
{
if (row == col)
matrix.m[row][col] = 4096;
else
matrix.m[row][col] = 0;
}
}
return matrix;
}
int main(void)
{
MATRIX IDMATRIX = identity(3);
u_short BtnTimer = 0; // Timer to limit pad input rate
u_short polyCount = 1; // current polygon index
int otz; // z-index
struct polygon *CurrentPoly; // points to the address of selected polygon
// White cursor : shows which polygon is selected
struct polygon cursorS = {
cursorS.poly_f4,
{255, 255, 255}, // color
30, 30, // width, height
{0,0,0}, // RotV_L
{0,0,0, 0}, // TransV_L
{4096,4096,4096}, // ScaleV_L
{1,1,1}, // PivotV
{ // Verts[4]
{-1, -1, 1},
{ 1, -1, 1},
{-1, 1, 1},
{ 1, 1, 1}
},
IDMATRIX // Matrix
};
//Red
struct polygon polyS = {
polyS.poly_f4,
{255, 0, 0}, // color
30, 30, // width, height
{0,0,0}, // RotV_L
{-48, -30, 0, 0}, // TransV_L
{4096,4096,4096}, // ScaleV_L
{15,15,1}, // PivotV
{ // Verts[4]
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}
},
IDMATRIX, // Matrix
0,0, // depth, flag
8, // rotSpeed
1 // z-index
};
//Yellow
struct polygon poly1S = {
poly1S.poly_f4,
{255, 187, 0}, // color
28, 28, // width, height
{0,0,0}, // RotV_L
{-20, 10, 0, 0}, // TransV_L
{4096,4096,4096}, // ScaleV_L
{4,4,1}, // PivotV
{ // Verts[4]
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}
},
IDMATRIX, // Matrix
0,0, // depth, flag
-12, // rotSpeed
2 // z-index
};
//Green
struct polygon poly2S = {
poly2S.poly_f4,
{0, 255, 153}, // color
24, 24, // width, height
{0,0,0}, // RotV_L
{36, -10, 0, 0}, // TransV_L
{4096,4096,4096}, // ScaleV_L
{12,12,1}, // PivotV
{ // Verts[4]
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}
},
IDMATRIX, // Matrix
0,0, // depth, flag
-6, // rotSpeed
3 // z-index
};
//Blue
struct polygon poly3S = {
poly3S.poly_f4,
{112, 254, 254}, // color
26, 26, // width, height
{0,0,0}, // RotV_L
{20, 20, 0, 0}, // TransV_L
{4096,4096,4096}, // ScaleV_L
{13,13,1}, // PivotV
{ // Verts[4]
{0, 0, 0},
{0, 0, 0},
{0, 0, 0},
{0, 0, 0}
},
IDMATRIX, // Matrix
0,0, //depth, flag
256, //rotSpeed
4 // z-index
};
/////
CurrentPoly = &polyS;
pivotPoint(polyS.Verts, polyS.width, polyS.height, polyS.PivotV_L);
pivotPoint(poly1S.Verts, poly1S.width, poly1S.height, poly1S.PivotV_L);
pivotPoint(poly2S.Verts, poly2S.width, poly2S.height, poly2S.PivotV_L);
pivotPoint(poly3S.Verts, poly3S.width, poly3S.height, poly3S.PivotV_L);
init();
while (1)
{
ClearOTagR(ot[db], OTLEN);
cursorS.poly_f4 = (POLY_F4 *)nextpri;
RotMatrix(&cursorS.RotV_L , &cursorS.Matrix);
TransMatrix(&cursorS.Matrix, &CurrentPoly->TransV_L);
SetRotMatrix(&cursorS.Matrix);
SetTransMatrix(&cursorS.Matrix);
setPolyF4(cursorS.poly_f4);
setRGB0(cursorS.poly_f4,cursorS.color.r,cursorS.color.g,cursorS.color.b);
//~ setXY4(cursorS, MovVector.vx-1, MovVector.vy-1 ,MovVector.vx + 1, MovVector.vy -1,MovVector.vx-1, MovVector.vy+1,MovVector.vx+1, MovVector.vy+1);
RotTransPers4(
&cursorS.Verts[0], &cursorS.Verts[1], &cursorS.Verts[2], &cursorS.Verts[3],
(long*)&cursorS.poly_f4->x0, (long*)&cursorS.poly_f4->x1, (long*)&cursorS.poly_f4->x2, (long*)&cursorS.poly_f4->x3,
&cursorS.depth,
&cursorS.flag
);
addPrim(ot[db], cursorS.poly_f4);
nextpri += sizeof(POLY_F4);
///// Red
polyS.poly_f4 = (POLY_F4 *)nextpri;
polyS.RotV_L.vz += polyS.rotSpeed;
RotMatrix(&polyS.RotV_L, &polyS.Matrix);
TransMatrix(&polyS.Matrix, &polyS.TransV_L);
ScaleMatrix(&polyS.Matrix, &polyS.ScaleV_L);
SetRotMatrix(&polyS.Matrix);
SetTransMatrix(&polyS.Matrix);
setPolyF4(polyS.poly_f4);
setRGB0(polyS.poly_f4, polyS.color.r,polyS.color.g,polyS.color.b);
RotTransPers4(
&polyS.Verts[0], &polyS.Verts[1], &polyS.Verts[2], &polyS.Verts[3],
(long*)&polyS.poly_f4->x0, (long*)&polyS.poly_f4->x1, (long*)&polyS.poly_f4->x2, (long*)&polyS.poly_f4->x3,
&polyS.depth,
&polyS.flag
);
addPrim(ot[db]+polyS.otz, polyS.poly_f4);
nextpri += sizeof(POLY_F4);
///// Yellow
poly1S.poly_f4 = (POLY_F4 *)nextpri;
poly1S.RotV_L.vz += poly1S.rotSpeed;
RotMatrix(&poly1S.RotV_L, &poly1S.Matrix);
TransMatrix(&poly1S.Matrix, &poly1S.TransV_L);
ScaleMatrix(&poly1S.Matrix, &poly1S.ScaleV_L);
SetRotMatrix(&poly1S.Matrix);
SetTransMatrix(&poly1S.Matrix);
setPolyF4(poly1S.poly_f4);
setRGB0(poly1S.poly_f4, poly1S.color.r,poly1S.color.g,poly1S.color.b);
RotTransPers4(
&poly1S.Verts[0], &poly1S.Verts[1], &poly1S.Verts[2], &poly1S.Verts[3],
(long*)&poly1S.poly_f4->x0, (long*)&poly1S.poly_f4->x1, (long*)&poly1S.poly_f4->x2, (long*)&poly1S.poly_f4->x3,
&poly1S.depth,
&poly1S.flag
);
addPrim(ot[db]+poly1S.otz, poly1S.poly_f4);
nextpri += sizeof(POLY_F4);
///// Green
poly2S.poly_f4 = (POLY_F4 *)nextpri;
poly2S.RotV_L.vz += poly2S.rotSpeed;
RotMatrix(&poly2S.RotV_L, &poly2S.Matrix);
TransMatrix(&poly2S.Matrix, &poly2S.TransV_L);
ScaleMatrix(&poly2S.Matrix, &poly2S.ScaleV_L);
SetRotMatrix(&poly2S.Matrix);
SetTransMatrix(&poly2S.Matrix);
setPolyF4(poly2S.poly_f4);
setRGB0(poly2S.poly_f4, poly2S.color.r,poly2S.color.g,poly2S.color.b);
RotTransPers4(
&poly2S.Verts[0], &poly2S.Verts[1], &poly2S.Verts[2], &poly2S.Verts[3],
(long*)&poly2S.poly_f4->x0, (long*)&poly2S.poly_f4->x1, (long*)&poly2S.poly_f4->x2, (long*)&poly2S.poly_f4->x3,
&poly2S.depth,
&poly2S.flag
);
addPrim(ot[db]+poly2S.otz, poly2S.poly_f4);
nextpri += sizeof(POLY_F4);
///// Blue
poly3S.poly_f4 = (POLY_F4 *)nextpri;
poly3S.RotV_L.vz += poly3S.rotSpeed;
RotMatrix(&poly3S.RotV_L, &poly3S.Matrix);
TransMatrix(&poly3S.Matrix, &poly3S.TransV_L);
ScaleMatrix(&poly3S.Matrix, &poly3S.ScaleV_L);
SetRotMatrix(&poly3S.Matrix);
SetTransMatrix(&poly3S.Matrix);
setPolyF4(poly3S.poly_f4);
setRGB0(poly3S.poly_f4, poly3S.color.r,poly3S.color.g,poly3S.color.b);
RotTransPers4(
&poly3S.Verts[0], &poly3S.Verts[1], &poly3S.Verts[2], &poly3S.Verts[3],
(long*)&poly3S.poly_f4->x0, (long*)&poly3S.poly_f4->x1, (long*)&poly3S.poly_f4->x2, (long*)&poly3S.poly_f4->x3,
&poly3S.depth,
&poly3S.flag
);
addPrim(ot[db]+poly3S.otz, poly3S.poly_f4);
nextpri += sizeof(POLY_F4);
// Pad stuff
int pad = PadRead(0); // init pad
// Right D-pad
if(pad & PADRup){
if (CurrentPoly->PivotV_L.vy >= 0){
CurrentPoly->PivotV_L.vy -= 1;
pivotPoint(CurrentPoly->Verts, CurrentPoly->width, CurrentPoly->height, CurrentPoly->PivotV_L);
}
else {
CurrentPoly->PivotV_L.vy = CurrentPoly->PivotV_L.vy;
}
};
if(pad & PADRdown){
if (CurrentPoly->PivotV_L.vy <= CurrentPoly->height ){
CurrentPoly->PivotV_L.vy += 1;
pivotPoint(CurrentPoly->Verts, CurrentPoly->width, CurrentPoly->height, CurrentPoly->PivotV_L);
}
else {
CurrentPoly->PivotV_L.vy = CurrentPoly->PivotV_L.vy;
}
};
if(pad & PADRleft){
if (CurrentPoly->PivotV_L.vx >= 0){
CurrentPoly->PivotV_L.vx -= 1;
pivotPoint(CurrentPoly->Verts, CurrentPoly->width, CurrentPoly->height, CurrentPoly->PivotV_L);
}
else {
CurrentPoly->PivotV_L.vx = CurrentPoly->PivotV_L.vx;
}
};
if(pad & PADRright){
if (CurrentPoly->PivotV_L.vx <= CurrentPoly->width ){
CurrentPoly->PivotV_L.vx += 1;
pivotPoint(CurrentPoly->Verts, CurrentPoly->width, CurrentPoly->height, CurrentPoly->PivotV_L);
}
else {
CurrentPoly->PivotV_L.vx = CurrentPoly->PivotV_L.vx;
}
};
// R1, R2, L2, L2
if(pad & PADR1){
if(BtnTimer == 0){
if (polyCount < 4){
CurrentPoly -= 1;
BtnTimer = 10;
polyCount++;
}
else {
CurrentPoly = &polyS + 1;
polyCount = 0;
}
}
}
if(pad & PADR2){
if(BtnTimer == 0){
if(CurrentPoly->otz < 5 ){
CurrentPoly->otz += 1;
BtnTimer = 10;
} else {
CurrentPoly->otz = 1;
BtnTimer = 10;
}
}
}
if(pad & PADL1){
if(BtnTimer == 0){
if (CurrentPoly->rotSpeed <= 320){
CurrentPoly->rotSpeed += 8;
}
BtnTimer = 10;
}
}
if(pad & PADL2){
if(BtnTimer == 0){
if (CurrentPoly->rotSpeed >= -320){
CurrentPoly->rotSpeed -= 8;
}
BtnTimer = 10;
}
}
// Left D-Pad
if(pad & PADLup){
if(BtnTimer == 0){
CurrentPoly->TransV_L.vy -= 1;
//~ BtnTimer = 2;
}
}
if(pad & PADLdown){
if(BtnTimer == 0){
CurrentPoly->TransV_L.vy += 1;
//~ BtnTimer = 2;
}
}
if(pad & PADLleft){
if(BtnTimer == 0){
CurrentPoly->TransV_L.vx -= 1;
//~ BtnTimer = 2;
}
}
if(pad & PADLright){
if(BtnTimer == 0){
CurrentPoly->TransV_L.vx += 1;
//~ BtnTimer = 2;
}
}
if(pad & PADstart){
if(BtnTimer == 0){
CurrentPoly->ScaleV_L.vx += 100;
CurrentPoly->ScaleV_L.vy += 100;
//~ CurrentPoly->TransV_L.vz += 1;
}
}
if(pad & PADselect){
if(BtnTimer == 0){
CurrentPoly->ScaleV_L.vx -= 100;
CurrentPoly->ScaleV_L.vy -= 100;
//~ CurrentPoly->TransV_L.vz -= 1;
}
}
// Btn_timer decrement
if(BtnTimer > 0){
BtnTimer -= 1;
}
// Debug stuff
// Display Rotation matrix
//~ FntPrint("Rotmatrix:\n%d %d %d\n%d %d %d\n%d %d %d \n",
//~ Poly1Matrix.m[0][0], Poly1Matrix.m[0][1], Poly1Matrix.m[0][2],
//~ Poly1Matrix.m[1][0], Poly1Matrix.m[1][1], Poly1Matrix.m[1][2],
//~ Poly1Matrix.m[2][0], Poly1Matrix.m[2][1], Poly1Matrix.m[2][2]);
// Display Mem adress and values of verticess
//~ FntPrint("cur:%x\n 0:%x\n 1:%x\n 2:%x\n 3:%x\n", CurrentPoly, &polyS, &poly1S, &poly2S, &poly3S);
//~ FntPrint("timer:%d polyCount:%d speed:%d", BtnTimer, polyCount, CurrentPoly->rotSpeed );
//~ FntPrint("&poly->x0 Addr:%x Value:%d \n&poly->y0 Addr:%x Value:%d \n&poly->x1 Addr:%x Value:%d",
//~ (long)&poly->x0, poly->x0,
//~ (long)&poly->y0, poly->y0,
//~ (long)&poly->x1, poly->x1);
//~ FntPrint("otz : %d\n" , CurrentPoly->rotSpeed);
// On-screen instructions
FntPrint("\
D-Pad:move polygon.\n\
[],X,O,\/\\ : Move pivot point.\n\
L1,L2 : Rotations speed +/-\n\
R1 : select polygon\n\
R2 : change z-index\n\
Start,Select : Scale polygon +/-\
");
FntFlush(-1);
display();
}
return 0;
}