// --- Defender -------------------------------------------------------------- #include #include #include #include #include "pad.h" #define BAITER_TIM 0x80090000 #define BOMBER_TIM 0x800900b4 #define FONT_TIM 0x80090308 #define LANDER_TIM 0x8009231c #define LOGO_TIM 0x80092410 #define MAN_TIM 0x8009da54 #define MUTANT_TIM 0x8009daa8 #define POD_TIM 0x8009db9c #define SHIP_TIM 0x8009dc50 #define SHIP2_TIM 0x8009df7c #define SWARMER_TIM 0x8009e2a8 #define WILLIAMS_TIM 0x8009e30c #define SOUND_VH 0x8009ea70 #define SOUND_VB 0x800a0490 #define SOUND2_VH 0x800c4460 #define SOUND2_VB 0x800c5e80 #define SHIELD_TIM 0x800e4970 #define LPAD_TIM 0x800e5184 #define RPAD_TIM 0x800e7198 #define S250_TIM 0x800e91ac #define S500_TIM 0x800e9490 #define EXPLODE_TIM 0x800e9774 #define HG_TIM 0x800f4b88 #define SCENE_TIM 0x800fa79c #define OT_LEN 12 #define MAX_PACKETS 102400 #define SHIP_Y 120 #define SHIP_RIGHT_X 64 #define SHIP_LEFT_X (320 - SHIP_RIGHT_X - 32) #define SHIP_SPEED (6 << 1) #define MAX_TERRAIN 64 #define WORLD_SIZE (320 << 3) #define TERRAIN_LEN (320 >> 3) #define TERRAIN_HEIGHT (320 >> 5) #define CEILING 64 #define FLOOR 230 #define SCALE 64 #define MAX_MEN 8 #define MAX_SCORES 8 #define MAX_ALIENS 256 #define MAX_PARTICLES 512 #define MAX_FIRE 8 #define MAX_STATIC 16 #define MAX_EXPLODE 8 #define WAVE_TIME (10*50) #define BAITER_TIME (20*50) #define SHIELD_TIME (3*50) typedef enum { SPRITE_BAITER=0, SPRITE_BOMBER, SPRITE_FONT, SPRITE_LANDER, SPRITE_LOGO, SPRITE_MAN, SPRITE_MUTANT, SPRITE_SHIELD, SPRITE_POD, SPRITE_SHIP, SPRITE_SHIP2, SPRITE_SWARMER, SPRITE_WILLIAMS, SPRITE_LPAD, SPRITE_RPAD, SPRITE_S250, SPRITE_S500, SPRITE_EXPLODE, SPRITE_HG, SPRITE_SCENE, NUM_SPRITES } SPRITE_DATA; typedef enum { STATE_FRONTEND=0, STATE_GAME, STATE_RESULTS, NUM_GAME_STATES } STATE; typedef enum { ALIEN_LANDER=0, ALIEN_MUTANT, ALIEN_BAITER, ALIEN_BOMBER, ALIEN_POD, ALIEN_SWARMER, NUM_ALIEN_TYPES } ALIEN_TYPE; typedef enum { STATE_DEAD=0, STATE_NEW, STATE_NORMAL, STATE_LANDING, STATE_ASCEND, } ALIEN_STATE; typedef struct { int x; int y; int sy; int alive; int grab; int fall; } MAN_DATA; typedef struct { char name [4]; int score; } SCORE_DATA; typedef struct { ALIEN_TYPE type; ALIEN_STATE state; int xdir; int ydir; int x; int y; int grab; } ALIEN_DATA; typedef struct { int x; int y; int xdir; int ydir; int life; } PARTICLE_DATA; typedef struct { int x; int y; int dir; int speed; int start; int end; } FIRE_DATA; typedef struct { int x; int y; int life; int val; } STATIC_DATA; typedef struct { int x; int y; int frame; } EXPLODE_DATA; char tempstring [41]; u_long PADstatus = 0; volatile u_char *bb0, *bb1; int nBuffer; int nVab, nVab2; int shipx,shipy,shipright,speed; int mapx,mapy; int score,lives,smart,level; int hiscore = 0; int pause; int currentparticle = 0; int currentstatic = 0; int currentexplode = 0; int counter=0; int anim=0; int baiter; int wave; int wavetime; int aliensalive; int tr, tg, tb; int explode; int shield; int tune=-10; int mutantflash; long sync; unsigned char clearr, clearg, clearb; PACKET out_packet[2][MAX_PACKETS]; GsOT othWorld[2]; GsOT_TAG otWorld[2][1<>16; read |= temp; } return read; } //-------------------------------------------------------------- void FrameStart (void) { static long time=0; RECT clear={0,0,320,240}; time++; if (time < 100) { tr=128; tg=64; tb=128; } else if (time < 200) { tr=32; tg=128; tb=128; } else if (time < 300) { tr=128; tg=128; tb=32; } else if (time < 400) { tr=32; tg=128; tb=64; } else { time=0; } PADstatus=PadRead(0); nBuffer=GsGetActiveBuff(); GsSetWorkBase((PACKET*)out_packet[nBuffer]); GsClearOt(0, 0, &othWorld[nBuffer]); clear.y=(nBuffer * 240); ClearImage (&clear, clearr, clearg, clearb); clearr=0; clearg=0; clearb=0; } //-------------------------------------------------------------- void FrameEnd (void) { GsDrawOt(&othWorld[nBuffer]); DrawSync(0); sync=VSync(0); GsSwapDispBuff(); GsSortClear(0,0,0,&othWorld[nBuffer]); } //-------------------------------------------------------------- int LoadTIM(long addr, GsIMAGE * tim1) { RECT rect; 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() { LoadTIM (BAITER_TIM, &spritedata[SPRITE_BAITER]); LoadTIM (BOMBER_TIM, &spritedata[SPRITE_BOMBER]); LoadTIM (FONT_TIM, &spritedata[SPRITE_FONT]); LoadTIM (LANDER_TIM, &spritedata[SPRITE_LANDER]); LoadTIM (LOGO_TIM, &spritedata[SPRITE_LOGO]); LoadTIM (MAN_TIM, &spritedata[SPRITE_MAN]); LoadTIM (MUTANT_TIM, &spritedata[SPRITE_MUTANT]); LoadTIM (POD_TIM, &spritedata[SPRITE_POD]); LoadTIM (SHIP_TIM, &spritedata[SPRITE_SHIP]); LoadTIM (SWARMER_TIM, &spritedata[SPRITE_SWARMER]); LoadTIM (SHIP2_TIM, &spritedata[SPRITE_SHIP2]); LoadTIM (WILLIAMS_TIM, &spritedata[SPRITE_WILLIAMS]); LoadTIM (SHIELD_TIM, &spritedata[SPRITE_SHIELD]); LoadTIM (LPAD_TIM, &spritedata[SPRITE_LPAD]); LoadTIM (RPAD_TIM, &spritedata[SPRITE_RPAD]); LoadTIM (S250_TIM, &spritedata[SPRITE_S250]); LoadTIM (S500_TIM, &spritedata[SPRITE_S500]); LoadTIM (EXPLODE_TIM, &spritedata[SPRITE_EXPLODE]); LoadTIM (HG_TIM, &spritedata[SPRITE_HG]); LoadTIM (SCENE_TIM, &spritedata[SPRITE_SCENE]); SetVideoMode(MODE_PAL); GsInitGraph(320, 240, GsNONINTER|GsOFSGPU, 0, 0); GsDefDispBuff(0, 0, 0, 240); 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]); nVab=SsVabTransfer((u_char *)SOUND_VH, (u_char *)SOUND_VB, -1, 1); nVab2=SsVabTransfer((u_char *)SOUND2_VH, (u_char *)SOUND2_VB, -1, 1); SsSetMVol(127,127); } //-------------------------------------------------------------- void GetInput() { PADstatus=PadRead(0); } //-------------------------------------------------------------- int WorldToScreen (int x) { int ret=x; if ((x < 320) && (mapx > (WORLD_SIZE -320))) { ret=WORLD_SIZE - mapx + x; } else { ret -=mapx; } return ret; } //-------------------------------------------------------------- int ConstrainX (int x) { while (x < 0) { x +=WORLD_SIZE; } while (x >=WORLD_SIZE) { x -=WORLD_SIZE; } return x; } //-------------------------------------------------------------- int ConstrainY (int y) { if (y < CEILING) { y=CEILING; } else if (y > FLOOR) { y=FLOOR; } return y; } //-------------------------------------------------------------- int OnScreen (int x) { int ret=1; if (x < -32 || x > 352) { ret=0; } return ret; } //-------------------------------------------------------------- void DrawText (char * text, int x, int y) { int xoff, yoff; char cur; GsIMAGE tim1; GsSPRITE sprite={(1<<25), 0,0, 0,0, 0, 0,0, 0,0, 0,0,0, 0,0, 0,0, 0}; GsGetTimInfo((u_long *)FONT_TIM+1, &tim1); sprite.u=tim1.px % 64; sprite.v=tim1.py % 256; sprite.w=8; sprite.h=8; sprite.tpage=GetTPage(2, 0, tim1.px, tim1.py); sprite.r=tr; sprite.g=tg; sprite.b=tb; if (x<0 || x>320) { x=(320 - (strlen(text) * 8)) / 2; } sprite.x=x; sprite.y=y; while (*text) { cur=*text - 33; if (cur >=0) { xoff=(cur % 16) * 8; yoff=(cur / 16) * 8; sprite.u=tim1.px % 64; sprite.v=tim1.py % 256; sprite.u +=xoff; sprite.v +=yoff; sprite.tpage=GetTPage(2, 0, tim1.px, tim1.py); GsSortFastSprite(&sprite, &othWorld[nBuffer], 0); } sprite.x +=8; text++; } } // ---------------------------------------------------------------- void AddStatic (int x, int y, int val, int life) { staticdata [currentstatic].x=x; staticdata [currentstatic].y=y; staticdata [currentstatic].val=val; staticdata [currentstatic].life=life; currentstatic ++; if (currentstatic >=MAX_STATIC) { currentstatic=0; } } // ---------------------------------------------------------------- void AddExplode (int x, int y) { explodedata [currentexplode].x = x; explodedata [currentexplode].y = y; explodedata [currentexplode].frame = 0; currentexplode++; if (currentexplode >= MAX_EXPLODE) { currentexplode = 0; } } // ---------------------------------------------------------------- void AddParticle (int x, int y, int xdir, int ydir, int life) { static int currentparticle=0; if (xdir==0 && ydir==0) { return; } particle [currentparticle].x=x; particle [currentparticle].y=y; particle [currentparticle].xdir=xdir; particle [currentparticle].ydir=ydir; particle [currentparticle].life=life; currentparticle ++; if (currentparticle >=MAX_PARTICLES) { currentparticle=0; } } // ---------------------------------------------------------------- #define EXPLODE_SMALL_LIFE 128 void ExplodeSmall (int x, int y) { int count; for (count=0; count < 64; count++) { AddParticle ((x + (rand () % 22)) * SCALE, (y + (rand () % 8)) * SCALE, ((rand () % (20*SCALE)) - (10*SCALE)), ((rand () % (8*SCALE)) - (4*SCALE)), EXPLODE_SMALL_LIFE - (rand() % EXPLODE_SMALL_LIFE)); } } //-------------------------------------------------------------- #define EXPLODE_SHIP_LIFE 128 void ExplodeShip (int x, int y) { int count; explode=EXPLODE_SHIP_LIFE; SsUtKeyOn (nVab, 0,0, 48, 0, 128, 128); for (count=0; count < MAX_PARTICLES; count++) { AddParticle ((x + (rand () % 22)) * SCALE, (y + (rand () % 8)) * SCALE, ((rand () % (20*SCALE)) - (10*SCALE)), ((rand () % (8*SCALE)) - (4*SCALE)), EXPLODE_SHIP_LIFE - (rand() % EXPLODE_SHIP_LIFE)); } for (count = 0; count < MAX_MEN; count++) { if (man [count].grab == MAX_ALIENS) { man [count].sy = man [count].y * SCALE; } } } //-------------------------------------------------------------- void KillAlien (int count) { int slot; int swarmer; int lastscore=score; if ((alien [count].state==STATE_DEAD) || (alien [count].state==STATE_NEW)) { return; } switch (alien [count].type) { case ALIEN_LANDER: SsUtKeyOn (nVab2, 2,0, 48, 0, 128, 128); if ((alien [count].grab !=-1) && (alien [count].state==STATE_ASCEND)) { man [alien [count].grab].fall=0; man [alien [count].grab].sy=man [alien [count].grab].y * SCALE; } score +=150; break; case ALIEN_MUTANT: SsUtKeyOn (nVab2, 1,0, 48, 0, 128, 128); score +=150; break; case ALIEN_BAITER: SsUtKeyOn (nVab2, 1,0, 48, 0, 128, 128); score +=200; break; case ALIEN_BOMBER: SsUtKeyOn (nVab2, 3,0, 48, 0, 128, 128); score +=250; break; case ALIEN_POD: score +=1000; for (swarmer=0; swarmer < 5; swarmer++) { slot=GetAlienSlot(); alien [slot].state=STATE_NEW; alien [slot].type=ALIEN_SWARMER; alien [slot].x=ConstrainX (alien [count].x + (rand() % 64) - 32); alien [slot].y=ConstrainY (alien [count].y - 8 - (rand() % 64)); } SsUtKeyOn (nVab, 6,0, 48, 0, 128, 128); break; case ALIEN_SWARMER: SsUtKeyOn (nVab2, 3,0, 48, 0, 128, 128); score +=150; break; default: break; } alien [count].state=STATE_DEAD; alien [count].grab=-1; if ((score / 10000) > (lastscore / 10000)) { if ((lives < 5) && (smart < 5)) { if (lives < 5) { lives++; } if (smart < 5) { smart++; } } SsUtKeyOn (nVab, 2,0, 48, 0, 128, 128); } if (hiscore < score) { hiscore=score; } ExplodeSmall (alien [count].x + 4, alien [count].y + 2); AddExplode (alien [count].x - 6, alien [count].y - 21); } //-------------------------------------------------------------- void KillMan (int count) { man [count].alive=0; man [count].fall=-1; man [count].grab=-1; ExplodeSmall (man [count].x + 2, man [count].y + 3); SsUtKeyOn (nVab, 0,0, 48, 0, 128, 128); for (count = 0; count < MAX_MEN; count++) { if (man [count].alive) { return; } } mutantflash = 100; for (count = 0; count < MAX_ALIENS; count++) { if (alien [count].type == ALIEN_LANDER) { alien [count].type = ALIEN_MUTANT; } } } // ---------------------------------------------------------------- #define LANDER_ROOF 150 #define LANDER_FLOOR 200 void MoveLander (count) { int rman; rman=rand () % MAX_MEN; switch (alien [count].state) { case STATE_NORMAL: if (alien [count].xdir) { alien [count].x +=2; } else { alien [count].x -=2; } if (alien [count].ydir) { alien [count].y ++; } else { alien [count].y --; } if (alien [count].y <=LANDER_ROOF) { alien [count].ydir=1; } else if (alien [count].y >=LANDER_FLOOR) { alien [count].ydir=0; } if ((alien [count].x >=(man [rman].x - 5)) && (alien [count].x <=(man [rman].x - 3))) { if ((man [rman].alive) && (man [rman].grab==-1)) { alien [count].x=(man [rman].x - 4); man [rman].grab=count; alien [count].grab=rman; alien [count].state=STATE_LANDING; } } break; case STATE_LANDING: if (!man [alien [count].grab].alive) { alien [count].state=STATE_NORMAL; return; } if (!(counter % 4)) { alien [count].y ++; } if ((alien[count].y + 8) >=man [alien [count].grab].y) { alien [count].state=STATE_ASCEND; } break; case STATE_ASCEND: if (!man [alien [count].grab].alive) { alien [count].state=STATE_NORMAL; return; } if (!(counter % 8)) { alien [count].y --; } man [alien [count].grab].y=alien [count].y + 10; if (alien [count].y <=CEILING) { KillMan (alien [count].grab); alien [count].type=ALIEN_MUTANT; } break; } } // ---------------------------------------------------------------- #define BOMBER_ROOF 70 #define BOMBER_FLOOR 180 void MoveBomber (count) { switch (alien [count].state) { case STATE_NORMAL: if (alien [count].xdir) { alien [count].x +=2; } else { alien [count].x -=2; } if (alien [count].ydir) { alien [count].y ++; } else { alien [count].y --; } if (alien [count].y <=BOMBER_ROOF) { alien [count].ydir=1; } else if (alien [count].y >=BOMBER_FLOOR) { alien [count].ydir=0; } break; } } // ---------------------------------------------------------------- #define MUTANT_WOBBLE 4 #define MUTANT_RANGE 200 void MoveMutant (count) { int dis; if ((alien [count].x > shipx) || (explode)) { alien [count].x -=4; dis=alien [count].x - shipx; } else if (alien [count].x < shipx) { alien [count].x +=4; dis=shipx - alien [count].x; } alien [count].x +=(rand() % MUTANT_WOBBLE) - (MUTANT_WOBBLE/2); alien [count].y +=(rand() % MUTANT_WOBBLE) - (MUTANT_WOBBLE/2); if (dis < MUTANT_RANGE) { if (alien [count].y > shipy) { alien [count].y -=2; } else if (alien [count].y < shipy) { alien [count].y +=2; } } } // ---------------------------------------------------------------- void MoveBaiter (count) { int dis = 0; if ((alien [count].x < shipx) || (explode)) { dis=(SHIP_SPEED/2); } else if (alien [count].x > shipx) { dis=-(SHIP_SPEED/2); } alien [count].x +=dis; if (alien [count].y > (shipy - 4)) { alien [count].y -=1; } else if (alien [count].y < (shipy - 4)) { alien [count].y +=1; } } // ---------------------------------------------------------------- void MovePod (count) { if (! (alien [count].xdir % 4)) { alien [count].x ++; } alien [count].xdir ++; } // ---------------------------------------------------------------- void MoveSwarmer (count) { int dis; if ((alien [count].x > shipx) || (explode)) { alien [count].x -=3; dis=alien [count].x - shipx; } else if (alien [count].x < shipx) { alien [count].x +=3; dis=shipx - alien [count].x; } if (dis < 200) { if (alien [count].y > shipy - 8) { alien [count].y -=1; } else if (alien [count].y < shipy - 8) { alien [count].y +=1; } } alien[count].x +=(rand() % 5) - 2; alien[count].y +=(rand() % 5) - 2; } // ---------------------------------------------------------------- void MoveAliens () { int count; for (count=0; count < MAX_ALIENS; count++) { if (alien [count].state !=STATE_DEAD) { if (alien [count].state==STATE_NEW) { alien [count].state=STATE_NORMAL; } switch (alien [count].type) { case ALIEN_LANDER: MoveLander (count); break; case ALIEN_MUTANT: MoveMutant (count); break; case ALIEN_BAITER: MoveBaiter (count); break; case ALIEN_BOMBER: MoveBomber (count); break; case ALIEN_POD: MovePod (count); break; case ALIEN_SWARMER: MoveSwarmer (count); break; default: break; } alien [count].x=ConstrainX (alien [count].x); alien [count].y=ConstrainY (alien [count].y); } } } // ---------------------------------------------------------------- void MoveMen (void) { int count; int total = 0; RECT manrect={0,0,4,8}; RECT shiprect={0,0,22,8}; for (count=0; count < MAX_MEN; count++) { if (man [count].grab == MAX_ALIENS) { total ++; } } for (count=0; count < MAX_MEN; count++) { if (man [count].fall !=-1) { man [count].fall +=2; man [count].sy +=man [count].fall; man [count].y=man [count].sy / SCALE; shiprect.x=shipx; shiprect.y=shipy; manrect.x=man [count].x; manrect.y=man [count].y; if ((RectInRect (&manrect, &shiprect)) && (!total) && (!explode)) { man [count].fall=-1; man [count].grab=MAX_ALIENS; SsUtKeyOn (nVab, 3,0, 48, 0, 128, 128); score +=500; AddStatic (man [count].x - 8, man [count].y - 8, 500, 100); } if (man [count].y > 220) { if (man [count].fall > 128) { KillMan (count); } else { man [count].fall=-1; SsUtKeyOn (nVab, 1,0, 48, 0, 128, 128); score +=250; AddStatic (man [count].x - 8, man [count].y - 8, 250, 100); } } } else if (man [count].grab==MAX_ALIENS) { if (explode) { man [count].grab =- 1; man [count].fall = 0; } man [count].x=shipx + 7; man [count].y=shipy + 8; if (man [count].y > 220) { man [count].grab=-1; man [count].fall=-1; SsUtKeyOn (nVab, 1,0, 48, 0, 128, 128); score +=500; AddStatic (man [count].x - 8, man [count].y - 8, 500, 100); } } } } // ---------------------------------------------------------------- void UpdateParticles (void) { int count; for (count=0; count < MAX_PARTICLES; count++) { if (particle [count].life > 0) { particle [count].life -=2; particle [count].x +=particle [count].xdir; particle [count].y +=particle [count].ydir; if ((particle [count].y > (240 * SCALE)) || (particle [count].y < (CEILING*SCALE))) { particle [count].life=0; } } } } //-------------------------------------------------------------- void UpdateExplode (void) { int count; for (count = 0; count < MAX_EXPLODE; count ++) { if (explodedata [count].frame != -1) { explodedata [count].frame++; if (explodedata [count].frame >= 16) { explodedata [count].frame = -1; } } } } //-------------------------------------------------------------- #define FIRE_SPEED 16 void CheckFire (void) { int x; static int on=0; static int slot=0; if (PADstatus & PADRleft) { if (!on) { on=1; fire [slot].y=shipy + 4; fire [slot].speed=speed/2; fire [slot].start=0; fire [slot].end=0; if (shipright) { fire [slot].x=shipx + 24; fire [slot].dir=FIRE_SPEED; } else { fire [slot].x=shipx - 2; fire [slot].dir=-FIRE_SPEED; } slot ++; if (slot >=MAX_FIRE) { slot=0; } SsUtKeyOn (nVab2, 4,0, 48, 0, 64, 64); } } else { on=0; } } //-------------------------------------------------------------- void MoveFire (void) { int count; for (count=0; count < MAX_FIRE; count++) { if (fire [count].start !=-1) { fire [count].x +=fire [count].speed; fire [count].x=ConstrainX (fire[count].x); if ((fire [count].start < 256) && (fire [count].start > -256)) { fire [count].start +=fire [count].dir; } else if ((fire [count].end < 256) && (fire [count].end > -256)) { fire [count].end +=fire [count].dir; } else { fire [count].start=-1; } } } } //-------------------------------------------------------------- void DrawGameScreen (void) { static GsLINE line[8]={{0, 0,10, 320,10, 0,0,255}, {0, 0,58, 320,58, 0,0,255}, {0, 140,10, 180,10, 0,255,255}, {0, 140,58, 180,58, 0,255,255}, {0, 140,10, 140,12, 0,255,255}, {0, 140,56, 140,58, 0,255,255}, {0, 180,10, 180,12, 0,255,255}, {0, 180,56, 180,58, 0,255,255}}; GsSortLine (&line[0], &othWorld[nBuffer], 1); GsSortLine (&line[1], &othWorld[nBuffer], 1); GsSortLine (&line[2], &othWorld[nBuffer], 0); GsSortLine (&line[3], &othWorld[nBuffer], 0); GsSortLine (&line[4], &othWorld[nBuffer], 0); GsSortLine (&line[5], &othWorld[nBuffer], 0); GsSortLine (&line[6], &othWorld[nBuffer], 0); GsSortLine (&line[7], &othWorld[nBuffer], 0); sprintf(tempstring, "%d", lives); DrawText (tempstring, 32,0); sprintf(tempstring, "%d", smart); DrawText (tempstring, 64,0); sprintf(tempstring, "%5.5d", score); DrawText (tempstring, 200,0); sprintf(tempstring, "%5.5d", hiscore); DrawText (tempstring, 264,0); counter ++; if (counter > 8) { counter=0; anim++; if (anim >=3) { anim=0; } } } //-------------------------------------------------------------- void MoveShip (void) { if (PADstatus & PADLup) { shipy -=3; if (shipy < CEILING) { shipy=CEILING; } } else if (PADstatus & PADLdown) { shipy +=3; if (shipy > FLOOR) { shipy=FLOOR; } } if (PADstatus & PADLleft) { shipright=0; } else if (PADstatus & PADLright) { shipright=1; } if (PADstatus & PADRdown) { if (shipright==0) { speed --; if (speed < -SHIP_SPEED) { speed=-SHIP_SPEED; } } else { speed ++; if (speed > SHIP_SPEED) { speed=SHIP_SPEED; } } } else if ((PADstatus & PADL1) || (PADstatus & PADL2)) { shipright=0; speed --; if (speed < -SHIP_SPEED) { speed=-SHIP_SPEED; } } else if ((PADstatus & PADR1) || (PADstatus & PADR2)) { shipright=1; speed ++; if (speed > SHIP_SPEED) { speed=SHIP_SPEED; } } else { if (speed > 0) { speed --; } else if (speed < 0) { speed ++; } } shipx +=speed >> 1; shipx=ConstrainX (shipx); } //-------------------------------------------------------------- void DrawShip (void) { int count; static int rot=0; RECT shiprect; GsIMAGE tim1; GsSPRITE sprite={(1<<6)|(1<<25), 0,0, 0,0, 0, 0,0, 0,0, 255,255,255, 0,0, 0,0, 0}; GsSPRITE ss={(1<<25)|(1<<28)|(1<<30), 0,0, 0,0, 0, 0,0, 0,0, 255,255,255, 0,0, ONE,ONE, 0}; if (shipright) { GsGetTimInfo((u_long *)SHIP_TIM + 1, &tim1); } else { GsGetTimInfo((u_long *)SHIP2_TIM + 1, &tim1); } sprite.x=WorldToScreen (shipx); sprite.y=shipy; sprite.w=tim1.pw; sprite.h=tim1.ph / 3; sprite.u=tim1.px % 64; sprite.v=tim1.py + (sprite.h * (anim % 3)); sprite.tpage=GetTPage(2, 0, tim1.px, tim1.py); GsSortFastSprite(&sprite, &othWorld[nBuffer], 1); if (shield) { shield --; GsGetTimInfo ((u_long *)SHIELD_TIM + 1, &tim1); ss.x=WorldToScreen (shipx) + 11; ss.y=shipy + 4; ss.w=tim1.pw; ss.h=tim1.ph; ss.mx=tim1.pw/2; ss.my=tim1.ph/2; ss.u=tim1.px % 64; ss.v=tim1.py % 256; ss.tpage=GetTPage (2, 0, tim1.px, tim1.py); if (counter >= 4 ) { ss.r=54; ss.g=44; ss.b=54; } else { ss.r=44; ss.g=24; ss.b=44; } for (count=0; count < 4; count++) { rot +=4096; if (count & 1) { ss.rotate=rot + (count * (4096 * 90)); } else { ss.rotate=(-rot) + (count * (4096 * 90)); } GsSortSprite (&ss, &othWorld[nBuffer], 0); } } } //-------------------------------------------------------------- void HyperSpace (void) { static int on=0; if (PADstatus & PADRup) { if (!on) { shipx=rand() % WORLD_SIZE; SsUtKeyOn (nVab, 7,0, 48, 0, 128, 128); on=1; } } else { on=0; } } //-------------------------------------------------------------- int RectInRect (RECT * r1, RECT * r2) { int ret=0; if ((r1->x < (r2->x + r2->w)) && ((r1->x + r1->w) > r2->x)) { if ((r1->y < (r2->y + r2->h)) && ((r1->y + r1->h) > r2->y)) { ret=1; } } return ret; } //-------------------------------------------------------------- void FireAlienCollision (void) { int count; int f; int ax, fx; RECT firerect={0,0,0,2}; RECT alienrect={0,0,8,8}; for (count=0; count < MAX_ALIENS; count++) { if (alien [count].state !=STATE_DEAD) { ax=WorldToScreen (alien [count].x); if ((ax > -8) && (ax < 320)) { for (f=0; f < MAX_FIRE; f++) { if (fire [f].start !=-1) { alienrect.x=alien [count].x; alienrect.y=alien [count].y; if (fire [f].dir > 0) { firerect.x=fire [f].x + fire [f].end; } else { firerect.x=fire [f].x + fire [f].start; } firerect.w=fire [f].start - fire [f].end; if (firerect.w < 0) { firerect.w=0 - firerect.w; } firerect.y=fire [f].y; firerect.x=WorldToScreen (firerect.x); alienrect.x=WorldToScreen (alienrect.x); if (RectInRect (&firerect, &alienrect)) { KillAlien (count); fire [f].start =-1; } } } } } } } //-------------------------------------------------------------- void FireManCollision (void) { int count; int f; int ax, fx; RECT firerect={0,0,0,2}; RECT manrect={0,0,8,8}; for (count=0; count < MAX_MEN; count++) { if (man [count].alive) { ax=WorldToScreen (man [count].x); if ((ax > -8) && (ax < 320)) { for (f=0; f < MAX_FIRE; f++) { if (fire [f].start !=-1) { manrect.x=man [count].x; manrect.y=man [count].y; if (fire [f].dir > 0) { firerect.x=fire [f].x + fire [f].end; } else { firerect.x=fire [f].x + fire [f].start; } firerect.w=fire [f].start - fire [f].end; if (firerect.w < 0) { firerect.w=0 - firerect.w; } firerect.y=fire [f].y; firerect.x=WorldToScreen (firerect.x); manrect.x=WorldToScreen (manrect.x); if (RectInRect (&firerect, &manrect)) { KillMan (count); } } } } } } } //-------------------------------------------------------------- void ShipAlienCollision (void) { int count; RECT shiprect; RECT alienrect; shiprect.x=shipx; shiprect.y=shipy; shiprect.w=22; shiprect.h=8; for (count=0; count < MAX_ALIENS; count++) { if (alien [count].state !=STATE_DEAD) { alienrect.x=alien [count].x; alienrect.y=alien [count].y; alienrect.w=8; alienrect.h=8; if (RectInRect (&shiprect, &alienrect)) { ExplodeShip (shipx, shipy); } } } } //-------------------------------------------------------------- void SmartBomb (void) { int count; int x; static int on=0; if (PADstatus & PADRright) { if ((!on) && (smart)) { clearr=255; clearg=255; clearb=255; SsUtKeyOn (nVab, 0,0, 48, 0, 128, 128); for (count=0; count < MAX_ALIENS; count++) { x=WorldToScreen (alien [count].x); if ((x >=0) && (x < 340)) { KillAlien (count); } } on=1; smart --; } } else { on=0; } } //-------------------------------------------------------------- void DrawTerrain (void) { static GsLINE line; int start,end; int segment; static int slide=SHIP_RIGHT_X; if (shipright) { if (slide > SHIP_RIGHT_X) { slide -=4; } } else if (slide < SHIP_LEFT_X) { slide +=4; } mapx=ConstrainX (shipx - slide); if (mutantflash == -1) { start=(mapx / TERRAIN_LEN); for (segment=0; segment <=8 ; segment ++) { end=start + 1; if (end >=MAX_TERRAIN) { end=0; } line.attribute=0; line.r=255; line.g=0; line.b=0; line.x0=WorldToScreen (start * TERRAIN_LEN); line.x1=line.x0 + TERRAIN_LEN; line.y0=230 - (terrain [start] * TERRAIN_HEIGHT); line.y1=230 - (terrain [end] * TERRAIN_HEIGHT); GsSortLine (&line, &othWorld[nBuffer], 0); start ++; if (start >=MAX_TERRAIN) { start=0; } } } } //-------------------------------------------------------------- void WorldToScanner (int x, int y, GsLINE * line) { line -> x0=((x - mapx) >> 3) + 140; while (line -> x0 < 0) { line -> x0 +=320; } while (line -> x0 >=320) { line -> x0 -=320; } line -> y0=(y >> 2) - 3; line -> x1=line -> x0+1; line -> y1=line -> y0; } //-------------------------------------------------------------- void DrawScanner (void) { int temp; int count; GsIMAGE tim1; GsLINE line={0, 0,0,0,0, 255,255,255}; if (!explode) { WorldToScanner (shipx, shipy, &line); line.x1 +=2; GsSortLine (&line, &othWorld[nBuffer], 0); } for (count=0; count < MAX_ALIENS; count++) { if (alien [count].state !=STATE_DEAD) { switch (alien [count].type) { case ALIEN_LANDER: line.r=0; line.g=200; line.b=0; break; case ALIEN_MUTANT: line.r=200; line.g=0; line.b=200; break; case ALIEN_SWARMER: line.r=255; line.g=0; line.b=0; break; case ALIEN_BOMBER: temp = anim %3; if (temp == 0) { line.r=200; line.g=0; line.b=0; } else if (temp == 1) { line.r=200; line.g=200; line.b=0; } else if (temp == 2) { line.r=0; line.g=0; line.b=255; } break; case ALIEN_BAITER: case ALIEN_POD: line.r=255; line.g=255; line.b=255; break; default: break; } WorldToScanner (alien [count].x, alien [count].y, &line); GsSortLine (&line, &othWorld[nBuffer], 0); } } for (count=0; count < MAX_MEN; count++) { if (man [count].alive) { line.r=0; line.g=100; line.b=200; WorldToScanner (man [count].x, man [count].y, &line); GsSortLine (&line, &othWorld[nBuffer], 0); } } } //-------------------------------------------------------------- void DrawMen (void) { int count; GsIMAGE tim1; GsSPRITE sprite={(1<<6)|(1<<25), 0,0, 0,0, 0, 0,0, 0,0, 255,255,255, 0,0, 0,0, 0}; GsGetTimInfo((u_long *)MAN_TIM+1, &tim1); sprite.u=tim1.px % 64; sprite.v=tim1.py % 256; sprite.w=tim1.pw; sprite.h=tim1.ph; sprite.tpage=GetTPage(2, 0, tim1.px, tim1.py); for (count=0; count < MAX_MEN; count++) { if (man [count].alive) { sprite.x=WorldToScreen (man [count].x); if (OnScreen (sprite.x)) { sprite.y=man [count].y; GsSortFastSprite(&sprite, &othWorld[nBuffer], 0); } } } } //-------------------------------------------------------------- void DrawStatic (void) { int count; GsIMAGE tim1; GsSPRITE sprite={(1<<6)|(1<<25), 0,0, 0,0, 0, 0,0, 0,0, 255,255,255, 0,0, 0,0, 0}; for (count=0; count < MAX_STATIC; count++) { if (staticdata [count].life) { staticdata [count].life --; if (staticdata [count].val==250) { GsGetTimInfo((u_long *)S250_TIM+1, &tim1); } else if (staticdata [count].val==500) { GsGetTimInfo((u_long *)S500_TIM+1, &tim1); } sprite.x=WorldToScreen (staticdata [count].x); sprite.y=staticdata [count].y; sprite.w=tim1.pw; sprite.h=tim1.ph / 3; sprite.u=tim1.px % 64; sprite.v=(tim1.py + ((anim % 3) * 5)) % 256; sprite.tpage=GetTPage(2, 0, tim1.px, tim1.py); GsSortFastSprite(&sprite, &othWorld[nBuffer], 0); } } } //-------------------------------------------------------------- void DrawExplode (void) { int count; GsIMAGE tim1; GsSPRITE sprite={(1<<25), 0,0, 0,0, 0, 0,0, 0,0, 128,128,128, 0,0, 0,0, 0}; for (count=0; count < MAX_EXPLODE; count++) { if (explodedata [count].frame != -1) { GsGetTimInfo ((u_long *)EXPLODE_TIM+1, &tim1); sprite.x = WorldToScreen (explodedata [count].x); sprite.y = explodedata [count].y; sprite.w = 32; sprite.h = 45; sprite.u = (tim1.px + ((explodedata [count].frame & 1) * sprite.w)) % 64; sprite.v = (tim1.py + ((explodedata [count].frame >> 1) * sprite.h)) % 256; sprite.tpage=GetTPage(2, 0, tim1.px, (tim1.py + ((explodedata [count].frame >> 1) * sprite.h))); GsSortFastSprite (&sprite, &othWorld [nBuffer], 0); } } } //-------------------------------------------------------------- void DrawParticles (void) { int count; GsLINE line={0, 0,0,0,0, 128,128,128}; for (count=0; count < MAX_PARTICLES; count++) { if (particle [count].life > 0) { line.x0=WorldToScreen (particle [count].x / SCALE); line.y0=particle [count].y / SCALE; if (line.x0 < 0 || line.x0 > 320) { particle [count].life=0; } else { line.x1=line.x0+2; line.y1=line.y0; line.r = particle [count].life; line.g = particle [count].life; line.b = particle [count].life; GsSortLine (&line, &othWorld[nBuffer], 0); } } } } //-------------------------------------------------------------- void DrawFire (void) { int count; GsGLINE line={0, 0,0,0,0, 50,60,30, 200,230,100}; for (count=0; count < MAX_FIRE; count++) { if (fire [count].start !=-1) { line.x0=WorldToScreen (fire [count].x + fire [count].end); line.x1=line.x0 + fire [count].start; line.y0=fire [count].y; line.y1=line.y0; GsSortGLine (&line, &othWorld[nBuffer], 11); } } } //-------------------------------------------------------------- void DrawAliens (void) { int count; GsIMAGE tim1; GsSPRITE sprite={(1<<6)|(1<<25), 0,0, 0,0, 0, 0,0, 0,0, 255,255,255, 0,0, 0,0, 0}; aliensalive=0; for (count=0; count < MAX_ALIENS; count++) { if (alien [count].state !=STATE_DEAD) { aliensalive ++; switch (alien [count].type) { case ALIEN_LANDER: GsGetTimInfo ((u_long *)LANDER_TIM+1, &tim1); sprite.v=tim1.py % 256; sprite.h=tim1.ph; break; case ALIEN_MUTANT: GsGetTimInfo ((u_long *)MUTANT_TIM+1, &tim1); sprite.v=tim1.py % 256; sprite.h=tim1.ph; break; case ALIEN_BAITER: GsGetTimInfo ((u_long *)BAITER_TIM+1, &tim1); sprite.v=tim1.py % 256; sprite.h=tim1.ph; break; case ALIEN_BOMBER: GsGetTimInfo ((u_long *)BOMBER_TIM+1, &tim1); sprite.h=tim1.ph / 3; sprite.v=(tim1.py % 256) + (sprite.h * (anim % 3)); break; case ALIEN_POD: GsGetTimInfo ((u_long *)POD_TIM+1, &tim1); sprite.v=tim1.py % 256; sprite.h=tim1.ph; break; case ALIEN_SWARMER: GsGetTimInfo ((u_long *)SWARMER_TIM+1, &tim1); sprite.v=tim1.py % 256; sprite.h=tim1.ph; break; default: break; } sprite.u=tim1.px % 64; sprite.w=tim1.pw; sprite.tpage=GetTPage (2, 0, tim1.px, tim1.py); sprite.x=WorldToScreen (alien [count].x); sprite.y=alien [count].y; if (OnScreen (sprite.x)) { GsSortFastSprite(&sprite, &othWorld[nBuffer], 0); } } } } //-------------------------------------------------------------- int GetAlienSlot (void) { int slot=0; while (alien [slot].state !=STATE_DEAD) { slot++; if (slot >=MAX_ALIENS) { printf ("Out of alien slots\n"); return 0; } } return slot; } //-------------------------------------------------------------- #define LANDERS_IN_WAVE 8 #define LANDER_ENTRY_HEIGHT 70 void WarpInLanders (void) { int count; int slot=0; for (count=0; count < LANDERS_IN_WAVE + level; count++) { slot=GetAlienSlot(); if (mutantflash == -1) { alien [slot].type=ALIEN_LANDER; } else { alien [slot].type=ALIEN_MUTANT; } alien [slot].state=STATE_NORMAL; alien [slot].x=rand () % WORLD_SIZE; alien [slot].y=LANDER_ENTRY_HEIGHT + (rand () % LANDER_ENTRY_HEIGHT); alien [slot].xdir=rand () & 1; } SsUtKeyOn (nVab, 7,0, 48, 0, 128, 128); } //-------------------------------------------------------------- void InitialiseLevel (void) { int count; int t; int start; int slot; clearr=0; clearg=0; clearb=0; shipright=1; shipx=SHIP_RIGHT_X; shipy=SHIP_Y; speed=0; pause=2; baiter=BAITER_TIME; wavetime=5; wave=(3 + (level >> 1)); shield=SHIELD_TIME; mutantflash = -1; for (count=0; count < MAX_MEN; count++) { t=((count * 8) + (rand() % 2)); man[count].x=t * TERRAIN_LEN; man[count].x=ConstrainX (man[count].x); man[count].y=233 - (terrain [t] * TERRAIN_HEIGHT); man[count].alive=1; man[count].fall=-1; man[count].grab=-1; } for (count=0; count < MAX_FIRE; count++) { fire [count].start=-1; } for (count=0; count < MAX_ALIENS; count++) { alien [count].state=STATE_DEAD; } for (count = 0; count < MAX_EXPLODE; count ++) { explodedata [count].frame = -1; } if (level > 1) { t=(4 + level) & 0xf; for (count=0; count < t; count++) { if (!count & 0x3) { start=rand () % WORLD_SIZE; } slot=GetAlienSlot(); alien [slot].state=STATE_NORMAL; alien [slot].type=ALIEN_BOMBER; alien [slot].x=ConstrainX (start + (count * 64)); alien [slot].y=CEILING + count * 16; } t=(level >> 1) & 0x7; for (count=0; count < t; count++) { slot=GetAlienSlot(); alien [slot].state=STATE_NORMAL; alien [slot].type=ALIEN_POD; alien [slot].x=ConstrainX (rand () % WORLD_SIZE); alien [slot].y=FLOOR - (rand() % 100); } } } //-------------------------------------------------------------- void InitialiseGame (void) { level=10; score=0; lives=3; smart=3; SsUtKeyOn (nVab, 5,0, 48, 0, 128, 128); } //-------------------------------------------------------------- void FrontendLoop() { int count; char temp[32]; RECT logo; static int timer=0; static int flash=0; if (tune==-10) { tune=SsUtKeyOn (nVab2, 0,0, 60, 0, 128, 128); } logo.x=spritedata [SPRITE_WILLIAMS].px; logo.w=spritedata [SPRITE_WILLIAMS].pw; logo.h=spritedata [SPRITE_WILLIAMS].ph; logo.y=spritedata [SPRITE_WILLIAMS].py; MoveImage (&logo, 124, 8 + (nBuffer * 240)); logo.x=spritedata [SPRITE_LOGO].px; logo.w=spritedata [SPRITE_LOGO].pw; logo.h=spritedata [SPRITE_LOGO].ph; logo.y=spritedata [SPRITE_LOGO].py; MoveImage (&logo, 50, 28 + (nBuffer * 240)); if (timer > 1600) { logo.x=spritedata [SPRITE_HG].px; logo.w=spritedata [SPRITE_HG].pw; logo.h=spritedata [SPRITE_HG].ph; logo.y=spritedata [SPRITE_HG].py; MoveImage (&logo, 68, 149 + (nBuffer * 240)); } else if (timer > 1200) { logo.x=spritedata [SPRITE_SCENE].px; logo.w=spritedata [SPRITE_SCENE].pw; logo.h=spritedata [SPRITE_SCENE].ph; logo.y=spritedata [SPRITE_SCENE].py; MoveImage (&logo, 68, 149 + (nBuffer * 240)); } else if (timer > 600) { logo.x=spritedata [SPRITE_LPAD].px; logo.w=spritedata [SPRITE_LPAD].pw; logo.h=spritedata [SPRITE_LPAD].ph; logo.y=spritedata [SPRITE_LPAD].py; MoveImage (&logo, 50, 149 + (nBuffer * 240)); logo.x=spritedata [SPRITE_RPAD].px; logo.w=spritedata [SPRITE_RPAD].pw; logo.h=spritedata [SPRITE_RPAD].ph; logo.y=spritedata [SPRITE_RPAD].py; MoveImage (&logo, 198, 150 + (nBuffer * 240)); DrawText ("UP" ,74, 143); DrawText ("DOWN",67, 214); DrawText ("LEFT" ,19, 178); DrawText ("RIGHT" ,113, 178); DrawText ("HYPER SPACE" ,188, 143); DrawText ("ACCELERATE" ,192, 214); DrawText ("FIRE" ,168, 178); DrawText ("SMART" ,263, 173); DrawText ("BOMB" ,266, 184); } else if (timer > 200) { logo.x=spritedata [SPRITE_LANDER].px; logo.w=spritedata [SPRITE_LANDER].pw; logo.h=spritedata [SPRITE_LANDER].ph; logo.y=spritedata [SPRITE_LANDER].py; MoveImage (&logo, 73, 130 + (nBuffer * 240)); logo.x=spritedata [SPRITE_MUTANT].px; logo.w=spritedata [SPRITE_MUTANT].pw; logo.h=spritedata [SPRITE_MUTANT].ph; logo.y=spritedata [SPRITE_MUTANT].py; MoveImage (&logo, 153, 130 + (nBuffer * 240)); logo.x=spritedata [SPRITE_BAITER].px; logo.w=spritedata [SPRITE_BAITER].pw; logo.h=spritedata [SPRITE_BAITER].ph; logo.y=spritedata [SPRITE_BAITER].py; MoveImage (&logo, 229, 135 + (nBuffer * 240)); logo.x=spritedata [SPRITE_BOMBER].px; logo.w=spritedata [SPRITE_BOMBER].pw; logo.h=spritedata [SPRITE_BOMBER].ph/3; logo.y=spritedata [SPRITE_BOMBER].py; MoveImage (&logo, 73, 180 + (nBuffer * 240)); logo.x=spritedata [SPRITE_POD].px; logo.w=spritedata [SPRITE_POD].pw; logo.h=spritedata [SPRITE_POD].ph; logo.y=spritedata [SPRITE_POD].py; MoveImage (&logo, 156, 181 + (nBuffer * 240)); logo.x=spritedata [SPRITE_SWARMER].px; logo.w=spritedata [SPRITE_SWARMER].pw; logo.h=spritedata [SPRITE_SWARMER].ph; logo.y=spritedata [SPRITE_SWARMER].py; MoveImage (&logo, 235, 182 + (nBuffer * 240)); DrawText ("LANDER", 56, 144); DrawText ("150", 68, 156); DrawText ("MUTANT", 136, 144); DrawText ("150", 148, 156); DrawText ("BAITER", 216, 144); DrawText ("200", 228, 156); DrawText ("BOMBER", 56, 194); DrawText ("250", 68, 206); DrawText ("POD", 148, 194); DrawText ("1000", 144, 206); DrawText ("SWARMER", 212, 194); DrawText ("150", 228, 206); } else { if (flash > 10) { DrawText ("PRESS START", -1, 160); } flash ++; if (flash > 30) { flash=0; } DrawText ("YAROZE CONVERSION BY BEN JAMES", -1, 210); DrawText ("ADDITIONAL GRAPHICS BY NICK VINCENT", -1, 222); } timer ++; if (timer > 2000) { timer=0; } if (PADstatus & PADstart) { timer=0; state=STATE_GAME; InitialiseGame (); InitialiseLevel (); SsUtKeyOff (tune, nVab2,0,0,60); } } //-------------------------------------------------------------- void AddBaiter (void) { int slot; slot=GetAlienSlot(); SsUtKeyOn (nVab, 7,0, 48, 0, 128, 128); alien [slot].state=STATE_NORMAL; alien [slot].type=ALIEN_BAITER; alien [slot].x=ConstrainX (shipx - (WORLD_SIZE/2)); alien [slot].y=shipy; } //-------------------------------------------------------------- void GameLoop() { static int endtime=50; static int gameover=0; if ((aliensalive==0) && (wave==0)) { endtime--; if (!endtime) { state=STATE_RESULTS; endtime=50; } } baiter--; if (baiter <=0) { AddBaiter(); baiter=BAITER_TIME; } if (wave) { wavetime--; if (wavetime <=0) { WarpInLanders(); wavetime=WAVE_TIME; wave --; } } if (mutantflash > 0) { mutantflash --; if (counter & 8) { clearr=200; clearg=200; clearb=0; } else { clearr=200; clearg=0; clearb=200; } } MoveAliens (); UpdateParticles (); UpdateExplode (); if (!explode) { CheckFire(); GetInput(); HyperSpace(); SmartBomb(); FireAlienCollision(); FireManCollision(); if (!shield) { ShipAlienCollision(); } MoveShip(); } MoveFire (); MoveMen (); if (!explode) { DrawShip(); } DrawGameScreen(); DrawTerrain(); DrawFire(); DrawAliens(); DrawMen(); DrawScanner(); DrawParticles(); DrawStatic(); DrawExplode(); if (explode) { explode--; if (explode==0) { if (lives) { lives --; if (lives==0) { explode=200; gameover=1; } else { shield=SHIELD_TIME; } } else { state=STATE_FRONTEND; tune=-10; } } else { if (lives==0) { DrawText ("GAME OVER", -1, 128); } } } } //-------------------------------------------------------------- void ResultsLoop (void) { int count; int lastscore; static int total=-1; static int timer=250; static int men=0; GsIMAGE tim1; GsSPRITE sprite={(1<<6)|(1<<25), 0,0, 0,0, 0, 0,0, 0,0, 255,255,255, 0,0, 0,0, 0}; if (total==-1) { total=0; for (count=0; count < MAX_MEN; count++) { if (man[count].alive) { total++; } } } else { sprintf (tempstring, "ATTACK WAVE %d COMPLETED", level); DrawText (tempstring, -1, 84); DrawText ("BONUS X 100", -1, 108); if (!(timer % 10)) { if (men < total) { men ++; lastscore=score; score +=100; if ((score / 10000) > (lastscore / 10000)) { lives++; smart++; SsUtKeyOn (nVab, 2,0, 48, 0, 128, 128); } } } GsGetTimInfo ((u_long *)MAN_TIM+1, &tim1); sprite.u=tim1.px % 64; sprite.v=tim1.py % 256; sprite.w=tim1.pw; sprite.h=tim1.ph; sprite.tpage=GetTPage (2, 0, tim1.px, tim1.py); for (count=0; count < men; count++) { sprite.x=124 + (count * 8); sprite.y=132; GsSortFastSprite(&sprite, &othWorld[nBuffer], 0); } } timer --; if (timer <=0) { level++; InitialiseLevel (); timer=250; state=STATE_GAME; total=-1; men=0; } } //-------------------------------------------------------------- int main() { RECT rVMem={0,0,1024,512}; srand(3107); PadInit(); Initialise(); while(!(PADstatus & PADselect)) { FrameStart(); switch (state) { case STATE_FRONTEND: FrontendLoop(); break; case STATE_GAME: GameLoop(); break; case STATE_RESULTS: ResultsLoop(); break; default: break; } FrameEnd(); } SsUtAllKeyOff (0); SsVabClose (nVab2); SsVabClose (nVab); ClearImage (&rVMem,0,0,0); ResetGraph (3); return 0; }