// *********************************************** // MAIN.C - main file // *********************************************** #define DRAWPLAYER0 #define DRAWPLAYER1 #define DRAWPLAYER2 #define DRAWPLAYER3 #define CLIPSIZE (6) #define SCREENW (160) #define VSYNCS (4) #define PROJECTION (100) #define _DEBUG_ #ifdef _DEBUG_ #define printd(_t) printf(_t) #else #define () (_t) #endif // **** includes #define MAPX (10) #define MAPY (10) #define TEXTURE1 (0x80090000) #define TEXTURE2 (0x80098000) #define TEXTURE3 (0x800a0000) #define TEXTURE4 (0x800a8000) #define FREE_MEM (0x80090000) #define TRUE (1) #define FALSE (0) #include #include "pad.h" #include "creation.h" #include "init.h" #include "graphics.h" Model CAMERAMODEL[4]; // **** global variable extern DISPENV GsDISPENV; DRAWENV SplitScreenInfo[8]; static u_long STANDARDMODELATTRIBUTE; static GsRVIEW2 ViewPoint[4]; static GsSPRITE playerSprite; u_char WALLS[MAPX][MAPY] = { {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 1, 0, 0, 0, 0, 0, 1}, {1, 0, 0, 1, 0, 1, 0, 1, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 0, 1, 0, 1, 0, 1, 0, 1}, {1, 1, 1, 1, 0, 0, 0, 0, 0, 1}, {1, 0, 0, 0, 0, 1, 1, 0, 0, 1}, {1, 0, 0, 1, 1, 1, 1, 0, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1, 1, 1}}; u_char WALLSRGB[MAPX][MAPY][3]; static Model WALLMODEL[MAPX][MAPY]; typedef struct { long x,z; u_char r,g,b; u_long str; } lightsource; #define NUMLIGHTS (5) lightsource L[NUMLIGHTS]; // **** function prototypes void UpdateProgram(void); void RenderProgram(void); void CreateLight(lightsource*,long,long,u_char,u_char,u_char,u_long); void CalculateLight(long tx, long tz, u_char *tcol); u_long ProcessPad(void); void SetPlayerWindow(DRAWENV*, u_long, u_long); void draw_3dsprite (GsSPRITE *sprite,long x,long y,long z,GsOT* tOT); u_long checkcollide(long tx, long tz); // **** read and act on pad u_long ProcessPad() { #define CHECK (270) u_long PAD1, PAD2; u_long test0, test1, test2; long attemptx, attemptz, tangle; PAD2 = (PAD1 = ReadPad()) >> 16; //player0 if (PAD1& PADup) { tangle = CAMERAMODEL[0].Orientation.vy; ReturnMoveForward(&CAMERAMODEL[0], 0, 0, 44*VSYNCS, &attemptx, &attemptz); if ((tangle>=0) && (tangle<1024)) { test0 = checkcollide(CAMERAMODEL[0].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[0].Object_Coord.coord.t[2]+attemptz+CHECK); test1 = checkcollide(CAMERAMODEL[0].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[0].Object_Coord.coord.t[2]+attemptz+CHECK); test2 = checkcollide(CAMERAMODEL[0].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[0].Object_Coord.coord.t[2]+attemptz-CHECK); } else if ((tangle>=1024) && (tangle<2048)) { test0 = checkcollide(CAMERAMODEL[0].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[0].Object_Coord.coord.t[2]+attemptz-CHECK); test1 = checkcollide(CAMERAMODEL[0].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[0].Object_Coord.coord.t[2]+attemptz-CHECK); test2 = checkcollide(CAMERAMODEL[0].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[0].Object_Coord.coord.t[2]+attemptz+CHECK); } else if ((tangle>2048) && (tangle<3072)) { test0 = checkcollide(CAMERAMODEL[0].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[0].Object_Coord.coord.t[2]+attemptz-CHECK); test1 = checkcollide(CAMERAMODEL[0].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[0].Object_Coord.coord.t[2]+attemptz-CHECK); test2 = checkcollide(CAMERAMODEL[0].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[0].Object_Coord.coord.t[2]+attemptz+CHECK); } else { test0 = checkcollide(CAMERAMODEL[0].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[0].Object_Coord.coord.t[2]+attemptz+CHECK); test1 = checkcollide(CAMERAMODEL[0].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[0].Object_Coord.coord.t[2]+attemptz+CHECK); test2 = checkcollide(CAMERAMODEL[0].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[0].Object_Coord.coord.t[2]+attemptz-CHECK); } if (test0 && test2) attemptx=attemptz=0; else if (test0) attemptz=0; else if (test2) attemptx=0; else if (test1) attemptx=attemptz=0; CAMERAMODEL[0].Object_Coord.coord.t[0]+=attemptx; CAMERAMODEL[0].Object_Coord.coord.t[2]+=attemptz; CAMERAMODEL[0].Object_Coord.flg = 0; } if (PAD1& PADdown) MoveModelForward(&CAMERAMODEL[0], 0, 0, -32*VSYNCS); if (PAD1& PADleft) RotateModel(&CAMERAMODEL[0], 0, -25*VSYNCS, 0); if (PAD1& PADright) RotateModel(&CAMERAMODEL[0], 0, +25*VSYNCS, 0); //player1 if (PAD1& PADtriangle) { tangle = CAMERAMODEL[1].Orientation.vy; ReturnMoveForward(&CAMERAMODEL[1], 0, 0, 44*VSYNCS, &attemptx, &attemptz); if ((tangle>=0) && (tangle<1024)) { test0 = checkcollide(CAMERAMODEL[1].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[1].Object_Coord.coord.t[2]+attemptz+CHECK); test1 = checkcollide(CAMERAMODEL[1].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[1].Object_Coord.coord.t[2]+attemptz+CHECK); test2 = checkcollide(CAMERAMODEL[1].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[1].Object_Coord.coord.t[2]+attemptz-CHECK); } else if ((tangle>=1024) && (tangle<2048)) { test0 = checkcollide(CAMERAMODEL[1].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[1].Object_Coord.coord.t[2]+attemptz-CHECK); test1 = checkcollide(CAMERAMODEL[1].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[1].Object_Coord.coord.t[2]+attemptz-CHECK); test2 = checkcollide(CAMERAMODEL[1].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[1].Object_Coord.coord.t[2]+attemptz+CHECK); } else if ((tangle>2048) && (tangle<3072)) { test0 = checkcollide(CAMERAMODEL[1].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[1].Object_Coord.coord.t[2]+attemptz-CHECK); test1 = checkcollide(CAMERAMODEL[1].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[1].Object_Coord.coord.t[2]+attemptz-CHECK); test2 = checkcollide(CAMERAMODEL[1].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[1].Object_Coord.coord.t[2]+attemptz+CHECK); } else { test0 = checkcollide(CAMERAMODEL[1].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[1].Object_Coord.coord.t[2]+attemptz+CHECK); test1 = checkcollide(CAMERAMODEL[1].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[1].Object_Coord.coord.t[2]+attemptz+CHECK); test2 = checkcollide(CAMERAMODEL[1].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[1].Object_Coord.coord.t[2]+attemptz-CHECK); } if (test0 && test2) attemptx=attemptz=0; else if (test0) attemptz=0; else if (test2) attemptx=0; else if (test1) attemptx=attemptz=0; CAMERAMODEL[1].Object_Coord.coord.t[0]+=attemptx; CAMERAMODEL[1].Object_Coord.coord.t[2]+=attemptz; CAMERAMODEL[1].Object_Coord.flg = 0; } if (PAD1& PADcross) MoveModelForward(&CAMERAMODEL[1], 0, 0, -32*VSYNCS); if (PAD1& PADsquare) RotateModel(&CAMERAMODEL[1], 0, -25*VSYNCS, 0); if (PAD1& PADcircle) RotateModel(&CAMERAMODEL[1], 0, +25*VSYNCS, 0); //player2 if (PAD2& PADup) { tangle = CAMERAMODEL[2].Orientation.vy; ReturnMoveForward(&CAMERAMODEL[2], 0, 0, 44*VSYNCS, &attemptx, &attemptz); if ((tangle>=0) && (tangle<1024)) { test0 = checkcollide(CAMERAMODEL[2].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[2].Object_Coord.coord.t[2]+attemptz+CHECK); test1 = checkcollide(CAMERAMODEL[2].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[2].Object_Coord.coord.t[2]+attemptz+CHECK); test2 = checkcollide(CAMERAMODEL[2].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[2].Object_Coord.coord.t[2]+attemptz-CHECK); } else if ((tangle>=1024) && (tangle<2048)) { test0 = checkcollide(CAMERAMODEL[2].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[2].Object_Coord.coord.t[2]+attemptz-CHECK); test1 = checkcollide(CAMERAMODEL[2].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[2].Object_Coord.coord.t[2]+attemptz-CHECK); test2 = checkcollide(CAMERAMODEL[2].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[2].Object_Coord.coord.t[2]+attemptz+CHECK); } else if ((tangle>2048) && (tangle<3072)) { test0 = checkcollide(CAMERAMODEL[2].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[2].Object_Coord.coord.t[2]+attemptz-CHECK); test1 = checkcollide(CAMERAMODEL[2].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[2].Object_Coord.coord.t[2]+attemptz-CHECK); test2 = checkcollide(CAMERAMODEL[2].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[2].Object_Coord.coord.t[2]+attemptz+CHECK); } else { test0 = checkcollide(CAMERAMODEL[2].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[2].Object_Coord.coord.t[2]+attemptz+CHECK); test1 = checkcollide(CAMERAMODEL[2].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[2].Object_Coord.coord.t[2]+attemptz+CHECK); test2 = checkcollide(CAMERAMODEL[2].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[2].Object_Coord.coord.t[2]+attemptz-CHECK); } if (test0 && test2) attemptx=attemptz=0; else if (test0) attemptz=0; else if (test2) attemptx=0; else if (test1) attemptx=attemptz=0; CAMERAMODEL[2].Object_Coord.coord.t[0]+=attemptx; CAMERAMODEL[2].Object_Coord.coord.t[2]+=attemptz; CAMERAMODEL[2].Object_Coord.flg = 0; } if (PAD2& PADdown) MoveModelForward(&CAMERAMODEL[2], 0, 0, -32*VSYNCS); if (PAD2& PADleft) RotateModel(&CAMERAMODEL[2], 0, -25*VSYNCS, 0); if (PAD2& PADright) RotateModel(&CAMERAMODEL[2], 0, +25*VSYNCS, 0); //player3 if (PAD2& PADtriangle) { tangle = CAMERAMODEL[3].Orientation.vy; ReturnMoveForward(&CAMERAMODEL[3], 0, 0, 44*VSYNCS, &attemptx, &attemptz); if ((tangle>=0) && (tangle<1024)) { test0 = checkcollide(CAMERAMODEL[3].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[3].Object_Coord.coord.t[2]+attemptz+CHECK); test1 = checkcollide(CAMERAMODEL[3].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[3].Object_Coord.coord.t[2]+attemptz+CHECK); test2 = checkcollide(CAMERAMODEL[3].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[3].Object_Coord.coord.t[2]+attemptz-CHECK); } else if ((tangle>=1024) && (tangle<2048)) { test0 = checkcollide(CAMERAMODEL[3].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[3].Object_Coord.coord.t[2]+attemptz-CHECK); test1 = checkcollide(CAMERAMODEL[3].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[3].Object_Coord.coord.t[2]+attemptz-CHECK); test2 = checkcollide(CAMERAMODEL[3].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[3].Object_Coord.coord.t[2]+attemptz+CHECK); } else if ((tangle>2048) && (tangle<3072)) { test0 = checkcollide(CAMERAMODEL[3].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[3].Object_Coord.coord.t[2]+attemptz-CHECK); test1 = checkcollide(CAMERAMODEL[3].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[3].Object_Coord.coord.t[2]+attemptz-CHECK); test2 = checkcollide(CAMERAMODEL[3].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[3].Object_Coord.coord.t[2]+attemptz+CHECK); } else { test0 = checkcollide(CAMERAMODEL[3].Object_Coord.coord.t[0]+attemptx+CHECK, CAMERAMODEL[3].Object_Coord.coord.t[2]+attemptz+CHECK); test1 = checkcollide(CAMERAMODEL[3].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[3].Object_Coord.coord.t[2]+attemptz+CHECK); test2 = checkcollide(CAMERAMODEL[3].Object_Coord.coord.t[0]+attemptx-CHECK, CAMERAMODEL[3].Object_Coord.coord.t[2]+attemptz-CHECK); } if (test0 && test2) attemptx=attemptz=0; else if (test0) attemptz=0; else if (test2) attemptx=0; else if (test1) attemptx=attemptz=0; CAMERAMODEL[3].Object_Coord.coord.t[0]+=attemptx; CAMERAMODEL[3].Object_Coord.coord.t[2]+=attemptz; CAMERAMODEL[3].Object_Coord.flg = 0; } if (PAD2& PADcross) MoveModelForward(&CAMERAMODEL[3], 0, 0, -32*VSYNCS); if (PAD2& PADsquare) RotateModel(&CAMERAMODEL[3], 0, -25*VSYNCS, 0); if (PAD2& PADcircle) RotateModel(&CAMERAMODEL[3], 0, +25*VSYNCS, 0); if ((PAD1& PADstart) && (PAD1& PADselect)) return TRUE; return FALSE; } // **** update the world //void UpdateProgram() // { // } // **** draw the world void RenderProgram(void) { static u_long cTime, hTime=0, lTime=5000; u_long counter0, counter1; u_long currentBuffer = GsGetActiveBuff(); long tcellx, tcellz; long Xlo, Xhi, Zhi, Zlo; #ifdef DRAWPLAYER0 // draw screen TOPLEFT (0) DrawSync(0); GsClearOt(0, 0, &OTable_Header[currentBuffer]); GsSetWorkBase((PACKET*)Packet_Memory[currentBuffer]); GsSetRefView2(&ViewPoint[0]); tcellx = CAMERAMODEL[0].Object_Coord.coord.t[0]/1024; tcellz = CAMERAMODEL[0].Object_Coord.coord.t[2]/1024; Xlo = (tcellx(MAPX-(CLIPSIZE+1)))?MAPX:tcellx+(CLIPSIZE+1); Zlo = (tcellz(MAPY-(CLIPSIZE+1)))?MAPY:tcellz+(CLIPSIZE+1); for (counter0=Xlo; counter0tcellx-2) && (counter0tcellz-2) && (counter1(MAPX-(CLIPSIZE+1)))?MAPX:tcellx+(CLIPSIZE+1); Zlo = (tcellz(MAPY-(CLIPSIZE+1)))?MAPY:tcellz+(CLIPSIZE+1); for (counter0=Xlo; counter0(MAPX-(CLIPSIZE+1)))?MAPX:tcellx+(CLIPSIZE+1); Zlo = (tcellz(MAPY-(CLIPSIZE+1)))?MAPY:tcellz+(CLIPSIZE+1); for (counter0=Xlo; counter0(MAPX-(CLIPSIZE+1)))?MAPX:tcellx+(CLIPSIZE+1); Zlo = (tcellz(MAPY-(CLIPSIZE+1)))?MAPY:tcellz+(CLIPSIZE+1); for (counter0=Xlo; counter0hTime) hTime=cTime; if (cTimex = tx; tlight->z = tz; tlight->r = tr; tlight->g = tg; tlight->b = tb; tlight->str = tstr; } void CalculateLight(long tx, long tz, u_char *tcol) { u_long tr=0, tg=0, tb=0; u_long tDist; u_long tStr; u_long tCounter; for (tCounter=0; tCounter>8) * L[tCounter].r) >> 8; tg += ((tStr-tDist)/(tStr>>8) * L[tCounter].g) >> 8; tb += ((tStr-tDist)/(tStr>>8) * L[tCounter].b) >> 8; } } if (tr>255) tr = 255; if (tg>255) tg = 255; if (tb>255) tb = 255; if (tr<24) tr = 24; if (tg<24) tg = 24; if (tb<24) tb = 24; tcol[0] = tr; tcol[1] = tg; tcol[2] = tb; } void SetPlayerWindow(DRAWENV *tdisp, u_long tx, u_long ty) { tdisp->clip.x = tx; // set split 1 on buffer 0 tdisp->clip.y = ty; tdisp->clip.w = SCREENW; tdisp->clip.h = 128; tdisp->ofs[0] = tx+SCREENW/2; // set origin into middle of window tdisp->ofs[1] = ty+64; tdisp++; tdisp->clip.x = tx; // set split 1 on buffer 0 tdisp->clip.y = ty+256; tdisp->clip.w = SCREENW; tdisp->clip.h = 128; tdisp->ofs[0] = tx+SCREENW/2; // set origin into middle of window tdisp->ofs[1] = ty+64+256; } void draw_3dsprite (GsSPRITE *sprite,long x,long y,long z,GsOT* tOT) { VECTOR spritePosition,transformedPosition; long tTempZ; long Xcell = x/1024; long Ycell = z/1024; // This is the position of your sprite in 3d space spritePosition.vx=x; spritePosition.vy=y; spritePosition.vz=z; ApplyMatrixLV(&GsWSMATRIX,&spritePosition,&transformedPosition); transformedPosition.vx+=GsWSMATRIX.t[0]; transformedPosition.vy+=GsWSMATRIX.t[1]; transformedPosition.vz+=GsWSMATRIX.t[2]; tTempZ = (transformedPosition.vz>>(18-OTABLE_LENGTH)); // FntPrint("Z depth %d\n", tTempZ); // Only draw tree sprite if its in front of the camera if (tTempZ>0) { // Scales the tree - 16777216=4096<<12 is a constant (works for me) sprite->r = WALLSRGB[Xcell][Ycell][0]; sprite->g = WALLSRGB[Xcell][Ycell][1]; sprite->b = WALLSRGB[Xcell][Ycell][2]; sprite->scalex=sprite->scaley=(1024<<12)/transformedPosition.vz; sprite->x=transformedPosition.vx*PROJECTION/transformedPosition.vz; sprite->y=transformedPosition.vy*PROJECTION/transformedPosition.vz; GsSortSprite(sprite,tOT,(tTempZ>0)?tTempZ-1:0); } } u_long checkcollide(long tx, long tz) { if (WALLS[tx/1024][tz/1024] != 0) return 1; return 0; }