//-------------------------------------------------------------- // Playstation Psycheual (Psychon) //-------------------------------------------------------------- #include #include #include #include #include "pad.h" #define SOUNDS_VH 0x80090000 #define SOUNDS_VB 0x80091a20 #define BANNER_TIM 0x800adc10 #define BLITFORM_TIM 0x800b7c24 #define BOBS_TIM 0x800fdc38 #define CLEAR_TIM 0x800ffecc #define FALL_TIM 0x801032e0 #define FLAME_TIM 0x80106ef4 #define FONT_TIM 0x80107408 #define MAIN_TIM 0x8010ea44 #define NUMBERS_TIM 0x801104c0 #define PANEL_TIM 0x8011072c #define TITLE_TIM 0x80111640 #define WORLD_TIM 0x80116054 #define MAPS_DAT 0x8013b868 #define DEAD_TIM 0x8014f868 #define CONTROL_TIM 0x80153bfc #define TIME_TIM 0x8015a790 #define GLOBE_TIM 0x8015b1a4 #define INTRO_TIM 0x8015b280 #define SOUNDS2_VH 0x80180a94 #define SOUNDS2_VB 0x801824b4 #define EARTH_TIM 0x80192f14 #define CURSOR_TIM 0x80199bd0 #define SOUNDS3_VB 0x8019a2e4 #define SOUNDS3_VH 0x801ad324 #define OT_LEN 12 #define MAX_PACKETS 102400 #define MAX_ENEMIES 200 #define MAX_BSPLATS 256 #define SPACE 8 #define PISTOL 5 #define SHOTGUN 6 #define AUTOGUN 7 #define MACHINEGUN 8 #define AUTOPISTOL 9 //-------------------------------------------------------------- typedef struct { GsSPRITE sprite; GsSPRITE flame; GsIMAGE image; int x,y; int d,a,dir; int lx,ly; int mx,my; int score; int lives; int energy, shield; int ammo, keys; int damage, rounds; int panel, pon; int holdL1, holdSQ, holdTR; }Player; typedef struct { GsSPRITE sprite; int dx,dy; int x,y; int energy; }Enemy; typedef struct { GsGLINE line; int x,y; int ax,ay; }BSplat; u_long PADstatus=0; volatile u_char *bb0, *bb1; int nFired; int nTarget; int nEnemies; int nKilled; int nGlobes; int nMin, nSec, nSplit; int nBuffer; int bPlaying; int bRunning=1; int bComplete; int nVab; int nVab2; int nVab3; int nMapx; int nMapy; int nLevel; int nMap[4096]; int nGrid[3]; int nFont[91]={0,5,12,25,35,48,59,63,69,74,80,90,93,99,102,110,120,128,137,146,157,167,177,185,195,205,209,213,223,233,243,253,268,278,289,299,310,318,325,336,346,351,358,368,375,389, 0,11,20,31,41,50,59,70,79,95,104,113,121,126,133,139,147,158,165,174,184,194,203,212,219,228,238,243,249,258,263,278,288,298,307,317,324,332,339,348,357,369,378,386,393}; int nDoor[2]; char szScroll[230]="Welcome to Psychon. Created with the Net Yaroze tools and libraries. See www.netyaroze-europe.com for more information. Psychon code, graphics and sound by Ben James. Special thanks to Craig Smith for his design ideas."; char szNames[10][4]={"ELV", "EMA", "JON", "TRI", "POD", "XNA", "SAM", "C J", "ZIQ", "LBE"}; int nScore[10]={10000, 9000, 8000, 7000, 6000, 5000, 4000, 3000, 2000, 1000}; PACKET out_packet[2][MAX_PACKETS]; GsOT othWorld[2]; GsOT_TAG otWorld[2][1<-1) { if(player->energy>=0) GetInput(); else KillPlayer(); DrawPlayer(); if(player->rounds) FireGun(); } DrawPanel(0,256); player=&player2; if(player2.lives>-1) { if(player->energy>=0) GetInput(); else KillPlayer(); DrawPlayer(); if(player->rounds) FireGun(); } DrawPanel(200,272); DrawTime(); MoveEnemies(); OtherChecks(); DrawSplats(); DrawEnemies(); if(CheckDoors(nDoor[0])) { SsUtKeyOn(nVab2, 0,0, 48, 0, 128,128); nDoor[0]=0; } if(CheckDoors(nDoor[1])) nDoor[1]=0; GsDrawOt(&othWorld[nBuffer]); FntFlush(-1); DrawSync(0); lSync=VSync(0); GsSwapDispBuff(); GsSortClear(0,0,0,&othWorld[nBuffer]); nSplit--; if(nSplit<0) { nSplit=50; nSec--; } if(nSec<0) { nSec=59; nMin--; } if(nMin<0) bPlaying=0; if(!nStrobe) SsUtKeyOn(nVab3, 0,0, 36, 0, 70,70); nStrobe++; if(nStrobe>=160) nStrobe=0; } SsUtKeyOn(nVab, 0,0, 48, 0, 128,128); if(bComplete) { SmearClear(128,127,127,1,0,0); LevelClear(); SsUtKeyOn(nVab, 0,0, 48, 0, 128,128); SmearClear(127,127,128,1,1,0); nLevel++; } else { SmearClear(128,127,127,1,0,1); GameOver(); SmearClear(128,127,127,2,0,1); } } if(nLevel==11) Complete(); if(player1.lives>-1) { player=&player1; if(player->score>nScore[9]) EnterName(); } if(player2.lives>-1) { player=&player2; if(player->score>nScore[9]) EnterName(); } } SsVabClose(nVab); SsVabClose(nVab2); SsVabClose(nVab3); ClearImage(&rClear,0,0,0); ResetGraph(3); return 0; } //-------------------------------------------------------------- int ShowTitles(void) { int nSound=250; int nTimer=0; int nOff; int nCount; int nPlayer; int nNumPlayers=0; char szText[128]; RECT rClear={0,0,320,512}; RECT rArea={704,325,320,64}; RECT rPlanet={0,0,320,0}; RECT rControl={832,426,160,86}; GsSPRITE title; title.attribute=1<<25; title.w=256; title.h=37; title.mx=128; title.my=18; title.u=0; title.v=32; title.tpage=GetTPage(2, 0, 704, 288); nCount=360; ClearImage(&rClear, 0, 0, 0); rClear.h=256; LoadTIM(TITLE_TIM); LoadTIM(BANNER_TIM); LoadTIM(CONTROL_TIM); do { nBuffer=GsGetActiveBuff(); GsSetWorkBase((PACKET*)out_packet[nBuffer]); GsClearOt(0, 0, &othWorld[nBuffer]); rClear.y=nBuffer*256; ClearImage(&rClear, 0, 0, 0); if(nTimer==2000) { SsUtKeyOn(nVab, 0,0, 48, 0, 128,128); SmearClear(128,128,128,1,0,-1); nSound+=92; } else if(nTimer==3329) { SsUtKeyOn(nVab, 0,0, 48, 0, 128,128); SmearClear(128,128,128,1,0,1); nSound+=92; } if(nTimer<2000) { if(!nTimer) { title.r=127; title.g=127; title.b=127; SsUtKeyOn(nVab2, 1,0, 44, 0, 128,128); } MoveImage(&rArea, 0, (nBuffer*256)); if(nCount>=0) { title.scalex=ONE+(8*nCount); title.scaley=ONE+(8*nCount); title.rotate=ONE*nCount; title.x=160; title.y=32+(nCount/2); nCount-=10; } else if(title.r==127) { SsUtKeyOn(nVab, 1,0, 48, 0, 128,128); title.r=248; title.g=248; title.b=248; } else if(title.r>128) { title.r-=10; title.g-=10; title.b-=10; } else { nCount--; if(nCount<-50) nCount=-1; } if((nTimer<1000)&&(nTimer>100)) { strcpy(szText, "CONTROLS"); OutputString(szText, -1, GetCentre(szText), 70); MoveImage(&rControl, 80, 100+(nBuffer*256)); if(nCount<-10) { strcpy(szText, "Controller 1 START - 1 Player"); OutputString(szText, -1, GetCentre(szText) ,193); strcpy(szText, "Controller 2 START - 2 Players"); OutputString(szText, -1, GetCentre(szText) ,217); } } else if(nTimer>100) { nOff=16320-(nTimer*16); if(nOff<10) nOff=10; if(nTimer==1000) SsUtKeyOn(nVab2, 1,0, 44, 0, 128,128); strcpy(szText, "Today's Best Scores"); OutputString(szText, -1, GetCentre(szText), 70); for(nPlayer=1; nPlayer<=5; nPlayer++) { sprintf(szText, "%d", nPlayer); OutputString(szText, -1, nOff+0, 80+(nPlayer*23)); OutputString(szNames[nPlayer-1], -1, nOff+24, 80+(nPlayer*23)); sprintf(szText, "%5.5d", nScore[nPlayer-1]); OutputString(szText, -1, nOff+80, 80+(nPlayer*23)); } for(nPlayer=6; nPlayer<=10; nPlayer++) { sprintf(szText, "%d", nPlayer); OutputString(szText, -1, 190-nOff, 80+((nPlayer-5)*23)); OutputString(szNames[nPlayer-1], -1, 214-nOff, 80+((nPlayer-5)*23)); sprintf(szText, "%5.5d", nScore[nPlayer-1]); OutputString(szText, -1, 270-nOff, 80+((nPlayer-5)*23)); } } GsSortSprite(&title, &othWorld[nBuffer], 0); } else { nCount=nTimer-2000; if(nCount>200) nCount=200; rPlanet.y=240-nCount+(nBuffer*256); rPlanet.h=nCount; LoadImage(&rPlanet, (u_long *)WORLD_TIM+5); OutputString(szScroll, -1, 4400-(nTimer*2), 0); } nTimer++; if(nTimer>3330) nTimer=0; GsDrawOt(&othWorld[nBuffer]); DrawSync(0); VSync(0); GsSwapDispBuff(); GsSortClear(0,0,0,&othWorld[nBuffer]); nSound++; if(nSound>340) { SsUtKeyOn(nVab3, 2,0, 36, 0, 128,128); nSound=0; } PADstatus=PadRead(0); if(PADstatus & PADselect) bRunning=0; if(PADstatus & PADstart) nNumPlayers=1; PADstatus=PADstatus>>16; if(PADstatus & PADstart) nNumPlayers=2; } while(!nNumPlayers&&bRunning); return nNumPlayers; } //-------------------------------------------------------------- int LoadTIM(long addr) { RECT rect; GsIMAGE tim1; GsGetTimInfo((u_long *)(addr+4),&tim1); rect.x=tim1.px; rect.y=tim1.py; rect.w=tim1.pw; rect.h=tim1.ph; LoadImage(&rect,tim1.pixel); if((tim1.pmode>>3)&0x01) { rect.x=tim1.cx; rect.y=tim1.cy; rect.w=tim1.cw; rect.h=tim1.ch; LoadImage(&rect,tim1.clut); } DrawSync(0); return(0); } //-------------------------------------------------------------- void Initialise() { SetVideoMode(MODE_PAL); GsInitGraph(320, 240, GsINTER|GsOFSGPU, 0, 0); GsDefDispBuff(0, 0, 0, 256); othWorld[0].length=OT_LEN; othWorld[1].length=OT_LEN; othWorld[0].org=otWorld[0]; othWorld[1].org=otWorld[1]; GsClearOt(0,0,&othWorld[0]); GsClearOt(0,0,&othWorld[1]); LoadTIM(FONT_TIM); LoadTIM(NUMBERS_TIM); GsGetTimInfo((unsigned long *)MAIN_TIM+4, &player1.image); GsGetTimInfo((unsigned long *)MAIN_TIM+4, &player2.image); player1.sprite.attribute= 1 << 25; player1.sprite.w=26; player1.sprite.h=26; player1.sprite.r=128; player1.sprite.g=128; player1.sprite.b=128; player1.sprite.scalex=ONE; player1.sprite.scaley=ONE; player1.sprite.mx=13; player1.sprite.my=13; player1.sprite.u=0; player2.sprite.attribute= 1 << 25; player2.sprite.w=26; player2.sprite.h=26; player2.sprite.r=128; player2.sprite.g=128; player2.sprite.b=128; player2.sprite.scalex=ONE; player2.sprite.scaley=ONE; player2.sprite.mx=13; player2.sprite.my=13; player2.sprite.u=0; player1.flame.attribute=(1<<25); player1.flame.w=16; player1.flame.h=40; player1.flame.mx=8; player1.flame.my=40; player1.flame.tpage=GetTPage(2, 0, 768, 0); player2.flame.attribute=(1<<25); player2.flame.w=16; player2.flame.h=40; player2.flame.mx=8; player2.flame.my=40; player2.flame.tpage=GetTPage(2, 0, 768, 0); nVab=SsVabTransfer((u_char *)SOUNDS_VH, (u_char *)SOUNDS_VB, -1, 1); nVab2=SsVabTransfer((u_char *)SOUNDS2_VH, (u_char *)SOUNDS2_VB, -1, 1); nVab3=SsVabTransfer((u_char *)SOUNDS3_VH, (u_char *)SOUNDS3_VB, -1, 1); } //-------------------------------------------------------------- void NewGame(int numplayers) { RECT rPanel={704,256,120,16}; LoadTIM(BLITFORM_TIM); LoadTIM(MAIN_TIM); LoadTIM(FLAME_TIM); LoadTIM(BOBS_TIM); LoadTIM(FALL_TIM); LoadTIM(PANEL_TIM); MoveImage(&rPanel, 704, 272); nLevel=1; nMin=60; nSec=0; nSplit=50; player1.a=0; player1.keys=20; player1.ammo=500; player1.damage=PISTOL; player1.energy=100; player1.score=0; player1.pon=1; player1.flame.r=128; player1.flame.g=128; player1.flame.b=128; player1.flame.scalex=ONE; player1.flame.scaley=ONE; player2.a=0; player2.keys=20; player2.ammo=500; player2.damage=PISTOL; player2.energy=100; player2.score=0; player2.flame.r=128; player2.flame.g=128; player2.flame.b=128; player2.flame.scalex=ONE; player2.flame.scaley=ONE; player1.lives=3; if(numplayers==2) { player2.lives=3; player2.pon=1; } else { player2.lives=-1; player2.pon=0; } } //-------------------------------------------------------------- void NewLevel() { int nCount; int nEnemy=0; unsigned char * lSource; static int x[10]={32,32,32,32,32,32,32,32,16,0}; static int y[10]={-16,-16,0,0,0,0,0,-16,-32,-32}; LoadTIM(TIME_TIM); LoadTIM(GLOBE_TIM); nGlobes=0; nFired=0; nTarget=0; nEnemies=0; nKilled=0; for(nCount=0; nCount>16; otherplayer=&player1; } else otherplayer=&player2; if(PADstatus & PADLup) player->y-=2; else if(PADstatus & PADLdown) player->y+=2; GetGrid(player->x, player->y, 12, otherplayer); player->my=player->y; if(IsObjectOverWall(player->x, player->y, 12, 1)) { if(player->yly) { if(!nGrid[0]) player->x-=2; if(!nGrid[1]) player->x+=2; } else { if(!nGrid[2]) player->x-=2; if(!nGrid[3]) player->x+=2; } player->y=player->ly; } if((Difference(player->y,otherplayer->y)>=240)&&(otherplayer->lives>-1)) player->y=player->ly; if(otherplayer->lives>-1) { if((Difference(player->x, otherplayer->x)<22)&&(Difference(player->y, otherplayer->y)<22)) //if(Collision(player->x, player->y, otherplayer->x, otherplayer->y, 20)) player->y=player->ly; } if(PADstatus & PADLleft) player->x-=2; else if(PADstatus & PADLright) player->x+=2; GetGrid(player->x, player->y, 12, otherplayer); player->mx=player->x; if(IsObjectOverWall(player->x, player->y, 12, 1)) { if(player->xlx) { if(!nGrid[0]) player->y-=2; if(!nGrid[2]) player->y+=2; } else { if(!nGrid[1]) player->y-=2; if(!nGrid[3]) player->y+=2; } player->x=player->lx; } if((Difference(player->x,otherplayer->x)>=320)&&(otherplayer->lives>-1)) player->x=player->lx; if(otherplayer->lives>-1) { if((Difference(player->x, otherplayer->x)<22)&&(Difference(player->y, otherplayer->y)<22)) //if(Collision(player->x, player->y, otherplayer->x, otherplayer->y, 20)) player->x=player->lx; } if(Difference(player->x, player->lx)>2) { if(player->x>player->lx) player->x=player->lx+2; else player->x=player->lx-2; } if(Difference(player->y, player->ly)>2) { if(player->y>player->ly) player->y=player->ly+2; else player->y=player->ly-2; } CheckPickups(player->x+4, player->y+4); CheckPickups(player->x+4, player->y-4); CheckPickups(player->x-4, player->y+4); CheckPickups(player->x-4, player->y-4); //if(PADstatus & PADL1) //bComplete=1; if(PADstatus & PADRup) { if(!player->holdTR) player->pon=!player->pon; player->holdTR=1; } else player->holdTR=0; if(PADstatus & PADselect) bPlaying=0; if(PADstatus & PADRdown) { if((!player->rounds)&&(!player->holdSQ)) StartFiring(); player->holdSQ=1; } else player->holdSQ=0; if(!player->shield) { if(IsObjectOverEnemy(player->x, player->y, 12)) { player->energy--; player->sprite.r=255; player->sprite.g=255; player->sprite.b=255; player->x=player->lx; player->y=player->ly; } } } //-------------------------------------------------------------- void GetGrid(int x, int y, int r, Player* otherplayer) { int nAddr; nAddr=((x-r)>>4)+(((y-r)<<2)&0xffc0); if((nMap[nAddr]>=197)&&(nMap[nAddr]<=390)) nGrid[0]=1; else nGrid[0]=0; nAddr=((x+r)>>4)+(((y-r)<<2)&0xffc0); if((nMap[nAddr]>=197)&&(nMap[nAddr]<=390)) nGrid[1]=1; else nGrid[1]=0; nAddr=((x+r)>>4)+(((y+r)<<2)&0xffc0); if((nMap[nAddr]>=197)&&(nMap[nAddr]<=390)) nGrid[3]=1; else nGrid[3]=0; nAddr=((x-r)>>4)+(((y+r)<<2)&0xffc0); if((nMap[nAddr]>=197)&&(nMap[nAddr]<=390)) nGrid[2]=1; else nGrid[2]=0; if(otherplayer->lives>-1) { if((Difference(x-r, otherplayer->x)<12)&&(Difference(y-r, otherplayer->y)<12)) nGrid[0]=1; if((Difference(x+r, otherplayer->x)<12)&&(Difference(y-r, otherplayer->y)<12)) nGrid[1]=1; if((Difference(x+r, otherplayer->x)<12)&&(Difference(y+r, otherplayer->y)<12)) nGrid[3]=1; if((Difference(x-r, otherplayer->x)<12)&&(Difference(y+r, otherplayer->y)<12)) nGrid[2]=1; } } //-------------------------------------------------------------- void KillPlayer() { int nCount; if(player->energy==-1) { SsUtKeyOn(nVab2, 6,0, 48, 0, 128,128); player->lives--; if(player->lives==-1) player->pon=0; } player->energy--; nCount=50+player->energy; if(nCount) { player->sprite.scalex=ONE-(81*(-player->energy)); player->sprite.scaley=ONE-(81*(-player->energy)); player->sprite.rotate=nCount*20*ONE; } else { player->energy=100; player->sprite.scalex=ONE; player->sprite.scaley=ONE; player->sprite.rotate=0; player->shield=50; } } //-------------------------------------------------------------- int Collision(long cx, long cy, long x, long y, long r) { if((x>cx-r && xcy-r && y-1) { if(((enemy[nCount].sprite.x>-13)&&(enemy[nCount].sprite.x<333))&& ((enemy[nCount].sprite.y>-13)&&(enemy[nCount].sprite.y<253))) { lx=enemy[nCount].x; ly=enemy[nCount].y; switch(enemy[nCount].sprite.rotate) { case 0: enemy[nCount].y-=2; break; case 45*ONE: enemy[nCount].x+=2; enemy[nCount].y-=2; break; case 90*ONE: enemy[nCount].x+=2; break; case 135*ONE: enemy[nCount].x+=2; enemy[nCount].y+=2; break; case 180*ONE: enemy[nCount].y+=2; break; case 225*ONE: enemy[nCount].x-=2; enemy[nCount].y+=2; break; case 270*ONE: enemy[nCount].x-=2; break; case 315*ONE: enemy[nCount].x-=2; enemy[nCount].y-=2; break; default: break; } if((IsObjectOverEnemy(enemy[nCount].x, enemy[nCount].y, 12))||(IsObjectOverWall(enemy[nCount].x, enemy[nCount].y, 12, 0))) { enemy[nCount].x=lx; enemy[nCount].y=ly; enemy[nCount].sprite.rotate+=(45*ONE); if(enemy[nCount].sprite.rotate>=360*ONE) enemy[nCount].sprite.rotate=0; } else { if(rand()>31500) { enemy[nCount].sprite.rotate-=(45*ONE); if(enemy[nCount].sprite.rotate<0) enemy[nCount].sprite.rotate=315*ONE; } if(player1.lives>-1) { if(Collision(enemy[nCount].x, enemy[nCount].y, player1.x, player1.y, 20)) { enemy[nCount].x=lx; enemy[nCount].y=ly; enemy[nCount].sprite.rotate+=(45*ONE); if(enemy[nCount].sprite.rotate>=360*ONE) enemy[nCount].sprite.rotate=0; } } if(player2.lives>-1) { if(Collision(enemy[nCount].x, enemy[nCount].y, player2.x, player2.y, 20)) { enemy[nCount].x=lx; enemy[nCount].y=ly; enemy[nCount].sprite.rotate+=(45*ONE); if(enemy[nCount].sprite.rotate>=360*ONE) enemy[nCount].sprite.rotate=0; } } } } } else if((enemy[nCount].dx)||(enemy[nCount].dy)) { enemy[nCount].x+=enemy[nCount].dx; if(IsObjectOverWall(enemy[nCount].x, enemy[nCount].y, 12, 0)) { enemy[nCount].x-=enemy[nCount].dx; enemy[nCount].dx=0; } enemy[nCount].y+=enemy[nCount].dy; if(IsObjectOverWall(enemy[nCount].x, enemy[nCount].y, 12, 0)) { enemy[nCount].y-=enemy[nCount].dy; enemy[nCount].dy=0; } if(enemy[nCount].dx>0) enemy[nCount].dx--; else if(enemy[nCount].dx<0) enemy[nCount].dx++; if(enemy[nCount].dy>0) enemy[nCount].dy--; else if(enemy[nCount].dy<0) enemy[nCount].dy++; } } } //-------------------------------------------------------------- void CalcScreen() { int x=0,y=0,c=0; if(player1.lives>-1) { x=player1.x; y=player1.y; c=1; } if(player2.lives>-1) { x+=player2.x; y+=player2.y; c++; } nMapx=(x/c)-160; nMapy=(y/c)-120; if(nMapx<0) nMapx=0; else if(nMapx>(44*16)) nMapx=(44*16); if(nMapy<0) nMapy=0; else if(nMapy>(49*16)) nMapy=(49*16); } //-------------------------------------------------------------- void DrawMap() { int nX; int nY; int nBlock; static int nAnim=0; RECT rBlock={0,0,320,240}; rBlock.y=nBuffer*256; if((player1.lives<0)||(player2.lives<0)) LoadImage(&rBlock, (u_long *)WORLD_TIM+5); rBlock.w=16; rBlock.h=16; nAnim++; if(nAnim>=16) nAnim=0; for(nY=0; nY<16; nY++) { for(nX=0; nX<21; nX++) { nBlock=nMap[(nX+(nMapx/16))+((nY+(nMapy/16))*64)]; if(nBlock) { nBlock--; if((nBlock>=286)&&(nBlock<510)) nBlock+=(nAnim/2); rBlock.x=336+((nBlock%20)*16); rBlock.y=(nBlock/20)*16; MoveImage(&rBlock, nX*16-(nMapx%16), (nBuffer*256)+nY*16-(nMapy%16)); } else if((player1.lives>-1)&&(player2.lives>-1)) { rBlock.x=nX*16-(nMapx%16); rBlock.y=(nBuffer*256)+nY*16-(nMapy%16); ClearImage(&rBlock, 0,0,0); } } } } //-------------------------------------------------------------- void DrawPlayer() { player->sprite.u=0; player->sprite.v=player->a*player->sprite.h; player->sprite.x=player->x-nMapx; player->sprite.y=player->y-nMapy; player->sprite.tpage=GetTPage(2, 0, 704, 0); if((player->mx==player->lx)&&(player->myly)) player->sprite.rotate=0; else if((player->mx>player->lx)&&(player->myly)) player->sprite.rotate=45*ONE; else if((player->mx>player->lx)&&(player->my==player->ly)) player->sprite.rotate=90*ONE; else if((player->mx>player->lx)&&(player->my>player->ly)) player->sprite.rotate=135*ONE; else if((player->mx==player->lx)&&(player->my>player->ly)) player->sprite.rotate=180*ONE; else if((player->mxlx)&&(player->my>player->ly)) player->sprite.rotate=225*ONE; else if((player->mxlx)&&(player->my==player->ly)) player->sprite.rotate=270*ONE; else if((player->mxlx)&&(player->myly)) player->sprite.rotate=315*ONE; if(!(player->shield&1)) GsSortSprite(&player->sprite, &othWorld[nBuffer], 0); if((player->lx!=player->x)||(player->ly!=player->y)) player->a+=player->dir; if(player->a>=4) player->dir=-1; else if(player->a<=0) player->dir=1; if(player->shield) player->shield--; player->lx=player->x; player->ly=player->y; player->sprite.r=128; player->sprite.g=128; player->sprite.b=128; } //-------------------------------------------------------------- void DrawEnemies() { int nPri; int nCount=0; static int nAnim=0; for(nCount=0; nCount-9) { enemy[nCount].sprite.x=enemy[nCount].x-nMapx; enemy[nCount].sprite.y=enemy[nCount].y-nMapy; if(((enemy[nCount].sprite.x>-13)&&(enemy[nCount].sprite.x<333))&& ((enemy[nCount].sprite.y>-13)&&(enemy[nCount].sprite.y<253))) { if(enemy[nCount].energy>-1) { enemy[nCount].sprite.v=23*nAnim; enemy[nCount].sprite.tpage=GetTPage(2, 0, 832, 0); nPri=1; } else { enemy[nCount].sprite.mx=16; enemy[nCount].sprite.my=15; enemy[nCount].sprite.w=32; enemy[nCount].sprite.h=30; enemy[nCount].sprite.v=30*(-(enemy[nCount].energy+1)); enemy[nCount].sprite.tpage=GetTPage(2, 0, 896, 0); if(enemy[nCount].energy>-8) { if(nAnim&1) enemy[nCount].energy--; enemy[nCount].sprite.rotate+=ONE*11; } nPri=2; } GsSortSprite(&enemy[nCount].sprite, &othWorld[nBuffer], nPri); enemy[nCount].sprite.r=128; enemy[nCount].sprite.g=128; enemy[nCount].sprite.b=128; } } else nCount=MAX_ENEMIES; } nAnim++; if(nAnim>=8) nAnim=0; } //-------------------------------------------------------------- void DrawPanel(int x, int y) { GsSPRITE panel; //RECT rPanel={704,0,120,16}; panel.attribute=1<<25; panel.w=120; panel.h=16; panel.u=0; panel.v=y-256; panel.r=128; panel.g=128; panel.b=128; panel.tpage=GetTPage(2,0,704,y); if((player->pon)&&(player->panel<16)) player->panel++; else if((!player->pon)&&(player->panel>0)) player->panel--; if(player->panel) { OutputNum(player->ammo, 4, 704+18,y+3); OutputNum(player->keys, 3, 704+48,y+3); OutputNum(player->lives, 2, 704+73,y+3); OutputNum(player->energy, 3, 704+93,y+3); panel.y=player->panel-16; panel.x=x; GsSortFastSprite(&panel, &othWorld[nBuffer], 0); //rPanel.y=y+(16-player->panel); //rPanel.h=player->panel; //MoveImage(&rPanel, x, nBuffer*256); } } //-------------------------------------------------------------- void DrawTime() { int y; //RECT rArea={832,256,80,16}; GsSPRITE panel; panel.attribute=1<<25; panel.w=80; panel.h=16; panel.u=0; panel.v=0; panel.r=128; panel.g=128; panel.b=128; panel.tpage=GetTPage(2,0,832,256); if(player1.panel>player2.panel) y=player1.panel; else y=player2.panel; if(y) { OutputNum(nMin, 2, 832+29,259); OutputNum(nSec, 2, 832+43,259); //rArea.y=272-y; //rArea.h=y; //MoveImage(&rArea, 120, nBuffer*256); panel.x=120; panel.y=y-16; GsSortFastSprite(&panel, &othWorld[nBuffer], 0); } } //-------------------------------------------------------------- void StartFiring() { if(!player->ammo) { SsUtKeyOn(nVab2, 4,0, 48, 0, 128,128); return; } switch(player->damage) { case PISTOL: SsUtKeyOn(nVab, 4,0, 48, 0, 128,128); player->rounds=2; break; case SHOTGUN: SsUtKeyOn(nVab2, 2,0, 48, 0, 128,128); player->rounds=4; break; case AUTOGUN: player->rounds=10; SsUtKeyOn(nVab, 2,0, 48, 0, 128,128); break; case MACHINEGUN: SsUtKeyOn(nVab, 7,0, 48, 0, 128,128); player->rounds=12; break; case AUTOPISTOL: player->rounds=14; SsUtKeyOn(nVab2, 7,0, 48, 0, 128,128); break; default: break; } } //-------------------------------------------------------------- #define BRES 16; void FireGun() { int x,y,ax,ay; player->flame.rotate=player->sprite.rotate; if(!player->ammo) { player->rounds=0; return; } if(player->rounds&1) { switch(player->flame.rotate) { case 0: player->flame.x=player->sprite.x; player->flame.y=player->sprite.y-13; ax=0; ay=-BRES; break; case 45*ONE: player->flame.x=player->sprite.x+10; player->flame.y=player->sprite.y-10; ax=BRES; ay=-BRES; break; case 90*ONE: player->flame.x=player->sprite.x+13; player->flame.y=player->sprite.y; ax=BRES; ay=0; break; case 135*ONE: player->flame.x=player->sprite.x+10; player->flame.y=player->sprite.y+10; ax=BRES; ay=BRES; break; case 180*ONE: player->flame.x=player->sprite.x; player->flame.y=player->sprite.y+13; ax=0; ay=BRES; break; case 225*ONE: player->flame.x=player->sprite.x-10; player->flame.y=player->sprite.y+10; ax=-BRES; ay=BRES; break; case 270*ONE: player->flame.x=player->sprite.x-13; player->flame.y=player->sprite.y; ax=-BRES; ay=0; break; case 315*ONE: player->flame.x=player->sprite.x-10; player->flame.y=player->sprite.y-10; ax=-BRES; ay=-BRES; break; default: break; } GsSortSprite(&player->flame, &othWorld[nBuffer], 0); player->ammo--; nFired++; x=player->x+ax; y=player->y+ay; while(!CheckBullet(x, y)) { x+=ax; y+=ay; } } player->rounds--; } //-------------------------------------------------------------- #define FRES 8 int CheckBullet(int x, int y) { int nCount; if(IsCoordAWall(x,y)) { StartSplat(1,x,y); StartSplat(1,x,y); StartSplat(1,x,y); StartSplat(1,x,y); StartSplat(1,x,y); StartSplat(1,x,y); StartSplat(1,x,y); StartSplat(1,x,y); StartSplat(1,x,y); StartSplat(1,x,y); StartSplat(1,x,y); StartSplat(1,x,y); StartSplat(1,x,y); StartSplat(1,x,y); StartSplat(1,x,y); StartSplat(1,x,y); return 1; } if((xnMapx+320)||(ynMapy+240)) return 1; for(nCount=0; nCount-1) { if(((enemy[nCount].sprite.x>-13)&&(enemy[nCount].sprite.x<333))&& ((enemy[nCount].sprite.y>-13)&&(enemy[nCount].sprite.y<253))) { if(Collision(enemy[nCount].x, enemy[nCount].y, x,y, 16)) { nTarget++; enemy[nCount].energy-=player->damage; if(enemy[nCount].energy<-1) enemy[nCount].energy=-1; StartSplat(0,x,y); StartSplat(0,x,y); StartSplat(0,x,y); StartSplat(0,x,y); StartSplat(0,x,y); StartSplat(0,x,y); StartSplat(0,x,y); StartSplat(0,x,y); StartSplat(0,x,y); StartSplat(0,x,y); StartSplat(0,x,y); StartSplat(0,x,y); StartSplat(0,x,y); StartSplat(0,x,y); StartSplat(0,x,y); StartSplat(0,x,y); if(enemy[nCount].energy==-1) { enemy[nCount].sprite.rotate=(rand()/10)*ONE; SsUtKeyOn(nVab2, 5,0, 48, 0, 128,128); nKilled++; player->score+=25; switch(player->sprite.rotate) { case 0: enemy[nCount].dy=-FRES; break; case 45*ONE: enemy[nCount].dx=FRES; enemy[nCount].dy=-FRES; break; case 90*ONE: enemy[nCount].dx=FRES; break; case 135*ONE: enemy[nCount].dx=+FRES; enemy[nCount].dy=+FRES; break; case 180*ONE: enemy[nCount].dy=FRES; break; case 225*ONE: enemy[nCount].dx=-FRES; enemy[nCount].dy=FRES; break; case 270*ONE: enemy[nCount].dx=-FRES; break; case 315*ONE: enemy[nCount].dx=-FRES; enemy[nCount].dy=-FRES; break; default: break; } } enemy[nCount].sprite.r=255; enemy[nCount].sprite.g=255; enemy[nCount].sprite.g=255; return 1; } } } } return 0; } //-------------------------------------------------------------- int IsCoordAWall(int x, int y) { int nAddr; nAddr=(x>>4)+((y<<2)&0xffc0); if(((nMap[nAddr]>=194)&&(nMap[nAddr]<=389))||((nMap[nAddr]>=511)&&(nMap[nAddr]<=518))) return 1; return 0; } //-------------------------------------------------------------- int IsObjectOverWall(int x, int y, int r, int p) { int nAddr; static int nRad; nAddr=((x-r)>>4)+(((y-r)<<2)&0xffc0); if((nMap[nAddr]>=197)&&(nMap[nAddr]<=390)) return 1; nAddr=((x+r)>>4)+(((y-r)<<2)&0xffc0); if((nMap[nAddr]>=197)&&(nMap[nAddr]<=390)) return 1; nAddr=((x+r)>>4)+(((y+r)<<2)&0xffc0); if((nMap[nAddr]>=197)&&(nMap[nAddr]<=390)) return 1; nAddr=((x-r)>>4)+(((y+r)<<2)&0xffc0); if((nMap[nAddr]>=197)&&(nMap[nAddr]<=390)) return 1; nAddr=((x-r)>>4)+(((y)<<2)&0xffc0); if((nMap[nAddr]>=511)&&(nMap[nAddr]<=518)) { if(p&!player->d) { if(OpenDoor(nAddr)) return 1; } else return 1; } else if((nMap[nAddr]>=197)&&(nMap[nAddr]<=390)) return 1; nAddr=((x+r)>>4)+(((y)<<2)&0xffc0); if((nMap[nAddr]>=511)&&(nMap[nAddr]<=518)) { if(p&!player->d) { if(OpenDoor(nAddr)) return 1; } else return 1; } else if((nMap[nAddr]>=197)&&(nMap[nAddr]<=390)) return 1; nAddr=((x)>>4)+(((y-r)<<2)&0xffc0); if((nMap[nAddr]>=511)&&(nMap[nAddr]<=518)) { if(p&!player->d) { if(OpenDoor(nAddr)) return 1; } else return 1; } else if((nMap[nAddr]>=197)&&(nMap[nAddr]<=390)) return 1; nAddr=((x)>>4)+(((y+r)<<2)&0xffc0); if((nMap[nAddr]>=511)&&(nMap[nAddr]<=518)) { if(p&!player->d) { if(OpenDoor(nAddr)) return 1; } else return 1; } else if((nMap[nAddr]>=197)&&(nMap[nAddr]<=390)) return 1; if(p) { nAddr=(x>>4)+((y<<2)&0xffc0); if((nMap[nAddr]>=174)&&(nMap[nAddr]<=189)) { nRad++; if((nRad>=32-nLevel)&&(!player->shield)) { player->sprite.r=255; player->sprite.g=255; player->sprite.b=255; player->energy--; nRad=0; } } } return 0; } //-------------------------------------------------------------- int IsObjectOverEnemy(int x, int y, int r) { int nCount; for(nCount=0; nCount=0) { if(Collision(x,y, enemy[nCount].x, enemy[nCount].y, 22)) //if(Difference(x, enemy[nCount].x)<22)&&(Difference(y, enemy[nCount].y)<22)) { if((enemy[nCount].x!=x)||(enemy[nCount].y!=y)) return 1; } } } } //-------------------------------------------------------------- void CheckPickups(int x, int y) { Player * otherplayer; int nAddr; if(player==&player1) otherplayer=&player2; else otherplayer=&player1; nAddr=(x>>4)+((y<<2)&0xffc0); if(((nMap[nAddr]>=37)&&(nMap[nAddr]<=53))||((nMap[nAddr]>=23)&&(nMap[nAddr]<32))) SsUtKeyOn(nVab3, 1,0, 48, 0, 64,64); switch(nMap[nAddr]) { case 23: player->energy+=5; nMap[nAddr]=1; break; case 24: player->energy+=5; nMap[nAddr]=4; break; case 25: player->energy+=5; nMap[nAddr]=141; break; case 26: player->energy+=5; nMap[nAddr]=144; break; case 27: player->energy+=15; nMap[nAddr]=1; break; case 28: player->energy+=15; nMap[nAddr]=4; break; case 29: player->energy+=15; nMap[nAddr]=141; break; case 30: player->energy+=15; nMap[nAddr]=144; break; case 31: player->shield=250; nMap[nAddr]=1; break; case 32: player->ammo+=100; nMap[nAddr]=1; break; case 33: if(player->damage!=AUTOGUN) { player->flame.r=168; player->flame.g=168; player->flame.b=120; player->flame.scalex=ONE; player->flame.scaley=ONE+(ONE/4); player->damage=AUTOGUN; if((otherplayer->damage==AUTOGUN)||(otherplayer->lives<0)) nMap[nAddr]=1; SsUtKeyOn(nVab, 5,0, 48, 0, 128,128); } break; case 34: if(player->damage!=AUTOPISTOL) { player->flame.r=188; player->flame.g=158; player->flame.b=120; player->flame.scalex=ONE; player->flame.scaley=ONE*2; player->damage=AUTOPISTOL; if((otherplayer->damage==AUTOPISTOL)||(otherplayer->lives<0)) nMap[nAddr]=1; SsUtKeyOn(nVab, 5,0, 48, 0, 128,128); } break; case 35: if(player->damage!=MACHINEGUN) { player->flame.r=198; player->flame.g=158; player->flame.b=128; player->flame.scalex=ONE; player->flame.scaley=ONE+(ONE/2); player->damage=MACHINEGUN; if((otherplayer->damage==MACHINEGUN)||(otherplayer->lives<0)) nMap[nAddr]=1; SsUtKeyOn(nVab, 5,0, 48, 0, 128,128); } break; case 36: if(player->damage!=SHOTGUN) { player->flame.r=148; player->flame.g=148; player->flame.b=100; player->flame.scalex=ONE+(ONE/2); player->flame.scaley=ONE; player->damage=SHOTGUN; if((otherplayer->damage==SHOTGUN)||(otherplayer->lives<0)) nMap[nAddr]=1; SsUtKeyOn(nVab, 5,0, 48, 0, 128,128); } break; case 37: player->keys+=3; nMap[nAddr]=1; break; case 38: player->keys+=3; nMap[nAddr]=4; break; case 39: player->keys+=3; nMap[nAddr]=141; break; case 40: player->keys+=3; nMap[nAddr]=144; break; case 41: player->keys++; nMap[nAddr]=1; break; case 42: player->keys++; nMap[nAddr]=4; break; case 43: player->keys++; nMap[nAddr]=141; break; case 44: player->keys++; nMap[nAddr]=144; break; case 45: player->ammo+=15; nMap[nAddr]=1; break; case 46: player->ammo+=15; nMap[nAddr]=4; break; case 47: player->ammo+=15; nMap[nAddr]=141; break; case 48: player->ammo+=15; nMap[nAddr]=144; break; case 49: player->energy=100; nMap[nAddr]=1; break; case 50: player->energy=100; nMap[nAddr]=4; break; case 51: player->energy=100; nMap[nAddr]=141; break; case 52: player->energy=100; nMap[nAddr]=144; break; case 53: if(player->energy==100) player->lives++; else player->energy=100; nMap[nAddr]=1; break; case 439: case 447: case 455: case 463: ActivateGlobe(nAddr); break; case 471: case 479: case 487: case 495: if(nGlobes==4) bComplete=1; break; default: break; } if(player->energy>100) player->energy=100; } //-------------------------------------------------------------- int OpenDoor(int nAddr) { static n=0; if(!player->keys) return 1; nDoor[0]=nAddr; if(!player->d) { player->d=1; player->keys--; SsUtKeyOn(nVab, 6,0, 48, 0, 128,128); } switch(nMap[nAddr]) { case 511: nDoor[1]=nAddr+64; break; case 512: nDoor[1]=nAddr-64; break; case 513: nDoor[1]=nAddr+1; break; case 514: nDoor[1]=nAddr-1; break; case 515: nDoor[1]=nAddr+64; break; case 516: nDoor[1]=nAddr-64; break; case 517: nDoor[1]=nAddr+1; break; case 518: nDoor[1]=nAddr-1; break; default: break; } return 0; } //-------------------------------------------------------------- int CheckDoors(int nAddr) { if(!nAddr) return 0; if((nMap[nAddr]>=511)&&(nMap[nAddr]<=518)) nMap[nAddr]=((nMap[nAddr]-511)<<2)+519; else { nMap[nAddr]++; if(nMap[nAddr]&2) return 1; } return 0; } //-------------------------------------------------------------- void ActivateGlobe(int nAddr) { RECT rGlobe={912,256,10,10}; switch(nMap[nAddr]) { case 447: nAddr-=64; break; case 455: nAddr-=1; break; case 463: nAddr-=65; break; default: break; } nMap[nAddr]=2; nMap[nAddr+1]=3; nMap[nAddr+64]=9; nMap[nAddr+65]=10; nGlobes++; SsUtKeyOn(nVab2, 3,0, 48, 0, 128,128); if(nGlobes==1) MoveImage(&rGlobe,832+17, 256); if(nGlobes==2) MoveImage(&rGlobe,832+54, 256); if(nGlobes==3) MoveImage(&rGlobe,832+7, 256); if(nGlobes==4) MoveImage(&rGlobe,832+64, 256); } //-------------------------------------------------------------- void LevelClear() { int nTimer=0; int nX; int nCount; int nAcc, nEff; RECT rClear={0,0,320,512}; GsSPRITE title; char szText[8][64]; title.attribute=1<<25; title.r=128; title.g=128; title.b=128; title.w=256; title.h=26; title.mx=128; title.my=0; title.u=0; title.v=144; title.tpage=GetTPage(2, 0, 704, 400); title.scalex=ONE; title.scaley=ONE; title.rotate=0; ClearImage(&rClear, 0, 0, 0); rClear.h=256; LoadTIM(CLEAR_TIM); SsUtKeyOn(nVab2, 1,0, 44, 0, 128,128); nEff=(nKilled*100)/nEnemies; if(nFired) nAcc=(nTarget*100)/nFired; else nAcc=0; sprintf(szText[0], "Bullets fired: %d", nFired); sprintf(szText[1], "Bullets on target: %d", nTarget); sprintf(szText[2], "Accuracy: %d%%", nAcc); if(nAcc>=80) { strcat(szText[2], " - EXTRA LIFE!"); if(player1.lives>-1) player1.lives++; if(player2.lives>-1) player2.lives++; } sprintf(szText[4], "Enemies on level: %d", nEnemies); sprintf(szText[5], "Enemies eliminated: %d", nKilled); sprintf(szText[6], "Efficiency: %d%%", nEff); if(nEff>=90) { strcat(szText[6], " - BONUS AMMO!"); player1.ammo+=500; player2.ammo+=500; } strcpy(szText[3], ""); strcpy(szText[7], ""); do { PADstatus=PadRead(1); nBuffer=GsGetActiveBuff(); GsSetWorkBase((PACKET*)out_packet[nBuffer]); GsClearOt(0, 0, &othWorld[nBuffer]); rClear.y=nBuffer*256; ClearImage(&rClear, 0, 0, 0); title.x=160; title.y=240-nTimer; if(title.y<0) title.y=0; GsSortSprite(&title, &othWorld[nBuffer], 0); for(nCount=0; nCount<8; nCount++) { nX=320-nTimer+(nCount*64); if(nX<20) nX=20; OutputString(szText[nCount], -1, nX, (45+(nCount*23))); } if(nTimer<1500) nTimer+=16; GsDrawOt(&othWorld[nBuffer]); DrawSync(0); VSync(0); GsSwapDispBuff(); GsSortClear(0,0,0,&othWorld[nBuffer]); } while((!(PADstatus & PADRdown))||(nTimer<320)); } //-------------------------------------------------------------- void GameOver() { int nTimer=0; RECT rClear={0,0,320,512}; RECT rArea={704, 130, 72, 0}; char szDead[13]="YOU ARE DEAD"; char szOver[10]="GAME OVER"; char szPress[8]="PRESS X"; ClearImage(&rClear, 0, 0, 0); rClear.h=256; LoadTIM(DEAD_TIM); do { PADstatus=PadRead(1); nBuffer=GsGetActiveBuff(); GsSetWorkBase((PACKET*)out_packet[nBuffer]); GsClearOt(0, 0, &othWorld[nBuffer]); rClear.y=nBuffer*256; ClearImage(&rClear, 0, 0, 0); rArea.h=nTimer*2; if(rArea.h>120) rArea.h=120; MoveImage(&rArea, 124,20+(nBuffer*256)); if(nTimer>90) OutputString(szDead, nTimer-90, GetCentre(szDead), 150); if(nTimer>150) OutputString(szOver, nTimer-150, GetCentre(szOver), 180); if(nTimer>500) OutputString(szPress, nTimer-150, GetCentre(szPress), 210); if(nTimer<1500) nTimer++; GsDrawOt(&othWorld[nBuffer]); DrawSync(0); VSync(0); GsSwapDispBuff(); GsSortClear(0,0,0,&othWorld[nBuffer]); } while((!(PADstatus & PADRdown))||(nTimer<10)); } //-------------------------------------------------------------- void Complete() { int nScroll=400; int nTimer=0; RECT rClear={0,0,320,512}; RECT rArea={320,0,122,114}; char sz1[28]="CONGRATULATIONS!"; char sz2[500]="You reach the final deck lift in the nick of time. The doomed space station explodes taking the Psychon virus with it. You escape the inferno and return to Earth having "; char sz4[185]="saved it from a brutal death. You will be remembered. For more information on the Net Yaroze point your browser at: www.netyaroze-europe.com. Thank you for playing!"; char sz3[8]="PRESS X"; LoadTIM(EARTH_TIM); strcat(sz2, sz4); ClearImage(&rClear, 0, 0, 0); rClear.h=256; do { PADstatus=PadRead(1); nBuffer=GsGetActiveBuff(); GsSetWorkBase((PACKET*)out_packet[nBuffer]); GsClearOt(0, 0, &othWorld[nBuffer]); rClear.y=nBuffer*256; ClearImage(&rClear, 0, 0, 0); rArea.h=nTimer*2; if(rArea.h>114) rArea.h=114; MoveImage(&rArea, 96,(nBuffer*256)+80); OutputString(sz1, nTimer, GetCentre(sz1), 10); OutputString(sz2, -1, nScroll, 40); if(nTimer>3000) OutputString(sz3, -1, GetCentre(sz3), 220); GsDrawOt(&othWorld[nBuffer]); DrawSync(0); VSync(0); GsSwapDispBuff(); GsSortClear(0,0,0,&othWorld[nBuffer]); nTimer++; if(nTimer>4000) nTimer=4000; nScroll--; if(nScroll<-3800) nScroll=400; } while((!(PADstatus & PADRdown))||(nTimer<3000)); SsUtKeyOn(nVab, 0,0, 48, 0, 128,128); SmearClear(127,128,128,1,0,-1); } //-------------------------------------------------------------- void SmearClear(int r, int g, int b, int s, int ax, int ay) { int nCount; char lLine[640]; RECT rLine={0,0,320,1}; RECT rImage={0,0,320,240}; GsSPRITE screen; GsSPRITE screen2; for(rLine.y=(1-nBuffer)*256; rLine.y<((1-nBuffer)*256)+240; rLine.y++) { StoreImage(&rLine, (u_long *)&lLine[0]); for(nCount=0; nCount<640; nCount+=2) lLine[nCount+1]|=0x80; LoadImage(&rLine, (u_long *)&lLine[0]); } screen.attribute=(1<<25)+(1<<30); screen.r=r; screen.g=g; screen.b=b; screen.mx=160; screen.my=120; screen.x=160; screen.y=120; screen.w=160; screen.h=240; screen.u=0; screen.v=0; screen.rotate=ONE*(2/s); screen.scalex=ONE+(512/s); screen.scaley=ONE+(512/s); screen2.attribute=(1<<25)+(1<<30); screen2.r=r; screen2.g=g; screen2.b=b; screen2.mx=0; screen2.my=120; screen2.x=160; screen2.y=120; screen2.w=160; screen2.h=240; screen2.rotate=ONE*(2/s); screen2.scalex=ONE+(512/s); screen2.scaley=ONE+(512/s); screen2.u=32; screen2.v=0; rImage.y=(1-nBuffer)*256; MoveImage(&rImage, 0, nBuffer*256); for(nCount=92*s; nCount>0; nCount--) { if(nCount==64*s) { screen.r=127; screen.g=127; screen.b=127; screen2.r=127; screen2.g=127; screen2.b=127; } if(nCount>64) { screen.x+=ax; screen.y+=ay; screen2.x+=ax; screen2.y+=ay; } else { screen.x=160; screen.y=120; screen2.x=160; screen2.y=120; } GsSetWorkBase((PACKET*)out_packet[nBuffer]); GsClearOt(0, 0, &othWorld[nBuffer]); screen.tpage=GetTPage(2,0, 0, (1-nBuffer)*256); GsSortSprite(&screen, &othWorld[nBuffer], 0); screen2.tpage=screen.tpage+2; GsSortSprite(&screen2, &othWorld[nBuffer], 1); GsDrawOt(&othWorld[nBuffer]); DrawSync(0); VSync(0); GsSwapDispBuff(); nBuffer=GsGetActiveBuff(); GsSortClear(0,0,0,&othWorld[nBuffer]); } } //-------------------------------------------------------------- void OutputString(char * string, int len, int x, int y) { RECT rChar; while(len&&*string) { if(*string==32) rChar.w=SPACE; else { rChar.x=nFont[*string-33]+336; rChar.w=(nFont[*string-32]+336)-rChar.x; if(rChar.w<0) rChar.w=398-nFont[*string-33]; if((x<0)&&(rChar.w>-x)) { rChar.x-=x; rChar.w+=x; x=0; } if((x+rChar.w>320)&&(x<320)) rChar.w=320-x; rChar.h=19; if(*string>'N') rChar.y=467; else rChar.y=448; if((x<320)&&(y<256)&&(x+rChar.w>0)) MoveImage(&rChar, x,y+(nBuffer*256)); } x+=rChar.w; string++; len--; } } //-------------------------------------------------------------- int GetCentre(char * string) { int nLen=0; int nAdd; while(*string) { if(*string==32) nAdd=SPACE; else nAdd=(nFont[*string-32])-(nFont[*string-33]); if(nAdd<0) nAdd=398-nFont[*string-33]; nLen+=nAdd; string++; } nLen=160-(nLen>>1); return nLen; } //-------------------------------------------------------------- void OutputNum(int num, int len, int x, int y) { RECT rArea={704, 389, 5, 6}; int nCol; if(num<0) num=0; while(len) { if(num) nCol=num%10; else nCol=0; num-=nCol; num/=10; rArea.x=(nCol*5)+704; MoveImage(&rArea, x+(5*(len-1)), y); len--; } } //-------------------------------------------------------------- int Difference(int a, int b) { if(a>b) return a-b; else return b-a; } //-------------------------------------------------------------- void OtherChecks() { int nRand; if((player1.lives<0)&&(player2.lives<0)) bPlaying=0; player1.d=0; player2.d=0; nRand=rand()/48; if(nRand==1) SsUtKeyOn(nVab, 0,0, 36, 0, 32,128); if(nRand==2) SsUtKeyOn(nVab, 0,0, 36, 0, 128,32); } //-------------------------------------------------------------- void Intro() { int nCount=0; RECT rClear={0,0,320,240}; ClearImage(&rClear, 0, 0, 0); rClear.h=256; while(nCount<260) { PADstatus=PadRead(1); nBuffer=GsGetActiveBuff(); GsSetWorkBase((PACKET*)out_packet[nBuffer]); GsClearOt(0, 0, &othWorld[nBuffer]); rClear.y=nBuffer*256; LoadImage(&rClear, (u_long *)INTRO_TIM+5); GsDrawOt(&othWorld[nBuffer]); DrawSync(0); VSync(0); GsSwapDispBuff(); GsSortClear(0,0,0,&othWorld[nBuffer]); nCount++; } } //-------------------------------------------------------------- void EnterName() { int nPos=0; int nHold=0; int nHoldX=0; int nHoldT=0; int nRank; int nCount; int nLetter=0; int x[30]={4,14,25,35,45,53,61,72,80,86,94,103,113,125,134,144,154,165,175,184,194,204,216,229,238,246,255,260}; char szPlayer[9]="PLAYER 1"; char sz1[32]="You have achieved a great score"; char sz2[32]="Please enter your initials"; char szLetters[40]="ABCDEFGHIJKLMNOPQRSTUVWXYZ ."; char szRank[24]=""; char szName[5]="..."; RECT rClear={0,0,320,240}; GsSPRITE cursor; LoadTIM(CURSOR_TIM); cursor.attribute=1<<25; cursor.w=28; cursor.h=32; cursor.u=26; cursor.v=0; cursor.r=128; cursor.g=128; cursor.b=128; cursor.tpage=GetTPage(2,0,922,256); nRank=10; while((player->score>nScore[nRank-1])&&(nRank)) nRank--; sprintf(szRank, "Your ranking is %d", nRank+1); if(nRank==0) strcat(szRank, "st"); else if(nRank==1) strcat(szRank, "nd"); else if(nRank==2) strcat(szRank, "rd"); else strcat(szRank, "th"); do { PADstatus=PadRead(1); if(player==&player2) { PADstatus=PADstatus>>16; szPlayer[7]='2'; } nBuffer=GsGetActiveBuff(); GsSetWorkBase((PACKET*)out_packet[nBuffer]); GsClearOt(0, 0, &othWorld[nBuffer]); rClear.y=nBuffer*256; ClearImage(&rClear, 0,0,0); OutputString(szPlayer, -1, GetCentre(szPlayer), 10); OutputString(sz1, -1, GetCentre(sz1), 50); OutputString(sz2, -1, GetCentre(sz2), 80); OutputString(szLetters, -1, GetCentre(szLetters), 120); OutputString(szName, -1, GetCentre(szName), 150); OutputString(szRank, -1, GetCentre(szRank), 190); if(PADstatus & PADLleft) { if(!nHold) { SsUtKeyOn(nVab3, 1,0, 48, 0, 64,64); nPos--; nHold=1; } } else if(PADstatus & PADLright) { if(!nHold) { SsUtKeyOn(nVab3, 1,0, 48, 0, 64,64); nPos++; nHold=1; } } else nHold=0; if(PADstatus & PADRdown) { if(!nHoldX) { if(nPos<=25) szName[nLetter]=nPos+65; else if(nPos==26) szName[nLetter]=' '; else if(nPos==27) szName[nLetter]='.'; nLetter++; nHoldX=1; if(nLetter<=3) SsUtKeyOn(nVab2, 2,0, 48, 0, 128,128); } } else nHoldX=0; if(PADstatus & PADRup) { if(!nHoldT) { if(nLetter) { nLetter--; szName[nLetter]='.'; SsUtKeyOn(nVab, 4,0, 48, 0, 128,128); } nHoldT=1; } } else nHoldT=0; if(nPos<0) nPos=27; else if(nPos>27) nPos=0; cursor.x=x[nPos]+16; cursor.y=114; GsSortFastSprite(&cursor, &othWorld[nBuffer], 0); GsDrawOt(&othWorld[nBuffer]); DrawSync(0); VSync(0); GsSwapDispBuff(); GsSortClear(0,0,0,&othWorld[nBuffer]); }while(nLetter<4); for(nCount=9; nCount>=nRank; nCount--) { nScore[nCount]=nScore[nCount-1]; strcpy(szNames[nCount], szNames[nCount-1]); } szName[3]='\0'; nScore[nRank]=player->score; strcpy(szNames[nRank], szName); SsUtKeyOn(nVab, 0,0, 48, 0, 128,128); SmearClear(128,128,128,1,0,1); } //-------------------------------------------------------------- void StartSplat(int type, int x, int y) { int nCount=0; while(((splat[nCount].ax)||(splat[nCount].ay))&&(nCount0) splat[nCount].ax--; else if(splat[nCount].ax<0) splat[nCount].ax++; if(splat[nCount].ay>0) splat[nCount].ay--; else if(splat[nCount].ay<0) splat[nCount].ay++; splat[nCount].line.x0=splat[nCount].line.x1; splat[nCount].line.y0=splat[nCount].line.y1; splat[nCount].x+=splat[nCount].ax; splat[nCount].y+=splat[nCount].ay; splat[nCount].line.x1=splat[nCount].x-nMapx; splat[nCount].line.y1=splat[nCount].y-nMapy; GsSortGLine(&splat[nCount].line, &othWorld[nBuffer], 0); } } } //-------------------------------------------------------------- void PadInit (void) { GetPadBuf(&bb0, &bb1); } //-------------------------------------------------------------- u_long PadRead(int mode) { u_long read; u_long temp; read=(~(*(bb0+3) | *(bb0+2) << 8 | *(bb1+3) << 16 | *(bb1+2) << 24)); if(mode) { temp=read>>16; read|=temp; } return read; }