/*********************************** Sandstorm CONTROL.C ************************************/ /**** INCLUDES ****/ #include #include "main.h" #include "graphics.h" #include "pad.h" #include "control.h" #include "debug.h" #include "sprite.h" #include "collide.h" #include "fire.h" #include "ai.h" #include "cdread.h" #include "sound.h" /**** DEFINES ****/ #define COUNT_GAP (15) //smoother for menu system function /**** EXTERNS ****/ /**** CONTROL ****/ void Control( void ) { if((padd&PADselect)&&(padd&PADstart)) gameover=1; }// end Control /**** INITPOS ****/ //set initial attributes and coordinates for objects void InitPos( void ) { //looping variable int x; /***light source calculation flag***/ //pyramid.obj.attribute |= (1<<6); /***subdivision flag***/ sand.obj.attribute |= GsDIV1; //truck.obj.attribute |= GsDIV2; //pyramid.obj.attribute |= GsDIV2; /***sprite attributes***/ //lens flare sprite semitransparency attribute le1.attribute |=(3<<28); le2.attribute |=(3<<28); le3.attribute |=(3<<28); radar.attribute |=(3<<28); blank.attribute |=(2<<28); blank.attribute |=(2<<29); /***initialise coordinates of objects***/ truck[0].coord.coord.t[0]=-1000; truck[0].coord.coord.t[1]=0; truck[0].coord.coord.t[2]=0; truck[1].coord.coord.t[0]=200; truck[1].coord.coord.t[1]=0; truck[1].coord.coord.t[2]=0; truck[2].coord.coord.t[0]=-200; truck[2].coord.coord.t[1]=0; truck[2].coord.coord.t[2]=0; power_m.coord.coord.t[2]=-400; homing2_m.coord.coord.t[2]=-800; fire3_m.coord.coord.t[2]=1000; //2D tree coordinates pos[0].vx=0; pos[0].vy=-131; pos[0].vz=0; pos[1].vx=598; pos[1].vy=-131; pos[1].vz=342; pos[2].vx=381; pos[2].vy=-131; pos[2].vz=-438; pos[3].vx=-545; pos[3].vy=-131; pos[3].vz=-256; pos[4].vx=-411, pos[4].vy=-131; pos[4].vz=414; //sun coorinates sunpos.vx=0; sunpos.vy=-1000; sunpos.vz=-10000; //pickup icons coordinates in 3D space upg_ico_pos.vx=2000; upg_ico_pos.vy=-10; upg_ico_pos.vz=526; mine_ico_pos.vx=-1494; mine_ico_pos.vy=-10; mine_ico_pos.vz=-828; fire_ico_pos.vx=1156; fire_ico_pos.vy=-10; fire_ico_pos.vz=-255; hlt_ico_pos.vx=-2386; hlt_ico_pos.vy=-10; hlt_ico_pos.vz=462; hom_ico_pos.vx=1274; hom_ico_pos.vy=-10; hom_ico_pos.vz=-907; pow_ico_pos.vx=-1344; pow_ico_pos.vy=-10; pow_ico_pos.vz=-1618; rico_ico_pos.vx=477; rico_ico_pos.vy=-10; rico_ico_pos.vz=-2464; tbo_ico_pos.vx=-2311; tbo_ico_pos.vy=-10; tbo_ico_pos.vz=-897; time_ico_pos.vx=710; tbo_ico_pos.vy=-10; tbo_ico_pos.vz=-1029; mine_1_pos.vy=mine_2_pos.vy=mine_3_pos.vy=-30; //onscreen icon coordinates os_fire.x=os_pow.x=os_hom.x=os_rico.x=os_bullet.x=os_time.x=os_mine.x=67; os_fire.y=os_pow.y=os_hom.y=os_rico.y=os_bullet.y=os_time.y=os_mine.y=46; //GsBOXF coords turbo.x=121; turbo.y=46; //fire sprite VECTOR values f4a.vy=f4b.vy=f5a.vy=f5b.vy=f3a.vy=f3b.vy=-76; /*** preset variable values ****/ for(x=0;x<9;x++) timelimit[x]=250; //radians for car bounding spheres greencar.radius=100; whitecar.radius=99; redcar.radius=101; item.radius=40; bulletsphere.radius=40; missile.radius=30; mine_expl.radius=600; car_coll.radius=45; //ricochet variables x_speed=z_speed=20; //set item recharge rates timelimit[0]=700; timelimit[1]=1000; timelimit[2]=500; timelimit[3]=2000; timelimit[4]=300; timelimit[5]=300; timelimit[6]=1000; timelimit[7]=500; timelimit[8]=2000; //start with all items "on" for(x=0;x<9;x++) spot[x]=1; //start with some items p1items.upg=20; p1items.fire=3; p1items.hom=2; p1items.pow=2; //set game to title screen mode first debugmode=3; gamemode=1; } /**** MOVECAR ****/ void MoveCar( void ) { static int vel; static int accel=1; static int decel=1; static int rotanglespeed=(1<<12); static int maxvel=15; static int counter; static int turbo_count; if( (padd&PADstart) && (padd&PADselect) ) gameover=1; //exit game counter++; if(counter>100) counter=0; if(debugmode==3) { /**** turbo ****/ if( (padd&PADL1) && (p1items.tbo>0) ){ turbo_count++; if(turbo_count%13==0) { turbo.h--; turbo.y++; } if(turbo_count>494) { turbo_count=0; p1items.tbo--; if(p1items.tbo>0) { turbo.h=38; turbo.y=46; } } maxvel=30; } else maxvel=15; /**** rotation ****/ if(padd&PADLleft) rot-=rotanglespeed; if(padd&PADLright) rot+=rotanglespeed; //accelerate if(padd&PADRdown) vel+=accel; //decelerate if(padd&PADRleft) vel-=decel; //limit vel to maxvel if(vel>maxvel) vel=maxvel; if(vel<-maxvel) vel=-maxvel; if((!(padd&PADRdown)) && (!(padd&PADRleft)) && (!(padd&PADRright)) ) { if(vel>0) { if(counter%5==0) vel-=decel; } if(vel<0) { if(counter%5==0) vel+=accel; } } //rotation of cars if (rot < 0) rot += (360<<12); // add 360 degrees else if (rot > (360<<12)) rot -= (360<<12); // subtract 360 degrees else if (rot == (360<<12) ) //if the rotation angle is exactly 360 deg. rot = (0<<12); if( truck[0].vector.vy<(-4096) ) // add 4096 (ONE) truck[0].vector.vy+=4096; if( truck[0].vector.vy>4096 ) //subtract 4096 (ONE) truck[0].vector.vy-=4096; //assign vector value according to rot value truck[0].vector.vy=( (((rot>>12)*4096)/360)-1024 ); //move car in the direction it faces truck[0].coord.coord.t[0]+=((vel*SIN[rot>>12])>>12); truck[0].coord.coord.t[2]+=((vel*COS[rot>>12])>>12); } } /**** DISPLAYTEXT ****/ void DisplayText( void ) { FntPrint("\n\n\t\t~c990Sandstorm\n\n\n\n\n\n\n\n\n\n\t\t~c0901P Challenge"); FntPrint("\n\n\t\tDifficulty: ~c999"); if(level==0) FntPrint("[Easy]"); else if(level==1) FntPrint("[Normal]"); else FntPrint("[Hard]"); FntPrint("\n\n\t\t~c090Exit"); FntPrint("\n\n\n\n\n\n\n\t~c999Created by: Omar Metwally"); if((padd&PADselect) && (padd&PADstart) ) gameover=1; } //end DISPLAYTEXT /**** MENUSYSTEM ****/ void MenuSystem( void ) { static int count; static int diff_count; if(padd&PADLup) count--; if(count<-COUNT_GAP) count=0; if(padd&PADLdown) count++; if(count>COUNT_GAP) count=0; //reset if pad is not being pressed if(!(padd&PADLup)) { if(!(padd&PADLdown)) count=0; } //move if player presses UP if(count==-1 || count==-COUNT_GAP) { switch(dot.y) { case -1: { dot.y=-18; break; } case 14: { dot.y=-1; break; } } } //move cursor if player presses DOWN if(count==1 || count==COUNT_GAP) { switch(dot.y) { case -18: { dot.y=-1; break; } case -1: { dot.y=14; break; } } } /**** change difficulty level ****/ //diff_count smooths level change. if(dot.y==-1) { if(padd&PADLleft) { if(diff_count==2) diff_count=-1; } else if(padd&PADLright) { if(diff_count==2) diff_count=1; } else diff_count=2; } if(diff_count==-1) { level--; diff_count=0; } if(diff_count==1) { level++; diff_count=0; } //limit range of level variable if(level<0) level=0; if(level>2) level=2; /**** select options ****/ //check only if padd is pressed to save CPU time if( (padd&PADRdown) || (padd&PADRright) ) { switch(dot.y) { case -18: { gamemode=2; PlaySound(); break; } //1-player challenge //case -1: {gamemode=3; break; } //difficulty level change case 14: {gameover=1; break; } //end game } //end switch-case } //end if statement } //end MENUSYSTEM /**** FADE ****/ void Fade( void ) { static int destroyed; static int fade_count; static int wait; //pause if someone is destroyed if(p1destroyed==1) { pause=1; destroyed=1; } if(cpu1destroyed==1 && cpu2destroyed==1) {pause=1; destroyed=2; } //if anyone is destroyed fade screen to black if(destroyed>0) { fade_count++; if(fade_count>255) fade_count=0; if(blank.r<248) blank.r+=8; else blank.r=255; if(blank.r==8) StopSound(); //stop BGM if(blank.r>255) blank.r=255; blank.g=blank.b=blank.r; } //if screen is totally blank display message if(blank.r==255) { switch(destroyed) { case 1: { FntPrint("\n\n\n\n\n\n\n\n\n\n\t\t~c090Game Over\n\n\t\t~c999Press [Start]"); break; } case 2: { FntPrint("\n\n\n\n\n\n\n\n\n\n\t\t~c900You win.\n\n\t\t~c999Press [Start]"); break; } } //end switch-case if(padd&PADstart) { destroyed=0; blank.r=blank.g=blank.b=0; fade_count=0; wait=0; if(p1destroyed==1) wincount=0; else wincount++; pause=0; p1destroyed=0; cpu1destroyed=0; cpu2destroyed=0; //initialise GsBOXFs for energy bars and lens flare elements InitBox( &le1, (1<<30), -35, -35, 30, 30*240/320, 255, 255, 180 ); InitBox( &le2, (1<<30), 0, 0, 20, 20*240/320, 255, 255, 180 ); InitBox( &le3, (1<<30), 25, 25, 10, 10*240/320, 255, 255, 180 ); InitBox( &turbo, (1<<30), 0, 0, 11, 0, 8, 8, 240 ); InitBox( &life, (1<<30), -147, 66, 80, 16, 240, 0, 0 ); InitBox( &cpulife1, (0<<30), 0, 0, 40, 8, 0, 240, 0 ); InitBox( &cpulife2, (0<<30), 0, 0, 40, 8, 0, 240, 0 ); InitPos(); gamemode=1; //back to title screen printf("\n\ngame mode=%d\n",gamemode); } } //end if(blank.r==255) }