From d92934338cb801c92cb9ae76c878b4802d857c24 Mon Sep 17 00:00:00 2001 From: ABelliqueux Date: Thu, 18 Nov 2021 18:50:43 +0100 Subject: [PATCH] Add FXs example --- hello_fx/Makefile | 8 + hello_fx/TIM/bg.tim | Bin 0 -> 61984 bytes hello_fx/TIM/cube.tim | Bin 0 -> 16928 bytes hello_fx/TIM/sky.tim | Bin 0 -> 17056 bytes hello_fx/cubetex.c | 158 ++++++++++++++++++ hello_fx/hello_fx.c | 377 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 543 insertions(+) create mode 100644 hello_fx/Makefile create mode 100644 hello_fx/TIM/bg.tim create mode 100644 hello_fx/TIM/cube.tim create mode 100644 hello_fx/TIM/sky.tim create mode 100644 hello_fx/cubetex.c create mode 100644 hello_fx/hello_fx.c diff --git a/hello_fx/Makefile b/hello_fx/Makefile new file mode 100644 index 0000000..bc72a3b --- /dev/null +++ b/hello_fx/Makefile @@ -0,0 +1,8 @@ +TARGET = hello_fx + +SRCS = hello_fx.c \ +TIM/cube.tim \ +TIM/sky.tim \ +TIM/bg.tim \ + +include ../common.mk diff --git a/hello_fx/TIM/bg.tim b/hello_fx/TIM/bg.tim new file mode 100644 index 0000000000000000000000000000000000000000..90947a6986c5ac254ca942a560e4a7a22a6b3060 GIT binary patch literal 61984 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¥Dj)u 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 Rj^cM>>}P+I#9+_D{~sBKR)qin literal 0 HcmV?d00001 diff --git a/hello_fx/TIM/cube.tim b/hello_fx/TIM/cube.tim new file mode 100644 index 0000000000000000000000000000000000000000..a92f5673b9f79daf2293a318a29c2f67688f96b8 GIT binary patch literal 16928 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 +#include +#include +#include +#include +#include +#include +// Sample vector model +#include "cubetex.c" +#define VMODE 0 +// Number of primitives to draw +#define NUM_PRIM 2 +// Number of textures to load +#define NUM_TEX 3 +#define SCREENXRES 320 +#define SCREENYRES 240 +#define CENTERX SCREENXRES/2 +#define CENTERY SCREENYRES/2 +#define MARGINX 16 // margins for text display +#define MARGINY 16 +#define OTLEN 2048 // Maximum number of OT entries +#define PRIMBUFFLEN 32768 // Maximum number of POLY_GT3 primitives +// Display and draw environments, double buffered +DISPENV disp[2]; +DRAWENV draw[2]; +u_long ot[2][OTLEN]; // Ordering table (contains addresses to primitives) +char primbuff[2][PRIMBUFFLEN]; // Primitive list // That's our prim buffer +char * nextpri = primbuff[0]; // Primitive counter +short db = 0; // Current buffer counter +// Store TIM files in an array so we can iterate over them - see 'cubetex.c' for TIM_FILE struct and declaration +TIM_FILE * timFiles[3]; +TIM_IMAGE timImages[3]; +// Get included tim files address +extern TIM_FILE _binary_TIM_cube_tim_start; +extern TIM_FILE _binary_TIM_sky_tim_start; +extern TIM_FILE _binary_TIM_bg_tim_start; +// Light +CVECTOR BGc = {130, 200, 255, 0}; +// Back color +VECTOR BKc = {128, 128, 128, 0}; +// Light rotation angle +SVECTOR lgtang = {0, 0, 0}; +// These will be used to store the light rotation matrix, cube rotation matrix, and composite light matrix. +MATRIX rotlgt, rotcube, light; +// Local Light Matrix : Direction and reach of each light source. +MATRIX lgtmat = { +// X Y Z + 0, -ONE, 0, // Lightsource 1 : here, the light source is at the Bottom-Left of the screen, and points into the screen. + 0, 0, 0, // Lightsource 2 + 0, 0, 0, // Lightsource 3 + }; +// Local Color Matrix +MATRIX cmat = { +// L1 L2 L3 + 4096, 0, 0, // R + 4096, 0, 0, // G + 4096, 0, 0 // B + }; + +// Prototypes +void init(void); +void display(void); +void LoadTexture(TIM_FILE * tim, TIM_IMAGE * tparam); +void init(){ + // Reset the GPU before doing anything and the controller + PadInit(0); + ResetGraph(0); + // Initialize and setup the GTE + InitGeom(); + SetGeomOffset(CENTERX, CENTERY); // x, y offset + SetGeomScreen(CENTERX); // Distance between eye and screen + // Set the display and draw environments + 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); + // Set far color + SetFarColor( BGc.r, BGc.g, BGc.b ); + // Set Ambient color + SetBackColor( BKc.vx, BKc.vy, BKc.vz ); + // Set Color matrix + SetColorMatrix(&cmat); + // Set Fog settings + SetFogNearFar( 128, 1024, CENTERX ); + setRGB0(&draw[0], 0, 0, 0); + setRGB0(&draw[1], 0, 0, 0); + draw[0].isbg = 1; + draw[1].isbg = 1; + PutDispEnv(&disp[db]); + PutDrawEnv(&draw[db]); + // Init font system + FntLoad(960, 0); + FntOpen(MARGINX, MARGINY, SCREENXRES - MARGINX * 2, SCREENXRES - MARGINY * 2, 0, 512 ); +} +void display(void){ + DrawSync(0); + VSync(0); + PutDispEnv(&disp[db]); + PutDrawEnv(&draw[db]); + DrawOTag(&ot[db][OTLEN - 1]); + db = !db; + nextpri = primbuff[db]; + } +void LoadTexture(TIM_FILE * tim, TIM_IMAGE * tparam){ // This part is from Lameguy64's tutorial series : lameguy64.net/svn/pstutorials/chapter1/3-textures.html login/pw: annoyingmous + OpenTIM((u_long*)tim); // Open the tim binary data, feed it the address of the data in memory + ReadTIM(tparam); // This read the header of the TIM data and sets the corresponding members of the TIM_IMAGE structure + LoadImage(tparam->prect, tparam->paddr); // Transfer the data from memory to VRAM at position prect.x, prect.y + DrawSync(0); // Wait for the drawing to end + if (tparam->mode & 0x8){ // check 4th bit // If 4th bit == 1, TIM has a CLUT + LoadImage(tparam->crect, tparam->caddr); // Load it to VRAM at position crect.x, crect.y + DrawSync(0); // Wait for drawing to end + } +} +int main() { + // Populate array with pointers to TIM data + timFiles[0] = &_binary_TIM_cube_tim_start; + timFiles[1] = &_binary_TIM_sky_tim_start; + timFiles[2] = &_binary_TIM_bg_tim_start; + // Pad values + int pad, oldPad; + // Set semi-transparency on (1) and off (0) + int stpFlag = 1; + // Set primitive semi-transparency rate - See LibOver47.pdf, p.107 + int stpRate = 0; + // If set, rotate cube + int rotateCube = 1; + int offsetCube = 0; + // Array of pointers to a POLY_G4 we iterate over + POLY_GT3 * poly[NUM_PRIM]; + // Rotation vector + SVECTOR rotVector={ 384, 0, 128, 0 }; + // Translation vector + VECTOR transVector= { 0, 0, 256, 0}; + // BG sprt + POLY_FT4 * bg; + // Normalized UV coordinates for the X axis + long normH = ((255 << 12) / SCREENXRES); + + // Init Disp/Drawenv, Font, etc. + init(); + // Load textures to VRAM + for (char tex = 0; tex < NUM_TEX; tex++){ + LoadTexture(timFiles[tex], &timImages[tex]); + } + + // Main loop + while (1) { + // Work matrix + MATRIX Work= {0} ; + // Triangle counters array - one for each cube + long curTriangle[3] = {0,0,0}; + // Clear the current OT + ClearOTagR(ot[db], OTLEN); + // Draw BG + bg = (POLY_FT4 * )nextpri; + SetPolyFT4(bg); + bg->tpage = getTPage( timImages[2].mode&0x3, 0, + timImages[2].prect->x, + timImages[2].prect->y + ); + if ( (timImages[2].mode & 0x3) < 2 ) { + setClut( bg, + timImages[2].crect->x, + timImages[2].crect->y + ); + } + setRGB0(bg, 127,127,127); + setUV4(bg, 0, 0, + SCREENYRES, 0, + 0, SCREENYRES, + SCREENYRES, SCREENYRES + ); + setXY4(bg, 0 , 0, + SCREENXRES, 0, + 0 , SCREENYRES, + SCREENXRES, SCREENYRES); + addPrim(ot[db][OTLEN-1], bg); + nextpri += sizeof(POLY_FT4); + // Rotate cube + if(rotateCube) rotVector.vy += 10; + // Find and apply light rotation matrix + // Find rotmat from light angles + RotMatrix_gte(&lgtang, &rotlgt); + // Find rotmat from cube angles + RotMatrix_gte(&rotVector, &rotcube); + // RotMatrix cube * RotMatrix light + MulMatrix0(&rotcube, &rotlgt, &rotlgt); + // Light Matrix * RotMatrix light + MulMatrix0(&lgtmat, &rotlgt, &light); + // Set new light matrix + SetLightMatrix(&light); + // Apply Transl, Rot, then matrix + RotMatrix(&rotVector, &Work); + TransMatrix(&Work, &transVector); + SetRotMatrix(&Work); + SetTransMatrix(&Work); + long p, OTz, Flag; + // Draw NUM_PRIM primitives + for (int i = 0; i < (modelCube.len * 3); i += 3) { + // Set projection matrices + transVector.vx = 0; + TransMatrix(&Work, &transVector); + SetRotMatrix(&Work); + SetTransMatrix(&Work); + // Cast nextpri as POLY_GT3 + poly[0] = (POLY_GT3 *)nextpri; + poly[1] = (POLY_GT3 *)nextpri+sizeof(POLY_GT3); + // Initialize the primitives + SetPolyGT3(poly[0]); + SetPolyGT3(poly[1]); + + // Reflection Cube + // This cube has its UVs mapped directly to VRAM coordinates + // We're using the framebuffers as a texture (0,0 and 0,256) + // Get 256x256 texture page that's at x0, y0 + poly[1]->tpage = getTPage( 2, stpRate, + 0, + !(db) << 8 // Here, we're using db's value that can be either 0 or 1 to determine the texture page Y coordinate. + ); + // Set STP + SetSemiTrans(poly[1], stpFlag); + // Map coordinates from drawarea (320x240) to texture size (128x128) in fixed point math + // x = x * (256 / 320) => ( x * ( 128 * 4096 ) / 320 ) / 4096 + // y = y * (240 / 240) => ( y * ( 240 * 4096 ) / 240 ) / 4096 => y * 2184 >> 12 -> y + setUV3( poly[1], + (poly[1]->x0 * normH) >> 12, + poly[1]->y0 - (!(db) << 4) , // We're using db's value again to add a 16 pixels offset to the Y's coordinates of the UVs + (poly[1]->x1 * normH) >> 12, + poly[1]->y1 - (!(db) << 4), // We have to do that because the buffer is 240 high, whereas our texture page is 256, hence 256 - 240 == 16 + (poly[1]->x2 * normH) >> 12, + poly[1]->y2 - (!(db) << 4) + ); + + // Draw "container" cube + // This cube has a texture with transparent areas. + // STP bit is set on PNG's alpha channel : img2tim -usealpha -org 320 0 -o cube.tim cube.png + poly[0]->tpage = getTPage( timImages[0].mode&0x3, stpRate, + timImages[0].prect->x, + timImages[0].prect->y + ); + // If 8/4bpp, load CLUT to vram + if ( (timImages[0].mode & 0x3) < 2 ) { + setClut( poly[0], + timImages[0].crect->x, + timImages[0].crect->y + ); + } + // Set UV coordinates + setUV3(poly[0], modelCube.u[i].vx, modelCube.u[i].vy, + modelCube.u[i+2].vx, modelCube.u[i+2].vy, + modelCube.u[i+1].vx, modelCube.u[i+1].vy + ); + // Rotate, translate, and project the vectors and output the results into a primitive + // curTriangle, +1, +2 point to the vertices index of the triangle we're drawing. + OTz = RotTransPers(&modelCube_mesh[ modelCube_index[ curTriangle[0] ] ] , ( long * ) &poly[1]->x0, &p, &Flag); + OTz += RotTransPers(&modelCube_mesh[ modelCube_index[ curTriangle[0] + 2] ], ( long*) &poly[1]->x1, &p, &Flag); + OTz += RotTransPers(&modelCube_mesh[ modelCube_index[ curTriangle[0] + 1] ], ( long * ) &poly[1]->x2, &p, &Flag); + + // Here we're only messing with the matrices so that the foreground cube can be moved independantly from the backgound one. + // In real code, you don't want to do the same calculation twice ! + transVector.vx = offsetCube; + TransMatrix(&Work, &transVector); + SetRotMatrix(&Work); + SetTransMatrix(&Work); + + OTz = RotTransPers(&modelCube_mesh[ modelCube_index[ curTriangle[0] ] ] , ( long * ) &poly[0]->x0, &p, &Flag); + OTz += RotTransPers(&modelCube_mesh[ modelCube_index[ curTriangle[0] + 2] ], ( long*) &poly[0]->x1, &p, &Flag); + OTz += RotTransPers(&modelCube_mesh[ modelCube_index[ curTriangle[0] + 1] ], ( long * ) &poly[0]->x2, &p, &Flag); + + // The right way to do it is re-using the results from the first RotTransPer() batch + // i.e commenting lines 273 to 280 and uncommenting lines 284 to 289 + //~ poly[0]->x0 = poly[1]->x0; + //~ poly[0]->y0 = poly[1]->y0; + //~ poly[0]->x1 = poly[1]->x1; + //~ poly[0]->y1 = poly[1]->y1; + //~ poly[0]->x2 = poly[1]->x2; + //~ poly[0]->y2 = poly[1]->y2; + + // Average OTz value for 3 vertices + // OTz is 1/4 of screen to vertex length + OTz /= 3; + // Work color vectors + // This is the hue of the transparent cube + CVECTOR prismCol = {0xff,0xff,0x0,0x0}; + // This will store the result of the depth cueing. + CVECTOR outCol, outCol1, outCol2 = { 0,0,0,0 }; + // Find local color from three normal vectors and perform depth cueing. + gte_NormalColorDpq3( &modelCube.n[i+0], + &modelCube.n[i+2], + &modelCube.n[i+3], + &prismCol, p, &outCol, &outCol1, &outCol2); + // Set vertex colors on transparent/background cube + setRGB0(poly[1], outCol.r, outCol.g , outCol.b); + setRGB1(poly[1], outCol1.r, outCol1.g, outCol1.b); + setRGB2(poly[1], outCol2.r, outCol2.g, outCol2.b); + // Non-transparent/foreground cube color + // Find local color from three normal vectors and perform depth cueing. + gte_NormalColorDpq( &modelCube.n[i+0], &modelCube.c[i+0], p, &outCol); + gte_NormalColorDpq( &modelCube.n[i+2], &modelCube.c[i+2], p, &outCol2); + gte_NormalColorDpq( &modelCube.n[i+1], &modelCube.c[i+1], p, &outCol1); + // Set vertex colors + setRGB0(poly[0], outCol.r, outCol.g , outCol.b); + setRGB1(poly[0], outCol1.r, outCol1.g, outCol1.b); + setRGB2(poly[0], outCol2.r, outCol2.g, outCol2.b); + // If OTz is in range (not too close) + if ((OTz > 0) && (OTz < OTLEN)) + // Add to ordering table, at index OTz-2 + AddPrim(&ot[ db ][ OTz-2 ], poly[0]); + AddPrim(&ot[ db ][ OTz-2 ], poly[1]); + // Increment next primitive address + nextpri += sizeof(POLY_GT3)*2; + // Increment to next triangle + curTriangle[0] += 3; + curTriangle[1] += 3; + } + // Get pad input + pad = PadRead(0); + // If select button is used + if ( pad & PADselect && !(oldPad & PADselect) ){ + // Flip STP flag + stpFlag = !stpFlag; + // Set flag to avoir misfire + oldPad = pad; + } + // Reset flag when button released + if ( !(pad & PADselect) && oldPad & PADselect) { + oldPad = pad; + } + // If start button is used + if ( pad & PADstart && !( oldPad & PADstart ) ){ + // Switch STP rates + stpRate > 2 ? stpRate = 0 : stpRate++; + // Set flag to avoir misfire + oldPad = pad; + } + // Reset flag when button released + if (!(pad & PADstart) && oldPad & PADstart) { + oldPad = pad; + } + if ( pad & PADRdown && !( oldPad & PADRdown ) ){ + // Switch STP rates + offsetCube = 0; + // Set flag to avoir misfire + oldPad = pad; + } + // Reset flag when button released + if (!(pad & PADRdown) && oldPad & PADRdown) { + oldPad = pad; + } + if ( pad & PADLright && !( oldPad & PADLright ) ){ + offsetCube += 6; + } + if ( pad & PADLleft && !( oldPad & PADLleft ) ){ + offsetCube -= 6; + } + FntPrint("Hello fx !\n"); + FntPrint("Select: STP on/off\nStart: Cycle STP rates\nLeft/Right: Move FG cube.\nX: Reset cube pos\n"); + FntPrint("STP : %d\n", stpFlag); + FntPrint("STP rate : %d\n", stpRate); + FntFlush(-1); + display(); + } + return 0; +}