// --- Breach -------------------------------------------------------------- #include #include #include #include #include "pad.h" #include "dms.c" #define OT_LEN 12 #define MAX_PACKETS 51200 #define SCREEN_WIDTH 320 #define SCREEN_HEIGHT 256 #define SOUND_VH 0x80090000 #define SOUND_VB 0x80091a20 #define A1_TIM 0x800a3a10 #define A2_TIM 0x800a4c30 #define A3_TIM 0x800a5e50 #define A4_TIM 0x800a6170 #define A5_TIM 0x800a7390 #define A6_TIM 0x800a85b0 #define A7_TIM 0x800a88d0 #define A8_TIM 0x800a8a10 #define A9_TIM 0x800a9030 #define A10_TIM 0x800a9350 #define A11_TIM 0x800a9590 #define A12_TIM 0x800aa7b0 #define BLUR_TIM 0x800aaad0 #define CIRCLE2_TIM 0x800abcf0 #define FONT_TIM 0x800ac048 #define ION_TIM 0x800ae308 #define LASER2_TIM 0x800ae8e8 #define LOGO_TIM 0x800aefac #define SCENE_TIM 0x800b14cc #define SHIP_TIM 0x800b44ec #define TECHFONT_TIM 0x800b4b0c #define BANG_TIM 0x800b6d4c #define SIDEARM_TIM 0x800baf6c #define MINI_TIM 0x800bb38c #define CASE_TIM 0x800bb6ac #define BEAM_TIM 0x800bb6f0 #define CANNON_TIM 0x800bba30 #define STREAK_TIM 0x800bbe50 #define CYANBLOB_TIM 0x800bc290 #define PERNETIC_VB 0x800bc2d8 #define PERNETIC_VH 0x800e2cf8 #define PERNETIC_DMS 0x800e4d18 #define DOT_TIM 0x800e5f40 #define ELECBALL_TIM 0x800e5f84 #define EXHAUST_TIM 0x800e63e4 #define SNGLSHOT_TIM 0x800e6634 #define SHIELD1_TIM 0x800e66ac #define SHIELD2_TIM 0x800e6f0c #define SOUND2_VB 0x800e776c #define SOUND2_VH 0x800e7d0c #define BLUESHOT_TIM 0x800e972c #define REDSHOT_TIM 0x800e97a4 #define YELLBLOB_TIM 0x800e981c #define LEVEL1_MAR 0x800e986c #define B1_TIM 0x800eab2c #define B10_TIM 0x800eb14c #define B11_TIM 0x800eb76c #define B12_TIM 0x800ebd8c #define B13_TIM 0x800ec3ac #define B14_TIM 0x800ec9cc #define B2_TIM 0x800ecfec #define B3_TIM 0x800ed60c #define B4_TIM 0x800edc2c #define B5_TIM 0x800ee24c #define B6_TIM 0x800ee86c #define B7_TIM 0x800eee8c #define B8_TIM 0x800ef4ac #define B9_TIM 0x800efacc #define SPACE_TIM 0x800f00ec #define NUM_TIM 0x800f332c #define POWERBAR_TIM 0x800f3484 #define B15_TIM 0x800f3664 #define B16_TIM 0x800f3c84 #define B17_TIM 0x800f42a4 #define B18_TIM 0x800f48c4 #define B19_TIM 0x800f4ee4 #define B20_TIM 0x800f5504 #define B21_TIM 0x800f5b24 #define B22_TIM 0x800f6144 #define SHOP_TIM 0x800f6764 #define FLARE1_TIM 0x800fbfbc #define GLARE1_TIM 0x800fc7fc #define GLARE2_TIM 0x800fd03c #define SHOPCELL_TIM 0x800fd87c #define SHOPCURS_TIM 0x800fd93c #define BREACHPAD_TIM 0x800fda9c #define A13_TIM 0x8010455c #define CLAW_TIM 0x8010487c #define ORANGE_TIM 0x8010498c #define PURPLE_TIM 0x801049ec #define GREEN_TIM 0x80104aac #define B23_TIM 0x80104b4c #define B30_TIM 0x8010516c #define END_OF_DATA 0x8010578c #define SCALE 64 #define MAX_FIRE 32 #define MAX_LEVELS 1 #define MAX_ALIENS 64 #define MAX_PARTICLES 64 #define MAX_ALIEN_TYPES 14 #define MAX_MOVE_POINTS 8 #define MAX_MOVE_PATTERNS 2 #define MAX_SCORES 5 #define MAP_WIDTH 12 #define MAP_HEIGHT 200 //-------------------------------------------------------------- typedef signed long flt; #define FIXED_POINT 16 #define FLT_ONE ((flt) (1 << FIXED_POINT)) #define FLT(x) ((flt) ((x) * FLT_ONE)) #define FLT2INT(x) (((int) (x)) >> FIXED_POINT) #define INT2FLT(x) (((flt) (x)) << FIXED_POINT) //-------------------------------------------------------------- typedef enum { FONT_SPRITE = 0, SCENE_SPRITE, BLUR_SPRITE, LOGO_SPRITE, TECHFONT_SPRITE, SHIP_SPRITE, CIRCLE2_SPRITE, CLAW_SPRITE, ORANGE_SPRITE, PURPLE_SPRITE, GREEN_SPRITE, SNGLSHOT_SPRITE, ION_SPRITE, LASER2_SPRITE, SIDEARM_SPRITE, MINI_SPRITE, CASE_SPRITE, BEAM_SPRITE, CANNON_SPRITE, STREAK_SPRITE, CYANBLOB_SPRITE, ELECBALL_SPRITE, DOT_SPRITE, EXHAUST_SPRITE, SHIELD1_SPRITE, SHIELD2_SPRITE, REDSHOT_SPRITE, BLUESHOT_SPRITE, YELLBLOB_SPRITE, NUM_SPRITE, POWERBAR_SPRITE, SHOP_SPRITE, SHOPCELL_SPRITE, SHOPCURS_SPRITE, BREACHPAD_SPRITE, A1_SPRITE, A2_SPRITE, A3_SPRITE, A4_SPRITE, A5_SPRITE, A6_SPRITE, A7_SPRITE, A8_SPRITE, A9_SPRITE, A10_SPRITE, A11_SPRITE, A12_SPRITE, A13_SPRITE, B1_SPRITE, B2_SPRITE, B3_SPRITE, B4_SPRITE, B5_SPRITE, B6_SPRITE, B7_SPRITE, B8_SPRITE, B9_SPRITE, B10_SPRITE, B11_SPRITE, B12_SPRITE, B13_SPRITE, B14_SPRITE, B15_SPRITE, B16_SPRITE, B17_SPRITE, B18_SPRITE, B19_SPRITE, B20_SPRITE, B21_SPRITE, B22_SPRITE, B23_SPRITE, B30_SPRITE, BANG_SPRITE, SPACE_SPRITE, FLARE1_SPRITE, GLARE1_SPRITE, GLARE2_SPRITE, NUM_SPRITES } SPRITE_DATA; typedef enum { STATE_FRONTEND = 0, STATE_LEVELSTART, STATE_GAME, STATE_SHOP, STATE_RESULTS, STATE_INTRO, NUM_GAME_STATES } STATE; typedef enum { PARTICLE_EXPLODE = 0, PARTICLE_CASE, PARTICLE_CYANBLOB, PARTICLE_DOT, NUM_PARTICLE_TYPES } PARTICLE_TYPE; typedef enum { ADDON_NONE = 0, ADDON_MINI, ADDON_ELECBALL, NUM_ADDONS } ADDON_TYPE; typedef struct { int sprite; int * xoff; int height; int space; } FONT_DATA; typedef struct { int x; int y; int ax; int ay; int sprite; int active; int power; } FIRE_DATA; typedef struct { int x [MAX_MOVE_POINTS]; int y [MAX_MOVE_POINTS]; int maxpoints; } MOVE_DATA; typedef struct { int x; int y; int destx; int desty; flt turn; flt dirx; flt diry; flt max; int time; int change; int curpoint; int sprite; int energy; int flag; MOVE_DATA * move; } ALIEN_DATA; typedef struct { int type; int total; int freq; int timer; } SPAWN_DATA; typedef struct { int x; int y; int turnx; int turny; int dirx; int diry; int time; int life; int type; int sprite; int bright; int rot; int rotadd; } PARTICLE_DATA; typedef struct { int score; char name [4]; } SCORE_DATA; //-------------------------------------------------------------- PACKET out_packet[2][MAX_PACKETS]; GsOT othWorld[2]; GsOT_TAG otWorld[2][1< 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); } if ((tim1 -> pmode & 3) == 0) tim1 -> pw *= 4; else if ((tim1 -> pmode & 3) == 1) tim1 -> pw *= 2; DrawSync (0); return 0; } //-------------------------------------------------------------- void Init() { GetPadBuf(&bb0, &bb1); SetVideoMode (MODE_PAL); GsInitGraph (SCREEN_WIDTH, SCREEN_HEIGHT, GsNONINTER|GsOFSGPU, 0, 0); GsDefDispBuff (0, 0, 0, SCREEN_HEIGHT); GsDISPENV.screen.x = 0; GsDISPENV.screen.y = 20; GsDISPENV.screen.w = 320; GsDISPENV.screen.h = 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 (BEAM_TIM, &spritedata [BEAM_SPRITE]); LoadTIM (CANNON_TIM, &spritedata [CANNON_SPRITE]); LoadTIM (STREAK_TIM, &spritedata [STREAK_SPRITE]); LoadTIM (FONT_TIM, &spritedata [FONT_SPRITE]); LoadTIM (SCENE_TIM, &spritedata [SCENE_SPRITE]); LoadTIM (BLUR_TIM, &spritedata [BLUR_SPRITE]); LoadTIM (LOGO_TIM, &spritedata [LOGO_SPRITE]); LoadTIM (TECHFONT_TIM, &spritedata [TECHFONT_SPRITE]); LoadTIM (SHIP_TIM, &spritedata [SHIP_SPRITE]); LoadTIM (CIRCLE2_TIM, &spritedata [CIRCLE2_SPRITE]); LoadTIM (LASER2_TIM, &spritedata [LASER2_SPRITE]); LoadTIM (ION_TIM, &spritedata [ION_SPRITE]); LoadTIM (SIDEARM_TIM, &spritedata [SIDEARM_SPRITE]); LoadTIM (BANG_TIM, &spritedata [BANG_SPRITE]); LoadTIM (MINI_TIM, &spritedata [MINI_SPRITE]); LoadTIM (CASE_TIM, &spritedata [CASE_SPRITE]); LoadTIM (CYANBLOB_TIM, &spritedata [CYANBLOB_SPRITE]); LoadTIM (ELECBALL_TIM, &spritedata [ELECBALL_SPRITE]); LoadTIM (DOT_TIM, &spritedata [DOT_SPRITE]); LoadTIM (EXHAUST_TIM, &spritedata [EXHAUST_SPRITE]); LoadTIM (SNGLSHOT_TIM, &spritedata [SNGLSHOT_SPRITE]); LoadTIM (SHIELD1_TIM, &spritedata [SHIELD1_SPRITE]); LoadTIM (SHIELD2_TIM, &spritedata [SHIELD2_SPRITE]); LoadTIM (REDSHOT_TIM, &spritedata [REDSHOT_SPRITE]); LoadTIM (BLUESHOT_TIM, &spritedata [BLUESHOT_SPRITE]); LoadTIM (YELLBLOB_TIM, &spritedata [YELLBLOB_SPRITE]); LoadTIM (SPACE_TIM, &spritedata [SPACE_SPRITE]); LoadTIM (NUM_TIM, &spritedata [NUM_SPRITE]); LoadTIM (POWERBAR_TIM, &spritedata [POWERBAR_SPRITE]); LoadTIM (SHOP_TIM, &spritedata [SHOP_SPRITE]); LoadTIM (SHOPCELL_TIM, &spritedata [SHOPCELL_SPRITE]); LoadTIM (SHOPCURS_TIM, &spritedata [SHOPCURS_SPRITE]); LoadTIM (GLARE1_TIM, &spritedata [GLARE1_SPRITE]); LoadTIM (GLARE2_TIM, &spritedata [GLARE2_SPRITE]); LoadTIM (FLARE1_TIM, &spritedata [FLARE1_SPRITE]); LoadTIM (BREACHPAD_TIM, &spritedata [BREACHPAD_SPRITE]); LoadTIM (CLAW_TIM, &spritedata [CLAW_SPRITE]); LoadTIM (ORANGE_TIM, &spritedata [ORANGE_SPRITE]); LoadTIM (PURPLE_TIM, &spritedata [PURPLE_SPRITE]); LoadTIM (GREEN_TIM, &spritedata [GREEN_SPRITE]); LoadTIM (B1_TIM, &spritedata [B1_SPRITE]); LoadTIM (B2_TIM, &spritedata [B2_SPRITE]); LoadTIM (B3_TIM, &spritedata [B3_SPRITE]); LoadTIM (B4_TIM, &spritedata [B4_SPRITE]); LoadTIM (B5_TIM, &spritedata [B5_SPRITE]); LoadTIM (B6_TIM, &spritedata [B6_SPRITE]); LoadTIM (B7_TIM, &spritedata [B7_SPRITE]); LoadTIM (B8_TIM, &spritedata [B8_SPRITE]); LoadTIM (B9_TIM, &spritedata [B9_SPRITE]); LoadTIM (B10_TIM, &spritedata [B10_SPRITE]); LoadTIM (B11_TIM, &spritedata [B11_SPRITE]); LoadTIM (B12_TIM, &spritedata [B12_SPRITE]); LoadTIM (B13_TIM, &spritedata [B13_SPRITE]); LoadTIM (B14_TIM, &spritedata [B14_SPRITE]); LoadTIM (B15_TIM, &spritedata [B15_SPRITE]); LoadTIM (B16_TIM, &spritedata [B16_SPRITE]); LoadTIM (B17_TIM, &spritedata [B17_SPRITE]); LoadTIM (B18_TIM, &spritedata [B18_SPRITE]); LoadTIM (B19_TIM, &spritedata [B19_SPRITE]); LoadTIM (B20_TIM, &spritedata [B20_SPRITE]); LoadTIM (B21_TIM, &spritedata [B21_SPRITE]); LoadTIM (B22_TIM, &spritedata [B22_SPRITE]); LoadTIM (B23_TIM, &spritedata [B23_SPRITE]); LoadTIM (B30_TIM, &spritedata [B30_SPRITE]); LoadTIM (A1_TIM, &spritedata [A1_SPRITE]); LoadTIM (A2_TIM, &spritedata [A2_SPRITE]); LoadTIM (A3_TIM, &spritedata [A3_SPRITE]); LoadTIM (A4_TIM, &spritedata [A4_SPRITE]); LoadTIM (A5_TIM, &spritedata [A5_SPRITE]); LoadTIM (A6_TIM, &spritedata [A6_SPRITE]); LoadTIM (A7_TIM, &spritedata [A7_SPRITE]); LoadTIM (A8_TIM, &spritedata [A8_SPRITE]); LoadTIM (A9_TIM, &spritedata [A9_SPRITE]); LoadTIM (A10_TIM, &spritedata [A10_SPRITE]); LoadTIM (A11_TIM, &spritedata [A11_SPRITE]); LoadTIM (A12_TIM, &spritedata [A12_SPRITE]); LoadTIM (A13_TIM, &spritedata [A13_SPRITE]); vab1 = SsVabTransfer ((u_char *)SOUND_VH, (u_char *)SOUND_VB, -1, 1); vab2 = SsVabTransfer ((u_char *)SOUND2_VH, (u_char *)SOUND2_VB, -1, 1); SsSetMVol (127,127); DMSInit(&d, 0, DMS_PAL, (unsigned char *)PERNETIC_VH, (unsigned char *)PERNETIC_VB, (unsigned char *)PERNETIC_DMS); DMSSetMasterVol (&d, 255); srand (VSync(-1)); font.sprite = TECHFONT_SPRITE; font.xoff = &fontpos[0]; font.height = 17; font.space = 8; state = STATE_INTRO; } //-------------------------------------------------------------- void SetDefaultSpriteData (GsSPRITE * sprite, int data) { sprite -> u = spritedata [data].px % 64; sprite -> v = spritedata [data].py % 256; sprite -> w = spritedata [data].pw; sprite -> h = spritedata [data].ph; sprite -> cx = spritedata [data].cx; sprite -> cy = spritedata [data].cy; if ((spritedata [data].pmode & 3) == 0) sprite -> u *= 4; else if ((spritedata [data].pmode & 3) == 1) sprite -> u *= 2; sprite -> tpage = GetTPage (spritedata [data].pmode, 0, spritedata [data].px, spritedata [data].py); sprite -> attribute = ((spritedata [data].pmode & 3)<< 24); sprite -> mx = 0; sprite -> my = 0; sprite -> scalex = ONE; sprite -> scaley = ONE; sprite -> rotate = 0; sprite -> r = 128; sprite -> g = 128; sprite -> b = 128; } //-------------------------------------------------------------- int GetCharXOff (char c) { return (*(font.xoff + (c-33))); } //-------------------------------------------------------------- int GetCharYOff (char c) { int ret = 0; if (c >= '8') { ret += font.height; } if (c >= 'F') { ret += font.height; } if (c >= 'Q') { ret += font.height; } return ret; } //-------------------------------------------------------------- int GetCharWidth (char c) { if (c < 33) { return font.space; } else if (c == '7' || c == 'E' || c == 'P') { return 21; } else { return (GetCharXOff (c+1) - GetCharXOff (c)); } } //-------------------------------------------------------------- int GetFontHeight (void) { return font.height; } //-------------------------------------------------------------- int GetStringLen (char * string) { int len = 0; char c; while (*string) { c = *string; len += GetCharWidth (c) + 1; string++; } return len; } //-------------------------------------------------------------- void DrawText (char * string, int x, int y, int r, int g, int b) { int temp; int width; char cur; GsSPRITE sprite; SetDefaultSpriteData (&sprite, font.sprite); if (r>=0) sprite.attribute |= 1 << 28 | 1 << 30; else { sprite.attribute |= 2 << 28 | 1 << 30; r = -r; g = -g; b = -b; } if (x < 0 || x > SCREEN_WIDTH) { x = (SCREEN_WIDTH - (GetStringLen (string) )) / 2; } sprite.x = x; sprite.y = y; sprite.r = r; sprite.g = g; sprite.b = b; while (*string) { cur = *string; if (cur >= 33) { sprite.u = GetCharXOff (cur); sprite.v = GetCharYOff (cur); sprite.w = GetCharWidth (cur); sprite.h = GetFontHeight () - 1; GsSortFastSprite (&sprite, &othWorld [nBuffer], 0); sprite.x += sprite.w + 1; } else { sprite.x += font.space; } string++; } } //-------------------------------------------------------------- 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; } //-------------------------------------------------------------- int WasButtonPressed (int key) { if ((PADstatus & key) && (!(PADlast & key))) { return 1; } else { return 0; } } //-------------------------------------------------------------- void InitLevel (void) { int count; for (count = 0; count < MAX_FIRE; count++) firedata [count].sprite = -1; for (count = 0; count < MAX_ALIENS; count++) aliendata [count].sprite = -1; for (count = 0; count < MAX_PARTICLES; count++) particledata [count].sprite = -1; shipx = (SCREEN_WIDTH - spritedata [SHIP_SPRITE].pw)/2; shipy = SCREEN_HEIGHT - (spritedata [SHIP_SPRITE].ph*2); gametime = 0; levelrow = ((MAP_HEIGHT-8)<<5)-1; firecount = 0; shield = 100; shieldhit = 0; exhaust = 0; currentspawn = spawndata [MAX_ALIEN_TYPES]; addonlstatus = ADDON_NONE; addonrstatus = ADDON_NONE; } //-------------------------------------------------------------- void InitGame (void) { DMSNoteKeyOffAll (&d); state = STATE_GAME; level = 0; score = 0; pause = 0; credits = 0; weapon = SNGLSHOT_SPRITE; power = 0; addonleft = ADDON_NONE; addonright = ADDON_NONE; InitLevel (); } //-------------------------------------------------------------- #define SHOP_MENU_ITEMS 12 void Shop (void) { static int itemx[SHOP_MENU_ITEMS] = { 78, 98,118,138,158,178,197,217, 90, 90,205,205 }; static int itemy[SHOP_MENU_ITEMS] = { 83, 78, 75, 73, 73, 75, 78, 83,120,140,120,140 }; static int menu = 0; GsSPRITE sprite; DrawText ("- DOCKED -", -1, 16-2, 0,64,64); DrawText ("- DOCKED -", -1, 16, -128,-128,-128); sprintf (tempstring, "CREDITS: %d", credits); DrawText (tempstring, -1, 16-2+15, 0,64,64); DrawText (tempstring, -1, 16+15, -128,-128,-128); DrawText ("PRESS START", -1, SCREEN_HEIGHT - 16 - font.height-2-15, 0,64,64); DrawText ("PRESS START", -1, SCREEN_HEIGHT - 16 - font.height-15, -128,-128,-128); DrawText ("WHEN READY", -1, SCREEN_HEIGHT - 16 - font.height-2, 0,64,64); DrawText ("WHEN READY", -1, SCREEN_HEIGHT - 16 - font.height, -128,-128,-128); SetDefaultSpriteData (&sprite, SHOPCURS_SPRITE); sprite.attribute |= 1 << 28 | 1 << 30; sprite.x = itemx [menu]; sprite.y = itemy [menu]; sprite.r = 80-(time%32); sprite.g = sprite.r; sprite.b = sprite.r; GsSortFastSprite (&sprite, &othWorld [nBuffer], 0); SetDefaultSpriteData (&sprite, SHOP_SPRITE); sprite.x = (SCREEN_WIDTH - spritedata [SHOP_SPRITE].pw) / 2; sprite.y = (SCREEN_HEIGHT - spritedata [SHOP_SPRITE].ph) / 2; GsSortFastSprite (&sprite, &othWorld [nBuffer], 0); if ((WasButtonPressed (PADLleft)) && (menu > 0)) { if (menu <= 7) menu --; if (menu >= 10) menu -= 2; } else if (WasButtonPressed (PADLright)) { if (menu < 7) menu ++; else if ((menu == 8) || (menu == 9)) menu += 2; } if ((WasButtonPressed (PADLup)) && (menu > 7)) { if (menu == 8) menu = 0; else if (menu == 10) menu = 7; else menu --; } else if (WasButtonPressed (PADLdown)) { if (menu <= 3) menu = 8; else if (menu <= 7) menu = 10; else if ((menu == 8) || (menu == 10)) menu ++; } if (WasButtonPressed (PADstart)) { menu = 0; state = STATE_GAME; } } //-------------------------------------------------------------- #define MAX_FLARES 7 void DrawFlare (int x, int y, int bright) { int count; long temp; static int flare [MAX_FLARES] = {-2500,-1500,-500,1000,2500,4000,5000}; static int scale [MAX_FLARES] = {1000,1500,4000,2500,1500,1000,4000}; static CVECTOR color [MAX_FLARES] = {{0,12,12},{0,16,16},{0,10,10},{0,13,13},{0,12,12},{0,10,10},{0,8,8}}; VECTOR line; static int rot = 0; GsSPRITE sprite; if (bright < 0) bright = 0; else if (bright > 128) bright = 128; SetDefaultSpriteData (&sprite, GLARE1_SPRITE); sprite.x = x; sprite.y = y; sprite.mx = spritedata [GLARE1_SPRITE].pw / 2; sprite.my = spritedata [GLARE1_SPRITE].ph / 2; sprite.attribute |= 1 << 28 | 1 << 30; sprite.rotate = rot; sprite.r = bright / 4; sprite.g = bright / 3; sprite.b = bright / 3; GsSortSprite (&sprite, &othWorld[nBuffer], 0); SetDefaultSpriteData (&sprite, GLARE2_SPRITE); sprite.x = x; sprite.y = y; sprite.mx = spritedata [GLARE2_SPRITE].pw / 2; sprite.my = spritedata [GLARE2_SPRITE].ph / 2; sprite.attribute |= 1 << 28 | 1 << 30; sprite.rotate = -rot; sprite.r = bright / 4; sprite.g = bright / 3; sprite.b = bright / 3; GsSortSprite (&sprite, &othWorld[nBuffer], 0); line.vx = (SCREEN_WIDTH / 2) - x; line.vy = (SCREEN_HEIGHT / 2) - y; for (count = 0; count < MAX_FLARES; count++) { SetDefaultSpriteData (&sprite, FLARE1_SPRITE); temp = (line.vx * flare [count]) / ONE; sprite.x = (short)temp + (SCREEN_WIDTH / 2); temp = (line.vy * flare [count]) / ONE; sprite.y = (short)temp + (SCREEN_HEIGHT / 2); sprite.mx = spritedata [FLARE1_SPRITE].pw / 2; sprite.my = spritedata [FLARE1_SPRITE].ph / 2; sprite.scalex = scale [count]; sprite.scaley = scale [count]; temp = (color [count].r * bright) / 128; sprite.r = (unsigned char)temp; temp = (color [count].g * bright) / 128; sprite.g = (unsigned char)temp; temp = (color [count].b * bright) / 128; sprite.b = (unsigned char)temp; sprite.attribute |= 1 << 28 | 1 << 30; GsSortSprite (&sprite, &othWorld[nBuffer], 0); } rot += 2048; } //-------------------------------------------------------------- #define SPACE_AREA 1024 #define SPACE_xTURN (FLT (0.05)) #define SPACE_YTURN (FLT (0.025)) #define SPACE_MAX (FLT (6.0)) void DrawSpace (int timer) { flt starx = FLT (SPACE_AREA + (SPACE_AREA / 2)); flt stary = FLT (SPACE_AREA + (SPACE_AREA / 2)); static flt x = FLT (SPACE_AREA + (SPACE_AREA / 2) - (SCREEN_WIDTH / 2)); static flt y = FLT (SPACE_AREA + (SPACE_AREA / 2) - (SCREEN_HEIGHT / 2)); static flt ax; static flt ay; static flt dx; static flt dy; GsSPRITE sprite; if (x > dx) ax -= SPACE_xTURN; else if (x < dx) ax += SPACE_xTURN; if (y > dy) ay -= SPACE_YTURN; else if (y < dy) ay += SPACE_YTURN; if (ax > SPACE_MAX) ax = SPACE_MAX; else if (ax < -SPACE_MAX) ax = -SPACE_MAX; if (ay > SPACE_MAX) ay = SPACE_MAX; else if (ay < -SPACE_MAX) ay = -SPACE_MAX; x += ax; y += ay; if (!(timer % 500)) { dx = FLT ((rand() % SPACE_AREA) + SPACE_AREA); dy = FLT ((rand() % SPACE_AREA) + SPACE_AREA); } if ((starx > (x-32)) && (starx < (x + FLT(SCREEN_WIDTH+32))) && (stary > (y-32)) && (stary < (y + FLT(SCREEN_HEIGHT+32)))) { int brightx = FLT2INT (starx - (x + FLT (SCREEN_WIDTH / 2) )); int brighty = FLT2INT (stary - (y + FLT (SCREEN_HEIGHT / 2) )); if (brightx < 0) brightx = -brightx; if (brighty < 0) brighty = -brighty; DrawFlare (FLT2INT (starx - x), FLT2INT (stary - y), 128 - ((brightx/3) + (brighty/3))); } SetDefaultSpriteData (&sprite, SPACE_SPRITE); sprite.r = 100 + (rand () % 16); sprite.g = sprite.r; sprite.b = sprite.r; sprite.x = -((FLT2INT(x)) % spritedata [SPACE_SPRITE].pw); sprite.y = -((FLT2INT(y)) % spritedata [SPACE_SPRITE].ph); GsSortFastSprite (&sprite, &othWorld [nBuffer], 10); sprite.x += spritedata [SPACE_SPRITE].pw; GsSortFastSprite (&sprite, &othWorld [nBuffer], 10); sprite.x += spritedata [SPACE_SPRITE].pw; GsSortFastSprite (&sprite, &othWorld [nBuffer], 10); sprite.x -= spritedata [SPACE_SPRITE].pw * 2; sprite.y += spritedata [SPACE_SPRITE].ph; GsSortFastSprite (&sprite, &othWorld [nBuffer], 10); sprite.x += spritedata [SPACE_SPRITE].pw; GsSortFastSprite (&sprite, &othWorld [nBuffer], 10); sprite.x += spritedata [SPACE_SPRITE].pw; GsSortFastSprite (&sprite, &othWorld [nBuffer], 10); sprite.x -= spritedata [SPACE_SPRITE].pw * 2; sprite.y += spritedata [SPACE_SPRITE].ph; GsSortFastSprite (&sprite, &othWorld [nBuffer], 10); sprite.x += spritedata [SPACE_SPRITE].pw; GsSortFastSprite (&sprite, &othWorld [nBuffer], 10); sprite.x += spritedata [SPACE_SPRITE].pw; GsSortFastSprite (&sprite, &othWorld [nBuffer], 10); } //-------------------------------------------------------------- void FrontendLoop (void) { int count; static int init = 0; static int timer; GsSPRITE sprite; if (init == 0) { DMSSongReset (&d); SetFrameSTP(); SetBlurParam (ONE, ONE, 0, 127,127,127); init = 1; timer = 0; } DrawSpace (timer); if (timer < 300) { SetDefaultSpriteData (&sprite, LOGO_SPRITE); sprite.x = (SCREEN_WIDTH - spritedata [LOGO_SPRITE].pw) / 2; sprite.y = (SCREEN_HEIGHT - spritedata [LOGO_SPRITE].ph) / 2; GsSortFastSprite (&sprite, &othWorld [nBuffer], 0); DrawText ("DEMO VERSION", -1, 85, 4, 16, 16); if (timer > 100) DrawText ("PRESS START", -1, 160, 16, 64-(time%32), 64-(time%32)); } else if (timer < 1100) { DrawText ("CONTROLS", -1, 45, 16,32,32); SetDefaultSpriteData (&sprite, BREACHPAD_SPRITE); sprite.attribute |= 1 << 28 | 1 << 30; sprite.r = 48; sprite.g = 48; sprite.b = 48; sprite.x = (SCREEN_WIDTH - spritedata [BREACHPAD_SPRITE].pw) / 2; sprite.y = (SCREEN_HEIGHT - spritedata [BREACHPAD_SPRITE].ph) / 2; GsSortFastSprite (&sprite, &othWorld [nBuffer], 0); } else if (timer < 1500) { DrawText ("TODAYS", -1, 50, 16,32,32); DrawText ("BEST SCORES", -1, 65, 16,32,32); for (count = 0; count < MAX_SCORES; count++) { DrawText (scoredata[count].name, 50 + (count*4), 95+(count*15), 8,24,24); sprintf (tempstring, "%d", scoredata [count].score); DrawText (tempstring, 140 + (count*4), 95+(count*15), 0,16,16); } } else if (timer < 1700) { DrawText ("CREDITS", -1, 50, 16,32,32); DrawText ("GAME", -1, 80, 0,16,16); DrawText ("BEN JAMES", -1, 95, 16,32,32); DrawText ("MUSIC PLAYER", -1, 120, 0,16,16); DrawText ("ELLIOT LEE", -1, 135, 16,32,32); DrawText ("ADDITONAL GFX", -1, 160, 0,16,16); DrawText ("RAY LARABIE", -1, 175, 16,32,32); } timer ++; if (timer > 1900) timer = 0; if (WasButtonPressed (PADstart)) { init = 0; InitGame (); } } //---------------------------------------------------------------- int InitParticle (int x, int y, int type) { int count; for (count = 0; count < MAX_PARTICLES; count++) { if (particledata [count].sprite == -1) { particledata [count] = defaultparticledata [type]; particledata [count].x = x; particledata [count].y = y; return count; } } return 0; } //-------------------------------------------------------------- void UpdateFire (void) { int count; for (count = 0; count < MAX_FIRE; count++) { if (firedata [count].active == 0) firedata [count].sprite = -1; if (firedata [count].sprite != -1) { firedata [count].x += firedata [count].ax; firedata [count].y += firedata [count].ay; if (firedata [count].x < -spritedata [firedata [count].sprite].pw) firedata [count].sprite = -1; else if (firedata [count].x > SCREEN_WIDTH) firedata [count].sprite = -1; else if (firedata [count].y < -spritedata [firedata [count].sprite].ph) firedata [count].sprite = -1; else if (firedata [count].y > SCREEN_HEIGHT) firedata [count].sprite = -1; } } } //-------------------------------------------------------------- void AddFire (int x, int y, int ax, int ay, int sprite) { int count; for (count = 0; count < MAX_FIRE; count++) { if (firedata [count].sprite == -1) { firedata [count].x = x; firedata [count].y = y; firedata [count].ax = ax; firedata [count].ay = ay; firedata [count].sprite = sprite; firedata [count].active = 1; switch (weapon) { case PURPLE_SPRITE: firedata [count].power = 1; break; case SNGLSHOT_SPRITE: firedata [count].power = 1; break; case LASER2_SPRITE: firedata [count].power = 4; break; default: firedata [count].power = 1; break; } count = MAX_FIRE; } } } //-------------------------------------------------------------- void FireWeapons () { int count; if (firecount) return; switch (weapon) { case SNGLSHOT_SPRITE: if (power == 0) { AddFire (shipx + 8, shipy - 8, 0, -11, BLUESHOT_SPRITE); AddFire (shipx + 21, shipy - 8, 0, -11, BLUESHOT_SPRITE); } if (power == 1) { AddFire (shipx + 8, shipy - 8, -1, -11, REDSHOT_SPRITE); AddFire (shipx + 14, shipy - 12, 0, -11, REDSHOT_SPRITE); AddFire (shipx + 21, shipy - 8, 1, -11, REDSHOT_SPRITE); } if (power == 2) { AddFire (shipx + 4, shipy - 4, -2, -11, SNGLSHOT_SPRITE); AddFire (shipx + 8, shipy - 8, -1, -11, SNGLSHOT_SPRITE); AddFire (shipx + 14, shipy - 12, 0, -11, SNGLSHOT_SPRITE); AddFire (shipx + 21, shipy - 8, 1, -11, SNGLSHOT_SPRITE); AddFire (shipx + 25, shipy - 4, 2, -11, SNGLSHOT_SPRITE); } firecount = 8; SsUtKeyOn (vab2, 0,0, 36, 0, 64,64); break; case CIRCLE2_SPRITE: if (power == 0) AddFire (shipx + 4, shipy - 14, 0, -10, CIRCLE2_SPRITE); if (power == 1) { AddFire (shipx + 4, shipy - 12, -1, -9, CIRCLE2_SPRITE); AddFire (shipx + 4, shipy - 12, 1, -9, CIRCLE2_SPRITE); } if (power == 2) { AddFire (shipx + 4, shipy - 14, 0, -10, CIRCLE2_SPRITE); AddFire (shipx + 4, shipy - 12, -3, -8, CIRCLE2_SPRITE); AddFire (shipx + 4, shipy - 12, 3, -8, CIRCLE2_SPRITE); } firecount = 6; SsUtKeyOn (vab2, 0,0, 36, 0, 64,64); break; case ION_SPRITE: if (power == 0) AddFire (shipx, shipy - 16, 0, -13, ION_SPRITE); if (power == 1) { AddFire (shipx, shipy - 16, -1, -12, ION_SPRITE); AddFire (shipx, shipy - 16, 1, -12, ION_SPRITE); } if (power == 2) { AddFire (shipx, shipy - 16, 0, -13, ION_SPRITE); AddFire (shipx, shipy - 16, -2, -12, ION_SPRITE); AddFire (shipx, shipy - 16, 2, -12, ION_SPRITE); } firecount = 12; SsUtKeyOn (vab1, 7,0, 36, 0, 64,64); break; case LASER2_SPRITE: if (power == 0) AddFire (shipx + 5, shipy - 22, 0, -26, LASER2_SPRITE); if (power == 1) { AddFire (shipx + 5, shipy - 22, -2, -26, LASER2_SPRITE); AddFire (shipx + 5, shipy - 22, 2, -26, LASER2_SPRITE); } if (power == 2) { AddFire (shipx + 5, shipy - 22, 0, -26, LASER2_SPRITE); AddFire (shipx + 5, shipy - 22, -4, -26, LASER2_SPRITE); AddFire (shipx + 5, shipy - 22, 4, -26, LASER2_SPRITE); } firecount = 8; SsUtKeyOn (vab1, 6,0, 36, 0, 48,48); break; case CLAW_SPRITE: AddFire (shipx + 8, shipy - 16, 0, -16, CLAW_SPRITE); firecount = 6; SsUtKeyOn (vab2, 0,0, 36, 0, 64,64); break; case ORANGE_SPRITE: AddFire (shipx + 12, shipy - 2, 0, -16, ORANGE_SPRITE); AddFire (shipx + 12, shipy - 16, 0, -16, ORANGE_SPRITE); firecount = 10; SsUtKeyOn (vab2, 0,0, 36, 0, 64,64); break; case PURPLE_SPRITE: for (count = 0; count < (power+2) * 3; count++) AddFire (shipx + 4 + (rand() & 7), shipy - 8 + (rand() & 15), (rand() % ((power+1)*2) ) - power, -(6+(rand()&3)), PURPLE_SPRITE); firecount = 16; SsUtKeyOn (vab2, 0,0, 36, 0, 64,64); break; case GREEN_SPRITE: AddFire (shipx + 12, shipy - 15, 0, -16, GREEN_SPRITE); firecount = 6; SsUtKeyOn (vab2, 0,0, 36, 0, 64,64); break; default: break; } } //-------------------------------------------------------------- void FireLeftAddOn(void) { int p; if (addonlstatus != addonleft) { addonlstatus = addonleft; switch (addonleft) { case ADDON_MINI: addlsound = SsUtKeyOn (vab1, 1,0, 48, 0, 64, 64); break; } } switch (addonleft) { case ADDON_MINI: AddFire (shipx - 4, shipy - 32, 0, -32 - (rand () % 32), MINI_SPRITE); p = InitParticle (shipx - 5, shipy + 16, PARTICLE_CASE); particledata [p].dirx = -4-(rand() % 4); particledata [p].diry = 2-(rand() % 2); particledata [p].rot = (rand () % 360) * ONE; particledata [p].rotadd = (rand () % (ONE * 60)) - (ONE * 30); // p = InitParticle (shipx - 5, shipy + 16, PARTICLE_SMOKE); // particledata [p].dirx = -4-(rand() % 4); // particledata [p].diry = 2-(rand() % 2); // particledata [p].rot = rand () % (ONE * 360); // particledata [p].rotadd = (ONE * 4); break; default: break; } } //-------------------------------------------------------------- void FireLeftAddOff(void) { if (addonlstatus == ADDON_MINI) { SsUtKeyOff (addlsound, vab1, 1, 0, 48); SsUtKeyOn (vab1, 2,0, 48, 0, 64, 64); } addonlstatus = ADDON_NONE; } //-------------------------------------------------------------- void FireRightAddOn (void) { switch (addonright) { case ADDON_ELECBALL: AddFire (shipx + 22, shipy - 60, 0, -32, ELECBALL_SPRITE); break; default: break; } } //-------------------------------------------------------------- void FireRightAddOff(void) { addonrstatus = ADDON_NONE; } //-------------------------------------------------------------- #define DEAD_ZONE 32 void GetPlayerInput () { int ax,ay; if (*(bb0+1) >> 4 == 7) { ax = (*(bb0+6)) - 128; ay = (*(bb0+7)) - 128; if (ax < DEAD_ZONE && ax > -DEAD_ZONE) ax = 0; if (ay < DEAD_ZONE && ay > -DEAD_ZONE) ay = 0; shipx += ax >> 5; shipy += ay >> 5; exhaust = -(ay >> 3); } else { if (PADstatus & PADLleft) shipx -= 4; else if (PADstatus & PADLright) shipx += 4; if (PADstatus & PADLup) { shipy -= 4; exhaust = (4 * 2); } else if (PADstatus & PADLdown) shipy += 4; } if (shipx < 0) shipx = 0; else if (shipx > SCREEN_WIDTH - spritedata [SHIP_SPRITE].pw) shipx = SCREEN_WIDTH - spritedata [SHIP_SPRITE].pw; if (shipy < 0) shipy = 0; else if (shipy > SCREEN_HEIGHT - spritedata [SHIP_SPRITE].ph) shipy = SCREEN_HEIGHT - spritedata [SHIP_SPRITE].ph; if (PADstatus & PADRdown) FireWeapons(); /* if (PADstatus & PADRleft) FireLeftAddOn(); else FireLeftAddOff();*/ /* if (PADstatus & PADRright) FireRightAddOn(); else FireRightAddOff();*/ if (WasButtonPressed (PADcircle)) { switch (weapon) { case PURPLE_SPRITE: weapon = SNGLSHOT_SPRITE; break; case SNGLSHOT_SPRITE: weapon = LASER2_SPRITE; break; case LASER2_SPRITE: weapon = PURPLE_SPRITE; break; default: weapon = SNGLSHOT_SPRITE; break; } } else if (WasButtonPressed (PADsquare)) { switch (weapon) { case PURPLE_SPRITE: weapon = LASER2_SPRITE; break; case SNGLSHOT_SPRITE: weapon = PURPLE_SPRITE; break; case LASER2_SPRITE: weapon = SNGLSHOT_SPRITE; break; default: weapon = SNGLSHOT_SPRITE; break; } } /* if (WasButtonPressed (PADL2)) { power ++; if (power >= 3) power = 0; }*/ if (WasButtonPressed (PADR1)) { shieldhit = 30; SsUtKeyOn (vab1, 3,0, 48, 0, 128, 128); } } //---------------------------------------------------------------- void UpdateDeathSeq (void) { int p; int count; static timer = 0; timer ++; if (timer < 50) { if (timer == 1) { for (count = 0; count < 32; count++) { p = InitParticle (shipx + (rand()%32), shipy + (rand()%32), PARTICLE_DOT); particledata [p].dirx = (rand () % 6) - 3; particledata [p].diry = (rand () % 6) - 3; particledata [p].life = 100; p = InitParticle (shipx + (rand()%32), shipy + (rand()%32), PARTICLE_CYANBLOB); particledata [p].dirx = (rand () % 4) - 2; particledata [p].diry = (rand () % 4) - 2; particledata [p].life = 100; } } if (!(timer % 5)) { SsUtKeyOn (vab1, 4,0, 44 + (rand()%6), 0, 128, 128); p = InitParticle (shipx + (rand()%16), shipy + (rand()%16), PARTICLE_EXPLODE); } DrawFlare (shipx+16, shipy+16, 50-timer + (rand()%50) ); } else if (timer < 550) { DrawText ("GAME OVER", -1, ((SCREEN_HEIGHT - font.height) / 2)-2, 32, 64,64); DrawText ("GAME OVER", -1, ((SCREEN_HEIGHT - font.height) / 2), -128,-128,-128); } else { timer = 0; state = STATE_FRONTEND; } if (WasButtonPressed (PADcross)) { timer = 550; } } //---------------------------------------------------------------- void UpdateParticles (void) { int count; for (count = 0; count < MAX_PARTICLES; count++) { if (particledata [count].sprite != -1) { particledata [count].time ++; if (particledata [count].time >= particledata [count].life) particledata[count].sprite = -1; else { particledata [count].x += particledata [count].dirx; particledata [count].y += particledata [count].diry; particledata [count].dirx += particledata [count].turnx; if (particledata [count].dirx == 0) particledata [count].turnx = 0; particledata [count].diry += particledata [count].turny; // if (particledata [count].diry == 0) // particledata [count].turny = 0; particledata [count].rot += particledata [count].rotadd; particledata [count].bright -= (127 / particledata [count].life); } } } } //---------------------------------------------------------------- void DrawParticles (void) { int count; GsSPRITE sprite; for (count = 0; count < MAX_PARTICLES; count++) { if (particledata [count].sprite != -1) { SetDefaultSpriteData (&sprite, particledata [count].sprite); sprite.x = particledata [count].x; sprite.y = particledata [count].y; switch (particledata [count].sprite) { case BANG_SPRITE: sprite.w /= 4; sprite.h /= 4; sprite.u = (particledata [count].time & 3) * sprite.w; sprite.v = (particledata [count].time >> 2) * sprite.h; break; default: sprite.r = particledata [count].bright/2; sprite.g = particledata [count].bright/2; sprite.b = particledata [count].bright/2; break; } sprite.attribute |= 1 << 28 | 1 << 30; if (particledata [count].rot) { sprite.rotate = particledata [count].rot; sprite.mx = spritedata [particledata [count].sprite].pw / 8; sprite.my = spritedata [particledata [count].sprite].ph / 2; GsSortSprite (&sprite, &othWorld [nBuffer], 0); } else GsSortFastSprite (&sprite, &othWorld [nBuffer], 0); } } } //---------------------------------------------------------------- int InitAlien (int type) { int count; for (count = 0; count < MAX_ALIENS; count++) { if (aliendata [count].sprite == -1) { aliendata [count] = defaultaliendata [type]; if (aliendata [count].x < 0) aliendata [count].x = (rand () % (SCREEN_WIDTH/2)) + SCREEN_WIDTH/4; aliendata [count].destx = aliendata [count].move -> x [0]; aliendata [count].desty = aliendata [count].move -> y [0]; return count; } } return 0; } //---------------------------------------------------------------- void UpdateAliens (void) { int a; int count; for (count = 0; count < MAX_ALIENS; count++) { if (aliendata [count].sprite != -1) { aliendata [count].x += FLT2INT (aliendata [count].dirx); aliendata [count].y += FLT2INT (aliendata [count].diry); if (aliendata [count].flag > 0) aliendata [count].flag --; if (aliendata [count].move) { if ((aliendata [count].x < aliendata [count].destx) && (aliendata [count].dirx < aliendata [count].max)) aliendata [count].dirx += aliendata [count].turn; else if ((aliendata [count].x > aliendata [count].destx) && (aliendata [count].dirx > -aliendata [count].max)) aliendata [count].dirx -= aliendata [count].turn; if ((aliendata [count].y < aliendata [count].desty) && (aliendata [count].diry < aliendata [count].max)) aliendata [count].diry += aliendata [count].turn; else if ((aliendata [count].y > aliendata [count].desty) && (aliendata [count].diry > -aliendata [count].max)) aliendata [count].diry -= aliendata [count].turn; aliendata [count].time ++; if (!(rand () % 100)) { a = InitAlien (MAX_ALIEN_TYPES-1); aliendata[a].x = aliendata [count].x; aliendata[a].y = aliendata [count].y; if (!(rand() % 3)) aliendata[a].dirx = FLT (1.0); else if (!(rand() % 2)) { aliendata[a].dirx = FLT (1.0); aliendata[a].dirx = -aliendata[a].dirx; } } if (aliendata [count].time > aliendata [count].change) { aliendata [count].time = 0; aliendata [count].curpoint++; if (aliendata [count].curpoint >= aliendata [count].move -> maxpoints) aliendata [count].sprite = -1; aliendata [count].destx = aliendata [count].move -> x [aliendata [count].curpoint]; aliendata [count].desty = aliendata [count].move -> y [aliendata [count].curpoint]; } } else { if (aliendata [count].x < -spritedata [aliendata [count].sprite].pw) aliendata [count].sprite = -1; else if (aliendata [count].x > SCREEN_WIDTH) aliendata [count].sprite = -1; else if (aliendata [count].y < -spritedata [aliendata [count].sprite].ph) aliendata [count].sprite = -1; else if (aliendata [count].y > SCREEN_HEIGHT) aliendata [count].sprite = -1; } } } } //-------------------------------------------------------------- void DrawAliens (void) { int count; GsSPRITE sprite; for (count = 0; count < MAX_ALIENS; count++) { if (aliendata [count].sprite != -1) { SetDefaultSpriteData (&sprite, aliendata [count].sprite); sprite.x = aliendata [count].x; sprite.y = aliendata [count].y; sprite.r = 64; sprite.g = 64; sprite.b = 64; switch (aliendata [count].sprite) { default: sprite.attribute |= 1 << 28 | 1 << 30; break; } if (aliendata [count].flag) { sprite.r = 255; sprite.g = 255; sprite.b = 255; } GsSortFastSprite (&sprite, &othWorld [nBuffer], 0); } } } //-------------------------------------------------------------- void KillAlien (int acount) { int count; int p; SsUtKeyOn (vab1, 4,0, 48, 0, 128, 128); aliendata [acount].sprite = -1; p = InitParticle (aliendata [acount].x - 8, aliendata [acount].y - 8, PARTICLE_EXPLODE); particledata [p].dirx = FLT2INT (aliendata [acount].dirx); particledata [p].diry = FLT2INT (aliendata [acount].diry); for (count = 0; count < 8; count++) { p = InitParticle (aliendata [acount].x + 8, aliendata [acount].y + 8, PARTICLE_DOT); particledata [p].dirx = (rand () % 6) - 3 + FLT2INT (aliendata [acount].dirx); particledata [p].diry = (rand () % 6) - 3 + FLT2INT (aliendata [acount].diry); } score += 10; } //-------------------------------------------------------------- void Collision (void) { int fcount; int acount; RECT frect; RECT arect; for (fcount = 0; fcount < MAX_FIRE; fcount++) { if (firedata [fcount].sprite != -1) { frect.x = firedata [fcount].x; frect.y = firedata [fcount].y; frect.w = spritedata [firedata [fcount].sprite].pw; frect.h = spritedata [firedata [fcount].sprite].ph; for (acount = 0; acount < MAX_ALIENS; acount++) { if ((aliendata [acount].sprite != -1) && (aliendata [acount].sprite != YELLBLOB_SPRITE)) { arect.x = aliendata [acount].x + 3; arect.y = aliendata [acount].y + 3; arect.w = spritedata [aliendata [acount].sprite].pw - 3; arect.h = spritedata [aliendata [acount].sprite].ph - 3; if (RectInRect (&frect, &arect)) { firedata [fcount].active = 0; aliendata [acount].energy -= firedata [fcount].power; aliendata [acount].flag = 2; if (aliendata [acount].energy <= 0) { KillAlien (acount); } } } } } } frect.x = shipx+4; frect.y = shipy+4; frect.w = 24; frect.h = 24; for (acount = 0; acount < MAX_ALIENS; acount++) { if (aliendata [acount].sprite != -1) { arect.x = aliendata [acount].x + 3; arect.y = aliendata [acount].y + 3; arect.w = spritedata [aliendata [acount].sprite].pw - 3; arect.h = spritedata [aliendata [acount].sprite].ph - 3; if (RectInRect (&frect, &arect)) { shieldhit = 30; SsUtKeyOn (vab1, 3,0, 48, 0, 100, 100); KillAlien (acount); } } } } //-------------------------------------------------------------- void UpdateGame (void) { static unsigned char * lastmap = NULL; unsigned char * map; unsigned char cell; if (pause) return; else if (WasButtonPressed (PADstart)) pause = 1; if (WasButtonPressed (PADR2)) state = STATE_SHOP; gametime ++; if (gametime & 1) { if (levelrow > 0) levelrow --; } if (firecount > 0) firecount--; if (shieldhit > 0) { shield--; shieldhit -= 4; if (shieldhit < 0) shieldhit = 0; } if (exhaust > 0) exhaust--; UpdateFire (); UpdateAliens (); UpdateParticles (); if (shield > 0) { Collision (); GetPlayerInput (); } else { UpdateDeathSeq(); } map = (unsigned char *)LEVEL1_MAR + ((levelrow >> 5) * (MAP_WIDTH * 2)); if (map != lastmap) { lastmap = map; cell = (*map) >> 5; cell |= ((*(map+1)) & 0x07) << 4; // if (cell) // currentspawn = spawndata [cell-1]; } if (currentspawn.total > 0) { currentspawn.timer--; if (currentspawn.timer <= 0) { currentspawn.total--; currentspawn.timer = currentspawn.freq; InitAlien (currentspawn.type); } } else { currentspawn = spawndata [6 + (rand()%7)]; } } //-------------------------------------------------------------- void DrawFire () { int count; GsSPRITE sprite; for (count = 0; count < MAX_FIRE; count++) { if (firedata [count].sprite != -1) { SetDefaultSpriteData (&sprite, firedata [count].sprite); sprite.attribute |= 1 << 28 | 1 << 30; sprite.x = firedata [count].x; sprite.y = firedata [count].y; GsSortFastSprite (&sprite, &othWorld [nBuffer], 0); } } } //-------------------------------------------------------------- void DrawBG (void) { int x; int y; unsigned char * map; unsigned char cell; GsSPRITE sprite; SetDefaultSpriteData (&sprite, SPACE_SPRITE); sprite.r = 64 + (rand () % 16); sprite.g = sprite.r; sprite.b = sprite.r; sprite.y = -(levelrow >> 1) % spritedata [SPACE_SPRITE].ph; sprite.x = 0; GsSortFastSprite (&sprite, &othWorld [nBuffer], 10); sprite.x += spritedata [SPACE_SPRITE].pw; GsSortFastSprite (&sprite, &othWorld [nBuffer], 10); sprite.y += spritedata [SPACE_SPRITE].ph; sprite.x = 0; GsSortFastSprite (&sprite, &othWorld [nBuffer], 10); sprite.x += spritedata [SPACE_SPRITE].pw; GsSortFastSprite (&sprite, &othWorld [nBuffer], 10); sprite.y += spritedata [SPACE_SPRITE].ph; sprite.x = 0; GsSortFastSprite (&sprite, &othWorld [nBuffer], 10); sprite.x += spritedata [SPACE_SPRITE].pw; GsSortFastSprite (&sprite, &othWorld [nBuffer], 10); map = (unsigned char *)LEVEL1_MAR + ((levelrow >> 5) * (MAP_WIDTH * 2)); for (y = 0; y < 9; y++) { map += 4; for (x = 0; x < 10; x++) { cell = (*map) >> 5; cell |= (*(map+1)) << 3; if (cell) { SetDefaultSpriteData (&sprite, B1_SPRITE + cell - 1); sprite.x = x * 32; sprite.y = (y * 32) - (levelrow & 31); if (x > 4) sprite.r = 9-x; else sprite.r = x; sprite.r *= 6; sprite.r += 32; sprite.g = sprite.r; sprite.b = sprite.r; GsSortFastSprite (&sprite, &othWorld [nBuffer], 0); // sprintf (tempstring, "%d", cell); // DrawText (tempstring, sprite.x, sprite.y, 64,64,64); } map += 2; } } } //-------------------------------------------------------------- void DrawShip (void) { int temp; GsSPRITE sprite; if (shieldhit) { SetDefaultSpriteData (&sprite, SHIELD1_SPRITE); sprite.attribute |= 1 << 28 | 1 << 30; sprite.x = shipx + (spritedata [SHIP_SPRITE].pw / 2); sprite.y = shipy + 2 + (spritedata [SHIP_SPRITE].ph / 2); sprite.r = shieldhit<<2; sprite.g = 0; sprite.b = 0; sprite.mx = spritedata [SHIELD1_SPRITE].pw / 2; sprite.my = spritedata [SHIELD1_SPRITE].ph / 2; sprite.rotate = (gametime % 359) * (ONE * 8); GsSortSprite (&sprite, &othWorld [nBuffer], 0); SetDefaultSpriteData (&sprite, SHIELD2_SPRITE); sprite.attribute |= 1 << 28 | 1 << 30; sprite.x = shipx + (spritedata [SHIP_SPRITE].pw / 2); sprite.y = shipy + 2 + (spritedata [SHIP_SPRITE].ph / 2); sprite.r = shieldhit<<3; sprite.g = 0; sprite.b = 0; sprite.mx = spritedata [SHIELD2_SPRITE].pw / 2; sprite.my = spritedata [SHIELD2_SPRITE].ph / 2; sprite.rotate = -(gametime % 359) * (ONE * 8); GsSortSprite (&sprite, &othWorld [nBuffer], 0); } SetDefaultSpriteData (&sprite, SHIP_SPRITE); sprite.x = shipx; sprite.y = shipy; GsSortFastSprite (&sprite, &othWorld [nBuffer], 0); switch (addonleft) { case ADDON_MINI: SetDefaultSpriteData (&sprite, SIDEARM_SPRITE); sprite.x = shipx - 7; sprite.y = shipy - 3; GsSortFastSprite (&sprite, &othWorld [nBuffer], 0); break; default: break; } switch (addonright) { case ADDON_ELECBALL: SetDefaultSpriteData (&sprite, CANNON_SPRITE); sprite.x = shipx + 26; sprite.y = shipy - 3; GsSortFastSprite (&sprite, &othWorld [nBuffer], 0); break; default: break; } if (exhaust > 0) { SetDefaultSpriteData (&sprite, EXHAUST_SPRITE); sprite.attribute |= 1 << 28 | 1 << 30; sprite.r = exhaust << 2; sprite.g = exhaust << 2; sprite.b = exhaust << 2; sprite.x = shipx + 7; sprite.y = shipy + 23 + (exhaust >> 2); GsSortFastSprite (&sprite, &othWorld [nBuffer], 0); sprite.x = shipx + 11; sprite.y = shipy + 26 + (exhaust >> 2); GsSortFastSprite (&sprite, &othWorld [nBuffer], 0); sprite.x = shipx + 17; sprite.y = shipy + 26 + (exhaust >> 2); GsSortFastSprite (&sprite, &othWorld [nBuffer], 0); sprite.x = shipx + 21; sprite.y = shipy + 23 + (exhaust >> 2); GsSortFastSprite (&sprite, &othWorld [nBuffer], 0); } } //-------------------------------------------------------------- void DrawOSD (void) { int count; char * sub; GsSPRITE sprite; GsLINE line; SetDefaultSpriteData (&sprite, POWERBAR_SPRITE); sprite.attribute |= 1 << 28 | 1 << 30; sprite.x = 8; sprite.y = 16; sprite.r = 16; sprite.g = 16; sprite.b = 16; GsSortFastSprite (&sprite, &othWorld [nBuffer], 0); if (shield < 0) shield = 0; line.attribute=1<<30; line.r=0; line.g=0; line.b=0; line.y0=117; line.y1=117-shield; for (count = 0; count < 4; count++) { line.x0=10+count; line.x1=10+count; if (shield > 25) line.b=255 - (count * 50); else line.r=255 - (count * 50); GsSortLine (&line, &othWorld[nBuffer], 0); } sprintf (tempstring, "%8.8d", score); sub = &tempstring[0]; for (count = 0; count < 8; count++) { SetDefaultSpriteData (&sprite, NUM_SPRITE); sprite.attribute |= 1 << 28 | 1 << 30; sprite.x = 8; sprite.y = 128 + (count * 8); sprite.r = 16; sprite.g = 16; sprite.b = 16; sprite.w = 8; sprite.u += ((*sub)-'0') * 8; GsSortFastSprite (&sprite, &othWorld [nBuffer], 0); sub++; } if (levelrow <= 150) { DrawText ("DEMO COMPLETE", -1, SCREEN_HEIGHT - font.height-2, 32, 64,64); DrawText ("DEMO COMPLETE", -1, SCREEN_HEIGHT - font.height, -128,-128,-128); if (levelrow <= 0) state = STATE_FRONTEND; } } //-------------------------------------------------------------- void PauseMode (void) { static int move = 1; static int menu = 0; DrawText ("- PAUSED -", -1, ((SCREEN_HEIGHT - font.height) / 2) -25, 16, 32,32); DrawText ("- PAUSED -", -1, ((SCREEN_HEIGHT - font.height) / 2) -23, -128,-128,-128); if (menu == 0) { DrawText ("CONTINUE", -1, ((SCREEN_HEIGHT - font.height) / 2)+5, 16, 64-(time%32), 64-(time%32)); DrawText ("QUIT GAME", -1, ((SCREEN_HEIGHT - font.height) / 2)+20, 16, 32,32); } else { DrawText ("CONTINUE", -1, ((SCREEN_HEIGHT - font.height) / 2)+5, 16, 32, 32); DrawText ("QUIT GAME", -1, ((SCREEN_HEIGHT - font.height) / 2)+20, 16, 64-(time%32), 64-(time%32)); } DrawText ("CONTINUE", -1, ((SCREEN_HEIGHT - font.height) / 2)+7, -128,-128,-128); DrawText ("QUIT GAME", -1, ((SCREEN_HEIGHT - font.height) / 2)+22, -128,-128,-128); if (!move) { if ((WasButtonPressed (PADLup)) && menu != 0) menu = 0; if ((WasButtonPressed (PADLdown)) && menu != 1) menu = 1; if (WasButtonPressed (PADRdown)) { if (menu == 0) pause = 0; else state = STATE_FRONTEND; menu = 0; move = 1; } if (WasButtonPressed (PADstart)) { pause = 0; menu = 0; move = 1; } } else move --; } //-------------------------------------------------------------- void DrawGame (void) { // sprintf (tempstring, "%d", sync); // DrawText (tempstring, 10, 10, 32,32,32); if (pause) PauseMode(); if (state == STATE_GAME) { if (shield > 0) { DrawShip (); } DrawFire (); DrawAliens (); DrawParticles (); } DrawOSD (); DrawBG (); } //-------------------------------------------------------------- void ResultsLoop (void) { } //-------------------------------------------------------------- #define MAX_BLURS 4 #define BLUR_LEFT 60 #define BLUR_GAP ((SCREEN_WIDTH - (BLUR_LEFT * 2)) / MAX_BLURS) void IntroLoop (void) { int count; int temp; static int sound; static int color; static int fade = 0; static int init = 0; static int timer = 0; static int rot = 0; GsSPRITE sprite; if (init == 0) { SetFrameSTP(); timer = 0; fade = 0; color = rand() & 1; sound = SsUtKeyOn (vab1, 0,0, 24, 0, 128, 128); if (color) SetBlurParam (ONE + 512, ONE + 512, 0, 128,64,0); else SetBlurParam (ONE + 512, ONE + 512, 0, 0,32,128); init = 1; } if (timer < 230) { SetDefaultSpriteData (&sprite, BLUR_SPRITE); sprite.mx = 32; sprite.my = 32; sprite.attribute |= 1 << 28 | 1 << 30; if (color) { sprite.r = (250 - timer) >> 3; sprite.g = (250 - timer) >> 4; sprite.b = 0; } else { sprite.r = 0; sprite.g = (250 - timer) >> 4; sprite.b = (250 - timer) >> 3; } for (count = 0; count <= MAX_BLURS; count ++) { sprite.scalex = ONE + (rand() % ONE); sprite.scaley = ONE + (rand() % ONE); sprite.rotate = rot; sprite.x = BLUR_LEFT + (count * BLUR_GAP); sprite.y = SCREEN_HEIGHT/2; GsSortSprite (&sprite, &othWorld[nBuffer], 0); } if (fade < 128) { fade += 4; } SetDefaultSpriteData (&sprite, SCENE_SPRITE); sprite.x = 68; sprite.y = 96; sprite.r = fade; sprite.g = fade; sprite.b = fade; GsSortFastSprite (&sprite, &othWorld[nBuffer], 10); } timer++; rot += 256; if (PADstatus & PADstart) { SsUtKeyOff (sound, vab1,0,0,24); timer = 250; } if (timer >= 250) { init = 0; state = STATE_FRONTEND; } } //-------------------------------------------------------------- int main() { RECT vram = {0,0,1024,512}; ClearImage (&vram, 0,0,0); Init(); while(!(PADstatus & PADselect)) { switch (state) { case STATE_FRONTEND: FrameStart(0); FrontendLoop(); BlurScreen(); break; case STATE_GAME: FrameStart(0); UpdateGame(); DrawGame(); break; case STATE_SHOP: FrameStart(0); Shop(); DrawGame(); break; case STATE_RESULTS: FrameStart(1); ResultsLoop(); break; case STATE_INTRO: FrameStart(1); IntroLoop(); BlurScreen(); break; default: break; } FrameEnd(); } DMSDeInit(&d); SsUtAllKeyOff (0); SsVabClose (vab1); SsVabClose (vab2); ClearImage (&vram, 0,0,0); ResetGraph (3); return 0; }