Hi, I happen to have an aquaintance who taught a course in California on writing video games. This code fragment example is *hard* to find and *harder* to believe. With the Playstation PS2 selling 27 boxes a minute worldwide... and game consoles selling 5+ billion $ a year, the box is actually *easy* to program! The below is 100% of the source to make some stars fly by. The point is how totally ordinary this all is. Compiled under Linux with free compilers, yet! Sony has done a good job of making the last step of making a PS2 compliant CD very difficult. But, fooling the box for testing is reasonably easy. And they are not unreasonable about the publishing rights, etc. The below seems completely accessable. A few weird libraries in the includes and that's it! I don't know if you find this as unexpected as I do. I visualized it would take a dozen $100K programs glued together by weirdo "good luck" code to run. Don't forget this $250 computer has 15 times the throughput of a Pentium at 1 GHz. And an audiance that would crawl over broken glass to play. I think the audience on this email reflector might find this interesting. Hope I'm right on that... The author is on the CC line and the leading comments. Thanks for WWW access to this code! Regards to all, Dan Kolis // 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 <stdio.h> #include <stdlib.h> #include <assert.h> #include <unistd.h> #include <signal.h> #include <linux/ps2/dev.h> #include <ps2gs.h> #include <ps2dma.h> #include <math.h> 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 ); } } } Document end 02 Jan 2003 Dan Kolis - Lindsay Electronics Ltd dank@hq.lindsayelec.com 50 Mary Street West, Lindsay Ontario Canada K9V 2S7 (705) 324-2196 (705) 324-5474 Fax An ISO 9001 Company; SCTE Member ISM-127194 /Document end