// // MakeTMD - by Max // // Andrew Murray - 2001 Max Studios // // main.c - main source file // // ---------------- includes #include // playstation specific library #include #include #include "pad.h" // pad handling functions #include "tmd.h" // dynamic TMD functions #include "main.h" // miscellaneous functions // ----------------functions void Initialise(void) { PadInit(); // without this you can kiss the pad adios SetVideoMode(MODE_PAL); // this allows use of PAL resolutions // initialise the graphics engine with 640 x 512 resolution GsInitGraph(SCREEN_WIDTH,SCREEN_HEIGHT,GsOFSGPU,1,0); // set to GsINTER(laced) for hi-res GsDefDispBuff(0,0,0,0); // set this to 0,0,0,0 for hi-res GsDRAWENV.isbg = 1; // fix clear screen problem WorldOT[0].length = OT_LENGTH; // set OT length WorldOT[0].org = WorldTags[0]; // link in the OT units WorldOT[1].length = OT_LENGTH; WorldOT[1].org = WorldTags[1]; GsClearOt(0, 0, &WorldOT[0]); // initialise the OTs GsClearOt(0, 0, &WorldOT[1]); FntLoad(960, 256); // load the font FntOpen(10, 80, 256, 200, 0, 512); // open it to screen GsInit3D(); // initialise 3D graphics } void InitSceneLighting(void) { InitLight(&lights[0],0,30,30,30,128,128,128); // init a red tinted light InitLight(&lights[1],1,-30,30,30,128,128,128); // init a green tinted light InitLight(&lights[2],2,30,-30,30,128,128,128); // init a blue tinted light GsSetAmbient(100,100,100); // set scene ambient light GsSetLightMode(0); // turn on lighting } void DrawCube(CubeStruct *cube,GsOT *ot) { MATRIX lw, ls; // temporary calculation matrices GsGetLws(cube->objectHandler.coord2, &lw, &ls); GsSetLightMatrix(&lw); // set the lights GsSetLsMatrix(&ls); // set the local screen matrix GsSortObject4(&cube->objectHandler,ot,2,(u_long *)getScratchAddr(0)); // register object in OT } void BuildCube(u_long *addr,CubeStruct *cube) // address of TMD, cube object to build { TMD_VERT *vertPtr; // a pointer to vertices so that memory isn't chucked around TMD_NORM *normPtr; // same as above for normals TMD_FT4 *primPtr; // same as above for primitives TMD_TEX texture1; // declare an instance of the TMD_TEX struct for texturing cube->cube.cubeHeader.id = 0x41; // standard TMD version as in docs cube->cube.cubeHeader.flag = 1; // addressing is mapped not absoloute cube->cube.cubeHeader.nobjs = 1; // there is only one object to the TMD cube->cube.cubeObject.vert_top = (unsigned long int*) cube->cube.cubeVertices; // vertices table cube->cube.cubeObject.n_vert = 8; // number of vertices cube->cube.cubeObject.norm_top = (unsigned long int*) cube->cube.cubeNormals; // normal table cube->cube.cubeObject.n_norm = 6; // number of normals cube->cube.cubeObject.prim_top = (unsigned long int*) cube->cube.cubeSides; // primatives table cube->cube.cubeObject.n_prim = 6; // number of primatives cube->cube.cubeObject.scale = ONE; // -----------------------------------------------Vertices vertPtr = cube->cube.cubeVertices; // assign the vertices of the TMD to a pointer // top, left, back, vert 0 vertPtr->vx = -25; vertPtr->vy = -25; vertPtr->vz = 25; vertPtr++; // increment to next vertex // top, left, front, vert 1 vertPtr->vx = -25; vertPtr->vy = -25; vertPtr->vz = -25; vertPtr++; // increment to next vertex // top, right, front, vert 2 vertPtr->vx = 25; vertPtr->vy = -25; vertPtr->vz = -25; vertPtr++; // increment to next vertex // top, right, back, vert 3 vertPtr->vx = 25; vertPtr->vy = -25; vertPtr->vz = 25; vertPtr++; // increment to next vertex // bottom, left, back, vert 4 vertPtr->vx = -25; vertPtr->vy = 25; vertPtr->vz = 25; vertPtr++; // increment to next vertex // bottom, left, front, vert 5 vertPtr->vx = -25; vertPtr->vy = 25; vertPtr->vz = -25; vertPtr++; // increment to next vertex // bottom, right, front, vert 6 vertPtr->vx = 25; vertPtr->vy = 25; vertPtr->vz = -25; vertPtr++; // increment to next vertex // bottom, right, back, vert 7 vertPtr->vx = 25; vertPtr->vy = 25; vertPtr->vz = 25; // -------------------------------------------------Normals normPtr = cube->cube.cubeNormals; // top, normal 0 normPtr->nx = 0; normPtr->ny = -4096; normPtr->nz = 0; normPtr++; // front, normal 1 normPtr->nx = 0; normPtr->ny = 0; normPtr->nz = -4096; normPtr++; // left, normal 2 normPtr->nx = -4096; normPtr->ny = 0; normPtr->nz = 0; normPtr++; // back, normal 3 normPtr->nx = 0; normPtr->ny = 0; normPtr->nz = 4096; normPtr++; // right, normal 4 normPtr->nx = 4096; normPtr->ny = 0; normPtr->nz = 0; normPtr++; // bottom, normal 5 normPtr->nx = 0; normPtr->ny = 4096; normPtr->nz = 0; // -------------------------------------Aquire Textures for Cube LoadTMDTEX(TECHWALL_ADDR,&texture1); printf("Left: %d, Top: %d, Right: %d, Bottom: %d\n",texture1.left,texture1.top,texture1.right,texture1.bottom); // ------------------------------------Composition of Primitives primPtr = cube->cube.cubeSides; // top side, prim 0 primPtr->ilen = 7; primPtr->olen = 9; primPtr->flag = 0; // light source calculation carried out, single faced, not garuad shaded primPtr->mode = FT4; // set mode to flat textured quad primPtr->norm0 = 0; primPtr->vert0 = 0; primPtr->vert1 = 3; primPtr->vert2 = 1; primPtr->vert3 = 2; primPtr->u0 = texture1.left; primPtr->v0 = texture1.top; primPtr->u1 = texture1.right; primPtr->v1 = texture1.top; primPtr->u2 = texture1.left; primPtr->v2 = texture1.bottom; primPtr->u3 = texture1.right; primPtr->v3 = texture1.bottom; primPtr->cba = texture1.cba; primPtr->tsb = texture1.tsb; primPtr++; // jump to next primitive // front side, prim 1 *primPtr = *(primPtr - 1); primPtr->norm0 = 1; primPtr->vert0 = 1; primPtr->vert1 = 2; primPtr->vert2 = 5; primPtr->vert3 = 6; primPtr++; // jump to next primitive // left side, prim 2 *primPtr = *(primPtr - 1); primPtr->norm0 = 2; primPtr->vert0 = 0; primPtr->vert1 = 1; primPtr->vert2 = 4; primPtr->vert3 = 5; primPtr++; // jump to next primitive // back side, prim 3 *primPtr = *(primPtr - 1); primPtr->norm0 = 3; primPtr->vert0 = 3; primPtr->vert1 = 0; primPtr->vert2 = 7; primPtr->vert3 = 4; primPtr++; // jump to next primitive // right side, prim 4 *primPtr = *(primPtr - 1); primPtr->norm0 = 4; primPtr->vert0 = 2; primPtr->vert1 = 3; primPtr->vert2 = 6; primPtr->vert3 = 7; primPtr++; //bottom side prim 5 *primPtr = *(primPtr - 1); primPtr->norm0 = 5; primPtr->vert0 = 7; primPtr->vert1 = 4; primPtr->vert2 = 6; primPtr->vert3 = 5; GsInitCoordinate2(WORLD, &cube->objectCoord); // set the cubes coord system to be that of the WORLD GsLinkObject4((u_long)&cube->cube.cubeObject, &cube->objectHandler, 0); // link the TMD model data to the handler // set the model coord system to that of the declared GsCOORDINATE2 instance 'objectCoord' cube->objectHandler.coord2 = &cube->objectCoord; // set up coordinates of cube cube->objectCoord.coord.t[0] = 0; // X cube->objectCoord.coord.t[1] = 0; // Y cube->objectCoord.coord.t[2] = 0; // Z // setting the cubes objectCoord.flg to 0 indicates it is to be drawn cube->objectCoord.flg = 0; } void ResetMatrix(short m[3][3]) { m[0][0]=m[1][1]=m[2][2]=ONE; m[0][1]=m[0][2]=m[1][0]=m[1][2]=m[2][0]=m[2][1]=0; } void RotateModel (GsCOORDINATE2 *objCoord,SVECTOR *rVector , int nRX, int nRY, int nRZ ) { MATRIX matTmp; ResetMatrix(objCoord->coord.m ); // reset to identity to avoid error // Add the new rotation factors into the players rotation vector // and then set them to the remainder of division by ONE (4096) rVector->vx = (rVector->vx+nRX)%ONE; rVector->vy = (rVector->vy+nRY)%ONE; rVector->vz = (rVector->vz+nRZ)%ONE; RotMatrix(rVector, &matTmp); // set up the matrix coefficients for rotation MulMatrix0(&objCoord->coord, &matTmp, &objCoord->coord); // multiply the two matrices to get rotated matrix objCoord->flg = 0; // set the flag to redraw the object } void DealWithPad(CubeStruct *cube) { u_long PadStatus = 0; PadStatus = PadRead(); if((PadStatus & PADselect) && (PadStatus & PADstart)) PLAYING=0; if(PadStatus & PADLup) { RotateModel(&cube->objectCoord,&cube->rotate,64,0,0); } if(PadStatus & PADLdown) { RotateModel(&cube->objectCoord,&cube->rotate,-64,0,0); } if(PadStatus & PADLleft) { RotateModel(&cube->objectCoord,&cube->rotate,0,64,0); } if(PadStatus & PADLright) { RotateModel(&cube->objectCoord,&cube->rotate,0,-64,0); } if(PadStatus & PADL1) { RotateModel(&cube->objectCoord,&cube->rotate,0,0,64); } if(PadStatus & PADR1) { RotateModel(&cube->objectCoord,&cube->rotate,0,0,-64); } if(PadStatus & PADcross) { cube->objectCoord.coord.t[2] -= 5; } if(PadStatus & PADtriangle) { cube->objectCoord.coord.t[2] += 5; } } void main(void) { int currentBuffer, // holds current frame buffer vsync; // variable to track vsync static CubeStruct cube; // declare in instance of the cube Initialise(); // initialise OTs and graphics BuildCube((u_long *)CUBE_ADDR,&cube); // set up all the TMD data for the cube InitView(&view,300,0,0,0,-200,0,0,0); // set up the camera InitSceneLighting(); // set flat lights and ambient lighting currentBuffer = GsGetActiveBuff(); // find out what the current frame buffer is while(PLAYING) { FntPrint("FRAME: %d\n", frameNo); frameNo++; DealWithPad(&cube); GsSetWorkBase((PACKET *)packetArea[currentBuffer]); GsClearOt(0,0,&WorldOT[currentBuffer]); // draw code goes here DrawCube(&cube,&WorldOT[currentBuffer]); // calculate the world matrices and send to OT // end draw code DrawSync(0); // wait for all drawing commands to finish vsync = VSync(1); // then grab the VSync interval VSync(0); // block until vsync has occured FntPrint("HSYNC: %d\n", vsync); GsSwapDispBuff(); GsSortClear(0,0,0,&WorldOT[currentBuffer]); GsDrawOt(&WorldOT[currentBuffer]); // draw the current off screen buffer to the screen currentBuffer = currentBuffer^1; // change side to 1 or 0 FntFlush(-1); // print all font calls } ResetGraph(0); }