// --- Squeak! -------------------------------------------------------------- #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 MAX_CHARS 128 #define SOUND_VH 0x80090000 #define SOUND_VB 0x80091a20 #define SOUND2_VH 0x800a3670 #define SOUND2_VB 0x800a5090 #define ICEFIELD_VH 0x800a7000 #define ICEFIELD_VB 0x800a8620 #define ICEFIELD_DMS 0x800c7150 #define BANANA_TIM 0x800c7b88 #define CHERRY_TIM 0x800c7dc8 #define CHILLI_TIM 0x800c8008 #define GPEPPER_TIM 0x800c8248 #define GRAPES_TIM 0x800c8488 #define GREEN_TIM 0x800c86c8 #define LEMON_TIM 0x800c8908 #define LIME_TIM 0x800c8b48 #define MUSHROOM_TIM 0x800c8d88 #define ONION_TIM 0x800c8fc8 #define ORANGE_TIM 0x800c9208 #define PURPLE_TIM 0x800c9448 #define STRAWBERRY_TIM 0x800c9688 #define TOMATO_TIM 0x800c98c8 #define BACK3_TIM 0x800c9b08 #define FONT_TIM 0x800ca31c #define LOGO_TIM 0x800cc5dc #define SCENE_TIM 0x800d12fc #define BLUR_TIM 0x800d431c #define CURSOR_TIM 0x800d553c #define FLARE1_TIM 0x800d5b5c #define GLARE1_TIM 0x800d639c #define GLARE2_TIM 0x800d6bdc #define JOKER_TIM 0x800d741c #define POINTER_TIM 0x800d7a3c #define END_OF_DATA 0x800d805c //-------------------------------------------------------------- typedef enum { BANANA_SPRITE = 0, CHERRY_SPRITE, GRAPES_SPRITE, LEMON_SPRITE, LIME_SPRITE, ORANGE_SPRITE, STRAWBERRY_SPRITE, CHILLI_SPRITE, GPEPPER_SPRITE, GREEN_SPRITE, MUSHROOM_SPRITE, ONION_SPRITE, PURPLE_SPRITE, TOMATO_SPRITE, BACK3_SPRITE, FONT_SPRITE, LOGO_SPRITE, SCENE_SPRITE, BLUR_SPRITE, CURSOR_SPRITE, FLARE1_SPRITE, GLARE1_SPRITE, GLARE2_SPRITE, JOKER_SPRITE, POINTER_SPRITE, NUM_SPRITES } SPRITE_DATA; typedef enum { STATE_FRONTEND = 0, STATE_LEVELSTART, STATE_GAME, STATE_RESULTS, STATE_INTRO, NUM_GAME_STATES } STATE; typedef struct { int sprite; int * xoff; int height; int space; } FONT_DATA; typedef struct { int y; int ay; int x; int ax; int type; } CELL_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); } DrawSync (0); return 0; } //-------------------------------------------------------------- void Initialise() { 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]); 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 *)ICEFIELD_VH, (unsigned char *)ICEFIELD_VB, (unsigned char *)ICEFIELD_DMS); srand (VSync(-1)); LoadTIM (BANANA_TIM, &spritedata [BANANA_SPRITE]); LoadTIM (CHERRY_TIM, &spritedata [CHERRY_SPRITE]); LoadTIM (CHILLI_TIM, &spritedata [CHILLI_SPRITE]); LoadTIM (GPEPPER_TIM, &spritedata [GPEPPER_SPRITE]); LoadTIM (GRAPES_TIM, &spritedata [GRAPES_SPRITE]); LoadTIM (GREEN_TIM, &spritedata [GREEN_SPRITE]); LoadTIM (LEMON_TIM, &spritedata [LEMON_SPRITE]); LoadTIM (LIME_TIM, &spritedata [LIME_SPRITE]); LoadTIM (MUSHROOM_TIM, &spritedata [MUSHROOM_SPRITE]); LoadTIM (ONION_TIM, &spritedata [ONION_SPRITE]); LoadTIM (ORANGE_TIM, &spritedata [ORANGE_SPRITE]); LoadTIM (PURPLE_TIM, &spritedata [PURPLE_SPRITE]); LoadTIM (STRAWBERRY_TIM, &spritedata [STRAWBERRY_SPRITE]); LoadTIM (TOMATO_TIM, &spritedata [TOMATO_SPRITE]); LoadTIM (BACK3_TIM, &spritedata [BACK3_SPRITE]); LoadTIM (FONT_TIM, &spritedata [FONT_SPRITE]); LoadTIM (LOGO_TIM, &spritedata [LOGO_SPRITE]); LoadTIM (SCENE_TIM, &spritedata [SCENE_SPRITE]); LoadTIM (BLUR_TIM, &spritedata [BLUR_SPRITE]); LoadTIM (CURSOR_TIM, &spritedata [CURSOR_SPRITE]); LoadTIM (FLARE1_TIM, &spritedata [FLARE1_SPRITE]); LoadTIM (GLARE1_TIM, &spritedata [GLARE1_SPRITE]); LoadTIM (GLARE2_TIM, &spritedata [GLARE2_SPRITE]); LoadTIM (JOKER_TIM, &spritedata [JOKER_SPRITE]); LoadTIM (POINTER_TIM, &spritedata [POINTER_SPRITE]); font.sprite = FONT_SPRITE; font.xoff = &fontpos[0]; font.height = 23; font.space = 8; SetFrameSTP(); 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 -> w *= 4; sprite -> u *= 4; } else if ((spritedata [data].pmode & 3) == 1) { sprite -> w *= 2; 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 >= '<') { ret += font.height; } if (c >= 'T') { ret += font.height; } return ret; } //-------------------------------------------------------------- int GetCharWidth (char c) { if (c < 33) { return font.space; } else if (c == ';' || c == 'S') { return 7; } 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 (); 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; } } //-------------------------------------------------------------- #define MAX_FLARES 6 void DrawFlare (int x, int y, int bright) { int count; long temp; static int flare [MAX_FLARES] = {-2500,-1500,-500,1000,2500,4000}; static int scale [MAX_FLARES] = {1000,1500,4000,2500,1500,1000}; static CVECTOR color [MAX_FLARES] = {{32,8,4},{16,16,4},{0,0,20},{12,4,12},{16,8,0},{0,12,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/2; sprite.g = bright/2; sprite.b = bright/2; GsSortSprite (&sprite, &othWorld[nBuffer], 0); SetDefaultSpriteData (&sprite, GLARE2_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/2; sprite.g = bright/2; sprite.b = bright/2; 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 MENU_COLOR -32 void FrontendLoop (void) { int temp; static int fx,fy; static int sel; static int centre = 0; static timer = 0; static int cycle; static int init = 0; static int sound = -1; static int sound2 = -1; GsSPRITE sprite; GsLINE line = {0, 16,16,304,16,0,0,0}; if (!init) { timer = 0; cycle = 0; sel = 0; sound = SsUtKeyOn (vab1, 3,0, 48, 0, 128, 128); sound2 = SsUtKeyOn (vab1, 3,0, 36, 0, 64, 64); SetBlurParam (ONE+32, ONE, 0, 128,128,128); init = 1; } SetDefaultSpriteData (&sprite, LOGO_SPRITE); sprite.x = 32; sprite.y = 16; GsSortFastSprite (&sprite, &othWorld [nBuffer], 10); if (cycle & 1) { if ((fx >= 0) && (fx < SCREEN_WIDTH)) { fx += 4; if (time & 1) fy += 1; if (fx < (SCREEN_WIDTH)/2) temp = fx; else temp = SCREEN_WIDTH - fx; DrawFlare (fx, fy, temp); } } if (centre) { DrawText ("CENTRE SCREEN", -1, 90,MENU_COLOR,MENU_COLOR,MENU_COLOR); DrawText ("_ MOVE", -1, 130,MENU_COLOR,MENU_COLOR,MENU_COLOR); DrawText ("\\ BACK", -1, 160,MENU_COLOR,MENU_COLOR,MENU_COLOR); GsSortLine (&line, &othWorld [nBuffer], 0); line.x0 = 304; line.y0 = 240; GsSortLine (&line, &othWorld [nBuffer], 0); line.x1 = 16; line.y1 = 240; GsSortLine (&line, &othWorld [nBuffer], 0); line.x0 = 16; line.y0 = 16; GsSortLine (&line, &othWorld [nBuffer], 0); if (WasButtonPressed (PADtriangle)) { timer = 0; centre = 0; SsUtKeyOn (vab2, 2,0, 36, 0, 128, 128); } if (WasButtonPressed (PADLleft)) GsDISPENV.screen.x--; if (WasButtonPressed (PADLright)) GsDISPENV.screen.x++; if (WasButtonPressed (PADLup)) GsDISPENV.screen.y--; if (WasButtonPressed (PADLdown)) GsDISPENV.screen.y++; } else if (timer < 500) { DrawText ("MAIN MENU", -1, 90,MENU_COLOR,MENU_COLOR,MENU_COLOR); if (sel == 0) temp = -MENU_COLOR; else temp = MENU_COLOR; DrawText ("START GAME", -1, 125,temp,temp,temp); strcpy (tempstring, "DIFFICULTY: "); if (diff == 0) strcat (tempstring, "NO TIME LIMIT"); else if (diff == 1) strcat (tempstring, "EASY"); else if (diff == 2) strcat (tempstring, "NORMAL"); else if (diff == 3) strcat (tempstring, "HARD"); else strcat (tempstring, "VERY HARD"); if (sel == 1) temp = -MENU_COLOR; else temp = MENU_COLOR; DrawText (tempstring, -1, 150,temp,temp,temp); strcpy (tempstring, "MUSIC: "); if (music == 0) strcat (tempstring, "OFF"); else if (music == 1) strcat (tempstring, "LOW"); else strcat (tempstring, "HIGH"); if (sel == 2) temp = -MENU_COLOR; else temp = MENU_COLOR; DrawText (tempstring, -1, 175,temp,temp,temp); strcpy (tempstring, "GRAPHICS: "); if (cellgfx == 0) strcat (tempstring, "FRUIT!"); else strcat (tempstring, "VEG!"); if (sel == 3) temp = -MENU_COLOR; else temp = MENU_COLOR; DrawText (tempstring, -1, 200,temp,temp,temp); if (sel == 4) temp = -MENU_COLOR; else temp = MENU_COLOR; DrawText ("CENTRE SCREEN", -1, 225,temp,temp,temp); if (WasButtonPressed (PADLup)) { sel --; SsUtKeyOn (vab1, 5,0, 48, 0, 100, 100); } else if (WasButtonPressed (PADLdown)) { sel ++; SsUtKeyOn (vab1, 6,0, 48, 0, 100, 100); } if (sel < 0) sel = 4; if (sel > 4) sel = 0; if (WasButtonPressed (PADcross)) { SsUtKeyOn (vab1, 7,0, 36, 0, 100, 100); if (sel == 0) { SsUtKeyOff (sound, vab1, 3, 0, 48); SsUtKeyOff (sound2, vab1, 3, 0, 36); state = STATE_LEVELSTART; if (music == 1) DMSSetMasterVol (&d, 160); else if (music == 2) DMSSetMasterVol (&d, 255); else DMSSetMasterVol (&d, 0); score = 0; if (diff == 0) joker = 0; else joker = 1; level = 1; init = 0; } else if (sel == 1) { diff ++; if (diff >=5) diff = 0; } else if (sel == 2) { music++; if (music > 2) music = 0; } else if (sel == 3) cellgfx = 1-cellgfx; else if (sel == 4) { centre = 1; } } } else if (timer < 1000) { DrawText ("CONTROLS", -1, 90,MENU_COLOR,MENU_COLOR,MENU_COLOR); DrawText ("_ MOVE CURSOR", -1, 130,MENU_COLOR,MENU_COLOR,MENU_COLOR); DrawText ("[ SELECT CELL", -1, 160,MENU_COLOR,MENU_COLOR,MENU_COLOR); DrawText ("] USE JOKER", -1, 190,MENU_COLOR,MENU_COLOR,MENU_COLOR); } else if (timer < 1500) { DrawText ("CREDITS", -1, 90,MENU_COLOR,MENU_COLOR,MENU_COLOR); DrawText ("GAME: BEN JAMES", -1, 130,MENU_COLOR,MENU_COLOR,MENU_COLOR); DrawText ("MUSIC PLAYER: ELLIOT LEE", -1, 160,MENU_COLOR,MENU_COLOR,MENU_COLOR); DrawText ("ADDITIONAL GFX: CLIPSAHOY", -1, 190,MENU_COLOR,MENU_COLOR,MENU_COLOR); } else { cycle ++; fx = 0; fy = 32; if (cycle >= 4) { SsUtKeyOff (sound, vab1, 3, 0, 48); SsUtKeyOff (sound2, vab1, 3, 0, 36); state = STATE_INTRO; init = 0; } else { timer = 0; } } timer ++; if (PADstatus) { timer = 0; cycle = 0; } if (WasButtonPressed (PADcircle)) { SsUtKeyOff (sound, vab1, 3, 0, 48); SsUtKeyOff (sound2, vab1, 3, 0, 36); state = STATE_INTRO; init = 0; } } //-------------------------------------------------------------- int MoveCells (void) { int x; int y; int temp; int moved = 0; for (x = 0; x < 8; x++) { for (y = 0; y < 8; y++) { if (grid [x][y].ay != -1) { moved = 1; grid [x][y].ay++; grid [x][y].y += grid [x][y].ay; if (grid [x][y].y >= y*32) { grid [x][y].y = y*32; grid [x][y].ay = -1; } } } } return moved; } //-------------------------------------------------------------- void PlugHoles (void) { int x; int y; int temp; for (y = 7; y >= 0; y--) { for (x = 0; x < 8; x++) { if (grid [x][y].type == -1) { temp = y-1; while (temp >= 0) { if (grid [x][temp].type != -1) { grid [x][y].x = 32 + (x * 32); grid [x][y].ay = 0; grid [x][y].y = temp * 32; grid [x][y].type = grid [x][temp].type; grid [x][temp].type = -1; temp = -1; } temp --; } } } } for (x = 0; x < 8; x++) { for (y = 0; y < 8; y++) { if (grid [x][y].type == -1) { grid [x][y].type = rand() % 7; grid [x][y].x = 32 + (x * 32); grid [x][y].ay = 0; grid [x][y].y = -32; } } } } //-------------------------------------------------------------- void FoundRow (int x, int y, int dir) { int temp = 0; int add; int multi = 0; if (state != STATE_GAME) return; glb = 128; if (grid [x][y].type != -1) { grid [x][y].type = -1; SsUtKeyOn (vab1, 0,0, 48, 0, 128, 128); score += 10; add = 20-level; if (add<10) { add = 10; } limit += add; if (limit>=255) { score += 1000; level ++; if (!(level & 1)) joker++; if (joker > 1) joker = 1; state = STATE_RESULTS; } if (dir) { glx = 32+(x*32); gly = (y+1)*32; temp = y; while (temp >= 0) { if (grid [x][temp].type == grid [x][y+1].type) { grid [x][temp].type = -1; score += 10; multi = 1; } else temp = -1; temp --; } temp = y+3; while (temp < 8) { if (grid [x][temp].type == grid [x][y+1].type) { grid [x][temp].type = -1; score += 10; multi = 1; } else temp = 8; temp ++; } grid [x][y+1].type = -1; grid [x][y+2].type = -1; } else { glx = (x+2)*32; gly = y*32; temp = x; while (temp >= 0) { if (grid [temp][y].type == grid [x+1][y].type) { grid [temp][y].type = -1; score += 10; multi = 1; } else temp = -1; temp --; } temp = x+3; while (temp < 8) { if (grid [temp][y].type == grid [x+1][y].type) { grid [temp][y].type = -1; score += 10; multi = 1; } else temp = 8; temp ++; } grid [x+1][y].type = -1; grid [x+2][y].type = -1; } PlugHoles(); } } //-------------------------------------------------------------- int CheckForRows (int action) { int x; int y; int found = 0; for (y = 0; y < 8; y++) { for (x = 0; x < 6; x++) { if ((grid [x][y].type == grid [x+1][y].type) && (grid [x][y].type == grid [x+2][y].type)) { found = 1; if (action) { FoundRow (x, y, 0); } } } } for (x = 0; x < 8; x++) { for (y = 0; y < 6; y++) { if ((grid [x][y].type == grid [x][y+1].type) && (grid [x][y].type == grid [x][y+2].type)) { found = 1; if (action) { FoundRow (x, y, 1); } } } } return found; } //-------------------------------------------------------------- void CheckForValidMove (void) { int temp; static int hx = 0; static int hy = 0; static int vx = 0; static int vy = 0; static int found = 0; if (movemade) { movemade = 0; found = 0; hx = 0; hy = 0; vx = 0; vy = 0; } if (hx < 7) { temp = grid [hx][hy].type; grid [hx][hy].type = grid [hx+1][hy].type; grid [hx+1][hy].type = temp; if (CheckForRows (0)) found = 1; temp = grid [hx][hy].type; grid [hx][hy].type = grid [hx+1][hy].type; grid [hx+1][hy].type = temp; hy ++; if (hy >= 7) { hy = 0; hx ++; } } else if (vy < 7) { temp = grid [vx][vy].type; grid [vx][vy].type = grid [vx][vy+1].type; grid [vx][vy+1].type = temp; if (CheckForRows (0)) found = 1; temp = grid [vx][vy].type; grid [vx][vy].type = grid [vx][vy+1].type; grid [vx][vy+1].type = temp; vx++; if (vx >= 7) { vx = 0; vy ++; } } else if (!found) { nomove = 1; hx = 0; hy = 0; vx = 0; vy = 0; state = STATE_RESULTS; } else { hx = 0; hy = 0; vx = 0; vy = 0; } if (found) { hx = 0; hy = 0; vx = 0; vy = 0; } } //-------------------------------------------------------------- int ValidateExchange (void) { int ret = 0; if (curx == selx) { if ((cury == (sely-1)) || (cury == (sely+1))) { ret = 1; } } else if (cury == sely) { if ((curx == (selx-1)) || (curx == (selx+1))) { ret = 1; } } return ret; } //-------------------------------------------------------------- #define DEAD_ZONE 32 void GetPlayerInput (int move) { int ax; int ay; int temp; if (*(bb0+1) >> 4 != 7) { ptx = -1; if ((WasButtonPressed (PADLleft)) && (curx > 0)) { curx --; SsUtKeyOn (vab1, 2,0, 48, 0, 128, 128); } else if ((WasButtonPressed (PADLright)) && (curx < 7)) { curx ++; SsUtKeyOn (vab1, 2,0, 48, 0, 128, 128); } if ((WasButtonPressed (PADLup)) && (cury > 0)) { cury --; SsUtKeyOn (vab1, 2,0, 48, 0, 128, 128); } else if ((WasButtonPressed (PADLdown)) && (cury < 7)) { cury ++; SsUtKeyOn (vab1, 2,0, 48, 0, 128, 128); } } else { 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; ptx += ax >> 5; pty += ay >> 5; if (ptx < 32) ptx = 32; else if (ptx > 287) ptx = 287; if (pty < 0) pty = 0; else if (pty > 255) pty = 255; curx = (ptx - 32) >> 5; cury = pty >> 5; } if (move) return; if (WasButtonPressed (PADcross)) { if (selx == -1) { SsUtKeyOn (vab1, 1,0, 36, 0, 64, 64); selx = curx; sely = cury; } else if (ValidateExchange()) { temp = grid [curx][cury].type; grid [curx][cury].type = grid [selx][sely].type; grid [selx][sely].type = temp; if (!CheckForRows (0)) { // bad move SsUtKeyOn (vab2, 0,0, 36, 0, 128,128); temp = grid [curx][cury].type; grid [curx][cury].type = grid [selx][sely].type; grid [selx][sely].type = temp; } else { movemade = 1; } selx = -1; } else { // bad move SsUtKeyOn (vab2, 0,0, 36, 0, 128,128); selx = -1; } } if ((WasButtonPressed (PADcircle)) && (joker)) { state = STATE_RESULTS; } } //-------------------------------------------------------------- void InitialiseLevel (void) { int x,y; curx = 0; cury = 0; ptx = SCREEN_WIDTH/2; pty = SCREEN_HEIGHT/2; selx = -1; glb = 0; movemade = 0; nomove = 0; limit = 128-(level*8); if (limit < 32) { limit = 32; } do { for (x = 0; x < 8; x++) { for (y = 0; y < 8; y++) { grid [x][y].type = rand() % 7; grid [x][y].x = 32 + (x * 32); grid [x][y].ay = 0; grid [x][y].y = -(y * 24) - (x * 12); } } } while (CheckForRows(0)); SetBlurParam (ONE, ONE, 0, 128,128,128); } //-------------------------------------------------------------- void InitialiseGame (void) { } //-------------------------------------------------------------- void UpdateGame (void) { static char init = 0; if (pause) { if (WasButtonPressed (PADtriangle)) { init = 0; state = STATE_FRONTEND; DMSNoteKeyOffAll (&d); DMSSongReset (&d); } if (WasButtonPressed (PADstart)) { pause = 0; SsUtKeyOn (vab2, 2,0, 36, 0, 128, 128); } return; } if (WasButtonPressed (PADstart)) { pause = 1; SsUtKeyOn (vab2, 2,0, 36, 0, 128, 128); DMSNoteKeyOffAll (&d); return; } if (!init) { InitialiseGame(); init = 1; } if (diff == 0) { limit = 128; } else if (diff == 1) { if (!(time % 12)) limit --; } else if (diff == 2) { if (!(time % 9)) limit --; } else if (diff == 3) { if (!(time % 6)) limit --; } else { if (!(time % 4)) limit --; } if (limit <= 0) { state = STATE_RESULTS; } if (!MoveCells()) { GetPlayerInput(0); CheckForRows (1); CheckForValidMove(); } else { GetPlayerInput(1); } if (glb > 0) { glx += 2; gly += 2; glb -= 8; } } //-------------------------------------------------------------- void DrawGrid (void) { int x,y; GsSPRITE sprite; SetDefaultSpriteData (&sprite, BACK3_SPRITE); for (x = 0; x < 8; x++) { for (y = 0; y < 8; y++) { sprite.r = 100; sprite.g = sprite.r; sprite.b = sprite.r; sprite.x = 32 + (x * 32); sprite.y = y * 32; GsSortFastSprite (&sprite, &othWorld[nBuffer], 5); } } } //-------------------------------------------------------------- void DrawGameScreen (void) { int count; char temp [2]; GsGLINE line = {0,300,0,300,255, 0,255,0, 255,0,0}; GsLINE black = {1<<30|2<<28,300,0,300,0, 64,64,64}; GsSPRITE sprite; sprintf (tempstring, "%7.7d", score); for (count = 0; count < 7; count++) { strncpy (temp, &tempstring[count], 1); temp [1] = '\0'; DrawText (temp, 12, count * 16, 64,32+(count*4),0); } if (diff != 0) { if ((limit < 64) && ((time % 50) > 25)) { line.r0 = 64; line.b0 = 64; line.g1 = 64; line.b1 = 64; } for (count = 0; count < 7; count++) { GsSortGLine (&line, &othWorld [nBuffer], 1); line.x0++; line.x1++; } black.y1 = 255-limit; for (count = 0; count < 7; count++) { GsSortLine (&black, &othWorld [nBuffer], 0); black.x0++; black.x1++; } } if (pause) { DrawText ("PAUSED", -1, (SCREEN_HEIGHT-font.height)/2, 127,127,127); DrawText ("\\ QUIT GAME", -1, ((SCREEN_HEIGHT-font.height)/2) + 30, 127,127,127); } count = joker; SetDefaultSpriteData (&sprite, JOKER_SPRITE); while (count) { sprite.x = 0; sprite.y = (SCREEN_HEIGHT/2) + (count * 32); GsSortFastSprite (&sprite, &othWorld[nBuffer], 0); count--; } } //-------------------------------------------------------------- void DrawFruit (void) { int x,y; GsSPRITE sprite; for (x = 0; x < 8; x++) { for (y = 0; y < 8; y++) { if (grid[x][y].type != -1) { if (cellgfx) SetDefaultSpriteData (&sprite, CHILLI_SPRITE + grid[x][y].type); else SetDefaultSpriteData (&sprite, BANANA_SPRITE + grid[x][y].type); sprite.x = 32 + (x * 32); if (grid[x][y].ay != -1) { sprite.x = grid[x][y].x; sprite.y = grid[x][y].y; } else sprite.y = y * 32; GsSortFastSprite (&sprite, &othWorld[nBuffer], 2); } } } } //-------------------------------------------------------------- void DrawCursor (void) { int x,y; GsSPRITE sprite; SetDefaultSpriteData (&sprite, CURSOR_SPRITE); sprite.x = 32 + (curx * 32); sprite.y = cury * 32; GsSortFastSprite (&sprite, &othWorld[nBuffer], 2); if (selx != -1) { sprite.x = 32 + (selx * 32); sprite.y = sely * 32; sprite.r = 110; sprite.g = 110; sprite.b = 110; GsSortFastSprite (&sprite, &othWorld[nBuffer], 2); } if (glb>0) { DrawFlare (glx, gly, glb); } if (ptx != -1) { SetDefaultSpriteData (&sprite, POINTER_SPRITE); sprite.x = ptx; sprite.y = pty; GsSortFastSprite (&sprite, &othWorld[nBuffer], 1); } } //-------------------------------------------------------------- void DrawGame (void) { if (!pause) { DrawFruit(); DrawCursor(); } DrawGrid(); DrawGameScreen(); } //-------------------------------------------------------------- void DrawLevelStart (void) { int temp; static int init = 0; static int x; if (!init) { init = 1; SetBlurParam (ONE + 64, ONE + 512, 0, 128,128,128); x = -200; pause = 0; } DrawGrid(); sprintf (tempstring, "LEVEL %d - GET READY!", level); DrawText (tempstring, -1, (SCREEN_HEIGHT/2) - (font.height/2), 127,127,127); if (x > 0) { if (x < (SCREEN_WIDTH)/2) temp = x; else temp = SCREEN_WIDTH - x; DrawFlare (x, (SCREEN_HEIGHT/2), temp); } x+=5; if (x>SCREEN_WIDTH) { InitialiseLevel(); state = STATE_GAME; init = 0; } } //-------------------------------------------------------------- void ResultsLoop (void) { static init = 0; static donk = 0; int x,y; int end = 1; if (!init) { SsUtKeyOn (vab2, 1,0, 36, 0, 128,128); for (x = 0; x < 8; x++) { for (y = 0; y < 8; y++) { grid[x][y].x = 32 + (x*32); grid[x][y].y = y*32; grid[x][y].ax = (rand()%5)-2; grid[x][y].ay = -(rand()%4); } } init = 1; } for (x = 0; x < 8; x++) { for (y = 0; y < 8; y++) { grid[x][y].x += grid[x][y].ax; grid[x][y].y += grid[x][y].ay; grid[x][y].ay ++; if (grid[x][y].y >= 512) { grid[x][y].y = 512; grid[x][y].ax = 0; grid[x][y].ay = 0; } else end = 0; } } if ((limit <= 0) || (diff == 0)) { if (diff == 0) DrawText ("OUT OF MOVES", -1, 32, 64,64,64); else DrawText ("OUT OF TIME", -1, 32, 64,64,64); sprintf (tempstring, "YOU SCORED %d POINTS", score); DrawText (tempstring, -1, ((SCREEN_HEIGHT-font.height)/2)-16, 64,64,64); if (diff == 0) DrawText ("GAME OVER", -1, ((SCREEN_HEIGHT-font.height)/2)+16, 64,64,64); else { sprintf (tempstring, "AND REACHED LEVEL %d", level); DrawText (tempstring, -1, ((SCREEN_HEIGHT-font.height)/2)+16, 64,64,64); } if (end) { if (!donk) { SsUtKeyOn (vab2, 0,0, 36, 0, 128,128); donk = 1; } DrawText ("PRESS [", -1, SCREEN_HEIGHT-font.height- 32, 64,64,64); if (WasButtonPressed (PADcross)) { init = 0; donk = 0; state = STATE_FRONTEND; DMSNoteKeyOffAll (&d); DMSSongReset (&d); } } } else if (limit >= 255) { DrawText ("LEVEL CLEAR!", -1, (SCREEN_HEIGHT-font.height)/2, 127,127,127); if (end) { init = 0; state = STATE_LEVELSTART; } } else if (nomove) { DrawText ("REFRESHING...", -1, (SCREEN_HEIGHT-font.height)/2, 127,127,127); if (end) { init = 0; x = limit; InitialiseLevel(); limit = x; state = STATE_GAME; } } else { if (end) { init = 0; x = limit; InitialiseLevel(); limit = x+64; if (limit >= 254) limit = 254; joker --; if (joker < 0) joker = 1; state = STATE_GAME; } } DrawFruit(); DrawGrid(); } //-------------------------------------------------------------- #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 color; static int fade = 0; static int init = 0; static int timer = 0; static int rot = 0; GsSPRITE sprite; if (init == 0) { timer = 0; fade = 0; SsUtKeyOn (vab1, 4,0, 24, 0, 128, 128); color = rand() & 1; 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 (timer >= 250) { init = 0; state = STATE_FRONTEND; } } //-------------------------------------------------------------- int main() { RECT vram = {0,0,1024,512}; ClearImage (&vram, 0,0,0); Initialise(); while(!(PADstatus & PADselect)) { FrameStart(1); switch (state) { case STATE_FRONTEND: FrontendLoop(); break; case STATE_LEVELSTART: DrawLevelStart(); break; case STATE_GAME: UpdateGame(); DrawGame(); break; case STATE_RESULTS: ResultsLoop(); break; case STATE_INTRO: IntroLoop(); break; default: break; } FrameEnd(); } DMSDeInit(&d); SsUtAllKeyOff (0); SsVabClose (vab1); SsVabClose (vab2); ClearImage (&vram, 0,0,0); ResetGraph (3); return 0; }