/*LANDER WRITTEN USING CODE WARRIOR 2 COPY WRITE PETER BLACK 11.6.98 E MAIL ME pete.black@eidosnet.co.uk */ #include #include <__rts_info_t__.h> #include "padread.h" #include "my_maths.h" #include "data.h" //MACROS #define LANDER1_ADDR 0x80090000 #define LANDER2_ADDR 0x80091000 #define LANDER3_ADDR 0x80092000 #define LANDER4_ADDR 0x80093000 #define LANDER5_ADDR 0x80094000 #define BGTEXTURES 0x80098000 #define VH_ADDR 0x800a1000 #define VB_ADDR 0x800a3000 //code address 0x800ab000 #define OT_LENGTH 1 #define MVOL 127 #define INSTRUCTIONS 0 #define INTRO 1 #define GAME_ON 2 #define GAME_END 3 #define CRASH 4 //////////////////////////////////////////////////////////////////////// //GLOBAL VARIABLES //OT GsOT WorldOT[2]; GsOT_TAG OTTags[2][1<2000) { game=INTRO; } } } while(game==INTRO) { InitGameVars(); while(game==INTRO) { ClearOT(); ReadIntroData(); CollisionCheck(); Landed(); HitGround(); MoveShip(); DrawBackground(); DrawShip(); DrawSky(); DrawOT(); Sound(); SoundTrack(); FntPrint("\n Push Start fuel %d",fuel); FntFlush(-1); while(PadOneStart==1) { //wait for button release game=GAME_ON; } } } while(game==GAME_ON) { InitGameVars(); while(game==GAME_ON) { ClearOT(); ControllerRead(); CollisionCheck(); Landed(); HitGround(); MoveShip(); DrawBackground(); DrawShip(); DrawSky(); DrawOT(); Sound(); SoundTrack(); FntPrint("\n fuel %d",fuel); FntFlush(-1); } } while(game==CRASH) { int count=0; SetUpCrashSprites(); while(game==CRASH) { ClearOT(); DrawBackground(); DrawCrashBits(); DrawSky(); DrawOT(); Sound(); FntPrint("\n fuel %d",fuel); FntPrint("\n\n\n\n\n\n your score %d",(vpos_x/1000)); FntFlush(-1); while((PadOneStart==1)||((count++)==400)) { //wait for button release game=INSTRUCTIONS; } } } while(game==GAME_END) { ClearOT(); CollisionCheck(); Landed(); HitGround(); DrawBackground(); DrawShip(); DrawSky(); DrawOT(); Sound(); SoundTrack(); FntPrint("\n WELL DONE "); FntPrint("\n\n\n\n press start"); FntFlush(-1); while(PadOneStart==1) { game=INTRO; } } } } ///////////////////////////////////////////////////////////////////// //FUNCTIONS // ///////////////////////////////////////////////////////////////////// //PRINT INSTRUCTIONS // static void DrawInstructions() { FntPrint("\n LANDER "); FntPrint("\n BY PETER BLACK "); FntPrint("\n\n lander is a gentle game "); FntPrint("\n no aliens to shoot just"); FntPrint("\n see how far you can get "); FntPrint("\n take great care lander is fragile "); FntPrint("\n refuel at active landing pads "); FntPrint("\n refueling will activate next pad"); FntPrint("\n don't crash "); FntPrint("\n and don't run out of fuel "); FntPrint("\n use pad or analog pad"); FntPrint("\n letf/right D pad or left stick"); FntPrint("\n thrust cross or right stick"); FntPrint("\n push start "); FntFlush(-1); } ////////////////////////////////////////////////////////////////////// //INITIALISE GAME VAIABLES // void InitGameVars() { int i; SetUpBG_cells(); BG_x=0,BG_y=369000; vpos_x=144000,vpos_y=514000; vector_mod=0,vector_ang=0; momemtum_x=0,momemtum_y=0; fuel=0; data_count=0; duration=0; for(i=0;i<14;i++) { base_fuel[i]=400; } for(i=0;i<9;i++) { voice[i]=-1; } ClearOT(); DrawOT(); ClearOT(); DrawOT(); InitSound(); } ///////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// // CRASH // static void SetUpCrashSprites() { int pos_x; int pos_y; int i; GsSPRITE *sp; RECT rect; u_short tpage; u_char ix,iy; // pos_x=((vpos_x)-(BG_x))/1000; pos_y=((vpos_y)-(BG_y))/1000; vector_mod=0; rect.x=(pos_x-13); rect.y=(pos_y-13); rect.w=26; rect.h=26; MoveImage(&rect,704,0); DrawSync(0); tpage=GetTPage(2,0,704,0); ix=0; iy=0; for(i=0,sp=sprt+21;i<170;i++,sp++) { sp->attribute=(1<<25); sp->x=0; sp->y=0; sp->w=2; sp->h=2; sp->tpage=tpage; sp->u=ix; sp->v=iy; sp->cx=0; sp->cy=0; sp->r=sp->g=sp->b=128; sp->mx=1; sp->my=1; sp->scalex=ONE; sp->scaley=ONE; sp->rotate=0; crash_bits_x[i]=(pos_x*1000)+(ix*1000)-(13000); crash_bits_y[i]=(pos_y*1000)+(iy*1000)-(13000); crash_bits_dx[i]=(momemtum_x*2)+((rand()%4)-2); crash_bits_dy[i]=(momemtum_y*2)+((rand()%4)-2); iy+=2; if(iy>26) { iy=0; ix+=2; } } } ////////////////////////////////////////////////////////////////// // DRAW CRASH BITS // static void DrawCrashBits() { GsSPRITE *sp; RECT rect; u_long check; int chec; int i,j; sp=sprt+21; for(i=0;i<170;i++,sp++) { //effect of gravity on crash bits crash_bits_dy[i]+=2; rect.x=(crash_bits_x[i]/1000)+(crash_bits_dx[i]/1000); rect.y=(crash_bits_y[i]/1000)+(crash_bits_dy[i]/1000); rect.w=1; rect.h=1; StoreImage(&rect,&check); DrawSync(0); chec=check; chec=(chec)>>16; if ((chec==9)||(chec==208)||(chec==5816)||(chec==1023)) { crash_bits_dx[i]=((rand()%crash_bits_dx[i])*SgnFunc(crash_bits_dx[i]))*-1; crash_bits_dy[i]=((rand()%crash_bits_dy[i])*SgnFunc(crash_bits_dy[i]))*-1; for(j=1;j<2;j++) { if((j==(i/20))&&(voice[j]==-1)) { voice[j]=SsUtKeyOn(vabID,1,0,(10+(rand()%20)),0,MVOL,MVOL); } } } crash_bits_x[i]+=crash_bits_dx[i]; crash_bits_y[i]+=crash_bits_dy[i]; sp->x=crash_bits_x[i]/1000; sp->y=crash_bits_y[i]/1000; GsSortFastSprite(sp,&WorldOT[ActiveBuff],0); } } //////////////////////////////////////////////////////////////// // READ INTRO DATA vector_mod & vector_ang // static void ReadIntroData() { static int dur [30]={0,550,50,50,15,200,200,90,199,50,90,45,45,80,520, 140,10,150,5,100,50,300,150,150,290,30,10,200,100000}; static int v_mod [30]={0,0,40,40,40,30,0,20,0,20,70,20,50,20,0 ,50,30,30,0,20,0,0,40,0,20,70,0,30,30,0}; static int delta_v_ang [30]={0,0,0,0,3,0,0,-1,0,0,0,2,-1,0,0, 0,3,0,3,0,-1,0,0,0,0,0,0,2,0,0}; if(duration==0) { data_count++; duration=dur[data_count]; } vector_mod=v_mod[data_count]; vector_ang+=delta_v_ang[data_count]; if(vector_ang>360) { vector_ang-=360; } if(vector_ang<0) { vector_ang+=360; } duration--; } ///////////////////////////////////////////////////////////////// // LANDED ? // static void Landed() { int ix[13]={4,12,16,24,29,36,40,42,50,55,58,59,62}; int iy[13]={16,17,12,17,12,16,13,18,12,17,10,14,16}; int base_pos[13]={128000,384000,512000,768000,928000,1152000,1280000, 1344000,1600000,1760000,1856000,1888000,1984000}; int i; // one foot down if((col_chec[0]==2)&&(vector_ang<18)&&(vector_ang>0)&&(momemtum_x>-50)&&(momemtum_x<50)) { vector_ang-=1; } if((col_chec[1]==2)&&(vector_ang>342)&&(vector_ang<360)&&(momemtum_x>-50)&&(momemtum_x<50)) { vector_ang+=1; } if(((col_chec[0]==2)||(col_chec[1]==2))&&(vector_ang>17)&&(vector_ang<343)) { game=CRASH; } //two feet down if((col_chec[0]==2)&&(col_chec[1]==2)) { //crash landing if(momemtum_y>125) { if(game==GAME_ON) { game=CRASH; } } for(i=0;i<13;i++) { if((vpos_x>base_pos[i])&&(vpos_x<(base_pos[i]+32000))&&(game!=CRASH)) { momemtum_x=0; if(vector_mod<30){ momemtum_y=-2; } if(bg_cell[ix[i]][iy[i]]==20){ fuel+=((base_fuel[i]!=0)*100); base_fuel[i]-=(base_fuel[i]!=0); } if(base_fuel[i]==0) { bg_cell[ix[i]][iy[i]]=18; if(i<12) { bg_cell[ix[i+1]][iy[i+1]]=20; } } } } if((vpos_x>1984000)&&(vpos_x<2016000)&&(game==GAME_ON)) { game=GAME_END; } } } ///////////////////////////////////////////////////////////////// //CRASHED INTO GROUND // static void HitGround() { int i; for (i=0;i<12;i++) { if(col_chec[i]==1) { game=CRASH; } } } //////////////////////////////////////////////////////////////// //CLEAR OT // static void ClearOT() { ActiveBuff=GsGetActiveBuff(); GsSetWorkBase((PACKET*)GpuPacketArea[ActiveBuff]); GsClearOt(0,0,&WorldOT[ActiveBuff]); } ///////////////////////////////////////////////////////////////// //DRAW OT SWAP DISPLAY BUFFERS // static void DrawOT() { DrawSync(0); VSync(0); GsSwapDispBuff(); GsSortClear(0,0,0,&WorldOT[ActiveBuff]); GsDrawOt(&WorldOT[ActiveBuff]); } /////////////////////////////////////////////////////////////// //DRAW SHIP // static void DrawShip() { static int lander_sprite; int pos_x,pos_y; if(vector_mod<10)lander_sprite=0; if((vector_mod>9)&(vector_mod<30)) { lander_sprite++; if(lander_sprite>2)lander_sprite=1; } if(vector_mod>29) { lander_sprite++; if(lander_sprite>4)lander_sprite=3; } pos_x=((vpos_x)-(BG_x))/1000; pos_y=((vpos_y)-(BG_y))/1000; sprt[lander_sprite].x=pos_x; sprt[lander_sprite].y=pos_y; sprt[lander_sprite].rotate=vector_ang*ONE; GsSortSprite(&sprt[lander_sprite],&WorldOT[ActiveBuff],0); } //////////////////////////////////////////////////////////////// //DRAW SKY /////////////////////////////////////////////////////////////////////////// static void DrawSky() { int iy; for(iy=0;iy<240;iy++) { line.x0=0; line.y0=iy; line.x1=320; line.y1=iy; line.r=((BG_y+(iy*1000))/8800); line.g=((BG_y+(iy*1000))/4000); line.b=((BG_y+(iy*1000))/2500); GsSortLine(&line,&WorldOT[ActiveBuff],0); } } /////////////////////////////////////////////////////////////////////////////////// //MOVE SHIP // static void MoveShip() { int gravity=2; int vector_compo_x,vector_compo_y; vector_compo_x=((vector_mod*(SinFunc(vector_ang)))/1000); vector_compo_y=((vector_mod*(CosFunc(vector_ang)))/1000); momemtum_x+=(vector_compo_x/8); momemtum_y-=(vector_compo_y/8); //GRAVITY momemtum_y+=gravity; //LIMIT SHIP MOVEMENT TO VISIBLE SCREEN if((vpos_x<25000)&&(momemtum_x<0)) { momemtum_x=0; } if((vpos_x>2048000)&&(momemtum_x>0)) { momemtum_x=0; } if((vpos_y<32000)&&(momemtum_y<0)) { momemtum_y=0; } //ADD MOMEMTUM TO VPOS vpos_x+=momemtum_x; vpos_y+=momemtum_y; //ADJUST FUEL fuel-=vector_mod; // OUT OF FUEL if(fuel<1) { vector_mod=0; fuel=0; } } ///////////////////////////////////////////////////////////// //READ CONTROLLER // static void ControllerRead() { //no controller? while (PadOnePresent==0) { ClearOT(); DrawOT(); FntPrint("\n\n\n\n\n\n\n\n NO CONTROLLER"); FntFlush(-1); } if(fuel>0) { if(PadOneType==65) { //STANARD PAD if(PadOneCross==1) { vector_mod+=((vector_mod<70)*4); } else { vector_mod-=7; if(vector_mod<0){ vector_mod=0; } } vector_ang+=((PadOneDpadRight==1)*2)-((PadOneDpadLeft==1)*2); if(vector_ang>360) { vector_ang-=360; } if(vector_ang<0) { vector_ang+=360; } } if(PadOneType==115) { //ANALOUGUE CONTROLLER vector_mod=((128-RStickOneUD)*(RStickOneUD<100))/2; vector_ang-=(LStickOneLR-128)/32; //CORRECT vector_ang if >360 or <0 if(vector_ang>360) { vector_ang-=360; } if(vector_ang<0) { vector_ang+=360; } } } } //////////////////////////////////////////////////////////////////////// //DRAW BACKGROUD //////////////////////////////////////////////////////////////////////// void DrawBackground() { //VARIABLES static int base=18,base_rotate; int pos_x,pos_y; int offset_x,offset_y; int cell_x,cell_y; int cell_pos_x,cell_pos_y; int ix,iy; int sprite; pos_x=((vpos_x)-(BG_x))/1000; pos_y=((vpos_y)-(BG_y))/1000; //ADJUST BACKGROUND BG_ if((pos_x<75)&&(vpos_x>50000))BG_x-=1000; if((pos_x>245)&&(vpos_x<2008000))BG_x+=1000; if((pos_y<30)&&(vpos_y>32000))BG_y-=1000; if((pos_y>170)&&(vpos_y<640000))BG_y+=1000; //BACKGROUND CELLS cell_x=AbsFunc(BG_x/32000); cell_y=AbsFunc(BG_y/32000); offset_x=(BG_x/1000)-(cell_x*32); offset_y=(BG_y/1000)-(cell_y*32); //ROTATE BACE CELLS if(base_rotate++>7) { base_rotate=0; base++; if(base>20) { base=18; } } //SEND CELLS TO OT for(ix=0,cell_pos_x=cell_x;ix<11;ix++,cell_pos_x++) { for(iy=0,cell_pos_y=cell_y;iy<9;iy++,cell_pos_y++) { sprite=bg_cell[cell_pos_x][cell_pos_y]; if(sprite==20) { sprite=base; if(sprite==18) { sprite=18; } } sprt[sprite].x=(ix*32)-offset_x; sprt[sprite].y=(iy*32)-offset_y; if(sprite>4) { GsSortFastSprite(&sprt[sprite],&WorldOT[ActiveBuff],0); } } } } //////////////////////////////////////////////////////////////// //COLLISION DETECTION // static void CollisionCheck() { int vector_col_mod[12]={17,17,16,7,9,10,11,11,10,9,7,16}; int vector_col_ang[12]={330,30,33,73,97,125,167,192,234,263,287,326}; int i,chec; int ang_x,ang_y; int pos_x=((vpos_x)-(BG_x))/1000; int pos_y=((vpos_y)-(BG_y))/1000; u_long check[14]; RECT rect; for(i=0;i<12;i++) { ang_x=(360-vector_ang)+vector_col_ang[i]; if(ang_x>360) { ang_x-=360; } ang_y=(360-vector_ang)+vector_col_ang[i]; if(ang_y>360) { ang_y-=360; } rect.x=((SinFunc(ang_x)*vector_col_mod[i])/1000)+pos_x; rect.y=((CosFunc(ang_y)*vector_col_mod[i])/1000)+pos_y; rect.w=rect.h=1; StoreImage(&rect,&check[i]); DrawSync(0); col_chec[i]=0; chec=(check[i]); chec=(chec)>>16; if((chec==9)||(chec==208)||(chec==5816)) { col_chec[i]=1;//hit land } if((chec==31)||(chec==1023)) { col_chec[i]=2;//hit base } } } //////////////////////////////////////////////////////////////// //SET UP SPRITES/ // static void init_prim() { u_int addr[21]={0x80090000,0x80091000,0x80092000,0x80093000,0x80094000, 0x80098000,0x80098000,0x80098000,0x80098000,0x80098000,0x80098000, 0x80098000,0x80098000,0x80098000,0x80098000,0x80098000,0x80098000, 0x80098000,0x80098000,0x80098000,0x80098000}; int tpel3[21]={704,722,740,758,776,832,832,832,832,832,832,832,832, 832,832,832,832,832,832,832,832}; int tpel4; u_char off_x[21]={0,18,36,54,8,0,0,0,0,0,0,0,32,32,32,32,32,32,0,32,32}; u_char off_y[21]={0,0,0,0,0,0,32,64,96,128,160,192,160,0,32,64,96,128,224,192,224}; GsSPRITE *sp; u_short tpage; RECT rect; u_char offx,offy; short tim_x,tim_y,tim_width,tim_height; int i; for(i=0,sp=sprt;i<21;i++,sp++) { GsGetTimInfo((u_long*)((addr[i])+4),&(lander_image[i])); tim_x=0; tim_y=0; if(i<5) { tim_width=18; tim_height=25; tpel4=256; } else { tim_width=32; tim_height=32; tpel4=0; } tpage=GetTPage(2,0,tpel3[i],tpel4); offx=off_x[i]; offy=off_y[i]; rect.x=lander_image[i].px; rect.y=lander_image[i].py; rect.w=lander_image[i].pw; rect.h=lander_image[i].ph; LoadImage(&rect,lander_image[i].pixel); DrawSync(0); sp->attribute=(1<<25); sp->x=tim_x; sp->y=tim_y; sp->w=tim_width; sp->h=tim_height; sp->tpage=tpage; sp->u=offx; sp->v=offy; sp->cx=0; sp->cy=0; sp->r=sp->g=sp->b=128; sp->mx=9; sp->my=10; sp->scalex=ONE; sp->scaley=ONE; sp->rotate=0; } } //////////////////////////////////////////////////////////////////// //SET UP BACKGROUND CELLS // static void SetUpBG_cells() { int x,y,c=0; for(x=0;x<65;x++) { for(y=0;y<20;y++) { bg_cell[x][y]=cell_data[c++]; } } } ///////////////////////////////////////////////////////////////////// // SsVabTransfer // static void VabTranfer() { // vab opening and transmission to sound buffer vabID=SsVabTransfer((u_char*)VH_ADDR,(u_char*)VB_ADDR,-1,1); if(vabID<0) { printf("SsVabTransfer failed (%d)\n",vabID); return; } } //////////////////////////////////////////////////////////////////// // INIT SOUND // static void InitSound() { SsSetMVol(MVOL,MVOL); SsUtAllKeyOff(0); voice[9]=SsUtKeyOn(vabID,0,0,10,0,0,0); voice[8]=SsUtKeyOn(vabID,0,0,20,0,0,0); } ////////////////////////////////////////////////////////////////// //SOUND // static void Sound() { //adjust thrust volume vol=vector_mod; SsUtSetVVol(voice[9],vol,vol); SsUtSetVVol(voice[8],vol,vol); } ////////////////////////////////////////////////////////////////////// //SOUND TRACK // static void SoundTrack() { wait--; if(wait<1) { SsUtKeyOn(vabID,2,0,(1+(rand()%15)),0,80,80); wait=200+(rand()%2000); } }