// lilplasma.c // my non-vpu-using first attempt at PS2 graphics. // inefficient, but pretty! // // - barb@eng.utah.edu // (or) chad@playstation2-linux.com // to compile: // cc -o lilplasma lilplasma.c -lps2dev -lm #include #include #include #include #include #include #include #include #include static int gsFd = 0; static ps2_gs_gparam *gsParam; static ps2_gs_dbuff gsDb; static ps2_gs_finish gsFinish; typedef struct { ps2_giftag tag; ps2_gsreg_rgbaq rgb0; ps2_gsreg_addr rgb0Addr; ps2_gsreg_xyz xyz0; ps2_gsreg_addr xyz0Addr; ps2_gsreg_rgbaq rgb1; ps2_gsreg_addr rgb1Addr; ps2_gsreg_xyz xyz1; ps2_gsreg_addr xyz1Addr; ps2_gsreg_rgbaq rgb2; ps2_gsreg_addr rgb2Addr; ps2_gsreg_xyz xyz2; ps2_gsreg_addr xyz2Addr; } TriPacket __attribute__((aligned(16))); static TriPacket triPacket; static int costa[256]; static int t; void cleanup() { if (gsFd > 0) { ps2_gs_close(); } } void draw(); void renderinit(); int main( int argc, char *argv[] ) { int frame, field; signal( SIGINT, exit ); atexit( cleanup ); //triPacket = memalign( 128, 128 ); gsFd = ps2_gs_open(-1); assert( gsFd > 0 ); gsParam = ps2_gs_get_gparam(); ps2_gs_vc_graphicsmode(); ps2_gs_reset( 0, PS2_GS_INTERLACE, PS2_GS_VESA, PS2_GS_FRAME, PS2_GS_640x480, PS2_GS_60Hz ); ps2_gs_set_dbuff( &gsDb, PS2_GS_PSMCT32, gsParam->width, gsParam->height, PS2_GS_TEST_ZTST_NEVER, PS2_GS_PSMZ16S, 0 ); *(__u64 *)&gsDb.clear0.rgbaq = PS2_GS_SETREG_RGBAQ( 0,0,0, 0x80, 0x3f800000 ); *(__u64 *)&gsDb.clear1.rgbaq = PS2_GS_SETREG_RGBAQ( 0,0,0, 0x80, 0x3f800000 ); //ps2_gs_put_drawenv( &gsDb.giftag1 ); ps2_gs_set_finish( &gsFinish ); ps2_gs_wait_finish( &gsFinish ); ps2_gs_start_display(1); field = 0; frame = !ps2_gs_sync_v( 0 ); renderinit(); while(1) { ps2_gs_set_half_offset( frame ? &gsDb.draw1 : &gsDb.draw0, field ); ps2_gs_swap_dbuff( &gsDb, field ); draw(); ps2_gs_wait_finish( &gsFinish ); frame = !ps2_gs_sync_v( 0 ); field = field ^ 1; } return 0; } void renderinit( ) { triPacket.tag.NLOOP = 6; triPacket.tag.EOP = 1; triPacket.tag.PRE = 1; triPacket.tag.FLG = PS2_GIFTAG_FLG_PACKED; triPacket.tag.NREG = 1; triPacket.tag.REGS0 = PS2_GIFTAG_REGS_AD; triPacket.tag.PRIM = PS2_GS_SETREG_PRIM( PS2_GS_PRIM_PRIM_TRIANGLE, PS2_GS_PRIM_IIP_GOURAUD, PS2_GS_PRIM_TME_OFF, PS2_GS_PRIM_FGE_OFF, PS2_GS_PRIM_ABE_OFF, PS2_GS_PRIM_AA1_OFF, PS2_GS_PRIM_FST_STQ, PS2_GS_PRIM_CTXT_CONTEXT1, PS2_GS_PRIM_FIX_NOFIXDDA ); triPacket.rgb0Addr = PS2_GS_RGBAQ; triPacket.rgb1Addr = PS2_GS_RGBAQ; triPacket.rgb2Addr = PS2_GS_RGBAQ; triPacket.xyz0Addr = PS2_GS_XYZF2; triPacket.xyz1Addr = PS2_GS_XYZF2; triPacket.xyz2Addr = PS2_GS_XYZF2; triPacket.xyz0.Z = 0xFFFFFF; triPacket.xyz1.Z = 0xFFFFFF; triPacket.xyz2.Z = 0xFFFFFF; { int x; for (x = 0; x < 256; x++) { costa[x] = (int)(32767.0f * cos((float)x * 3.14159f * 2.0f / 256.0f)); } } } void triangle( unsigned char r0, unsigned char g0, unsigned char b0, int x0, int y0, unsigned char r1, unsigned char g1, unsigned char b1, int x1, int y1, unsigned char r2, unsigned char g2, unsigned char b2, int x2, int y2 ) { triPacket.rgb0.R = r0; triPacket.rgb0.G = g0; triPacket.rgb0.B = b0; triPacket.rgb1.R = r1; triPacket.rgb1.G = g1; triPacket.rgb1.B = b1; triPacket.rgb2.R = r2; triPacket.rgb2.G = g2; triPacket.rgb2.B = b2; triPacket.xyz0.X = (gsParam->center_x + x0) << 4; triPacket.xyz0.Y = (gsParam->center_y + y0) << 4; triPacket.xyz1.X = (gsParam->center_x + x1) << 4; triPacket.xyz1.Y = (gsParam->center_y + y1) << 4; triPacket.xyz2.X = (gsParam->center_x + x2) << 4; triPacket.xyz2.Y = (gsParam->center_y + y2) << 4; ps2_gs_put_drawenv( &(triPacket.tag) ); } void draw() { unsigned char r[64][48]; unsigned char g[64][48]; unsigned char b[64][48]; int x, y; t++; for (x = 0; x < 17; x++) { for (y = 0; y < 13; y++) { r[x][y] = (((int)costa[(x * 22 + t * 8) & 255] + (int)costa[(y * 19 + t * 6) & 255] + (int)costa[((x + x + y) * 9 + t * 4) & 255] + (int)costa[((x + x + x + y) * 10 + t * 2) & 255] ) >> 10) + 128; g[x][y] = (((int)costa[((x + y + y) * 18 + t * 3) & 255] + (int)costa[(y * 32 + t * 9) & 255] + (int)costa[(x * 17 - t * 4) & 255] + (int)costa[((x + y) * 12 + t * 5) & 255] ) >> 10) + 128; b[x][y] = (((int)costa[((x + x + y) * 18 + t * 2) & 255] + (int)costa[((y + x) * 8 + t * 7) & 255] + (int)costa[(x * 10 - t * 3) & 255] + (int)costa[(y * 23 + t * 5) & 255] ) >> 10) + 128; } } for (x = 0; x < 16; x++) { for (y = 0; y < 12; y++) { triangle( r[x][y], g[x][y], b[x][y], (x - 8) * 40 , (y - 6) * 40, r[x+1][y], g[x+1][y], b[x+1][y], (x - 8 + 1) * 40 , (y - 6) * 40, r[x][y+1], g[x][y+1], b[x][y+1], (x - 8) * 40 , (y - 6+1) * 40 ); triangle( r[x+1][y], g[x+1][y], b[x+1][y], (x - 8+1) * 40 , (y - 6) * 40, r[x+1][y+1], g[x+1][y+1], b[x+1][y+1], (x - 8+1) * 40 , (y - 6+1) * 40, r[x][y+1], g[x][y+1], b[x][y+1], (x - 8) * 40, (y - 6+1) * 40 ); } } }