/*************************************************************** main.c 'TANX' by Stuart Macdonald ====== ***************************************************************/ #include #include #include #include #include "pad.h" #define ORDERING_TABLE_LENGTH (10) #define MAX_NO_PACKETS (248000) #define SCREEN_WIDTH (512) #define SCREEN_HEIGHT (240) #define MAX_X (22) #define MAX_Z (22) #define MAX_WORLD_OBJECTS (130) #define SEPERATION (1200) #define VH_ADDR (0x800c0000) #define VB_ADDR (0x800d0000) //#define SEQ_ADDR (0x80110000) #define MAIN_VOL (127) //#define SEQ_VOL (127) #define MAX_NO_OF_BULLETS (10) #define CHASSIS (1) #define TURRET (2) #define SHOT (3) #define EXPLOSION (4) #define AIRSHIP (5) #define FLAG (6) #define SHIELD (7) #define SMOKE (8) #define MINE (9) #define GRASS_TEX_MEM_ADDR (0x80091ca0) #define CONC_TEX_MEM_ADDR (0x800922c0) #define GRA2CON1_TEX_MEM_ADDR (0x800928e0) #define GRA2CON2_TEX_MEM_ADDR (0x80092f00) #define WATER_TEX_MEM_ADDR (0x80093600) #define GRA2WAT1_TEX_MEM_ADDR (0x80093d00) #define GRA2WAT2_TEX_MEM_ADDR (0x800aa760) #define SQUARE1_MEM_ADDR (0x80091840) #define SQUARE2_MEM_ADDR (0x800918b0) #define SQUARE3_MEM_ADDR (0x80091920) #define SQUARE4_MEM_ADDR (0x80091990) #define SQUARE5_MEM_ADDR (0x80091a00) #define SQUARE6_MEM_ADDR (0x80091a70) #define SQUARE7_MEM_ADDR (0x80091ae0) #define SQUARE8_MEM_ADDR (0x80091b50) #define SQUARE9_MEM_ADDR (0x80091bc0) #define SQUARE10_MEM_ADDR (0x80091c30) #define SQUARE11_MEM_ADDR (0x80094780) #define SQUARE12_MEM_ADDR (0x80094df0) #define SQUARE13_MEM_ADDR (0x80094e60) #define SQUARE14_MEM_ADDR (0x80094ed0) #define SQUARE15_MEM_ADDR (0x80094f40) #define SQUARE16_MEM_ADDR (0x80094fb0) #define SQUARE17_MEM_ADDR (0x80095020) #define SQUARE18_MEM_ADDR (0x80095090) #define SQUARE19_MEM_ADDR (0x80095100) #define BLDG1_MEM_ADDR (0x800959f0) #define BLDGSIDE_TEX_MEM_ADDR (0x80095b3c) #define BLDGTOP_TEX_MEM_ADDR (0x80096d5c) #define CRATER_MEM_ADDR (0x8009f000) #define SHELL_MEM_ADDR (0x80090000) #define MISSILE_MEM_ADDR (0x800900dc) #define ARMOUR_MEM_ADDR (0x80090248) #define CHASSIS1_MEM_ADDR (0x80097f7c) #define CHASSIS2_MEM_ADDR (0x80099000) #define CHASSIS3_MEM_ADDR (0x8009a140) #define CHASSIS4_MEM_ADDR (0x8009b8d4) #define TURRET1_MEM_ADDR (0x8009c09c) #define TURRET2_MEM_ADDR (0x8009c830) #define TURRET3_MEM_ADDR (0x8009d360) #define TURRET4_MEM_ADDR (0x8009da38) #define AIRSHIP_MEM_ADDR (0x800a32f8) #define EXPLODE1_MEM_ADDR (0x8009f4f0) #define EXPLODE2_MEM_ADDR (0x8009fb40) #define EXPLODE3_MEM_ADDR (0x800a0780) #define EXPLODE4_MEM_ADDR (0x800a1468) #define EXPLODE5_MEM_ADDR (0x800a2150) #define EXPLODE6_MEM_ADDR (0x800a2b38) #define SHRPNEL1_MEM_ADDR (0x800a3748) #define SHRPNEL2_MEM_ADDR (0x800a38d0) #define SHRPNEL3_MEM_ADDR (0x800a3a58) #define SHRPNEL4_MEM_ADDR (0x800a3be0) #define SHRPNEL5_MEM_ADDR (0x800a3d68) #define SHRPNEL6_MEM_ADDR (0x800a3ef0) #define WALL1_MEM_ADDR (0x800a4078) #define WALL2_MEM_ADDR (0x800a41d0) #define WALL3_MEM_ADDR (0x800a4328) #define WALL4_MEM_ADDR (0x800a4568) #define WALL5_MEM_ADDR (0x800a47a8) #define WALL6_MEM_ADDR (0x800a49e8) #define WALL7_MEM_ADDR (0x800a4c28) #define WALL8_MEM_ADDR (0x800a4d80) #define WALL9_MEM_ADDR (0x800a4ed8) #define WALL10_MEM_ADDR (0x800a5030) #define HEALTH0_MEM_ADDR (0x800a5188) #define HEALTH1_MEM_ADDR (0x800a55a8) #define HEALTH2_MEM_ADDR (0x800a59c8) #define HEALTH3_MEM_ADDR (0x800a5de8) #define HEALTH4_MEM_ADDR (0x800a6208) #define VICTOR_MEM_ADDR (0x800a6628) #define ICON1_MEM_ADDR (0x800a7a50) #define ICON2_MEM_ADDR (0x800a7e00) #define TANX_MEM_ADDR (0x800a8120) #define FLAG1_MEM_ADDR (0x800aa340) #define FLAG2_MEM_ADDR (0x800aa550) #define BLDGDAM_TEX_MEM_ADDR (0x800aad80) #define RUBBLE_TEX_MEM_ADDR (0x800abfa0) #define CHASSIS5_MEM_ADDR (0x800ac5c0) #define BLDGDAM_MEM_ADDR (0x800acd7c) #define WALLDAM_MEM_ADDR (0x800acfcc) #define MINE_MEM_ADDR (0x800ad588) #define FIRE1_TEX_MEM_ADDR (0x800ad728) #define FIRE2_TEX_MEM_ADDR (0x800add48) #define SHIELD_MEM_ADDR (0x800ae588) #define SMOKE1_MEM_ADDR (0x800afac0) #define SMOKE1_TEX_MEM_ADDR (0x800ae860) #define SMOKE2_MEM_ADDR (0x800afb4c) #define SMOKE2_TEX_MEM_ADDR (0x800aee80) #define SMOKE3_MEM_ADDR (0x800afbd8) #define SMOKE3_TEX_MEM_ADDR (0x800af4a0) #define LARROW_MEM_ADDR (0x800ae368) #define RARROW_MEM_ADDR (0x800ae3c8) #define FLGSITE_TEX_MEM_ADDR (0x800afc64) #define FLGSITE_MEM_ADDR (0x800b0284) #define BCKGRND_MEM_ADDR (0x800b0300) #define NYSCRN1_MEM_ADDR (0x800e5000) #define NYSCRN2_MEM_ADDR (0x800f7000) // a variable to track the vsync interval u_long vsyncInterval=0; unsigned long PLAYING=0; unsigned long INGAME=1; u_long PADstatus=0; // We need two Ordering Table Headers, one for each buffer GsOT othWorld[2]; // And we need Two Ordering Tables, one for each buffer GsOT_TAG otWorld[2][1<lObjectPointer[theWorld->nTotalModels] = (unsigned long *)lModelAddress; //increment the pointer to move past the model id. (weird huh?) theWorld->lObjectPointer[theWorld->nTotalModels]++; // map tmd data to its actual address GsMapModelingData(theWorld->lObjectPointer[theWorld->nTotalModels]); // initialise the objects coordinate system - set to be that of the WORLD GsInitCoordinate2(WORLD, &theWorld->gsObjectCoord[theWorld->nTotalModels]); // increment pointer twice more - to point to top of model data (beats me!) theWorld->lObjectPointer[theWorld->nTotalModels]++; theWorld->lObjectPointer[theWorld->nTotalModels]++; // link the model (tmd) with the players object handler GsLinkObject4((unsigned long *)theWorld->lObjectPointer[theWorld->nTotalModels], &theWorld->gsObjectHandler[theWorld->nTotalModels], 0); // set the amount of polygon subdivision that will be done at runtime (none!) theWorld->gsObjectHandler[theWorld->nTotalModels].attribute = GsDIV1; // Assign the coordinates of the object model to the Object Handler theWorld->gsObjectHandler[theWorld->nTotalModels].coord2 = &theWorld->gsObjectCoord[theWorld->nTotalModels]; // Set The Position of the Object theWorld->gsObjectCoord[theWorld->nTotalModels].coord.t[0]=nX; // X theWorld->gsObjectCoord[theWorld->nTotalModels].coord.t[1]=nY; // Y theWorld->gsObjectCoord[theWorld->nTotalModels].coord.t[2]=nZ; // Z theWorld->drawflag[theWorld->nTotalModels] = 1; // Increment the object counter theWorld->nTotalModels++; // flag the object as needing to be drawn theWorld->gsObjectCoord[theWorld->nTotalModels].flg = 0; } // load up from conventional memeory into video memory int LoadTexture(long addr) { RECT rect; GsIMAGE tim1; // get tim info/header, again a little bit of majic is needd the pointer // is incremented past the first 4 positions to get to this! GsGetTimInfo((u_long *)(addr+4),&tim1); // set the rect struct to contain the images x and y offset, width and height rect.x=tim1.px; rect.y=tim1.py; rect.w=tim1.pw; rect.h=tim1.ph; //load image from main memory to video memory LoadImage(&rect,tim1.pixel); // if image has clut we need to load it too, //pmode =8 for 4 bit and 9 for 8 bit colour if((tim1.pmode>>3)&0x01) { // set the rect struct to contain the clut's x and y offset, width and height rect.x=tim1.cx; rect.y=tim1.cy; rect.w=tim1.cw; rect.h=tim1.ch; // load the clut into video memeory LoadImage(&rect,tim1.clut); } DrawSync(0); return(0); } void InitialiseSprite(unsigned long timaddr, GsSPRITE *loadsprite, int px, int py) { GsIMAGE tim; /* Used to store info on TIM file */ LoadTexture((long *)timaddr); /* Load tim into VRAM */ GsGetTimInfo((unsigned long *)(timaddr+4),&tim); /* Get info on TIM file, and put it in the tim GsIMAGE struct */ loadsprite->attribute=(unsigned long int)(tim.pmode<<24); /* Set sprite attribute to the value passed to function */ loadsprite->x=px; /* Set starting x pos to a passed value */ loadsprite->y=py; /* Set starting y pos to a passed value */ if((tim.pmode<<24)& 0x01000000) loadsprite->w=tim.pw*2; else if((tim.pmode<<24)& 0x02000000) loadsprite->w=tim.pw; else loadsprite->w=tim.pw*4; loadsprite->h=tim.ph; /* Set sprite height */ loadsprite->tpage=GetTPage(1,0, tim.px, tim.py); /* Texture page info */ loadsprite->u=0; /* Set tpage x offset */ loadsprite->v=0; /* Set tpage y offset */ loadsprite->cx=tim.cx; /* Tell sprite x pos of clut */ loadsprite->cy=tim.cy; /* Tell sprite y pos of clut */ loadsprite->r=128; /* Set the r brightness */ loadsprite->g=128; /* Set the g brightness */ loadsprite->b=128; /* Set the b brightness */ loadsprite->mx=0; /* Set manipulation point x */ loadsprite->my=0; /* Set manipulation point y */ loadsprite->scalex=ONE; /* scale in x direction */ loadsprite->scaley=ONE; /* scale in y direction */ loadsprite->rotate=0; /* amount of rotation */ } void InitialiseStars() { int n; int m; for(n=0; n < 2; n++){ for(m=0; m < 3; m++){ InitialiseSprite( ICON1_MEM_ADDR,&theStars[n].sprite[m], 96, 35+m*20); theStars[n].state[m] = 0; } } } void UpdateStars() { int n; int m; for(n=0; n < 2; n++){ for(m=0; m < 3; m++){ if(theStars[n].state[m] == 1){ InitialiseSprite( ICON2_MEM_ADDR,&theStars[n].sprite[m], 96, 35+m*20); } if(theStars[n].state[m] == 0){ InitialiseSprite( ICON1_MEM_ADDR,&theStars[n].sprite[m], 96, 35+m*20); } } } } void UpdateHealthBar( int n) { if(theCar[n].armour <= 0){ InitialiseSprite(HEALTH0_MEM_ADDR, &HealthBar[n], 85, 35); } if(theCar[n].armour <= 20 && theCar[n].armour > 0){ InitialiseSprite(HEALTH1_MEM_ADDR, &HealthBar[n], 85, 35); } if(theCar[n].armour <= 50 && theCar[n].armour > 20){ InitialiseSprite(HEALTH2_MEM_ADDR, &HealthBar[n], 85, 35); } if(theCar[n].armour <= 90 && theCar[n].armour > 50){ InitialiseSprite(HEALTH3_MEM_ADDR, &HealthBar[n], 85, 35); } if(theCar[n].armour > 90){ InitialiseSprite(HEALTH4_MEM_ADDR, &HealthBar[n], 85, 35); } } void InitialiseBldgs () { int tmpx,tmpz; int posx,posz; char c; int n; int xc; int zc; theBldgs[0].nTotalModels=0; theBldgs[1].nTotalModels=0; //initialise total number of models to zero // load up the square1 texture to video memeory LoadTexture(BLDGSIDE_TEX_MEM_ADDR); LoadTexture(BLDGTOP_TEX_MEM_ADDR); LoadTexture(CONC_TEX_MEM_ADDR); LoadTexture(GRA2CON1_TEX_MEM_ADDR); LoadTexture(BLDGDAM_TEX_MEM_ADDR); LoadTexture(RUBBLE_TEX_MEM_ADDR); for(n=0;n<2;n++){ posx = theCar[n].tileposx-4; posz = theCar[n].tileposz-4; // then for each element of the worldGroundData array if we find a 1 // then place an instance of square1.tmd at the appropriate position // in the world. for (zc = 0; zc < 13; zc++ ){ tmpx = posz + zc; for (xc = 0; xc < 10; xc++ ){ tmpz = posx + xc; c = BldgWorldData[tmpz][tmpx]; if(tmpz > 20 || tmpz < 0 || tmpx > 20 || tmpx < 0){ c = '0'; } switch(c) { case '1': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)BLDG1_MEM_ADDR); break; } case '2': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(-10), (tmpx * SEPERATION), (long *)CHASSIS2_MEM_ADDR); break; } case '3': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(-10), (tmpx * SEPERATION), (long *)CHASSIS3_MEM_ADDR); break; } case '4': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(-10), (tmpx * SEPERATION), (long *)CHASSIS4_MEM_ADDR); break; } case '5': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(-10), (tmpx * SEPERATION), (long *)TURRET2_MEM_ADDR); break; } case '6': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(-10), (tmpx * SEPERATION), (long *)TURRET3_MEM_ADDR); break; } case '7': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(-10), (tmpx * SEPERATION), (long *)TURRET4_MEM_ADDR); break; } case '8': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)ARMOUR_MEM_ADDR); break; } case 'X': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)CRATER_MEM_ADDR); break; } case 'b': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)WALL1_MEM_ADDR); break; } case 'a': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)WALL2_MEM_ADDR); break; } case 'd': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)WALL3_MEM_ADDR); break; } case 'e': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)WALL4_MEM_ADDR); break; } case 'f': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)WALL5_MEM_ADDR); break; } case 'c': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)WALL6_MEM_ADDR); break; } case 'h': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)WALL7_MEM_ADDR); break; } case 'i': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)WALL8_MEM_ADDR); break; } case 'j': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)WALL9_MEM_ADDR); break; } case 'g': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)WALL10_MEM_ADDR); break; } case 'B': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)BLDGDAM_MEM_ADDR); break; } case 'W': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)WALLDAM_MEM_ADDR); break; } case '*': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)FLAG1_MEM_ADDR); break; } case '&': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)FLAG2_MEM_ADDR); break; } case 'L': { AddModelToWorld(&theBldgs[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)CHASSIS5_MEM_ADDR); break; } default : { theBldgs[n].drawflag[theBldgs[n].nTotalModels] = 0; theBldgs[n].nTotalModels ++; } } //end of switch } //end for tmpx } //end for tmpz } } void InitialiseWorld () { int tmpx,tmpz; int posx,posz; char c; int n; int xc; int zc; theWorld[0].nTotalModels=0; theWorld[1].nTotalModels=0; //initialise total number of models to zero // load up the square1 texture to video memeory LoadTexture(GRASS_TEX_MEM_ADDR); LoadTexture(CONC_TEX_MEM_ADDR); LoadTexture(GRA2CON1_TEX_MEM_ADDR); LoadTexture(GRA2CON2_TEX_MEM_ADDR); LoadTexture(WATER_TEX_MEM_ADDR); LoadTexture(GRA2WAT1_TEX_MEM_ADDR); LoadTexture(GRA2WAT2_TEX_MEM_ADDR); LoadTexture(FLGSITE_TEX_MEM_ADDR); for(n=0;n<2;n++){ posx = theCar[n].tileposx-4; posz = theCar[n].tileposz-4; // then for each element of the worldGroundData array if we find a 1 // then place an instance of square1.tmd at the appropriate position // in the world. for (zc = 0; zc < 13; zc++ ){ tmpx = posz + zc; for (xc = 0; xc < 10; xc++ ){ tmpz = posx + xc; c = worldGroundData[tmpz][tmpx]; if(tmpz > 20 || tmpz < 0 || tmpx > 20 || tmpx < 0){ c = 'b'; } theWorld[n].drawflag[theWorld[n].nTotalModels] = 1; switch(c) { case '1': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)SQUARE1_MEM_ADDR); break; } case '2': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)SQUARE2_MEM_ADDR); break; } case '3': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)SQUARE3_MEM_ADDR); break; } case '4': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)SQUARE4_MEM_ADDR); break; } case '5': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)SQUARE5_MEM_ADDR); break; } case '6': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)SQUARE6_MEM_ADDR); break; } case '7': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)SQUARE7_MEM_ADDR); break; } case '8': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)SQUARE8_MEM_ADDR); break; } case '9': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)SQUARE9_MEM_ADDR); break; } case 'a': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)SQUARE10_MEM_ADDR); break; } case 'b': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)SQUARE11_MEM_ADDR); break; } case 'g': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)SQUARE12_MEM_ADDR); break; } case 'j': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)SQUARE13_MEM_ADDR); break; } case 'i': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)SQUARE14_MEM_ADDR); break; } case 'f': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)SQUARE15_MEM_ADDR); break; } case 'c': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)SQUARE16_MEM_ADDR); break; } case 'h': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)SQUARE17_MEM_ADDR); break; } case 'e': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)SQUARE18_MEM_ADDR); break; } case 'd': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)SQUARE19_MEM_ADDR); break; } case 'F': { AddModelToWorld(&theWorld[n], (tmpz * SEPERATION),(0), (tmpx * SEPERATION), (long *)FLGSITE_MEM_ADDR); break; } } } //end for tmpx } //end for tmpz } } void DrawWorld(WorldStructType0 *theWorld, GsOT *othWorld, int depth) { MATRIX tmpls, tmplw; int nCurrentModel; for (nCurrentModel = 0; nCurrentModel < theWorld->nTotalModels; nCurrentModel++) { if(theWorld->drawflag[nCurrentModel] == 1){ //SortObject( &theWorld.gsObjectHandler[nCurrentModel], &othWorld, 2); //SortObject( &theWorld.gsObjectHandler[nCurrentModel], &othWorld2, 2 ); //Get the local world and screen coordinates, needed for light calculations GsGetLws(theWorld->gsObjectHandler[nCurrentModel].coord2, &tmplw, &tmpls); // Set the resulting light source matrix GsSetLightMatrix(&tmplw); // Set the local screen matrix for the GTE (so it works out perspective etc) GsSetLsMatrix(&tmpls); // Send Object To Ordering Table GsSortObject4( &theWorld->gsObjectHandler[nCurrentModel], othWorld, depth,(u_long *)getScratchAddr(0)); } } } // This function associates a model with our player datastructure // later we will want to add more than one model to the player // to implement animation void AddModelToPlayer(PlayerStructType2 *thePlayer, int nX, int nY, int nZ, unsigned long *lModelAddress) { //increment the pointer to move past the model id. (weird huh?) lModelAddress++; // map tmd data to its actual address GsMapModelingData((unsigned long *)lModelAddress); // initialise the players coordinate system - set to be that of the world //GsInitCoordinate2(WORLD, &thePlayer->gsObjectCoord); if (thePlayer->id == TURRET || thePlayer->id == CHASSIS){ GsInitCoordinate2(WORLD, &thePlayer->gsObjectCoord); } if ( thePlayer->id == SHIELD){ GsInitCoordinate2(&theCar[thePlayer->allegance].gsObjectCoord, &thePlayer->gsObjectCoord); } if (thePlayer->id == SHOT || thePlayer->id == MINE){ GsInitCoordinate2(WORLD, &thePlayer->gsObjectCoord); } if (thePlayer->id == AIRSHIP || thePlayer->id == SMOKE){ GsInitCoordinate2(WORLD, &thePlayer->gsObjectCoord); } if (thePlayer->id == FLAG){ GsInitCoordinate2(WORLD, &thePlayer->gsObjectCoord); } // increment pointer twice more - to point to top of model data (beats me!) lModelAddress++; lModelAddress++; // link the model (tmd) with the players object handler GsLinkObject4((unsigned long *)lModelAddress, &thePlayer->gsObjectHandler,0); // Assign the coordinates of the object model to the Object Handler thePlayer->gsObjectHandler.coord2 = &thePlayer->gsObjectCoord; // setting the players gsObjectCoord.flg to 0 indicates it is to be drawn // Set the initial position of the object thePlayer->gsObjectCoord.coord.t[0]=nX; // X thePlayer->gsObjectCoord.coord.t[1]=nY; // Y thePlayer->gsObjectCoord.coord.t[2]=nZ; // Z // setting the players gsObjectCoord.flg to 0 indicates it is to be drawn thePlayer->gsObjectCoord.flg = 0; } void InitialisePlayer(PlayerStructType2 *thePlayer, int nX, int nY, int nZ, unsigned long *lModelAddress) { // initialise the players rotation vector to 0 thePlayer->rotation.vx=0;thePlayer->rotation.vy=0;thePlayer->rotation.vz=0; //initialise speed to 0 thePlayer->speed=0; // initialise other player variables and link in tmd thePlayer->collision=0; thePlayer->dx=0; thePlayer->dy=0; thePlayer->dz=0; thePlayer->armour=70; thePlayer->maxarmour=70; thePlayer->lModelPointer = (unsigned long *)lModelAddress; thePlayer->subtype = 1; thePlayer->lifespan = 0; thePlayer->alive = 1; thePlayer->flag = 0; thePlayer->drop = 0; thePlayer->shotPower = 0; thePlayer->reloadTime=10; thePlayer->deathframe=10; thePlayer->restart=0; if (thePlayer->id == CHASSIS){ thePlayer->speed=80; thePlayer->reloadTime=10; } if (thePlayer->id == TURRET){ thePlayer->shotPower = 10; thePlayer->speed=180; thePlayer->lifespan = 1400; thePlayer->reloadTime=10; } AddModelToPlayer(thePlayer, nX, nY,nZ,(unsigned long *)lModelAddress); //-200 } void DrawSprite(GsSPRITE *sprite, GsOT *othWorld, int depth) { GsSortFastSprite(sprite, othWorld, depth); } // This function deals with setting up matrices needed for rendering // and sends the object to the ordering table so it will be drawn void DrawPlayer(PlayerStructType2 *thePlayer, GsOT *othWorld, int depth) { //SortObject( &theCar.gsObjectHandler, &othWorld, 3 ); //SortObject( &theCar.gsObjectHandler, &othWorld2, 3 ); MATRIX tmpls, tmplw; //Get the local world and screen coordinates, needed for light calculations GsGetLws(thePlayer->gsObjectHandler.coord2, &tmplw, &tmpls); // Set the resulting light source matrix GsSetLightMatrix(&tmplw); // Set the local screen matrix for the GTE (so it works out perspective etc) GsSetLsMatrix(&tmpls); // Send Object To Ordering Table GsSortObject4( &thePlayer->gsObjectHandler,othWorld,depth,(u_long *)getScratchAddr(0)); } void DrawBullets( GsOT *othWorld) { MATRIX tmpls, tmplw; int nCurrentModel; for (nCurrentModel = 0; nCurrentModel < MAX_NO_OF_BULLETS; nCurrentModel++) { if (theBullets[nCurrentModel].alive == 1){ //SortObject( &theBullets[nCurrentModel].gsObjectHandler, &othWorld, 3 ); //SortObject( &theBullets[nCurrentModel].gsObjectHandler, &othWorld2, 3 ); //Get the local world and screen coordinates, needed for light calculations GsGetLws(theBullets[nCurrentModel].gsObjectHandler.coord2, &tmplw, &tmpls); // Set the resulting light source matrix GsSetLightMatrix(&tmplw); // Set the local screen matrix for the GTE (so it works out perspective etc) GsSetLsMatrix(&tmpls); // Send Object To Ordering Table GsSortObject4( &theBullets[nCurrentModel].gsObjectHandler, othWorld,4,(u_long *)getScratchAddr(0)); } } } void DrawFlags( GsOT *othWorld , int depth) { int n; MATRIX tmpls, tmplw; for(n=0;n<3;n++){ if(theFlags[n].flag > 0){ //Get the local world and screen coordinates, needed for light calculations GsGetLws(theFlags[n].gsObjectHandler.coord2, &tmplw, &tmpls); // Set the resulting light source matrix GsSetLightMatrix(&tmplw); // Set the local screen matrix for the GTE (so it works out perspective etc) GsSetLsMatrix(&tmpls); // Send Object To Ordering Table GsSortObject4( &theFlags[n].gsObjectHandler,othWorld,depth,(u_long *)getScratchAddr(0)); } } } void DrawExplosions( GsOT *othWorld) { MATRIX tmpls, tmplw; int nCurrentModel; for (nCurrentModel = 0; nCurrentModel < MAX_NO_OF_BULLETS; nCurrentModel++) { if (theExplosion[nCurrentModel].alive == 1){ //SortObject( &theBullets[nCurrentModel].gsObjectHandler, &othWorld, 3 ); //SortObject( &theBullets[nCurrentModel].gsObjectHandler, &othWorld2, 3 ); //Get the local world and screen coordinates, needed for light calculations GsGetLws(theExplosion[nCurrentModel].gsObjectHandler.coord2, &tmplw, &tmpls); // Set the resulting light source matrix GsSetLightMatrix(&tmplw); // Set the local screen matrix for the GTE (so it works out perspective etc) GsSetLsMatrix(&tmpls); // Send Object To Ordering Table GsSortObject4( &theExplosion[nCurrentModel].gsObjectHandler, othWorld,4,(u_long *)getScratchAddr(0)); } } } // This function deals with setting up matrices needed for rendering // and sends the object to the ordering table so it will be drawn // This function deals with double buffering and drawing of 3D objects void RenderWorld( void ) { RECT clip; int n; // This variable keeps track of the current buffer for double buffering int currentBuffer; //get the current buffer currentBuffer=GsGetActiveBuff(); // Set the address of the packet area that will contain drawing commands GsSetWorkBase((PACKET*)out_packet[currentBuffer]); InitialiseBldgs(); InitialiseWorld(); // Set the viewing system if(PLAYING){ UpdateView(&view[1],1); } GsSetRefView2(&view[1]); GsClearOt(0, 0, &othWorld2[currentBuffer]); if(TitleScreen == 0){ // Draw the world DrawWorld(&theWorld[1], &othWorld2[currentBuffer], 2); // Draw the Buildings DrawWorld(&theBldgs[1], &othWorld2[currentBuffer], 3); // Draw the player DrawPlayer(&theCar[0], &othWorld2[currentBuffer], 3); DrawPlayer(&theCar[1], &othWorld2[currentBuffer], 3); // Draw the playerTop DrawPlayer(&theTurret[0], &othWorld2[currentBuffer], 3); DrawPlayer(&theTurret[1], &othWorld2[currentBuffer], 3); if(theCar[0].shield > 0){ DrawPlayer(&theShield[0], &othWorld2[currentBuffer], 3); } if(theCar[1].shield > 0){ DrawPlayer(&theShield[1], &othWorld2[currentBuffer], 3); } // Draw the bullets DrawBullets(&othWorld2[currentBuffer]); // Draw the Explosions DrawExplosions(&othWorld2[currentBuffer]); // Draw the Airship if(theAirship.alive != 0){ DrawPlayer(&theAirship, &othWorld2[currentBuffer], 4); } DrawSprite(&HealthBar[1], &othWorld2[currentBuffer], 8); for(n=0;n<5;n++){ if(theMines[1][n].alive == 1){ DrawPlayer(&theMines[1][n], &othWorld2[currentBuffer], 3); } } if(PLAYING == 0 && (startP2 == 0 || startP1 == 0)){ DrawSprite(&Background[0], &othWorld2[currentBuffer], 8); DrawSprite(&Background[1], &othWorld2[currentBuffer], 8); DrawSprite(&Background[2], &othWorld2[currentBuffer], 8); DrawSprite(&Background[3], &othWorld2[currentBuffer], 8); } for(n=0;n<3;n++){ DrawSprite(&theStars[1].sprite[n], &othWorld2[currentBuffer], 7); } if(theVictor.state == 2){ DrawSprite(&theVictor.sprite, &othWorld2[currentBuffer], 7); } if(gametype > 0){ DrawFlags( &othWorld2[currentBuffer], 4); } if((theCar[1].alive == 0 && theCar[1].deathframe == 0)||(theCar[0].alive == 0 && theCar[0].deathframe == 0)){ DrawPlayer(&theSmoke, &othWorld2[currentBuffer], 3); } }// end of if(titleScreen == 0) else{ DrawSprite(&NYScrn2, &othWorld2[currentBuffer], 0); } // Set the viewing system if(PLAYING){ UpdateView(&view[0],0); } GsSetRefView2(&view[0]); // clear the ordering table GsClearOt(0, 0, &othWorld[currentBuffer]); if(TitleScreen == 0){ // Draw the world DrawWorld(&theWorld[0], &othWorld[currentBuffer], 2); // Draw the Buildings DrawWorld(&theBldgs[0], &othWorld[currentBuffer], 3); // Draw the player DrawPlayer(&theCar[0], &othWorld[currentBuffer], 3); DrawPlayer(&theCar[1], &othWorld[currentBuffer], 3); if(theCar[0].shield > 0){ DrawPlayer(&theShield[0], &othWorld[currentBuffer], 3); } if(theCar[1].shield > 0){ DrawPlayer(&theShield[1], &othWorld[currentBuffer], 3); } // Draw the playerTop DrawPlayer(&theTurret[0], &othWorld[currentBuffer], 3); DrawPlayer(&theTurret[1], &othWorld[currentBuffer], 3); // Draw the bullets DrawBullets(&othWorld[currentBuffer]); // Draw the Explosions DrawExplosions(&othWorld[currentBuffer]); // Draw the Airship if(theAirship.alive != 0){ DrawPlayer(&theAirship, &othWorld[currentBuffer], 4); } DrawSprite(&HealthBar[0], &othWorld[currentBuffer], 8); for(n=0;n<5;n++){ if(theMines[0][n].alive == 1){ DrawPlayer(&theMines[0][n], &othWorld[currentBuffer], 3); } } for(n=0;n<3;n++){ DrawSprite(&theStars[0].sprite[n], &othWorld[currentBuffer], 7); } if(theVictor.state == 1){ DrawSprite(&theVictor.sprite, &othWorld[currentBuffer], 7); } if(PLAYING == 0){ DrawSprite(&TanxLogo, &othWorld[currentBuffer], 7); DrawSprite(&LArrow, &othWorld[currentBuffer], 7); DrawSprite(&RArrow, &othWorld[currentBuffer], 7); DrawSprite(&LArrow2, &othWorld[currentBuffer], 7); DrawSprite(&RArrow2, &othWorld[currentBuffer], 7); if(startP1 == 0 || startP2 == 0){ DrawSprite(&Background[0], &othWorld[currentBuffer], 8); DrawSprite(&Background[1], &othWorld[currentBuffer], 8); DrawSprite(&Background[2], &othWorld[currentBuffer], 8); DrawSprite(&Background[3], &othWorld[currentBuffer], 8); } } if(gametype > 0){ DrawFlags( &othWorld[currentBuffer], 4 ); } if((theCar[1].alive == 0 && theCar[1].deathframe == 0)||(theCar[0].alive == 0 && theCar[0].deathframe == 0)){ DrawPlayer(&theSmoke, &othWorld[currentBuffer], 3); } }// end of if titlescreen is off else { DrawSprite(&NYScrn1, &othWorld[currentBuffer], 0); } // wait for end of drawing DrawSync(0); vsyncInterval=VSync(0); FntFlush(-1); // Swap The Buffers GsSwapDispBuff(); // register clear-command: clear to black //GsSortClear(0,0,0,&othWorld[currentBuffer]); GsSortClear(0,0,0,&othWorld2[currentBuffer]); // Set offset of left screen GsSetOffset(SCREEN_WIDTH * 3 / 4, SCREEN_HEIGHT / 2); // Set clipping for left screen clip.x = SCREEN_WIDTH/2; clip.y = 0; clip.w = SCREEN_WIDTH/2; clip.h = SCREEN_HEIGHT; GsSetClip(&clip); // Start Drawing left screen GsDrawOt(&othWorld2[currentBuffer]); // Set offset of right screen GsSetOffset(SCREEN_WIDTH / 4, SCREEN_HEIGHT / 2); // Set clipping for right screen clip.x = 0; clip.y = 0; clip.w = SCREEN_WIDTH / 2; clip.h = SCREEN_HEIGHT; GsSetClip(&clip); // Start Drawing right screen GsDrawOt(&othWorld[currentBuffer]); // force text output // print the vSync interval } void InitialiseLight(GsF_LIGHT *flLight, int nLight, int nX, int nY, int nZ, int nRed, int nGreen, int nBlue) { // Set the direction in which the light travels flLight->vx = nX;flLight->vy = nY; flLight->vz = nZ; // Set the colour flLight->r = nRed; flLight->g = nGreen; flLight->b = nBlue; // Activate light GsSetFlatLight(nLight, flLight); } void InitialiseTrackerView(GsRVIEW2 *view, int nProjDist, int nRZ, int nVPX, int nVPY, int nVPZ, int nVRX, int nVRY, int nVRZ) { // This is the distance between the eye // and the imaginary projection screen GsSetProjection(nProjDist); // Set the eye position or center of projection view->vpx = nVPX; view->vpy = nVPY; view->vpz = nVPZ; // Set the look at position view->vrx = nVRX; view->vry = nVRY; view->vrz = nVRZ; // Set which way is up view->rz=-nRZ; // Set the origin of the coord system in this case the car view->super = WORLD; //&theCar[0].gsObjectCoord // Activate view GsSetRefView2(view); } void UpdateView(GsRVIEW2 *view, int n) { view->vrx = theCar[n].gsObjectCoord.coord.t[0]; view->vry = theCar[n].gsObjectCoord.coord.t[1]; view->vrz = theCar[n].gsObjectCoord.coord.t[2]; view->vpx = theCar[n].gsObjectCoord.coord.t[0]; view->vpy = (theCar[n].gsObjectCoord.coord.t[1]-3300); view->vpz = (theCar[n].gsObjectCoord.coord.t[2]-2500); //GsSetRefView2(view); } void InitialiseAllLights() { InitialiseLight(&flLights[0], 0, -100, -100, -100, 0xff, 0xff, 0xff); InitialiseLight(&flLights[1], 1, 1000, 1000, 1000, 0xcc, 0xcc, 0xcc); GsSetAmbient(0,0,0); GsSetLightMode(0); } void InitialiseGraphics() { // Initialise The Graphics System to PAL as opposed to NTSC //SetVideoMode(MODE_PAL); // The Actual Size of the Video memory GsInitGraph(SCREEN_WIDTH, SCREEN_HEIGHT, GsINTER|GsOFSGPU, 1, 0); // The Top Left Coordinates Of The Two Buffers GsDefDispBuff(0, 0, 0, SCREEN_HEIGHT); GsDISPENV.screen.x = 6; GsDISPENV.screen.y = 16; GsDISPENV.screen.w = 255; GsDISPENV.screen.h = 240; // Initialise the 3D Graphics... // GsInit3D(); // Before we can use the ordering table headers, // we need to... // 1. Set them to the right length othWorld[0].length = ORDERING_TABLE_LENGTH; othWorld[1].length = ORDERING_TABLE_LENGTH; // 2. Associate them with an actual ordering table othWorld[0].org = otWorld[0]; othWorld[1].org = otWorld[1]; // 1. Set them to the right length othWorld2[0].length = ORDERING_TABLE_LENGTH; othWorld2[1].length = ORDERING_TABLE_LENGTH; // 2. Associate them with an actual ordering table othWorld2[0].org = otWorld2[0]; othWorld2[1].org = otWorld2[1]; // 3. initialise the World Ordering Table Headers and Arrays GsClearOt(0,0,&othWorld[0]); GsClearOt(0,0,&othWorld[1]); GsClearOt(0,0,&othWorld2[0]); GsClearOt(0,0,&othWorld2[1]); } 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; } // This rotation function avoids scaling problems that eventually occur from // successive errors accumulating in the players matrix by cumulatively // adding the angles in the players rotation vector and reseting the players // matrix each time with the new cululative rotation angle void RotateModel (GsCOORDINATE2 *gsObjectCoord,SVECTOR *rotateVector , int nRX, int nRY, int nRZ ) { MATRIX matTmp; // the reset the players coord system to the identity matrix ResetMatrix(gsObjectCoord->coord.m ); // Add the new rotation factors into the players rotation vector // and then set them to the remainder of division by ONE (4096) rotateVector->vx = (rotateVector->vx+nRX)%ONE; rotateVector->vy = (rotateVector->vy+nRY)%ONE; rotateVector->vz = (rotateVector->vz+nRZ)%ONE; // RotMatrix sets up the matrix coefficients for rotation RotMatrix(rotateVector, &matTmp); // Concatenate the existing objects matrix with the rotation matrix MulMatrix0(&gsObjectCoord->coord, &matTmp, &gsObjectCoord->coord); // set the flag to redraw the object gsObjectCoord->flg = 0; } void FindTilePosition(PlayerStructType2 *thePlayer) { int posx; int posz; posx=thePlayer->gsObjectCoord.coord.t[0]; posz=thePlayer->gsObjectCoord.coord.t[2]; thePlayer->tileposx=((posx+600)/1200); thePlayer->tileposz=((posz+600)/1200); } void InitialiseAllFlags() { int n; for(n=0;n<3;n++){ theFlags[n].id = FLAG; InitialisePlayer(&theFlags[n],0,0,0,(unsigned long*)FLAG1_MEM_ADDR); theFlags[n].subtype = 1; } } void InitialiseGameTypeTwo() { int FlagPos[3][2] = {{4,12},{9,11},{18,10}}; int n; for(n=0;n<3;n++){ theFlags[n].tileposx = FlagPos[n][0]; theFlags[n].tileposz = FlagPos[n][1]; BldgWorldData[FlagPos[n][0]][FlagPos[n][1]] = '*'; InitialiseBldgs(); theFlags[n].gsObjectCoord.flg = 0; } } void InitialiseGameTypeThree() { theFlags[0].tileposx = 2; theFlags[0].tileposz = 2; BldgWorldData[2][2] = '*'; InitialiseBldgs(); AddModelToPlayer(&theFlags[0], 3000, 0, 3000,(unsigned long*)FLAG1_MEM_ADDR); theFlags[0].allegance = 0; theFlags[0].flag = 0; theFlags[0].gsObjectCoord.flg = 0; theFlags[1].tileposx = 19; theFlags[1].tileposz = 19; BldgWorldData[19][19] = '&'; InitialiseBldgs(); AddModelToPlayer(&theFlags[1], 23400, 0, 23400,(unsigned long*)FLAG2_MEM_ADDR); theFlags[1].subtype = 2; theFlags[1].allegance = 1; theFlags[1].flag = 0; theFlags[1].gsObjectCoord.flg = 0; } void DropFlag(PlayerStructType2 *thePlayer) { int tiledropx; int tiledropz; FindTilePosition(thePlayer); tiledropx = thePlayer->tileposx; tiledropz = thePlayer->tileposz; FindFreeTilePos(thePlayer, tiledropx, tiledropz); tiledropx = thePlayer->tileposx; tiledropz = thePlayer->tileposz; if(thePlayer->subtype == 1){ BldgWorldData[tiledropx][tiledropz] = '*'; thePlayer->gsObjectCoord.flg = 1; thePlayer->flag = 0; } if(thePlayer->subtype == 2){ BldgWorldData[tiledropx][tiledropz] = '&'; thePlayer->gsObjectCoord.flg = 1; thePlayer->flag = 0; } InitialiseBldgs(); CheckScoring(thePlayer->allegance,(thePlayer->flag) - 1); } void PlayerDropFlag(int n) { int flag; int tiledropx; int tiledropz; flag = theCar[n].flag - 1; CarryFlag(n); tiledropx = theFlags[flag].tileposx; tiledropz = theFlags[flag].tileposz; if(tiledropx > 0 && tiledropz > 0 && tiledropx < 20 && tiledropz < 20){ if(BldgWorldData[tiledropx][tiledropz] == '0' || BldgWorldData[tiledropx][tiledropz] == 'X'){ if(worldGroundData[tiledropx][tiledropz] != 'b'){ theFlags[flag].gsObjectCoord.flg = 1; theFlags[flag].flag = 0; theCar[n].flag = 0; FindTilePosition(&theFlags[flag]); PlaySFX(&pickup); if(theFlags[flag].subtype == 1){ BldgWorldData[tiledropx][tiledropz] = '*'; InitialiseBldgs(); } if(theFlags[flag].subtype == 2){ BldgWorldData[tiledropx][tiledropz] = '&'; InitialiseBldgs(); } CheckScoring(n,flag); } } } } void CheckScoring(int n, int flag) { int fx; int fz; int sx; int sz; int c; int d; int score1; int score2; InitialiseStars(); score1 = theCar[0].score; score2 = theCar[1].score; theCar[0].score = 0; theCar[1].score = 0; //if(n == 0){ //int c; for(c=0;c<3;c++){ fx = theFlags[c].tileposx; fz = theFlags[c].tileposz; for(d=0;d<3;d++){ sx = P1SCORINGZONE[d][0]; sz = P1SCORINGZONE[d][1]; if(fx == sx && fz == sz && theFlags[c].flag == 0){ if ( gametype == 1){ AddStarForKill(0); } if( gametype == 2 && theFlags[c].allegance == 1){ AddStarForKill(0); AddStarForKill(0); AddStarForKill(0); } } } } //} //if(n == 1){ //int c; for(c=0;c<3;c++){ fx = theFlags[c].tileposx; fz = theFlags[c].tileposz; for(d=0;d<3;d++){ sx = P2SCORINGZONE[d][0]; sz = P2SCORINGZONE[d][1]; if(fx == sx && fz == sz && theFlags[c].flag == 0){ if ( gametype == 1){ AddStarForKill(1); } if( gametype == 2 && theFlags[c].allegance == 0){ AddStarForKill(1); AddStarForKill(1); AddStarForKill(1); } } } } //} if((score1 < theCar[0].score)||(score2 < theCar[1].score)){ PlaySFX(&ping); } } void CarryFlag(int n) { int flag; flag = theCar[n].flag - 1; theFlags[flag].gsObjectCoord.coord.t[0] = theCar[n].gsObjectCoord.coord.t[0]; theFlags[flag].gsObjectCoord.coord.t[1] = -200; theFlags[flag].gsObjectCoord.coord.t[2] = theCar[n].gsObjectCoord.coord.t[2]; theFlags[flag].tileposx = theCar[n].tileposx; theFlags[flag].tileposz = theCar[n].tileposz; theFlags[flag].gsObjectCoord.flg = 0; } void PickUpFlag(int type, PlayerStructType2 *thePlayer) { int n; int px; int pz; int fx; int fz; int dx; int dy; int dz; px = thePlayer->tileposx; pz = thePlayer->tileposz; for(n=0;n<3;n++){ fx = theFlags[n].tileposx; fz = theFlags[n].tileposz; if(thePlayer->flag == 0 && thePlayer->drop == 0 && px == fx && pz == fz){ PlaySFX(&pickup); theFlags[n].flag = thePlayer->allegance + 1; thePlayer->flag = n+1; CheckScoring(thePlayer->allegance, n); theFlags[n].gsObjectCoord.coord.t[0] = thePlayer->gsObjectCoord.coord.t[0]; theFlags[n].gsObjectCoord.coord.t[1] = -200; theFlags[n].gsObjectCoord.coord.t[2] = thePlayer->gsObjectCoord.coord.t[2]; dx = theFlags[n].gsObjectCoord.coord.t[0]; dy = theFlags[n].gsObjectCoord.coord.t[1]; dz = theFlags[n].gsObjectCoord.coord.t[2]; if(BldgWorldData[px][pz]=='*'){ theFlags[n].subtype = 1; if((thePlayer->allegance == 1)&& gametype == 2){ PlaySFX(&alarm); } theFlags[n].gsObjectCoord.flg = 0; } if(BldgWorldData[px][pz]=='&'){ theFlags[n].subtype = 2; if((thePlayer->allegance == 0)&& gametype == 2){ PlaySFX(&alarm); } theFlags[n].gsObjectCoord.flg = 0; } BldgWorldData[px][pz]='0'; } } } void FindFreeTilePos(PlayerStructType2 *thePlayer, int x, int z) { char c; char w; int n; int m; for(n=0;n<3;n++){ for(m=1;m<3;m++){ c=BldgWorldData[(x+n)][(z+m)]; w=worldGroundData[(x+n)][(z+m)]; if((c == '0' || c == 'X') && w != 'b'){ if((x+n)<20 && (z+m)<20){ thePlayer->tileposx = (x+n); thePlayer->tileposz = (z+m); return; } } c=BldgWorldData[(x-n)][(z-m)]; w=worldGroundData[(x-n)][(z-m)]; if((c == '0' || c == 'X') && w != 'b'){ if((x-n)>1 && (z-m)>1){ thePlayer->tileposx = (x-n); thePlayer->tileposz = (z-m); return; } } c=BldgWorldData[(x-n)][(z+m)]; w=worldGroundData[(x-n)][(z+m)]; if((c == '0' || c == 'X') && w != 'b'){ if((x-n)>1 && (z+m)<20){ thePlayer->tileposx = (x-n); thePlayer->tileposz = (z+m); return; } } c=BldgWorldData[(x+n)][(z-m)]; w=worldGroundData[(x+n)][(z-m)]; if((c == '0' || c == 'X') && w != 'b'){ if((x+n)<20 && (z-m)>1){ thePlayer->tileposx = (x+n); thePlayer->tileposz = (z-m); return; } } } } return; } void TestPlayerCollision(PlayerStructType2 *thePlayer, PlayerStructType2 *thePlayerTop,int n) { if (thePlayer->tileposx>0 && thePlayer->tileposz>0 && thePlayer->tileposx<21 && thePlayer->tileposz<21){ int nX; int nY; int nZ; int enX; int enY; int enZ; char c; char w; int cx; int cz; int bbox[4][2]; int nme; nme = 1-n; enX = theCar[nme].gsObjectCoord.coord.t[0]; enY = theCar[nme].gsObjectCoord.coord.t[1]; enZ = theCar[nme].gsObjectCoord.coord.t[2]; nX = thePlayer->gsObjectCoord.coord.t[0]; nY = thePlayer->gsObjectCoord.coord.t[1]; nZ = thePlayer->gsObjectCoord.coord.t[2]; bbox[0][0] = nX-250; bbox[0][1] = nZ+250; bbox[1][0] = nX+250; bbox[1][1] = nZ+250; bbox[2][0] = nX-250; bbox[2][1] = nZ-250; bbox[3][0] = nX+250; bbox[3][1] = nZ-250; cx = (thePlayer->tileposx*1200); cz = (thePlayer->tileposz*1200); c=BldgWorldData[(thePlayer->tileposx)][(thePlayer->tileposz)]; w=worldGroundData[(thePlayer->tileposx)][(thePlayer->tileposz)]; switch (c) { case '0' : { thePlayer->collision = 0; break; } case 'X' : { thePlayer->collision = 0; break; } case '2' : { thePlayer->collision = 0; thePlayer->lModelPointer = (unsigned long *)CHASSIS2_MEM_ADDR; thePlayer->speed = 100; thePlayer->armour = 130; thePlayer->maxarmour = 130; thePlayer->subtype = 2; AddModelToPlayer(thePlayer, nX, nY,nZ, (unsigned long *)CHASSIS2_MEM_ADDR); RotateModel (&theCar[n].gsObjectCoord,&theCar[n].rotation, 0, 0, 0 ); BldgWorldData[(thePlayer->tileposx)][(thePlayer->tileposz)]='0'; InitialiseBldgs(); theAirship.drop --; PlaySFX(&pickup); break; } case '3' : { thePlayer->collision = 0; thePlayer->lModelPointer = (unsigned long *)CHASSIS3_MEM_ADDR; thePlayer->speed = 150; thePlayer->armour = 80; thePlayer->maxarmour = 80; thePlayer->subtype = 3; AddModelToPlayer(thePlayer, nX, nY, nZ, (unsigned long *)CHASSIS3_MEM_ADDR); RotateModel (&theCar[n].gsObjectCoord,&theCar[n].rotation, 0, 0, 0 ); BldgWorldData[(thePlayer->tileposx)][(thePlayer->tileposz)]='0'; InitialiseBldgs(); theAirship.drop --; PlaySFX(&pickup); break; } case '4' : { thePlayer->collision = 0; thePlayer->lModelPointer = (unsigned long *)CHASSIS4_MEM_ADDR; thePlayer->speed = 10; thePlayer->armour = 100; thePlayer->maxarmour = 100; thePlayer->subtype = 4; AddModelToPlayer(thePlayer, nX, nY, nZ, (unsigned long *)CHASSIS4_MEM_ADDR); RotateModel (&theCar[n].gsObjectCoord,&theCar[n].rotation, 0, 0, 0 ); BldgWorldData[(thePlayer->tileposx)][(thePlayer->tileposz)]='0'; InitialiseBldgs(); theAirship.drop --; PlaySFX(&pickup); break; } case 'L' : { thePlayer->collision = 0; thePlayer->lModelPointer = (unsigned long *)CHASSIS5_MEM_ADDR; thePlayer->speed = 90; thePlayer->armour = 110; thePlayer->maxarmour = 110; thePlayer->subtype = 5; AddModelToPlayer(thePlayer, nX, nY, nZ, (unsigned long *)CHASSIS5_MEM_ADDR); RotateModel (&theCar[n].gsObjectCoord,&theCar[n].rotation, 0, 0, 0 ); BldgWorldData[(thePlayer->tileposx)][(thePlayer->tileposz)]='0'; InitialiseBldgs(); theAirship.drop --; PlaySFX(&pickup); break; } case '5' : { thePlayer->collision = 0; thePlayerTop->lModelPointer = (unsigned long *)TURRET2_MEM_ADDR; theTurret[n].subtype = 2; theTurret[n].speed = 170; theTurret[n].shotPower = 15; theTurret[n].lifespan = 2000; theTurret[n].reloadTime = 30; AddModelToPlayer(thePlayerTop, nX, nY,nZ, (unsigned long *)TURRET2_MEM_ADDR); RotateModel (&theTurret[n].gsObjectCoord,&theTurret[n].rotation, 0, 0, 0 ); BldgWorldData[(thePlayer->tileposx)][(thePlayer->tileposz)]='0'; InitialiseBldgs(); theAirship.drop --; PlaySFX(&pickup); break; } case '6': { thePlayer->collision = 0; thePlayerTop->lModelPointer = (unsigned long *)TURRET3_MEM_ADDR; theTurret[n].subtype = 3; theTurret[n].speed = 220; theTurret[n].shotPower = 30; theTurret[n].lifespan = 3600; theTurret[n].reloadTime = 50; AddModelToPlayer(thePlayerTop, nX, nY, nZ, (unsigned long *)TURRET3_MEM_ADDR); RotateModel (&theTurret[n].gsObjectCoord,&theTurret[n].rotation, 0, 0, 0 ); BldgWorldData[(thePlayer->tileposx)][(thePlayer->tileposz)]='0'; InitialiseBldgs(); theAirship.drop --; PlaySFX(&pickup); break; } case '7': { thePlayer->collision = 0; thePlayerTop->lModelPointer = (unsigned long *)TURRET4_MEM_ADDR; theTurret[n].subtype = 4; theTurret[n].speed = 290; theTurret[n].shotPower = 10; theTurret[n].lifespan = 1200; theTurret[n].reloadTime = 3; AddModelToPlayer(thePlayerTop, nX, nY, nZ, (unsigned long *)TURRET4_MEM_ADDR); RotateModel (&theTurret[n].gsObjectCoord,&theTurret[n].rotation, 0, 0, 0 ); BldgWorldData[(thePlayer->tileposx)][(thePlayer->tileposz)]='0'; InitialiseBldgs(); theAirship.drop --; PlaySFX(&pickup); break; } case '8': { thePlayer->collision = 0; if(thePlayer->armour < thePlayer->maxarmour){ thePlayer->armour += 20; BldgWorldData[(thePlayer->tileposx)][(thePlayer->tileposz)]='0'; InitialiseBldgs(); theAirship.drop --; PlaySFX(&pickup); } break; } case '*': { thePlayer->collision = 0; PickUpFlag(1,thePlayer); InitialiseBldgs(); break; } case '&': { thePlayer->collision = 0; PickUpFlag(2,thePlayer); InitialiseBldgs(); break; } case 'm': { if(n == 1){ thePlayer->collision = 0; } else{ int m; for(m = 0;m < 5;m++){ if(theMines[1][m].alive == 1){ if(theMines[1][m].tileposx == thePlayer->tileposx && theMines[1][m].tileposz == thePlayer->tileposz){ theMines[1][m].alive = 0; BldgWorldData[(thePlayer->tileposx)][(thePlayer->tileposz)]='0'; } } } PlaySFX(&bang); InitialiseExplosion(thePlayer->tileposx, thePlayer->tileposz, (thePlayer->tileposx * 1200), (thePlayer->tileposz * 1200), 4, n); if(theCar[0].shield <= 0){ thePlayer->armour -= 30; if (theCar[0].armour <= 0 && theCar[0].alive == 1){ if(gametype == 0){ AddStarForKill(1); } PlayerDeath(0); } } } break; } case 'M': { if(n == 0){ thePlayer->collision = 0; } else{ int m; for(m = 0;m < 5;m++){ if(theMines[0][m].alive == 1){ if(theMines[0][m].tileposx == thePlayer->tileposx && theMines[0][m].tileposz == thePlayer->tileposz){ theMines[0][m].alive = 0; BldgWorldData[(thePlayer->tileposx)][(thePlayer->tileposz)]='0'; } } } PlaySFX(&bang); InitialiseExplosion(thePlayer->tileposx, thePlayer->tileposz, (thePlayer->tileposx * 1200), (thePlayer->tileposz * 1200), 4, n); if(theCar[1].shield <= 0){ thePlayer->armour -= 30; if (thePlayer->armour <= 0 && thePlayer->alive == 1){ if(gametype == 0){ AddStarForKill(0); } PlayerDeath(1); } } } break; } default: { thePlayer->collision = 1; } } if (w == 'b' && theCar[n].subtype != 4){ thePlayer->collision = 1; } if (nX < enX+450 && nX > enX-450){ if (nZ < enZ+450 && nZ > enZ-450){ thePlayer->collision = 1; } } } else thePlayer->collision = 1; } int TestForCollision(int px, int pz, int bb1x, int bb2x, int bb1z, int bb2z ) { if(px >= bb1x && px <= bb2x){ if(pz <= bb1z && pz >= bb2z){ return(1); } } return(0); } // move the model nD steps in the direction it is pointing void AdvanceModel (GsCOORDINATE2 *gsObjectCoord, SVECTOR *rotateVector, int speed, int n) { // Moves the model nD units in the direction of its rotation vector MATRIX matTmp; SVECTOR startVector; SVECTOR currentDirection; // if nD = 0 there is no movement and we need to avois the // main body of the function which will cause a divide by zero error // set up original vector, pointing down the positive z axis startVector.vx = 0; startVector.vy = 0; startVector.vz = ONE; // RotMatrix sets up the matrix coefficients for rotation RotMatrix(rotateVector, &matTmp); // multiply startVector by mattmp and put the result in currentDirection // which is the vector defining the direction the player is pointing ApplyMatrixSV(&matTmp, &startVector, ¤tDirection); // currentDirection components have a maximum value of 4096 so we // scale nD to 4096 /nD then when we add the amount of // translation we divide by nD. This ensures that we will translate // the number of units originally specified by nD // nD = 4096 /nD ; if (n >= 0){ theCar[n].dx=(currentDirection.vx * (theTurret[n].speed))/4096; theCar[n].dy=(currentDirection.vy * (theTurret[n].speed))/4096; theCar[n].dz=(currentDirection.vz * (theTurret[n].speed))/4096; if(theCar[n].subtype != 4){ theCar[n].sx = (currentDirection.vx * speed)/4096; theCar[n].sz = (currentDirection.vz * speed)/4096; } else{ theCar[n].sx += (currentDirection.vx * speed)/4096; theCar[n].sz += (currentDirection.vz * speed)/4096; if(((theCar[n].sx * theCar[n].sx)+(theCar[n].sz * theCar[n].sz)) > 33000){ theCar[n].sx -= (currentDirection.vx * speed)/4096; theCar[n].sz -= (currentDirection.vz * speed)/4096; } } gsObjectCoord->coord.t[0] += theCar[n].sx; gsObjectCoord->coord.t[1] += 0; gsObjectCoord->coord.t[2] += theCar[n].sz; theTurret[n].gsObjectCoord.coord.t[0] = gsObjectCoord->coord.t[0]; theTurret[n].gsObjectCoord.coord.t[2] = gsObjectCoord->coord.t[2]; theTurret[n].gsObjectCoord.flg = 0; } else{ gsObjectCoord->coord.t[0] +=(currentDirection.vx * speed)/4096; gsObjectCoord->coord.t[1] +=(currentDirection.vy * speed)/4096; gsObjectCoord->coord.t[2] +=(currentDirection.vz * speed)/4096; } // Because It Has Changed, 0 Means that we will redraw it gsObjectCoord->flg = 0; } void SetShotDirection (GsCOORDINATE2 *gsObjectCoord, SVECTOR *rotateVector, int speed, int n) { // Moves the model nD units in the direction of its rotation vector MATRIX matTmp; SVECTOR startVector; SVECTOR currentDirection; // if nD = 0 there is no movement and we need to avois the // main body of the function which will cause a divide by zero error // set up original vector, pointing down the positive z axis startVector.vx = 0; startVector.vy = 0; startVector.vz = ONE; // RotMatrix sets up the matrix coefficients for rotation RotMatrix(rotateVector, &matTmp); // multiply startVector by mattmp and put the result in currentDirection // which is the vector defining the direction the player is pointing ApplyMatrixSV(&matTmp, &startVector, ¤tDirection); // currentDirection components have a maximum value of 4096 so we // scale nD to 4096 /nD then when we add the amount of // translation we divide by nD. This ensures that we will translate // the number of units originally specified by nD // nD = 4096 /nD ; theTurret[n].dx=(currentDirection.vx * (theTurret[n].speed))/4096; theTurret[n].dy=(currentDirection.vy * (theTurret[n].speed))/4096; theTurret[n].dz=(currentDirection.vz * (theTurret[n].speed))/4096; } void ProcessUserInput() { int FREEZE; int rotspeed; FREEZE = 0; PADstatus=PadRead(); if((PADstatus & PADRleft)||(PADstatus & PAD2Rleft)){ PlaySFX(&pickup); FREEZE = 1; while(FREEZE){ FntPrint(" PAUSED "); FntPrint("\n\n\nPress start to cancel "); FntPrint("\n\nPress select to quit"); PADstatus=PadRead(); if((PADstatus & PADstart)||(PADstatus & PAD2start)){ PlaySFX(&pickup); FREEZE = 0; } if((PADstatus & PAD2select)||(PADstatus & PADselect)){ PlaySFX(&bang2); PLAYING = 0; break; } RenderWorld(); } } if (theCar[0].alive == 1 ){ rotspeed = 80 + (theCar[0].subtype * 10); if(PADstatus & PADLleft){ RotateModel (&theCar[0].gsObjectCoord,&theCar[0].rotation,0,(0-rotspeed),-0); RotateModel (&theTurret[0].gsObjectCoord,&theTurret[0].rotation,0,(0-rotspeed),-0); } if(PADstatus & PADLright){ RotateModel (&theCar[0].gsObjectCoord,&theCar[0].rotation, 0, rotspeed, 0 ); RotateModel (&theTurret[0].gsObjectCoord,&theTurret[0].rotation, 0, rotspeed, 0 ); } if(RotTurret == 1){ if(PADstatus & PADL1){ RotateModel (&theTurret[0].gsObjectCoord,&theTurret[0].rotation,0,-64,-0); } if(PADstatus & PADR1){ RotateModel (&theTurret[0].gsObjectCoord,&theTurret[0].rotation,0,64,-0); } if((PADstatus & PADR2)||(PADstatus & PADL2)){ theTurret[0].rotation = theCar[0].rotation; RotateModel (&theTurret[0].gsObjectCoord,&theTurret[0].rotation,0,0,-0); } } if(PADstatus & PADRright){ if(theCar[0].subtype == 5){ LayMine(0); } } if(PADstatus & PADRup){ theCar[0].drop = 1; if(theCar[0].flag > 0){ PlayerDropFlag(0); } } if(PADstatus & PADLup){ AdvanceModel(&theCar[0].gsObjectCoord,&theCar[0].rotation,theCar[0].speed,0); FindTilePosition(&theCar[0]); TestPlayerCollision(&theCar[0],&theTurret[0],0); if (theCar[0].collision==1){ theCar[0].sx = (0-(theCar[0].sx)); theCar[0].sz = (0-(theCar[0].sz)); AdvanceModel(&theCar[0].gsObjectCoord,&theCar[0].rotation,(0-(theCar[0].speed)),0); if(theCar[0].subtype == 4){ TankBounce(0); } } } if(PADstatus & PADLdown){ if(theCar[0].subtype != 4){ AdvanceModel(&theCar[0].gsObjectCoord,&theCar[0].rotation,(0-(theCar[0].speed)),0); FindTilePosition(&theCar[0]); TestPlayerCollision(&theCar[0],&theTurret[0],0); if (theCar[0].collision==1){ AdvanceModel(&theCar[0].gsObjectCoord,&theCar[0].rotation,(theCar[0].speed),0); } } } if(PADstatus & PADcross){ FireBullet(0); } theCar[0].drop = 0; }// end if player1 alive if(theCar[1].alive == 1){ rotspeed = 80 + (theCar[1].subtype * 10); if(PADstatus & PAD2Lleft){ RotateModel (&theCar[1].gsObjectCoord,&theCar[1].rotation,0,(0-rotspeed),-0); RotateModel (&theTurret[1].gsObjectCoord,&theTurret[1].rotation,0,(0-rotspeed),-0); } if(PADstatus & PAD2Lright){ RotateModel (&theCar[1].gsObjectCoord,&theCar[1].rotation, 0, rotspeed, 0 ); RotateModel (&theTurret[1].gsObjectCoord,&theTurret[1].rotation, 0, rotspeed, 0 ); } if(RotTurret == 1){ if(PADstatus & PAD2L1){ RotateModel (&theTurret[1].gsObjectCoord,&theTurret[1].rotation,0,-64,-0); } if(PADstatus & PAD2R1){ RotateModel (&theTurret[1].gsObjectCoord,&theTurret[1].rotation,0,64,-0); } if((PADstatus & PAD2R2)||(PADstatus & PAD2L2)){ theTurret[1].rotation = theCar[1].rotation; RotateModel (&theTurret[1].gsObjectCoord,&theTurret[1].rotation,0,0,-0); } } if(PADstatus & PAD2Rright){ if(theCar[1].subtype == 5){ LayMine(1); } } if(PADstatus & PAD2Rup){ theCar[1].drop = 1; if(theCar[1].flag > 0){ PlayerDropFlag(1); } } if(PADstatus & PAD2Lup){ AdvanceModel(&theCar[1].gsObjectCoord,&theCar[1].rotation,theCar[1].speed,1); FindTilePosition(&theCar[1]); TestPlayerCollision(&theCar[1],&theTurret[1],1); if (theCar[1].collision==1){ theCar[1].sx = (0-(theCar[1].sx)); theCar[1].sz = (0-(theCar[1].sz)); AdvanceModel(&theCar[1].gsObjectCoord,&theCar[1].rotation,(0-(theCar[1].speed)),1); if(theCar[1].subtype == 4){ TankBounce(1); } } } if(PADstatus & PAD2Ldown){ if(theCar[1].subtype != 4){ AdvanceModel(&theCar[1].gsObjectCoord,&theCar[1].rotation,(0-(theCar[1].speed)),1); FindTilePosition(&theCar[1]); TestPlayerCollision(&theCar[1],&theTurret[1],1); if (theCar[1].collision==1){ AdvanceModel(&theCar[1].gsObjectCoord,&theCar[1].rotation,(theCar[1].speed),1); } } } if(PADstatus & PAD2cross){ FireBullet(1); } theCar[1].drop = 0; }// end if player2 alive } void LayMine( int n) { int freeMine = 0; int nX; int nY; int nZ; int m; for (m = 0; m < 5; m++ ){ if (theMines[n][m].alive == 0){ freeMine=m; break; } else freeMine=-1; } if(BldgWorldData[(theCar[n].tileposx)][(theCar[n].tileposz)] == '0'){ if (freeMine >= 0){ PlaySFX(&pickup); theMines[n][freeMine].alive = 1; theMines[n][freeMine].lifespan = 280; theMines[n][freeMine].shotPower = 30; theMines[n][freeMine].subtype = n; theMines[n][freeMine].speed = 0; theMines[n][freeMine].tileposx = theCar[n].tileposx; theMines[n][freeMine].tileposz = theCar[n].tileposz; nX = theMines[n][freeMine].tileposx * 1200; nY = 0; nZ = theMines[n][freeMine].tileposz * 1200; if(n == 0){ BldgWorldData[(theMines[n][freeMine].tileposx)][(theMines[n][freeMine].tileposz)] = 'M'; } if(n == 1){ BldgWorldData[(theMines[n][freeMine].tileposx)][(theMines[n][freeMine].tileposz)] = 'm'; } theMines[n][freeMine].id = MINE; AddModelToPlayer(&theMines[n][freeMine], nX, nY,nZ, (unsigned long *)MINE_MEM_ADDR); } } } void UpdateMines(int n) { int m; int px; int pz; for(m = 0;m < 5;m++){ if(theMines[n][m].alive == 1){ theMines[n][m].lifespan --; if(theMines[n][m].lifespan <= 0){ PlaySFX(&bang); BldgWorldData[(theMines[n][m].tileposx)][(theMines[n][m].tileposz)] = '0'; FindTilePosition(&theMines[n][m]); px = theMines[n][m].gsObjectCoord.coord.t[0]; pz = theMines[n][m].gsObjectCoord.coord.t[2]; InitialiseExplosion(theMines[n][m].tileposx, theMines[n][m].tileposz, px, pz, 4, n); theMines[n][m].alive = 0; } } } } void UpdateBullets() { int n; int bullet; if (theCar[0].reloadTime>0){ theCar[0].reloadTime --; } if (theCar[1].reloadTime>0){ theCar[1].reloadTime --; } for (n = 0; n < MAX_NO_OF_BULLETS; n++){ if (theBullets[n].alive == 1){ bullet = n; MoveBullets(bullet); } } } void MoveBullets(int activeBullet) { int px; int pz; px = theBullets[activeBullet].gsObjectCoord.coord.t[0]; pz = theBullets[activeBullet].gsObjectCoord.coord.t[2]; AdvanceModel(&theBullets[activeBullet].gsObjectCoord,&theBullets[activeBullet].rotation,theBullets[activeBullet].speed,64); CheckBulletCollision(activeBullet); theBullets[activeBullet].gsObjectCoord.flg = 0; theBullets[activeBullet].lifespan -= (theBullets[activeBullet].speed/2); if (theBullets[activeBullet].lifespan <= 0){ InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px, pz, theBullets[activeBullet].subtype, activeBullet); if( theBullets[activeBullet].subtype == 3){ PlaySFX(&bang2); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px+600, pz+600, 4, activeBullet); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px-600, pz+600, 4, activeBullet); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px+600, pz-600, 4, activeBullet); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px-600, pz-600, 4, activeBullet); } if( theBullets[activeBullet].subtype == 2){ PlaySFX(&bang2); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px, pz, 4, activeBullet); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px+300, pz+300, 2, activeBullet); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px-300, pz+300, 2, activeBullet); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px+300, pz-300, 2, activeBullet); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px-300, pz-300, 2, activeBullet); } if( theBullets[activeBullet].subtype == 1){ PlaySFX(&bang); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px, pz, 4, activeBullet); } if( theBullets[activeBullet].subtype == 4){ PlaySFX(&bang); } InitialiseBullet(activeBullet); theBullets[activeBullet].gsObjectCoord.flg = 1; } theBullets[activeBullet].gsObjectCoord.flg = 0; } void FireBullet(int activeCar) { int freeBullet = 0; int nX; int nY; int nZ; int n; for (n = 0; n < MAX_NO_OF_BULLETS; n++ ){ if (theBullets[n].alive == 0){ freeBullet=n; break; } else freeBullet=-1; } if (freeBullet >= 0 && theCar[activeCar].reloadTime <= 0){ theBullets[freeBullet].alive = 1; theBullets[freeBullet].lifespan = theTurret[activeCar].lifespan; theBullets[freeBullet].shotPower = theTurret[activeCar].shotPower; theBullets[freeBullet].subtype = theTurret[activeCar].subtype; theBullets[freeBullet].speed = theTurret[activeCar].speed; theBullets[freeBullet].tileposx = theCar[activeCar].tileposx; theBullets[freeBullet].tileposz = theCar[activeCar].tileposz; SetShotDirection(&theTurret[activeCar].gsObjectCoord,&theTurret[activeCar].rotation,theTurret[activeCar].speed,activeCar); nX = theCar[activeCar].gsObjectCoord.coord.t[0]; nY = -200; nZ = theCar[activeCar].gsObjectCoord.coord.t[2]; if (theBullets[freeBullet].subtype < 3){ if(theBullets[freeBullet].subtype == 1){ PlaySFX(&shell); } else PlaySFX(&shell2); AddModelToPlayer(&theBullets[freeBullet], nX, nY,nZ, (unsigned long *)SHELL_MEM_ADDR); } if (theBullets[freeBullet].subtype >2){ if(theBullets[freeBullet].subtype == 3){ PlaySFX(&missile2); } else PlaySFX(&missile); AddModelToPlayer(&theBullets[freeBullet], nX, nY,nZ, (unsigned long *)MISSILE_MEM_ADDR); } theBullets[freeBullet].rotation = theTurret[activeCar].rotation; theBullets[freeBullet].dx = theTurret[activeCar].dx; theBullets[freeBullet].dy = theTurret[activeCar].dy; theBullets[freeBullet].dz = theTurret[activeCar].dz; RotateModel (&theBullets[freeBullet].gsObjectCoord,&theBullets[freeBullet].rotation,0,0,-0); theBullets[freeBullet].allegance = theCar[activeCar].allegance; theCar[activeCar].reloadTime = theTurret[activeCar].reloadTime; } } void InitialiseBullet(int activeBullet) { theBullets[activeBullet].id = SHOT; theBullets[activeBullet].alive = 0; theBullets[activeBullet].lifespan = 0; theBullets[activeBullet].shotPower = 0; theBullets[activeBullet].subtype = 0; theBullets[activeBullet].speed = 0; theBullets[activeBullet].rotation.vx=0;theBullets[activeBullet].rotation.vy=0;theBullets[activeBullet].rotation.vz=0; theBullets[activeBullet].dx = 0; theBullets[activeBullet].dy = 0; theBullets[activeBullet].dz = 0; theBullets[activeBullet].tileposx = 0; theBullets[activeBullet].tileposz = 0; theBullets[activeBullet].allegance = 1; theBullets[activeBullet].collision = 0; theBullets[activeBullet].reloadTime = 0; theBullets[activeBullet].lModelPointer = (unsigned long *)SHELL_MEM_ADDR; AddModelToPlayer(&theBullets[activeBullet], 0, 0, 0, (unsigned long *)SHELL_MEM_ADDR); } void InitialiseAllBullets() { int n; for (n = 0; n < MAX_NO_OF_BULLETS; n++ ){ InitialiseBullet(n); } } void CheckBulletCollision(int activeBullet) { char c; int bbox[2][2]; int px, pz; int enemyPlayer; int player; player = theBullets[activeBullet].allegance; enemyPlayer = 1-theBullets[activeBullet].allegance; bbox[0][0] = theCar[enemyPlayer].gsObjectCoord.coord.t[0]-250; bbox[0][1] = theCar[enemyPlayer].gsObjectCoord.coord.t[2]+250; bbox[1][0] = theCar[enemyPlayer].gsObjectCoord.coord.t[0]+250; bbox[1][1] = theCar[enemyPlayer].gsObjectCoord.coord.t[2]-250; px = theBullets[activeBullet].gsObjectCoord.coord.t[0]; pz = theBullets[activeBullet].gsObjectCoord.coord.t[2]; FindTilePosition(&theBullets[activeBullet]); c=BldgWorldData[(theBullets[activeBullet].tileposx)][(theBullets[activeBullet].tileposz)]; if (theBullets[activeBullet].tileposx<=0 || theBullets[activeBullet].tileposz<=0 || theBullets[activeBullet].tileposx>=21 || theBullets[activeBullet].tileposz>=21){ SetUpBulletExplosions( activeBullet, px, pz); InitialiseBullet(activeBullet); } if (c == '1' || c == 'a' || c == 'b' || c == 'c' || c == 'd' || c == 'e' || c == 'f' || c == 'g' || c == 'h' || c == 'i' || c == 'j'|| c == 'B'|| c == 'W'){ SetUpBulletExplosions( activeBullet, px, pz); if(c == '1'){ PlaySFX(&bang2); BldgWorldData[(theBullets[activeBullet].tileposx)][(theBullets[activeBullet].tileposz)] = 'B'; InitialiseBldgs(); InitialiseBullet(activeBullet); } if(c == 'a' || c == 'b' || c == 'c' || c == 'd' || c == 'e' || c == 'f' || c == 'g' || c == 'h' || c == 'i' || c == 'j'){ PlaySFX(&bang); PlaySFX(&bang2); BldgWorldData[(theBullets[activeBullet].tileposx)][(theBullets[activeBullet].tileposz)] = 'W'; InitialiseBldgs(); InitialiseBullet(activeBullet); } if(c == 'W'){ PlaySFX(&bang2); BldgWorldData[(theBullets[activeBullet].tileposx)][(theBullets[activeBullet].tileposz)] = '0'; InitialiseBldgs(); InitialiseBullet(activeBullet); } InitialiseBullet(activeBullet); } if (theBullets[activeBullet].alive && theCar[enemyPlayer].shield <= 0){ if (px>bbox[0][0] && pzbbox[1][1]){ PlaySFX(&bang); SetUpBulletExplosions( activeBullet, px, pz); theCar[enemyPlayer].armour -= theBullets[activeBullet].shotPower; InitialiseBullet(activeBullet); if (theCar[enemyPlayer].armour <= 0 && theCar[enemyPlayer].alive == 1){ PlayerDeath(enemyPlayer); if(gametype == 0){ AddStarForKill(player); } } } } } void SetUpBulletExplosions(int activeBullet, int px, int pz) { InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px, pz, theBullets[activeBullet].subtype, activeBullet); if( theBullets[activeBullet].subtype == 3){ PlaySFX(&bang2); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px+600, pz+600, 4, activeBullet); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px-600, pz+600, 4, activeBullet); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px+600, pz-600, 4, activeBullet); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px-600, pz-600, 4, activeBullet); } if( theBullets[activeBullet].subtype == 2){ PlaySFX(&bang2); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px, pz, 4, activeBullet); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px+300, pz+300, 2, activeBullet); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px-300, pz+300, 2, activeBullet); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px+300, pz-300, 2, activeBullet); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px-300, pz-300, 2, activeBullet); } if( theBullets[activeBullet].subtype == 1){ PlaySFX(&bang); InitialiseExplosion(theBullets[activeBullet].tileposx, theBullets[activeBullet].tileposz, px, pz, 4, activeBullet); } if( theBullets[activeBullet].subtype == 4){ PlaySFX(&bang); } } void AddStarForKill(int player) { PlaySFX(&ping); theCar[player].score++; theStars[player].state[3-theCar[player].score] = 1; UpdateStars(); if(theCar[player].score == 3){ InitialiseVictory(player);//insert victory funct call here } } void CheckSplashDamage(int posx, int posz, int range) { int n; int ax; int bx; int az; int bz; int px; int pz; int player; ax = posx - range; az = posz + range; bx = posx + range; bz = posz - range; for (n = 0; n <= 1; n++){ if(theCar[n].shield <= 0){ player = 1 - n; px = theCar[n].gsObjectCoord.coord.t[0]; pz = theCar[n].gsObjectCoord.coord.t[2]; if( px!=posx && pz!=posz){ if(px > ax && px < bx && pz > bz && pz < az){ theCar[n].armour -= 2 ; if (theCar[n].armour <= 0 && theCar[n].alive == 1){ if(gametype == 0){ AddStarForKill(player); } PlayerDeath(n); } } } } } } void PlayerDeath( int enemyPlayer) { int px; int pz; LoadLevel(1); if(gametype > 0 && theCar[enemyPlayer].flag > 0){ int flag; flag = theCar[enemyPlayer].flag - 1; CarryFlag(enemyPlayer); DropFlag(&theFlags[flag]); theCar[enemyPlayer].flag = 0; } PlaySFX(&bang2); InitialiseExplosion(theCar[enemyPlayer].tileposx, theCar[enemyPlayer].tileposz, theCar[enemyPlayer].gsObjectCoord.coord.t[0], theCar[enemyPlayer].gsObjectCoord.coord.t[2], 4, 0); FindTilePosition(&theCar[enemyPlayer]); if(BldgWorldData[(theCar[enemyPlayer].tileposx)][(theCar[enemyPlayer].tileposz)]=='0'){ BldgWorldData[(theCar[enemyPlayer].tileposx)][(theCar[enemyPlayer].tileposz)]='X'; InitialiseBldgs(); } theCar[enemyPlayer].alive = 0; theSmoke.alive = 1; theSmoke.id = SMOKE; LoadTexture(SMOKE1_TEX_MEM_ADDR); LoadTexture(SMOKE2_TEX_MEM_ADDR); LoadTexture(SMOKE3_TEX_MEM_ADDR); px = theCar[enemyPlayer].gsObjectCoord.coord.t[0]; pz = theCar[enemyPlayer].gsObjectCoord.coord.t[2]; InitialisePlayer(&theSmoke, px, -100, pz, (unsigned long*)SMOKE1_MEM_ADDR); theSmoke.subtype = 1; } void InitialiseVictory(int n) { int counter; int startagain; startagain = 0; counter = 120; theVictor.state = n+1; InitialiseSprite(VICTOR_MEM_ADDR, &theVictor.sprite, -32, -64); while(startagain == 0){ PADstatus=PadRead(); if(counter <= 0){ startagain = 1; PLAYING = 0; } if(PADstatus & PADstart){ startagain = 1; PLAYING = 0; } if(PADstatus & PAD2start){ startagain = 1; PLAYING = 0; } if(theCar[0].alive == 0 || theCar[1].alive == 0){ UpdateKilledPlayer(); } UpdateBullets(); UpdateExplosions(); RenderWorld(); counter --; } } void InitialisePlayerOne() { theCar[0].id = CHASSIS; theCar[0].tileposz=3; theCar[0].tileposx=3; theCar[0].allegance = 0; theCar[0].shield = 250; theCar[0].startposz=3600; theCar[0].startposx=3600; InitialisePlayer(&theCar[0], 3600, 0, 3600, (unsigned long*)CHASSIS1_MEM_ADDR); theTurret[0].id = TURRET; theTurret[0].allegance = 0; InitialisePlayer(&theTurret[0], 3600, 0, 3600, (unsigned long*)TURRET1_MEM_ADDR); //AdvanceModel(&theCar[0].gsObjectCoord,&theCar[0].rotation,50,64); InitialiseTrackerView(&view[0], 250, 0, 3600, -3300, -1300, 3600, 0, 3600 ); UpdateView(&view[0],0); InitialiseShield(0); } void InitialisePlayerTwo() { theCar[1].id = CHASSIS; theCar[1].tileposz=18; theCar[1].tileposx=18; theCar[1].allegance = 1; theCar[1].shield = 250; theCar[1].startposz=21600; theCar[1].startposx=21600; InitialisePlayer(&theCar[1], 21600, 0, 21600, (unsigned long*)CHASSIS1_MEM_ADDR); theTurret[1].id = TURRET; theTurret[1].allegance = 1; InitialisePlayer(&theTurret[1], 21600, 0, 21600, (unsigned long*)TURRET1_MEM_ADDR); //AdvanceModel(&theCar[1].gsObjectCoord,&theCar[1].rotation,50,64); InitialiseTrackerView(&view[1], 250, 0, 21600, -3300, 20100, 21600, 0, 21600 ); UpdateView(&view[1],1); InitialiseShield(1); } void InitialiseShield(int n) { theShield[n].allegance = n; theShield[n].id = SHIELD; InitialisePlayer(&theShield[n], 0, 0, 0, (unsigned long*)SHIELD_MEM_ADDR); theShield[n].gsObjectHandler.attribute = theShield[n].gsObjectHandler.attribute | (1 << 30); } void PlayerDeathSequence(int n) { int rX; int rY; int rZ; int time; time = theCar[n].deathframe; rX = DeathSequenceRotation[time][0]; rY = DeathSequenceRotation[time][1]; rZ = DeathSequenceRotation[time][2]; RotateModel (&theCar[n].gsObjectCoord,&theCar[n].rotation,rX,rY,rZ); RotateModel (&theTurret[n].gsObjectCoord,&theTurret[n].rotation,rX,rY,rZ); theCar[n].gsObjectCoord.flg = 0; theTurret[n].gsObjectCoord.flg = 0; theCar[n].deathframe --; } void HomingCamera(int n) { if (theCar[n].restart == 0){ if (theCar[n].gsObjectCoord.coord.t[0] > theCar[n].startposx){ theCar[n].gsObjectCoord.coord.t[0] -= 100; } if (theCar[n].gsObjectCoord.coord.t[0] < theCar[n].startposx){ theCar[n].gsObjectCoord.coord.t[0] += 100; } if (theCar[n].gsObjectCoord.coord.t[2] > theCar[n].startposx){ theCar[n].gsObjectCoord.coord.t[2] -= 100; } if (theCar[n].gsObjectCoord.coord.t[2] < theCar[n].startposx){ theCar[n].gsObjectCoord.coord.t[2] += 100; } UpdateView(&view[n],n); FindTilePosition(&theCar[n]); } if (theCar[n].gsObjectCoord.coord.t[0] >= (theCar[n].startposx - 150) && theCar[n].gsObjectCoord.coord.t[0] <= (theCar[n].startposx + 150)){ if (theCar[n].gsObjectCoord.coord.t[2] >= (theCar[n].startposz - 150) && theCar[n].gsObjectCoord.coord.t[2] <= (theCar[n].startposz + 150)){ theCar[n].restart = 1; } } LoadLevel(1); } void InitialiseAllExplosions() { int n; for (n = 0; n < MAX_NO_OF_BULLETS; n++ ){ theExplosion[n].id = EXPLOSION; theExplosion[n].alive = 0; theExplosion[n].lifespan = 0; theExplosion[n].shotPower = 0; theExplosion[n].subtype = 0; theExplosion[n].speed = 0; theExplosion[n].rotation.vx=0;theExplosion[n].rotation.vy=0;theExplosion[n].rotation.vz=0; theExplosion[n].dx = 0; theExplosion[n].dy = 0; theExplosion[n].dz = 0; theExplosion[n].tileposx = 0; theExplosion[n].tileposz = 0; theExplosion[n].allegance = 1; theExplosion[n].collision = 0; theExplosion[n].reloadTime = 0; theExplosion[n].lModelPointer = (unsigned long *)EXPLODE1_MEM_ADDR; LoadTexture(FIRE1_TEX_MEM_ADDR); LoadTexture(FIRE2_TEX_MEM_ADDR); } } void InitialiseExplosion(int tilex, int tilez, int x, int z, int type, int Bullet) { int free = 0; int n; for (n = 0; n < MAX_NO_OF_BULLETS; n++ ){ if (theExplosion[n].alive == 0){ free = n; break; } else free = -1; } theExplosion[free].subtype = type; if (free >= 0){ theExplosion[free].alive = 1; if(type == 3 || type == 4) { theExplosion[free].lifespan = 6; AddModelToPlayer(&theExplosion[free], x, 0, z, (unsigned long *)EXPLODE1_MEM_ADDR); theExplosion[free].rotation.vx=0;theExplosion[free].rotation.vy=0;theExplosion[free].rotation.vz=0; } if(type == 1 || type == 2) { theExplosion[free].lifespan = 6; AddModelToPlayer(&theExplosion[free], x, 0, z, (unsigned long *)SHRPNEL1_MEM_ADDR); theExplosion[free].rotation = theBullets[Bullet].rotation; } theExplosion[free].shotPower = 0; theExplosion[free].subtype = type; theExplosion[free].speed = 0; theExplosion[free].tileposx = tilex; theExplosion[free].tileposz = tilez; theExplosion[free].dx = x; theExplosion[free].dy = 0; theExplosion[free].dz = z; RotateModel (&theExplosion[free].gsObjectCoord,&theExplosion[free].rotation,0,0,-0); } } void UpdateExplosions() { int explosion; int n; for (n = 0; n < MAX_NO_OF_BULLETS; n++){ if (theExplosion[n].alive == 1){ explosion = n; UpdateExplosionAnimation(explosion); theExplosion[n].lifespan--; if (theExplosion[n].lifespan <= 0){ theExplosion[n].alive = 0; AddModelToPlayer(&theExplosion[n], 0, 0, 0, (unsigned long *)EXPLODE1_MEM_ADDR); } } } } void UpdateExplosionAnimation( int explosion ) { int x; int z; x = theExplosion[explosion].gsObjectCoord.coord.t[0]; z = theExplosion[explosion].gsObjectCoord.coord.t[2]; FindTilePosition(&theExplosion[explosion]); if(theExplosion[explosion].subtype == 3 || theExplosion[explosion].subtype == 4) { if(theExplosion[explosion].subtype == 3) { CheckSplashDamage(x, z, 1800); } switch (theExplosion[explosion].lifespan) { case 6: { AddModelToPlayer(&theExplosion[explosion], x, 0, z, (unsigned long *)EXPLODE1_MEM_ADDR); theExplosion[explosion].gsObjectCoord.flg = 0; break; } case 5: { AddModelToPlayer(&theExplosion[explosion], x, 0, z, (unsigned long *)EXPLODE2_MEM_ADDR); theExplosion[explosion].gsObjectCoord.flg = 0; break; } case 4: { AddModelToPlayer(&theExplosion[explosion], x, 0, z, (unsigned long *)EXPLODE3_MEM_ADDR); theExplosion[explosion].gsObjectCoord.flg = 0; break; } case 3: { AddModelToPlayer(&theExplosion[explosion], x, 0, z, (unsigned long *)EXPLODE4_MEM_ADDR); theExplosion[explosion].gsObjectCoord.flg = 0; break; } case 2: { AddModelToPlayer(&theExplosion[explosion], x, 0, z, (unsigned long *)EXPLODE5_MEM_ADDR); theExplosion[explosion].gsObjectCoord.flg = 0; break; } case 1: { AddModelToPlayer(&theExplosion[explosion], x, 0, z, (unsigned long *)EXPLODE6_MEM_ADDR); theExplosion[explosion].gsObjectCoord.flg = 0; break; } } } if(theExplosion[explosion].subtype < 3) { if(theExplosion[explosion].subtype == 2) { CheckSplashDamage(x, z, 800); } switch (theExplosion[explosion].lifespan) { case 6: { AddModelToPlayer(&theExplosion[explosion], x, 0, z, (unsigned long *)SHRPNEL1_MEM_ADDR); theExplosion[explosion].gsObjectCoord.flg = 0; break; } case 5: { AddModelToPlayer(&theExplosion[explosion], x, 0, z, (unsigned long *)SHRPNEL2_MEM_ADDR); theExplosion[explosion].gsObjectCoord.flg = 0; break; } case 4: { AddModelToPlayer(&theExplosion[explosion], x, 0, z, (unsigned long *)SHRPNEL3_MEM_ADDR); theExplosion[explosion].gsObjectCoord.flg = 0; break; } case 3: { AddModelToPlayer(&theExplosion[explosion], x, 0, z, (unsigned long *)SHRPNEL4_MEM_ADDR); theExplosion[explosion].gsObjectCoord.flg = 0; break; } case 2: { AddModelToPlayer(&theExplosion[explosion], x, 0, z, (unsigned long *)SHRPNEL5_MEM_ADDR); theExplosion[explosion].gsObjectCoord.flg = 0; break; } case 1: { AddModelToPlayer(&theExplosion[explosion], x, 0, z, (unsigned long *)SHRPNEL6_MEM_ADDR); theExplosion[explosion].gsObjectCoord.flg = 0; break; } } } } void InitialiseAirship() { theAirship.id = AIRSHIP; theAirship.alive = 0; theAirship.lifespan = 0; theAirship.shotPower = 0; theAirship.subtype = 0; theAirship.speed = 0; theAirship.rotation.vx=0;theAirship.rotation.vy=0;theAirship.rotation.vz=0; theAirship.dx = 0; theAirship.dy = 0; theAirship.dz = 0; theAirship.tileposx = 0; theAirship.tileposz = 0; theAirship.allegance = 0; theAirship.collision = 0; theAirship.reloadTime = 0; theAirship.drop = 10; theAirship.lModelPointer = (unsigned long *)AIRSHIP_MEM_ADDR; AddModelToPlayer(&theAirship, 0, 0, 0, (unsigned long *)AIRSHIP_MEM_ADDR); } void SetupAirship() { int nX; int nY; int nZ; if (AirshipDirection == 0){ theAirship.dx = 30; theAirship.dz = 0; theAirship.gsObjectCoord.coord.t[0] = (AirshipOffset[AirshipPos] * 1200); theAirship.gsObjectCoord.coord.t[1] = -100; theAirship.gsObjectCoord.coord.t[2] = 600; nX = theAirship.gsObjectCoord.coord.t[0]; nY = theAirship.gsObjectCoord.coord.t[1]; nZ = theAirship.gsObjectCoord.coord.t[2]; AddModelToPlayer(&theAirship, nX, nY, nZ, (unsigned long *)AIRSHIP_MEM_ADDR); theAirship.rotation.vx = 0; theAirship.rotation.vy = 0; theAirship.rotation.vz = ONE; } if (AirshipDirection == 1){ theAirship.dx = 0; theAirship.dz = 30; theAirship.gsObjectCoord.coord.t[0] = 600; theAirship.gsObjectCoord.coord.t[1] = -100; theAirship.gsObjectCoord.coord.t[2] = (AirshipOffset[AirshipPos] * 1200); nX = theAirship.gsObjectCoord.coord.t[0]; nY = theAirship.gsObjectCoord.coord.t[1]; nZ = theAirship.gsObjectCoord.coord.t[2]; AddModelToPlayer(&theAirship, nX, nY, nZ, (unsigned long *)AIRSHIP_MEM_ADDR); theAirship.rotation.vx = 0; theAirship.rotation.vy = 0; theAirship.rotation.vz = ONE; RotateModel (&theAirship.gsObjectCoord,&theAirship.rotation, 0, 1024, 0 ); } FindTilePosition(&theAirship); theAirship.speed = 30; theAirship.alive = 1; //theAirship.gsObjectCoord.flg = 0; } void MoveAirship() { int tile; int lasttile; int x; int z; lasttile = theAirship.tileposx + theAirship.tileposz; AdvanceModel(&theAirship.gsObjectCoord,&theAirship.rotation,theAirship.speed,-1); theAirship.gsObjectCoord.flg = 0; FindTilePosition(&theAirship); tile = theAirship.tileposx + theAirship.tileposz; x = theAirship.gsObjectCoord.coord.t[0]; z = theAirship.gsObjectCoord.coord.t[2]; if(x > 23200 || z > 23200){ theAirship.alive = 0; AirshipDirection = 1 - AirshipDirection; InitialiseAirship(); } if(theAirship.alive == 1 && lasttile < tile){ if(x < 23200 && z < 23200){ if(x > 1200 && z > 1200){ if (AirshipDrop[DropPos] > 0){ DropItem(theAirship.tileposx, theAirship.tileposz); } DropPos ++; if (DropPos > 30){ DropPos = 0; } } } } } void DropItem(int tilex, int tilez) { char w; char c; char i; w = worldGroundData[tilex][tilez]; c = BldgWorldData[tilex][tilez]; i = DropType[DropPos]; if (c == '0' && w != 'b' && theAirship.drop <= 8){ BldgWorldData[tilex][tilez] = i; InitialiseBldgs(); } theAirship.drop ++; } void ReadOptionsPad() { PADstatus=PadRead(); if((PADstatus & PADstart)&& startP1 == 0){ startP1=1; PlaySFX(&shell2); } if((PADstatus & PAD2start)&& startP2 == 0){ startP2=1; PlaySFX(&shell2); } if(select == 0){ if((PADstatus & PADLright)||(PADstatus & PAD2Lright)){ if(keypress1 == 1){ } else{ PlaySFX(&pickup); gametype ++; keypress1 = 1; LoadLevel(2); } } else { keypress1 = 0; } if(gametype > 2){ gametype = 0; LoadLevel(2); } if((PADstatus & PADLleft)||(PADstatus & PAD2Lleft)){ if(keypress2 == 1){ } else{ gametype --; PlaySFX(&pickup); keypress2 = 1; LoadLevel(2); } } else{ keypress2 = 0; } if(gametype < 0){ gametype = 2; LoadLevel(2); } } if(select == 1 ){ if((PADstatus & PADLright)||(PADstatus & PAD2Lright)){ if(keypress1 == 1){ } else{ level ++; PlaySFX(&pickup); keypress1 = 1; } if(level > 2)level = 0; LoadLevel(2); } else{ keypress1 = 0; } if((PADstatus & PADLleft)||(PADstatus & PAD2Lleft)){ if(keypress2 == 1){ } else{ level --; PlaySFX(&pickup); keypress2 = 1; } if(level < 0)level = 2; LoadLevel(2); } else { keypress2 = 0; } } if(select == 2 ){ if((PADstatus & PADLright)||(PADstatus & PAD2Lright)){ if(keypress1 == 1){ } else{ RotTurret ++; PlaySFX(&pickup); keypress1 = 1; } if(RotTurret > 1)RotTurret = 0; } else{ keypress1 = 0; } if((PADstatus & PADLleft)||(PADstatus & PAD2Lleft)){ if(keypress2 == 1){ } else{ RotTurret --; PlaySFX(&pickup); keypress2 = 1; } if(RotTurret < 0)RotTurret = 1; } else { keypress2 = 0; } } if((PADstatus & PADLup)||(PADstatus & PAD2Lup)){ if(keypress3 == 1){ } else{ select --; PlaySFX(&pickup); keypress3 = 1; } if(select < 0)select = 2; SetArrows(select * 16); } else { keypress3 = 0; } if((PADstatus & PADLdown)||(PADstatus & PAD2Ldown)){ if(keypress4 == 1){ } else{ select ++; PlaySFX(&pickup); keypress4 = 1; } if(select > 2)select = 0; SetArrows(select * 16); } else{ keypress4 = 0; } } void UpdateKilledPlayer() { int n; for(n=0;n<2;n++){ if(theCar[n].alive == 0 && theCar[n].deathframe == 0){ UpdateSmoke(); if(theVictor.state <= 0){ HomingCamera(n); } if( theCar[n].restart == 1){ if(n == 0){ InitialisePlayerOne(); } if(n == 1){ InitialisePlayerTwo(); } } } if(theCar[n].alive == 0 && theCar[n].deathframe > 0){ PlayerDeathSequence(n); } } } void UpdateSmoke() { int nX; int nZ; nX = theSmoke.gsObjectCoord.coord.t[0]; nZ = theSmoke.gsObjectCoord.coord.t[2]; switch(theSmoke.subtype){ case 9 : { AddModelToPlayer(&theSmoke, nX, -100 ,nZ, (unsigned long *)SMOKE1_MEM_ADDR); theSmoke.subtype = 0; theSmoke.gsObjectCoord.flg = 0; break; } case 6 : { AddModelToPlayer(&theSmoke, nX, -100 ,nZ, (unsigned long *)SMOKE3_MEM_ADDR); theSmoke.gsObjectCoord.flg = 0; break; } case 3 : { AddModelToPlayer(&theSmoke, nX, -100 ,nZ, (unsigned long *)SMOKE2_MEM_ADDR); theSmoke.gsObjectCoord.flg = 0; break; } } theSmoke.subtype ++; } void LoadLevel(int loadtype) { int tmpx,tmpz; char w; char b; int n; char WorldLevel1[MAX_Z][MAX_X] ={ {'b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b'}, {'b','c','j','j','j','j','h','b','c','j','j','j','j','j','j','j','j','j','j','j','h','b'}, {'b','g','2','2','6','6','6','2','6','2','2','2','2','2','2','2','2','6','6','a','i','b'}, {'b','g','2','2','4','4','4','2','4','2','2','2','2','2','2','2','2','4','2','3','i','b'}, {'b','d','5','3','1','1','i','b','g','5','2','2','2','2','2','2','3','1','5','3','i','b'}, {'b','b','2','2','2','1','i','b','g','8','2','2','4','4','4','4','7','1','5','3','i','b'}, {'b','b','2','2','2','1','i','b','d','f','2','2','f','f','f','f','f','f','2','2','e','b'}, {'b','b','g','5','3','1','i','b','b','b','2','2','b','b','b','b','b','b','2','2','b','b'}, {'b','b','g','5','3','1','1','j','j','j','2','2','j','j','j','h','b','c','2','2','h','b'}, {'b','b','g','5','2','6','6','6','6','6','2','2','6','6','a','i','b','g','5','3','i','b'}, {'b','b','g','8','4','4','4','4','4','2','2','2','2','2','3','i','b','g','5','2','i','b'}, {'b','b','d','1','1','1','f','f','f','8','2','2','4','4','7','e','b','g','8','4','i','b'}, {'b','b','b','g','1','i','b','b','b','g','5','3','1','f','e','b','b','d','1','1','e','b'}, {'b','b','b','g','1','e','b','b','b','g','5','3','i','b','b','b','b','b','g','i','b','b'}, {'b','b','b','d','e','b','b','b','b','g','5','3','i','b','b','b','b','b','g','i','b','b'}, {'b','b','b','b','b','b','b','b','b','g','5','3','1','h','b','b','b','c','1','i','b','b'}, {'b','b','c','j','h','b','b','b','c','9','2','2','6','a','h','b','c','1','1','1','h','b'}, {'b','b','g','9','6','h','b','c','1','5','2','2','2','3','1','j','1','1','1','1','i','b'}, {'b','c','9','2','2','a','j','1','9','2','2','2','2','2','6','6','6','6','2','2','i','b'}, {'b','g','8','4','4','7','f','f','5','2','2','2','2','2','4','4','4','4','2','2','i','b'}, {'b','d','f','f','f','e','b','b','d','f','f','f','f','f','f','f','f','f','f','f','e','b'}, {'b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b'}, }; char WorldLevel2[MAX_Z][MAX_X] ={ {'b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b'}, {'b','c','j','j','j','j','j','j','j','h','b','c','j','j','j','j','j','j','h','b','b','b'}, {'b','g','2','2','6','6','2','2','2','2','j','1','2','2','2','2','2','1','i','b','b','b'}, {'b','g','2','2','4','4','2','2','2','2','6','6','2','1','1','1','2','1','i','b','b','b'}, {'b','g','5','3','9','6','2','2','2','2','2','2','2','6','6','6','a','1','e','b','b','b'}, {'b','g','5','3','5','2','2','2','2','2','2','2','2','2','2','2','2','i','b','b','b','b'}, {'b','g','5','3','5','2','2','2','2','2','2','2','2','2','2','2','2','i','b','b','b','b'}, {'b','g','5','2','2','2','2','2','f','f','f','f','f','f','2','2','2','i','b','b','b','b'}, {'b','d','8','2','2','2','2','i','c','j','j','j','j','h','d','f','f','e','b','b','b','b'}, {'b','b','d','8','2','2','2','i','g','2','2','1','1','i','c','j','j','h','b','b','b','b'}, {'b','b','b','g','2','2','2','i','g','1','1','1','1','i','g','2','2','i','b','2','b','b'}, {'b','b','b','d','f','f','f','e','g','1','1','1','2','e','g','2','2','i','b','b','b','b'}, {'b','b','c','j','j','j','j','h','d','f','f','f','e','c','2','2','2','2','j','j','h','b'}, {'b','b','g','2','2','2','2','2','j','j','j','j','j','2','2','2','2','2','6','a','i','b'}, {'b','b','g','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','2','3','i','b'}, {'b','b','d','2','2','2','2','2','2','2','2','2','2','2','2','2','2','3','5','3','i','b'}, {'b','b','b','g','2','2','2','2','2','2','2','2','2','2','2','2','2','3','5','3','i','b'}, {'b','b','b','g','2','2','2','2','2','2','2','2','2','2','2','4','4','7','5','3','i','b'}, {'b','b','c','2','2','2','2','2','3','1','1','f','2','5','2','6','6','6','2','2','i','b'}, {'b','c','2','2','2','2','2','2','2','f','e','b','g','8','4','4','4','4','2','2','i','b'}, {'b','d','f','f','f','f','f','f','e','b','b','b','d','f','f','f','f','f','f','f','e','b'}, {'b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b'}, }; char WorldLevel3[MAX_Z][MAX_X] ={ {'b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b'}, {'b','c','j','j','h','b','b','c','j','j','j','j','j','j','h','b','b','b','c','h','b','b'}, {'b','g','2','2','2','2','2','2','2','2','1','1','2','2','2','2','2','2','1','i','b','b'}, {'b','g','2','2','i','b','b','d','2','2','2','2','2','2','e','b','b','c','1','1','h','b'}, {'b','d','2','f','e','b','b','b','d','f','2','2','2','e','b','b','b','d','1','1','i','b'}, {'b','b','2','b','b','b','b','b','b','b','d','f','2','b','b','b','b','b','g','1','e','b'}, {'b','b','2','b','b','c','j','j','h','b','b','b','2','b','c','h','b','c','1','e','b','b'}, {'b','b','2','b','b','d','1','1','1','h','b','c','2','j','1','2','2','2','i','b','b','b'}, {'b','b','2','b','b','b','d','1','1','e','b','g','1','1','1','i','b','d','f','j','h','b'}, {'b','c','2','j','h','b','b','d','e','b','b','d','f','2','f','i','b','b','b','d','e','b'}, {'b','g','1','1','i','b','b','b','b','b','b','b','b','2','b','d','j','h','b','b','b','b'}, {'b','d','1','1','1','j','j','j','j','h','b','b','b','2','b','b','d','1','j','h','b','b'}, {'b','b','d','2','f','1','1','1','1','e','b','c','j','2','b','b','b','d','2','e','b','b'}, {'b','b','b','2','b','d','1','1','2','2','2','2','1','1','h','b','b','b','2','b','b','b'}, {'b','b','c','2','b','b','d','e','b','b','b','d','f','1','1','h','b','b','2','b','b','b'}, {'b','c','1','1','h','b','b','b','c','h','b','b','b','d','f','e','b','b','2','b','b','b'}, {'b','d','f','1','1','h','b','b','g','1','j','h','b','b','b','b','b','b','2','b','b','b'}, {'b','b','b','g','1','2','2','2','2','2','2','2','j','h','b','b','b','c','2','j','h','b'}, {'b','b','c','1','1','i','b','b','d','2','2','2','2','2','2','2','2','2','2','2','i','b'}, {'b','c','1','1','f','e','b','b','b','d','f','2','2','2','f','e','b','g','2','2','i','b'}, {'b','d','f','e','b','b','b','b','b','b','b','d','f','e','b','b','b','d','f','f','e','b'}, {'b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b','b'}, }; char BldgsLevel1[MAX_Z][MAX_X] ={ {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','j','a','a','a','a','a','a','a','a','h','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','0','1','0','0','0','0','0','0','8','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','0','8','0','1','L','0','0','7','0','0','0'}, {'0','0','0','0','0','8','0','0','g','0','0','1','0','0','1','0','0','g','0','0','0','0'}, {'0','0','0','0','1','0','0','0','b','0','0','0','0','0','3','0','0','b','0','0','0','0'}, {'0','0','0','0','0','0','0','0','f','h','0','0','j','a','a','a','a','e','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','8','0','0','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','8','8','0','0','0','0','0','j','a','a','d','0','6','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','b','0','0','0','0','0','0'}, {'0','0','0','0','0','0','2','0','0','1','1','0','0','0','0','i','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','0','0','g','4','0','0','0','8','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','0','j','e','0','0','0','0','8','0','0','0'}, {'0','0','0','0','6','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','0','j','d','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','0','5','b','8','0','0','0','0','0','0','0'}, {'0','0','0','4','0','0','0','0','0','2','0','1','0','i','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','L','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}, {'0','0','7','0','0','0','0','0','g','1','0','1','0','0','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','f','a','a','a','a','h','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}, }; char BldgsLevel2[MAX_Z][MAX_X] ={ {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','1','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','1','0','0','0','0','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','1','1','1','0','1','0','0','4','0','0','0','0','0'}, {'0','0','0','0','c','a','1','0','0','0','0','1','0','1','a','a','a','d','0','0','0','0'}, {'0','0','0','0','b','1','1','0','0','0','0','b','0','0','0','0','1','b','0','0','0','0'}, {'0','0','0','0','1','2','f','a','1','0','0','1','0','0','0','0','L','b','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','1','0','0','b','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','1','1','a','a','1','1','0','0','1','0','0','0','0'}, {'0','0','0','5','1','0','0','1','0','1','1','0','0','b','0','0','0','1','0','0','0','0'}, {'0','0','0','0','b','0','0','0','0','0','0','0','0','b','0','0','0','b','0','6','0','0'}, {'0','0','0','0','1','0','0','0','0','0','7','0','1','1','0','0','0','b','0','0','0','0'}, {'0','0','0','2','1','0','0','0','0','1','1','a','1','1','0','0','0','1','0','0','0','0'}, {'0','0','c','a','1','a','1','0','0','1','1','0','b','0','0','0','0','0','0','0','0','0'}, {'0','0','1','7','0','L','0','0','0','1','3','0','b','0','0','1','0','0','0','0','0','0'}, {'0','0','f','1','0','0','0','1','0','0','0','0','1','a','1','1','1','d','0','8','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','1','b','0','8','0','0'}, {'0','0','0','1','8','0','0','0','1','1','1','1','0','0','0','1','a','e','0','0','0','0'}, {'0','0','c','1','8','0','0','0','0','0','0','f','1','0','0','0','0','0','0','0','0','0'}, {'0','c','1','1','8','1','2','1','1','0','4','0','b','0','0','0','0','0','0','0','0','0'}, {'0','f','a','a','a','a','a','a','e','0','0','0','b','0','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}, }; char BldgsLevel3[MAX_Z][MAX_X] ={ {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','1','0','0','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','8','1','0','5','0','0','1','8','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','1','0','0','8','0','0','0','0','0','2','0','0'}, {'0','0','0','0','0','0','0','0','0','0','8','0','0','0','0','0','0','0','0','0','0','0'}, {'0','0','8','0','0','0','c','a','d','0','0','0','0','0','0','0','0','0','0','0','0','0'}, {'0','0','8','0','0','0','b','6','b','0','0','0','0','0','8','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','f','a','e','0','0','0','0','0','0','0','0','0','0','7','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','3','0','0','0','8','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','3','0','0','0','0','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','8','0','0','0'}, {'0','0','0','0','0','0','0','0','8','8','0','0','0','0','2','0','0','0','8','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','8','0','0','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','1','0','0','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','1','0','0','0','0','0','0','0','0','0','0','0','0'}, {'0','0','7','0','0','0','0','0','0','0','0','2','1','0','0','8','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}, {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}, }; for (tmpz = 0; tmpz < MAX_Z; tmpz++ ){ for (tmpx = 0; tmpx < MAX_X; tmpx++ ){ if(level == 0){ b = BldgsLevel1[tmpz][tmpx]; w = WorldLevel1[tmpz][tmpx]; } if(level == 1){ b = BldgsLevel2[tmpz][tmpx]; w = WorldLevel2[tmpz][tmpx]; } if(level == 2){ b = BldgsLevel3[tmpz][tmpx]; w = WorldLevel3[tmpz][tmpx]; } worldGroundData[tmpz][tmpx] = w; if(loadtype == 2){ BldgWorldData[tmpz][tmpx] = b; } } } if(gametype > 0){ for(n=0;n<4;n++){ worldGroundData[P1SCORINGZONE[n][0]][P1SCORINGZONE[n][1]] = 'F'; worldGroundData[P2SCORINGZONE[n][0]][P2SCORINGZONE[n][1]] = 'F'; } } BldgWorldData[0][0] = '0'; worldGroundData[0][0] = 'b'; } void InitSound( void ) { // return vab_id (0-15), open VAB and transfer to sound buffer vab_id = SsVabTransfer((u_char*)VH_ADDR, (u_char*)VB_ADDR,-1,1); if( vab_id < 0 ) { //printf(" vab:%d", vab_id); //printf(" ERROR: VAB fail (LINE:%d)(FILE:%s)\n", // __LINE__,__FILE__); } // set main volume SsSetMVol(MAIN_VOL,MAIN_VOL); }// end InitSound void InitSFX( voice_ptr sound_effect, short vab_id, short program, short tone, short note, short vol_l, short vol_r ) { sound_effect->vabid = vab_id; sound_effect->program = program; sound_effect->tone = tone; sound_effect->note = note; sound_effect->vol_l = vol_l; sound_effect->vol_r = vol_r; }// end InitSFX void PlaySFX( voice_ptr sound_effect ) { SsUtKeyOn(sound_effect->vabid, sound_effect->program, sound_effect->tone, sound_effect->note, 0, sound_effect->vol_l, sound_effect->vol_r); }// end PlaySFX void StopSound( void ) { // close vab SsVabClose(vab_id); }// end StopSound void SetArrows(int y) { InitialiseSprite(LARROW_MEM_ADDR, &LArrow, -80, y); InitialiseSprite(RARROW_MEM_ADDR, &RArrow, 72, y); InitialiseSprite(LARROW_MEM_ADDR, &LArrow2, -88, y); InitialiseSprite(RARROW_MEM_ADDR, &RArrow2, 80, y); } void UpdateHovercraft(int n) { AdvanceModel(&theCar[n].gsObjectCoord,&theCar[n].rotation,0,n); FindTilePosition(&theCar[n]); TestPlayerCollision(&theCar[n],&theTurret[n],n); if (theCar[n].collision==1){ theCar[n].sx = (0-(theCar[n].sx)); theCar[n].sz = (0-(theCar[n].sz)); AdvanceModel(&theCar[n].gsObjectCoord,&theCar[n].rotation,0,n); TankBounce(n); } theCar[n].sx -= (theCar[n].sx/30); theCar[n].sz -= (theCar[n].sz/30); } void TankBounce(int n) { if((theCar[n].sx != 0) || (theCar[n].sz != 0)){ theCar[n].sx = (theCar[n].sx); theCar[n].sz = 0-(theCar[n].sz); AdvanceModel(&theCar[n].gsObjectCoord,&theCar[n].rotation,0,n); FindTilePosition(&theCar[n]); TestPlayerCollision(&theCar[n],&theTurret[n],n); if(theCar[n].collision==1){ theCar[n].sx = (0-(theCar[n].sx)); theCar[n].sz = (0-(theCar[n].sz)); AdvanceModel(&theCar[n].gsObjectCoord,&theCar[n].rotation,0,n); AdvanceModel(&theCar[n].gsObjectCoord,&theCar[n].rotation,0,n); } } theCar[n].sx = (theCar[n].sx/3); theCar[n].sz = (theCar[n].sz/3); } int main() { int titlecounter; // set up print-to-screen font FntLoad(960, 256); FntOpen(-90, 0, 240, 320, 0, 512); // set up the controller pad PadInit(); InitialiseGraphics(); InitialiseAllLights(); titlecounter = 500; TitleScreen = 1; InitialiseSprite(NYSCRN1_MEM_ADDR, &NYScrn1, -128, -120); InitialiseSprite(NYSCRN2_MEM_ADDR, &NYScrn2, -128, -120); while(titlecounter > 0){ RenderWorld(); titlecounter --; } InitSound(); //vab_id, program, tone, note, fine(pitch), voll, volr InitSFX(&bang,vab_id,0,0,64,127,127); InitSFX(&pickup,vab_id,0,1,64,127,127); InitSFX(&missile,vab_id,0,2,64,127,127); InitSFX(&missile2,vab_id,0,3,64,127,127); InitSFX(&shell2,vab_id,0,4,64,127,127); InitSFX(&shell,vab_id,0,5,64,127,127); InitSFX(&bang2,vab_id,0,6,64,127,127); InitSFX(&ping,vab_id,0,7,64,127,127); InitSFX(&alarm,vab_id,0,8,64,100,100); level = 0; gametype = 0; TitleScreen = 0; while(INGAME){ LoadLevel(2); InitialisePlayerOne(); theCar[0].score = 0; InitialisePlayerTwo(); theCar[1].score = 0; theVictor.state = 0; select = 0; keypress1 = 0; keypress2 = 0; keypress3 = 0; keypress4 = 0; RotTurret = 1; InitialiseAllBullets(); InitialiseAllExplosions(); InitialiseWorld(); InitialiseBldgs(); InitialiseAirship(); InitialiseSprite(HEALTH4_MEM_ADDR, &HealthBar[0], 85, 35); InitialiseSprite(HEALTH4_MEM_ADDR, &HealthBar[1], 85, 35); InitialiseSprite(TANX_MEM_ADDR, &TanxLogo, -64, -90); InitialiseSprite(LARROW_MEM_ADDR, &LArrow, -80, 0); InitialiseSprite(RARROW_MEM_ADDR, &RArrow, 72, 0); InitialiseSprite(LARROW_MEM_ADDR, &LArrow2, -88, 0); InitialiseSprite(RARROW_MEM_ADDR, &RArrow2, 80, 0); InitialiseSprite(BCKGRND_MEM_ADDR, &Background[0], -128, -120); InitialiseSprite(BCKGRND_MEM_ADDR, &Background[1], -64, -120); InitialiseSprite(BCKGRND_MEM_ADDR, &Background[2], 0, -120); InitialiseSprite(BCKGRND_MEM_ADDR, &Background[3], 64, -120); InitialiseStars(); InitialiseAllFlags(); AirshipPos = 0; DropPos = 0; counter = 60; AirshipCounter = 200 + (AirshipOffset[AirshipPos] * 100); AirshipDirection = 1; startP1 = 0; startP2 = 0; InitialiseTrackerView(&view[0], 250, 0, 2000, -900, 2000, 12600, 0, 12600 ); InitialiseTrackerView(&view[1], 250, 0, 23400, -900, 23420, 12600, 0, 12600 ); while(PLAYING == 0){ if(counter <= 0){ PLAYING = 1; } if(startP1 == 1){ RotateModel (&theShield[0].gsObjectCoord,&theShield[0].rotation, 0, (70 - counter), 0 ); view[0].vpx = 3500-(counter * 25); view[0].vpy = (counter * 40)-3300; view[0].vpz = (counter * 15)+1100; view[0].vrx = 3600+(counter * 150); view[0].vrz = 3600+(counter * 150); //InitialiseTrackerView(&view[0], 250, 0, 3600 - (counter * 25), (counter * 40)-3300 , (counter * 55)-1300, 3600+(counter * 15), 0, 3600+(counter * 15) ); GsSetRefView2(&view[0]); theShield[0].gsObjectCoord.flg = 0; } if(startP2 == 1){ RotateModel (&theShield[1].gsObjectCoord,&theShield[1].rotation, 0, (70 - counter), 0 ); view[1].vpx = 21600+(counter * 30); view[1].vpy = (counter * 40)-3300; view[1].vpz = 19100+(counter * 72); view[1].vrx = 21600-(counter * 150); view[1].vrz = 21600-(counter * 150); //InitialiseTrackerView(&view[0], 250, 0, 21600+(counter * 25), (counter * 40)-3300 , 20100+(counter * 55), 21600-(counter * 15), 0, 21600-(counter * 15) ); GsSetRefView2(&view[1]); theShield[1].gsObjectCoord.flg = 0; } if(startP1 == 1 && startP2 == 1){ SetArrows(0); FntPrint(" Ready! "); counter --; } if(startP1 == 0 || startP2 == 0){ ReadOptionsPad(); if(gametype == 0){ FntPrint(" Duel "); } if(gametype == 1){ FntPrint(" Search & Retrieve "); } if(gametype == 2){ FntPrint(" Capture the Flag "); } if(level == 0){ FntPrint("\n\n map one "); } if(level == 1){ FntPrint("\n\n map two "); } if(level == 2){ FntPrint("\n\n map three "); } if(RotTurret == 0){ FntPrint("\n\n fixed turret "); } if(RotTurret == 1){ FntPrint("\n\n rotating turret "); } if(startP1 == 0){ FntPrint("\n\n\nPlayer 1 press start"); } else{ FntPrint("\n\n\n "); } if(startP2 == 0){ FntPrint("\nPlayer 2 press start"); } else{ FntPrint("\n "); } } RenderWorld(); } if(gametype == 1){ InitialiseGameTypeTwo(); } if(gametype == 2){ InitialiseGameTypeThree(); } InitialiseBldgs(); while(PLAYING){ UpdateBullets(); counter ++; if (theAirship.alive == 0 && AirshipCounter == counter){ SetupAirship(); counter = 0; AirshipPos ++; if (AirshipPos > 12){ AirshipPos = 0; } AirshipCounter = 500 + (AirshipOffset[AirshipPos] * 100); } if(theCar[0].subtype == 4 && theCar[0].alive == 1){ UpdateHovercraft(0); } if(theCar[1].subtype == 4 && theCar[1].alive == 1){ UpdateHovercraft(1); } if(gametype > 0){ int n; for(n=0;n<2;n++){ if(theCar[n].flag > 0){ CarryFlag(n); } } } if(theCar[0].shield > 0){ RotateModel (&theShield[0].gsObjectCoord,&theShield[0].rotation, 0, 48, 0 ); theShield[0].gsObjectCoord.flg = 0; theCar[0].shield --; if((theCar[0].shield == 60)||(theCar[0].shield == 40)||(theCar[0].shield == 20)){ PlaySFX(&alarm); } } if(theCar[1].shield > 0){ RotateModel (&theShield[1].gsObjectCoord,&theShield[1].rotation, 0, 48, 0 ); theShield[1].gsObjectCoord.flg = 0; theCar[1].shield --; if((theCar[1].shield == 60)||(theCar[1].shield == 40)||(theCar[1].shield == 20)){ PlaySFX(&alarm); } } ProcessUserInput(); if(theCar[0].alive == 0 || theCar[1].alive == 0){ UpdateKilledPlayer(); } if(theAirship.alive == 1 ){ MoveAirship(); } UpdateMines(0); UpdateMines(1); UpdateHealthBar(0); UpdateHealthBar(1); UpdateBullets(); UpdateExplosions(); RenderWorld(); }// end of playing loop }//end of ingame loop // clean up StopSound(); ResetGraph(0); return 0; }