// Penguin X : By David Worswick 1998. // DMS module player by Elliot Lee. // Controller routines by James Rutherford. #include #include #include #include int Button_Check(void); // checks for joypad button presses void Init_OT(void); // function prototypes. void Init_GFX(void); void Init_Background_Sprites(void); void Init_Ice(void); // Sets up the block images that can be moved void Draw_Background(void); void Draw_Ice(void); void Setup_Level(int *data); // function to set which blocks are displayed and which are not. void Fade_In_Level(void); void Fade_Out_Level(void); void Init_Player1(void); int Move_Ok(int BlockX, int BlockY); // Returns 0 if the sprite can move to the specified block positions void Move_Player1(void); // Checks joypad and moves Player 1 void Init_Animation_Tables(void); void Melt_This_Block(int sprite_number); // melt the sprite void Animate_Melt(void); // animates the blocks that are melting void Request_Block_Move(void); // check to see if player 1 wants to push or melt a block void Select_Next_Level(void); void Clear_Melting_Blocks(void); void Clear_Moving_Blocks(void); void Move_This_Block(int sprite_number, int dir, int speed); void Move_Blocks(void); void Adjust_Music_Vol(void); void Setup_Score_Display(void); void Draw_Score_Display(void); void Add_To_Score(int value); int Enemy_Melt_Block(void); int Select_Enemy_Move_Direction(void); void Init_Enemy(void); void Draw_Enemy(void); void Move_Enemy(void); void Add_Run_Energy(int ammount); unsigned char FControllerType(unsigned char port); unsigned short FSPadRead (unsigned char port); unsigned char FControllerConnected(unsigned char port); void FSetPortBuffers(void); void Check_For_Pause(void); // checks to see if we should pause the game void Fade_Out_Screen(void); // fades the whole screen out void Fade_In_Screen(void); // fades in the complete screen int Enemy_Can_See_Player(int bx,int by,int ex,int ey,int direction); void Check_For_Collisions(void); int All_Dead(void); void Display_Bonus_Objects(void); int Select_Bonus_Object(void); void Clear_Display_Buffers(void); void Add_Life(void); void Do_HighScore(void); void Do_Titles(void); void Show_Credits(void); #define Max_Enemy 8 #define Slide_Vol 100 #define BACKGROUND_GFX_ADDRESS 0x80100000 // Sprite graphics address in main memory #define PLAYER_GFX_ADDRESS 0x80101420 // Player graphics address in main memory #define ENEMY_GFX_ADDRESS 0x80125c40 // Enemy TIM data #define COMMAND_GFX_ADDRESS 0x80127660 // Text commands foe sprites #define BONUS_GFX_ADDRESS 0x8012c880 // Bonus objects TIM file #define POPCORN 0x80102e40 // Main tune module data #define POPCORN_VH 0x8010b1f0 #define POPCORN_VB 0x8010da10 #define MAIN_SFX_VB 0x8012e2a0 // Main Sound effects data #define MAIN_SFX_VH 0x80150130 #define HIGH_SCORE_GFX_ADDRESS 0x80152550 // High score screen gfx data #define HIGH_TUNE 0x8015a770 // Music module that plays on the High Score screen #define HIGH_TUNE_VB 0x8015bce8 #define HIGH_TUNE_VH 0x801825d8 #define TITLES_GFX_ADDRESS 0x801845f8 #define FONT_GFX_ADDRESS 0x80194818 // Font character graphics #define TITLES_TUNE 0x801bc830 #define TITLES_VH 0x801d0968 #define TITLES_VB 0x801bf938 #define STORY1_GFX_ADDRESS 0x801d2588 #define STORY2_GFX_ADDRESS 0x801dc7a8 #define CREDITS1_GFX_ADDRESS 0x801e69c8 #define CREDITS2_GFX_ADDRESS 0x801f0be8 #define SCREEN_WIDTH 320 // Screen size #define SCREEN_HEIGHT 256 #define MAX_SPRITES 600 // Maximum number of sprites on screen +1 #define OT_LENGTH 10 // Length of Ordering Table #define Ok 0 #define Dying 1 #define Killed 2 #define Flashing 3 #define Block_Crush_Score 15 #define PORT_ONE 0 #define PORT_TWO 1 // 0x4 >> STANDARD PAD << // .. controls #define SPADup (1<<12) #define SPADdown (1<<14) #define SPADleft (1<<15) #define SPADright (1<<13) // TRiangle, CIrcle, CRoss, SQuare #define SPADtr (1<< 4) #define SPADci (1<< 5) #define SPADcr (1<< 6) #define SPADsq (1<< 7) // Shoulder left and right (1 and 2) #define SPADl1 (1<< 2) #define SPADl2 (1<< 0) #define SPADr1 (1<< 3) #define SPADr2 (1<< 1) #define SPADstart (1<<11) #define SPADselect (1<< 8) #define TRUE 1 #define FALSE 0 // Controller Type Ids #define CONTYPE_NONE (0xF) #define CONTYPE_MOUSE (0x1) #define CONTYPE_NEGCON (0x2) #define CONTYPE_STANDARD_PAD (0x4) #define CONTYPE_ANALOGUE_JOY (0x5) #define CONTYPE_ANALOGUE_PAD (0x7) #define Slow 1 #define Fast 2 #define Up 1 #define Right 2 #define Down 3 #define Left 4 #define Enemy_OK 0 #define Enemy_Die 1 #define Enemy_Dead 2 #define Enemy_Begin 3 #define Enemy_Wait 4 #define MAX_LEVEL 12 #define Fade_In 1 // game modes #define Fade_Out 2 #define Setting_Up 0 #define Ready 3 #define Select_New_Level 4 #define Dead 5 #define Game_Over 6 #define Faded_Out 7 #define Paused 8 #define Nearly_Ready 9 #define High_Score 10 #define Titles 11 #define Level_Clear 12 #define The_End 13 #define Enter_High 14 #define Show_End_Credits 15 #define No_Fade 12 #define Complete_Fade_In 13 #define Complete_Fade_Out 14 #define Bonus_Letter_Off 0 #define Bonus_Letter_On 1 #define Bonus_Letter_Collected 2 #define Bonus_Item_On 0 #define Bonus_Item_Off 1 #define Bonus_B 0 #define Bonus_O 1 #define Bonus_N 2 #define Bonus_U 3 #define Bonus_S 4 #define Heart 0 #define Burger 1 #define Grapes 2 #define Money 3 #define Clock 4 #define Bomb 5 #define Melon 6 #define Cherry 7 #define Banana 8 #define Bonus_Letter_Timer 700 #define Bonus_Item_Timer 400 typedef struct // structure for holding the Bonus display { int status; int counter; GsSPRITE sprite; }Bonus; typedef struct // this is the structure { int status; int type; // bonus character int timer; int block_x; int block_y; int scale_val; int scale_direction; GsSPRITE sprite; }Show_Bonus; typedef struct // structure for the bad budes { int status; // enemy status 0=ok 1=dying 2=dead 3=initializing 4 =waiting for block to melt int frame; // holds current anim frame int frame_counter; // counter to see when we need to change anim frames int speed; // speed in pixels of the enemy sprite int moving; // 0=still 1=sprite currently moving int move_counter; // 0->16 int direction; // direction sprite is currently moving int block_x; // x coordinate in blocks int block_y; // y coordinate in blocks int timer; // general purposse timer int scale_value; // holds current scaling value (used when initializing) int Bup; // holds info on the blocks around the enemy sprite int Bdown; // 0= no block 1=block 2=can't move there int Bleft; int Bright; GsSPRITE sprite; // playstation sprite structure }Bad_Guy; typedef struct // structure for holding coordinates for the number graphics in the score display { int x; // x position of number in Tpage int y; // Y position int width; // width of number gfx }Num_Data; typedef struct // Structure for moving ice blocks { int avail; // 0=free 1=position taken int from; // holds the sprite number of the block that is moving int direction; // direction the block is to be moved int speed; // speed the block is to move in pixels either 1 2 or 4 int move_counter; // goes from 0->15 int old_x; // old x coordinate int old_y; // old y coordinate of the block that is moving int sfx_on; // 0=no sound 1=sound playing short channel; // channel that the sfx is played on int sfx_counter; short prog; // program number to play short note; // note the sample is played at }Move; typedef struct // structure to hold coordinates of animation frames, used for main player { int x; // x position in TPage int y; // y position in TPage }anim_frame; typedef struct // structure to hold details for melting blocks { int avail; // 0=position available 1=position taken int array_position; // number thar corresponds to the x,y position in the Movement array int frame_counter; // int frame; }Block_Melt; typedef struct // main structure for players { int frame; // animation frame counter int status; // status of player ; 0=ok 1=dying 2=dead 3=Invunerable int block_x; int block_y; int direction; // direction player is going int moving; // 0=still 1=moving int move_counter; // counter for keeping track on player movement int lives; // number of lives remaining int speed; // speed of sprite movement int anim_counter; int Flash_counter; int run_energy; // when at 0 player can no longer run GsSPRITE sprite; }player; int Enemy_Melt[]= {0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,0,0,1,-1};// 1=enemy will melt a block 0= block will not melt int Enemy_Move[]= {1,2,1,3,4,2,3,1,3,2,3,2,2,2,1,2,3,4,1,3,2,1,1,2,3,3,4,4,1,2,3,1,1,2,3,3,4,3,2,1,1,1,2,3,4,-1}; int Display_Letter[]= {3,1,0,2,3,4,1,2,4,0,2,-1}; // Which bonus letter to display int Display_Bonus[]= {5,0,1,2,3,4,5,6,6,7,8,7,6,8,6,3,2,1,2,8,7,1,2,3,5,6,7,8,1,2,3,2,8,6,3,-1}; // which bonus object to display int Level1[]= {0,3,5,1,2,5,176,3,3,49,3,7,209,2,2,130,3,5,19,3,3,83,3,4,132,3,3,196,3,2,197,2,5, 37,3,2,38,2,10,8,2,8,85,3,3,86,2,3,56,2,2,72,2,1,118,2,2,149,2,3,165,2,3,104,3,3, 168,3,3,215,2,9,26,2,1,185,2,4,106,3,5,59,2,2,76,3,7,139,2,1,62,3,3,126,3,5,31,2,1, 143,2,1,191,3,2,52,2,1,121,2,1,-1}; int Level2[]= {0,2,7,16,3,13,21,2,1,34,2,6,25,2,2,12,2,4,81,2,1,145,2,1,193,2,1,50,3,5,146,3,4, 67,3,3,68,2,3,100,3,8,213,2,1,149,2,6,102,3,2,55,2,2,41,3,4,87,2,2,104,3,2,74,3,2, 43,2,1,28,2,2,44,3,2,122,2,2,92,3,7,170,3,2,183,2,3,199,3,2,216,2,8,189,2,2,109,2,2, 94,2,1,79,3,9,31,3,2,27,2,1,171,2,1,-1}; int Level3[]= {0,2,6,16,3,5,18,3,2,112,3,2,176,3,3,81,2,3,35,2,3,51,3,2,99,3,3, 193,2,3,114,3,5,211,2,5,116,2,3,101,2,7,70,2,6,7,2,9,27,3,3,149,3,3, 198,2,3,182,2,1,134,3,2,186,3,3,184,2,1,169,3,2,152,2,8,187,2,3, 204,3,2,205,2,2,191,3,3,90,2,1,122,2,2,138,2,2,29,3,2,125,3,2,173,2,1, 31,3,8,120,2,1,-1}; int Level4[]= {0,3,3,1,3,3,34,3,2,96,2,2,82,3,6,160,2,2,176,3,3,209,2,2,3,2,1,5,3,3,36,3,12, 115,2,1,79,2,1,181,2,1,85,2,1,70,3,7,7,3,5,8,2,6,40,2,3,25,2,1,57,2,3,75,2,1, 89,2,4,119,2,4,106,2,1,138,2,6,29,2,2,45,2,1,15,3,5,78,2,1,111,3,2,108,2,2,125,2,1, 157,3,3,190,2,2,214,2,10,152,2,4,183,2,2,169,3,3,202,2,1,171,3,3,199,2,1,72,2,1,51,2,1,-1}; int Level5[]= {0,3,6,49,2,2,2,3,3,112,3,2,160,3,4,81,2,4,129,2,2,177,2,2,194,2,1, 146,3,2,114,2,4,99,2,5,19,2,2,36,3,3,211,2,5,180,3,2,148,3,1,133,3,4, 5,2,2,22,3,3,69,2,2,8,2,3,12,2,4,26,2,1,39,2,2,24,2,1,56,2,3,73,2,2,87,2,3, 105,2,3,44,2,3,31,3,2,62,2,1,60,3,3,134,2,2,151,2,2,183,3,2,184,2,6,218,2,2, 202,2,1,191,3,3,206,3,2,205,2,1,95,3,4,173,3,1,170,3,1,154,2,5,137,2,3,119,2,3, 123,2,1,141,2,2,93,3,3,-1}; int Level6[]= {0,2,4,16,3,6,18,3,4,128,3,6,97,3,4,177,2,1,209,2,1,35,2,3,21,2,2,5,2,2,53,3,2, 130,2,5,100,3,2,67,3,3,180,3,3,148,2,4,167,3,4,213,2,2,54,3,4,55,2,1,87,2,1, 8,3,10,153,2,3,217,2,2,185,3,2,186,2,4,205,2,3,221,2,3,173,2,3,171,2,1,157,2,1, 138,2,6,109,3,2,14,3,7,63,3,2,15,2,1,11,2,3,27,3,6,60,2,2,76,2,1,90,3,2,73,3,2, 9,3,2,-1}; int Level7[]= {0,3,4,1,3,2,96,2,2,18,2,3,4,2,1,35,2,4,144,3,5,209,2,5,49,2,1,66,3,8,145,2,1, 52,2,1,67,2,3,83,2,5,55,3,2,131,3,3,116,3,3,117,2,1,149,2,3,196,2,4,165,3,2, 216,2,3,153,3,3,186,3,2,154,2,1,123,3,6,124,3,3,141,3,6,190,3,3,207,3,2, 158,2,2,111,3,3,62,3,4,63,2,1,61,2,1,12,3,6,13,2,3,30,2,2,43,2,1,89,2,3,58,3,2, 41,3,2,23,2,3,6,2,5,119,2,3,-1}; int Level8[]= {0,3,14,81,2,4,18,3,3,129,2,4,116,2,3,100,2,1,4,3,5,161,3,2,210,2,2,5,2,3,21,2,3,38,2,1, 69,2,3,55,2,3,147,2,1,214,2,1,197,2,3,178,2,8,134,3,3,151,3,2,88,3,5,87,2,1,73,3,2,9,2,2, 25,2,3,42,2,2,13,3,2,59,2,5,15,3,3,153,3,2,90,3,5,75,3,2,218,2,1,222,2,2,201,2,7,142,3,3, 108,3,6,187,2,1,93,3,2,78,3,3,-1}; int Level9[]= {0,2,3,32,2,6,17,2,2,48,2,2,96,3,3,176,2,3,193,2,1,208,2,5,146,3,2,65,3,5,130,22,4, 148,2,1,163,2,3,99,2,2,67,2,2,5,2,4,22,3,4,118,3,7,71,3,5,104,3,3,105,3,2,199,3,2, 168,3,3,201,3,2,169,2,2,154,2,3,172,2,1,140,2,3,158,2,2,175,3,4,218,2,5,203,2,1, 15,3,8,12,2,3,28,3,5,75,3,4,122,2,1,72,2,3,40,2,3,26,2,1,124,2,1,-1}; int Level10[]= {0,2,5,16,2,5,34,2,3,48,3,2,96,2,4,112,2,2,52,3,2,66,2,2,82,2,2,192,3,2,129,3,6,162,3,2, 163,2,4,131,2,3,148,2,1,181,3,3,196,3,2,211,2,1,69,3,4,6,2,10,39,3,2,70,2,3,40,2,6, 28,2,1,58,3,2,75,3,3,60,3,4,199,3,2,168,3,3,169,2,3,186,2,2,203,2,5,220,2,4,175,3,2, 173,2,2,139,2,2,109,3,4,110,2,1,31,3,8,62,2,1,77,2,1,135,2,2,119,2,2,104,2,2,-1}; int Level11[]= {0,2,16,16,3,13,31,3,13,209,2,14,20,2,1,196,2,1,203,2,1,27,2,1,78,3,2,142,3,2, 65,3,2,129,3,2,102,2,5,117,2,5,86,2,1,137,2,1,34,3,10,45,3,10,68,3,6,75,3,6,35,2,10, 179,2,10,166,2,4,54,2,4,69,2,6,149,2,6,-1}; int Level12[]= {0,2,6,16,2,2,32,2,2,112,3,7,49,3,7,209,2,4,180,3,2,178,2,2,51,3,9,98,3,2,8,2,8,19,2,8, 39,2,2,52,2,10,116,2,1,69,3,7,71,3,5,104,2,3,120,2,3,91,3,5,152,2,3,214,2,3,219, 2,5,198,2,7,206,2,2,166,2,9,188,2,1,31,3,11,44,2,3,77,3,6,-1}; GsOT WorldOT[2]; // Setup 2 Ordering Table Structures GsOT_TAG OTTags[2][1<9 this structure holds the coordinates for the gfx Num_Data Font[26]; // Holds coordinates of all the font characters unsigned int P1_Score=0; // Holds Player 1s score. GsSPRITE Score_Sprite[7]; // Sprites for score display 6 sprites gives a max score of 999999. int Movement[224]; // This array determines if the players can move to a specified location DMS Popcorn_Module; // structure for the main music int Popcorn_VabID; int Popcorn_OK; DMS High_Module; int High_OK; DMS Title_Music; int Title_OK; int Music_Volume=170; // Default Music volume int Game_Over_Timer; // timer to determine how long the GAME OVER logo is displayed int activebuff; // Holds the current buffer id int Current_Level=0; int Ready_Counter=0; // counter to display GET READY ON SCREEN int Game_Mode; int Fade_Mode; int Level_Complete=1; // 0=level in prigress 1=complete int Enemy_Count; // shows number of baddies on current level int Bonus_Show=TRUE; int Bonus_Flash_Counter=0; int Bonus_Flash=0; int Flash_Repeat=0; int Highscore=2500; //************************************************************************************************************************** main() { RECT dave; // Used for setting the 2D clipping area RECT End1; RECT End2; dave.x=0; dave.y=0; dave.w=320; dave.h=256; SetVideoMode(MODE_PAL); GsInitGraph(SCREEN_WIDTH,SCREEN_HEIGHT,4,0,0); // Init the screen mode GsDefDispBuff(0,0,320,0); // Setup the display buffer area GsDISPENV.screen.h = 256; // need to set these 2 variables to enable the display to show 256 lines GsDISPENV.screen.y=20; GsSetClip2D(&dave); Popcorn_OK=DMSInit(&Popcorn_Module,0,DMS_PAL,(unsigned char*)POPCORN_VH,(unsigned char*)POPCORN_VB,(unsigned char*)POPCORN); // Init the main module Title_OK=DMSInit(&Title_Music,0,DMS_PAL,(unsigned char*)TITLES_VH,(unsigned char*)TITLES_VB,(unsigned char*)TITLES_TUNE); // Init the main module // reset score to 0 High_OK=DMSInit(&High_Module,0,DMS_PAL,(unsigned char*)HIGH_TUNE_VH,(unsigned char*)HIGH_TUNE_VB,(unsigned char*)HIGH_TUNE); // Init the high score module Main_Sfx_Vab_ID=SsVabTransfer((unsigned char*)MAIN_SFX_VH,(unsigned char*)MAIN_SFX_VB,-1,1); // setup the sound effects Init_OT(); // Init the Ordering Tables Init_GFX(); Init_Background_Sprites(); // Sets up the gfx for the backgrounds. Init_Animation_Tables(); FSetPortBuffers(); // Initialize controllers Show_Credits(); //Start here while(1==1) { Do_Titles(); Setup_Score_Display(); Init_Player1(); Current_Level=1; // set current Level Game_Mode=Setting_Up; Fade_Mode=Complete_Fade_In; P1_Score=0; // reset score to 0 DMSSongReset(&Popcorn_Module); Init_Ice(); Game_Over_Timer=170; // bonus display variables Bonus_Show=TRUE; Bonus_Flash_Counter=0; Bonus_Flash=0; Flash_Repeat=0; Music_Volume=170; do { if(Game_Mode==Setting_Up) // full screen needs fading in { Fade_In_Screen(); } if(Game_Mode==Fade_In) { Fade_In_Level(); // Fade blocks if required } if(Game_Mode==Fade_Out) { Fade_Out_Level(); } activebuff = GsGetActiveBuff(); // get active buffer GsSetWorkBase((PACKET *)GpuPacketArea[activebuff]); GsClearOt(0,0,&WorldOT[activebuff]); if(Game_Mode==Ready || Game_Mode==Paused) { Check_For_Pause(); // check to see if game should be paused } if(Game_Mode!=Titles && Game_Mode !=The_End && Game_Mode!=Show_End_Credits) { Draw_Background(); // Draw Background blocks Draw_Ice(); // Draw all remaining Ice blocks to the Ordering table Draw_Score_Display(); } if(Game_Mode==Ready || Game_Mode==Level_Clear) { Move_Enemy(); Request_Block_Move(); Move_Player1(); Move_Blocks(); Animate_Melt(); Check_For_Collisions(); // Adjust_Music_Vol(); } if((Game_Mode ==Ready || Game_Mode==Paused || Game_Mode==Nearly_Ready || Game_Mode==Level_Clear) ) { Display_Bonus_Objects(); Draw_Enemy(); // Draw enemy sprites GsSortSprite(&P1.sprite,&WorldOT[activebuff],50); // Put player 1 into the Ordering Table } if(Game_Mode==Nearly_Ready) { Command.x=160; // Make command sprite display GET READY Command.y=128; Command.w=98; Command.h=15; Command.u=0; Command.v=16; Command.mx=44; Command.my=7; GsSortSprite(&Command,&WorldOT[activebuff],9); // Place command sprite into OT Ready_Counter--; // decrease counter that determines how long GET READY will be displayed if(Ready_Counter==0) { Game_Mode=Ready; // counter has reached 0 so the game is started } } if(Game_Mode==Paused) // show onscreen that the game has been paused { Box_Pause.attribute=0; Box_Pause.attribute+=(1<<30)+(2<<28); // draw transparent box to meke on screen colours darker Box_Pause.x=0; Box_Pause.y=0; Box_Pause.w=320; Box_Pause.h=256; Box_Pause.r=50; Box_Pause.g=50; Box_Pause.b=50; Command.x=160; // Make command sprite display PAUSED Command.y=128; Command.w=71; Command.h=15; Command.u=0; Command.v=0; Command.mx=35; Command.my=7; GsSortBoxFill(&Box_Pause,&WorldOT[activebuff],9); // place box in OT GsSortSprite(&Command,&WorldOT[activebuff],8); // Place command sprite into OT } if(Game_Mode==Game_Over) // Show Game Over Sprite { Command.x=160; // Make command sprite display Game Over Command.y=128; Command.w=101; Command.h=15; Command.u=0; Command.v=32; Command.mx=50; Command.my=7; Game_Over_Timer--; if(Music_Volume !=0) Music_Volume--; GsSortSprite(&Command,&WorldOT[activebuff],8); // Place command sprite into OT if(Game_Over_Timer==0) { Game_Mode=Titles; // go to title screen SsUtAllKeyOff(0); // turn off all audio channels Clear_Display_Buffers(); GsClearOt(0,0,&WorldOT[0]); GsClearOt(0,0,&WorldOT[1]); } if(Fade_Mode==Complete_Fade_Out) { Fade_Out_Screen(); } } if(Game_Mode==The_End) { if(Music_Volume !=0) Music_Volume--; if(Music_Volume==0) { Game_Mode=Show_End_Credits; End1.x = Font_tim_data.px; // x position in frame buffer End1.y = Font_tim_data.py; // y position in frame buffer End1.w = Font_tim_data.pw; // width of image End1.h = 1; // height of image End2.x = Font_tim_data.px; // x position in frame buffer End2.y = Font_tim_data.py; // y position in frame buffer End2.w = Font_tim_data.pw; // width of image End2.h = 1; // height of image End_Number=0; End_Delay=0; } } if(Game_Mode==Show_End_Credits) // Show End Credits { MoveImage(&End1,0,0); MoveImage(&End2,320,0); DrawSync(0); if(End1.h <=250) End_Delay++; if(End_Delay==5) { End1.h++; End2.h++; End_Delay=0; } MoveImage(&End1,0,0); MoveImage(&End2,320,0); if(End1.h==251) { End_Number++; if(End_Number==300) { Game_Over_Timer=0; } } } if(Popcorn_OK == DMS_OK && (Game_Mode != Titles)) // Play the music module { DMSSetMasterVol(&Popcorn_Module,Music_Volume); // set volume of music DMSPoll(&Popcorn_Module); } DrawSync(0); VSync(0); GsSwapDispBuff(); GsSortClear(0,0,0,&WorldOT[activebuff]); GsDrawOt(&WorldOT[activebuff]); // Draw all Gfx to the screen if(Game_Mode !=Titles && Game_Mode !=The_End && Game_Mode !=Enter_High && Game_Mode !=Show_End_Credits) { Select_Next_Level(); } }while(Game_Over_Timer !=0); Do_HighScore(); // enter a new highscore } } //************************************************************************************************************************** void Init_OT(void) // sets up the ordering tables. { int i; // used in loop below for (i=0;i<2;i++) { WorldOT[i].length = OT_LENGTH; WorldOT[i].org = OTTags[i]; } } //************************************************************************************************************************ void Init_GFX(void) // sets up the GFX into the frame buffer { RECT rect; // define a rect structure int loop; int counter; GsGetTimInfo((u_long *)(BACKGROUND_GFX_ADDRESS+4),&BG_tim_data); // get the information from the graphics file and fill the tim_data structure // needs to skip the header by 4 bytes. // Load the background image into the frame buffer using the RECT structure. rect.x = BG_tim_data.px; // x position in frame buffer rect.y = BG_tim_data.py; // y position in frame buffer rect.w = BG_tim_data.pw; // width of image rect.h = BG_tim_data.ph; // height of image LoadImage(&rect,BG_tim_data.pixel); // load the image into the correct location in the frame buffer // Load the background CLUT into the frame buffer rect.x = BG_tim_data.cx; // x position in frame buffer rect.y = BG_tim_data.cy; // y position in frame buffer rect.w = BG_tim_data.cw; // width of CLUT rect.h = BG_tim_data.ch; // height of CLUT LoadImage(&rect,BG_tim_data.clut); GsGetTimInfo((u_long *)(PLAYER_GFX_ADDRESS+4),&Player_tim_data); // Store the info for the player gfx graphics // Load the player gfx image into the frame buffer using the RECT structure. rect.x = Player_tim_data.px; // x position in frame buffer rect.y = Player_tim_data.py; // y position in frame buffer rect.w = Player_tim_data.pw; // width of image rect.h = Player_tim_data.ph; // height of image LoadImage(&rect,Player_tim_data.pixel); // load the image into the correct location in the frame buffer // Load the player CLUT into the frame buffer rect.x = Player_tim_data.cx; // x position in frame buffer rect.y = Player_tim_data.cy; // y position in frame buffer rect.w = Player_tim_data.cw; // width of CLUT rect.h = Player_tim_data.ch; // height of CLUT LoadImage(&rect,Player_tim_data.clut); GsGetTimInfo((u_long *)(ENEMY_GFX_ADDRESS+4),&Enemy_tim_data); // Store the info for the Enemy gfx graphics // Load the Enemy gfx image into the frame buffer using the RECT structure. rect.x = Enemy_tim_data.px; // x position in frame buffer rect.y = Enemy_tim_data.py; // y position in frame buffer rect.w = Enemy_tim_data.pw; // width of image rect.h = Enemy_tim_data.ph; // height of image LoadImage(&rect,Enemy_tim_data.pixel); // load the image into the correct location in the frame buffer // Load the player CLUT into the frame buffer rect.x = Enemy_tim_data.cx; // x position in frame buffer rect.y = Enemy_tim_data.cy; // y position in frame buffer rect.w = Enemy_tim_data.cw; // width of CLUT rect.h = Enemy_tim_data.ch; // height of CLUT LoadImage(&rect,Enemy_tim_data.clut); GsGetTimInfo((u_long *)(COMMAND_GFX_ADDRESS+4),&Command_tim_data); // Store the info for the Commands gfx // Load the Commands gfx image into the frame buffer using the RECT structure. rect.x = Command_tim_data.px; // x position in frame buffer rect.y = Command_tim_data.py; // y position in frame buffer rect.w = Command_tim_data.pw; // width of image rect.h = Command_tim_data.ph; // height of image LoadImage(&rect,Command_tim_data.pixel); // load the image into the correct location in the frame buffer // Load the Commands CLUT into the frame buffer rect.x = Command_tim_data.cx; // x position in frame buffer rect.y = Command_tim_data.cy; // y position in frame buffer rect.w = Command_tim_data.cw; // width of CLUT rect.h = Command_tim_data.ch; // height of CLUT LoadImage(&rect,Command_tim_data.clut); GsGetTimInfo((u_long *)(BONUS_GFX_ADDRESS+4),&Bonus_tim_data); // Store the info for the Bonus gfx // Load the Bonus gfx image into the frame buffer using the RECT structure. rect.x = Bonus_tim_data.px; // x position in frame buffer rect.y = Bonus_tim_data.py; // y position in frame buffer rect.w = Bonus_tim_data.pw; // width of image rect.h = Bonus_tim_data.ph; // height of image LoadImage(&rect,Bonus_tim_data.pixel); // load the image into the correct location in the frame buffer // Load the Bonus CLUT into the frame buffer rect.x = Bonus_tim_data.cx; // x position in frame buffer rect.y = Bonus_tim_data.cy; // y position in frame buffer rect.w = Bonus_tim_data.cw; // width of CLUT rect.h = Bonus_tim_data.ch; // height of CLUT LoadImage(&rect,Bonus_tim_data.clut); GsGetTimInfo((u_long *)(HIGH_SCORE_GFX_ADDRESS+4),&High_Score_tim_data); // Store the info for the High score gfx // Load the High score gfx image into the frame buffer using the RECT structure. rect.x = High_Score_tim_data.px; // x position in frame buffer rect.y = High_Score_tim_data.py; // y position in frame buffer rect.w = High_Score_tim_data.pw; // width of image rect.h = High_Score_tim_data.ph; // height of image LoadImage(&rect,High_Score_tim_data.pixel); // load the image into the correct location in the frame buffer // Load the High score CLUT into the frame buffer rect.x = High_Score_tim_data.cx; // x position in frame buffer rect.y = High_Score_tim_data.cy; // y position in frame buffer rect.w = High_Score_tim_data.cw; // width of CLUT rect.h = High_Score_tim_data.ch; // height of CLUT LoadImage(&rect,High_Score_tim_data.clut); GsGetTimInfo((u_long *)(TITLES_GFX_ADDRESS+4),&Titles_tim_data); // Store the info for the titles gfx // Load the titles gfx image into the frame buffer using the RECT structure. rect.x = Titles_tim_data.px; // x position in frame buffer rect.y = Titles_tim_data.py; // y position in frame buffer rect.w = Titles_tim_data.pw; // width of image rect.h = Titles_tim_data.ph; // height of image LoadImage(&rect,Titles_tim_data.pixel); // load the image into the correct location in the frame buffer // Load the titles CLUT into the frame buffer rect.x = Titles_tim_data.cx; // x position in frame buffer rect.y = Titles_tim_data.cy; // y position in frame buffer rect.w = Titles_tim_data.cw; // width of CLUT rect.h = Titles_tim_data.ch; // height of CLUT LoadImage(&rect,Titles_tim_data.clut); GsGetTimInfo((u_long *)(FONT_GFX_ADDRESS+4),&Font_tim_data); // Store the info for the font gfx // Load the titles gfx image into the frame buffer using the RECT structure. rect.x = Font_tim_data.px; // x position in frame buffer rect.y = Font_tim_data.py; // y position in frame buffer rect.w = Font_tim_data.pw; // width of image rect.h = Font_tim_data.ph; // height of image LoadImage(&rect,Font_tim_data.pixel); // load the image into the correct location in the frame buffer GsGetTimInfo((u_long *)(STORY1_GFX_ADDRESS+4),&Story1_tim_data); // Store the info for the story // Load the titles gfx image into the frame buffer using the RECT structure. rect.x = Story1_tim_data.px; // x position in frame buffer rect.y = Story1_tim_data.py; // y position in frame buffer rect.w = Story1_tim_data.pw; // width of image rect.h = Story1_tim_data.ph; // height of image LoadImage(&rect,Story1_tim_data.pixel); // load the image into the correct location in the frame buffer // Load the titles CLUT into the frame buffer rect.x = Story1_tim_data.cx; // x position in frame buffer rect.y = Story1_tim_data.cy; // y position in frame buffer rect.w = Story1_tim_data.cw; // width of CLUT rect.h = Story1_tim_data.ch; // height of CLUT LoadImage(&rect,Story1_tim_data.clut); GsGetTimInfo((u_long *)(STORY2_GFX_ADDRESS+4),&Story2_tim_data); // Store the info for the story // Load the titles gfx image into the frame buffer using the RECT structure. rect.x = Story2_tim_data.px; // x position in frame buffer rect.y = Story2_tim_data.py; // y position in frame buffer rect.w = Story2_tim_data.pw; // width of image rect.h = Story2_tim_data.ph; // height of image LoadImage(&rect,Story2_tim_data.pixel); // load the image into the correct location in the frame buffer // Load the titles CLUT into the frame buffer rect.x = Story2_tim_data.cx; // x position in frame buffer rect.y = Story2_tim_data.cy; // y position in frame buffer rect.w = Story2_tim_data.cw; // width of CLUT rect.h = Story2_tim_data.ch; // height of CLUT LoadImage(&rect,Story2_tim_data.clut); GsGetTimInfo((u_long *)(CREDITS1_GFX_ADDRESS+4),&Credits1_tim_data); // Store the info for the credits // Load the titles gfx image into the frame buffer using the RECT structure. rect.x = Credits1_tim_data.px; // x position in frame buffer rect.y = Credits1_tim_data.py; // y position in frame buffer rect.w = Credits1_tim_data.pw; // width of image rect.h = Credits1_tim_data.ph; // height of image LoadImage(&rect,Credits1_tim_data.pixel); // load the image into the correct location in the frame buffer // Load the titles CLUT into the frame buffer rect.x = Credits1_tim_data.cx; // x position in frame buffer rect.y = Credits1_tim_data.cy; // y position in frame buffer rect.w = Credits1_tim_data.cw; // width of CLUT rect.h = Credits1_tim_data.ch; // height of CLUT LoadImage(&rect,Credits1_tim_data.clut); GsGetTimInfo((u_long *)(CREDITS2_GFX_ADDRESS+4),&Credits2_tim_data); // Store the info for the credits // Load the titles gfx image into the frame buffer using the RECT structure. rect.x = Credits2_tim_data.px; // x position in frame buffer rect.y = Credits2_tim_data.py; // y position in frame buffer rect.w = Credits2_tim_data.pw; // width of image rect.h = Credits2_tim_data.ph; // height of image LoadImage(&rect,Credits2_tim_data.pixel); // load the image into the correct location in the frame buffer // Load the titles CLUT into the frame buffer rect.x = Credits2_tim_data.cx; // x position in frame buffer rect.y = Credits2_tim_data.cy; // y position in frame buffer rect.w = Credits2_tim_data.cw; // width of CLUT rect.h = Credits2_tim_data.ch; // height of CLUT LoadImage(&rect,Credits2_tim_data.clut); for(loop=0;loop<6;loop++) // setup default highscore name DAVE.W { High_Score_Name[loop].attribute = 0+(1<<24); // 8bit sprite High_Score_Name[loop].x=110+10+(loop*16);; // Setup High sprite logo High_Score_Name[loop].y=150; High_Score_Name[loop].w=16; High_Score_Name[loop].h=16; High_Score_Name[loop].tpage = GetTPage(1,0,High_Score_tim_data.px,High_Score_tim_data.py); High_Score_Name[loop].u=0; High_Score_Name[loop].v=0; High_Score_Name[loop].cx=High_Score_tim_data.cx; High_Score_Name[loop].cy=High_Score_tim_data.cy; High_Score_Name[loop].r=128; High_Score_Name[loop].g=128; High_Score_Name[loop].b=128; High_Score_Name[loop].mx=8; High_Score_Name[loop].my=8; High_Score_Name[loop].rotate=0; High_Score_Name[loop].scalex=ONE; High_Score_Name[loop].scaley=ONE; } for(counter=0;counter<7;counter++) // sets up the score sprites { Score_Sprite[counter].attribute = 0x01000000 ; // to all zeros Score_Sprite[counter].x=280; Score_Sprite[counter].y=40+(counter*10); Score_Sprite[counter].w=7; Score_Sprite[counter].h=7; Score_Sprite[counter].tpage = GetTPage(1,0,Player_tim_data.px,Player_tim_data.py); Score_Sprite[counter].u=0; Score_Sprite[counter].v=40; Score_Sprite[counter].cx=Player_tim_data.cx; Score_Sprite[counter].cy=Player_tim_data.cy; Score_Sprite[counter].r=128; Score_Sprite[counter].g=128; Score_Sprite[counter].b=128; Score_Sprite[counter].mx=0; Score_Sprite[counter].my=0; Score_Sprite[counter].rotate=0; Score_Sprite[counter].scalex=ONE; Score_Sprite[counter].scaley=ONE; } High_Score_Name[0].u=48; //D High_Score_Name[0].v=96; High_Score_Name[1].u=0; //A High_Score_Name[1].v=96; High_Score_Name[2].u=80; //V High_Score_Name[2].v=128; High_Score_Name[3].u=64; //E High_Score_Name[3].v=96; High_Score_Name[4].u=32; //. High_Score_Name[4].v=144; High_Score_Name[5].u=96; //W High_Score_Name[5].v=128; Lives[0].x=0; // Tpage graphic offset for lives counter Lives[0].y=32; Lives[0].width=7; Lives[1].x=8; Lives[1].y=32; Lives[1].width=2; Lives[2].x=11; Lives[2].y=32; Lives[2].width=7; Lives[3].x=19; Lives[3].y=32; Lives[3].width=7; Lives[4].x=27; Lives[4].y=32; Lives[4].width=7; Lives[5].x=35; Lives[5].y=32; Lives[5].width=7; Lives[6].x=43; Lives[6].y=32; Lives[6].width=7; Lives[7].x=51; Lives[7].y=32; Lives[7].width=7; Lives[8].x=59; Lives[8].y=32; Lives[8].width=7; Lives[9].x=67; Lives[9].y=32; Lives[9].width=7; DrawSync(0); // Wait for all drawing to finish } //************************************************************************************************************************ void Init_Background_Sprites(void) //sets up the Background sprites. { int counter; int x=0; int y=0; for (counter=0;counter<(20*16);counter++) { Background[counter].attribute = 0x01000000 ; // 8 bit sprite Background[counter].x=x*16; // x and y screen coordinates Background[counter].y=y*16; Background[counter].w=16; Background[counter].h=16; Background[counter].tpage = GetTPage(1,0,BG_tim_data.px,BG_tim_data.py); Background[counter].u=0; Background[counter].v=0; Background[counter].r=128; Background[counter].g=128; Background[counter].b=128; Background[counter].cx=BG_tim_data.cx; // CLUT x and y values in Vram Background[counter].cy=BG_tim_data.cy; if(x==0 || (y==0 && x<=17) || (y==15 && x<=17) || x==17) Background[counter].u=32; // Change GFX block image if(x==0 && y==0) Background[counter].u=16; // Change GFX block image if(x==17 && y==0) Background[counter].u=16; // Change GFX block image if(x==0 && y==15) Background[counter].u=16; // Change GFX block image if(x==17 && y==15) Background[counter].u=16; // Change GFX block image if(Background[counter].u==0) { Background[counter].r=65; Background[counter].g=65; Background[counter].b=65; } if(x>17) // dim the gfx background for the score area { Background[counter].r=30; Background[counter].g=30; Background[counter].b=30; } Background[counter].mx=0; Background[counter].my=0; Background[counter].scalex=ONE; Background[counter].scaley=ONE; Background[counter].rotate=0; x++; if(x==20) // end of the row { x=0; y++; } } } //************************************************************************************************************************ void Draw_Background(void) // Puts BG images into OT { int counter; for(counter=0;counter<(20*16);counter++) { GsSortFastSprite(&Background[counter],&WorldOT[activebuff],1023-counter); } } //************************************************************************************************************************ void Init_Ice(void) // sets up the position of the ice blocks { int counter; int x=0; int y=0; int random,random1; int colour=0; for (counter=0;counter<224;counter++) { Movement[counter]=1; Ice_Blocks[counter].r=0; Ice_Blocks[counter].g=0; Ice_Blocks[counter].b=0; Ice_Blocks[counter].attribute = 0x01000000 ; // 8 bit sprite Ice_Blocks[counter].attribute +=(1<<30)+(1<<28); // set Transparency attrubutes Ice_Blocks[counter].x=(x*16)+16; // x and y screen coordinates Ice_Blocks[counter].y=(y*16)+16; Ice_Blocks[counter].w=16; Ice_Blocks[counter].h=16; Ice_Blocks[counter].tpage = GetTPage(1,0,BG_tim_data.px,BG_tim_data.py); random1=rand()%15; if(random1>5) { random = rand()%3; if(random==0) { // Block colours go off random numbers Ice_Blocks[counter].u=0; Ice_Blocks[counter].v=16; } if(random==1) { Ice_Blocks[counter].u=16; Ice_Blocks[counter].v=16; } if(random==2) { Ice_Blocks[counter].u=32; Ice_Blocks[counter].v=16; } } else { if(colour==0) { Ice_Blocks[counter].u=0; Ice_Blocks[counter].v=16; } if(colour==1) { Ice_Blocks[counter].u=16; Ice_Blocks[counter].v=16; } if(colour==2) { Ice_Blocks[counter].u=32; Ice_Blocks[counter].v=16; } colour++; if(colour==3) colour=0; } Ice_Blocks[counter].r=0; Ice_Blocks[counter].g=0; Ice_Blocks[counter].b=0; Ice_Blocks[counter].cx=BG_tim_data.cx; // CLUT x and y values in Vram Ice_Blocks[counter].cy=BG_tim_data.cy; x++; if(x==16) // change block x and y coordinates { x=0; y++; } } } //************************************************************************************************************************ void Draw_Ice(void) // draws ice blocks to screen { int counter; for(counter=0;counter<224;counter++) { if(Ice_Blocks[counter].attribute !=0) GsSortFastSprite(&Ice_Blocks[counter],&WorldOT[activebuff],511-counter); } } //************************************************************************************************************************ void Setup_Level(int *data) // defines which blocks are displayed in the level { // *data is the base address of the array that holds the level data int sprite_pos,direction,counter; while(*data != -1) { sprite_pos = *data++; direction = *data++; counter = *data++; while(counter !=0) { Movement[sprite_pos]=0; // make array element 0 which means the player can move here. Ice_Blocks[sprite_pos].attribute=0; // turn off sprite if(direction == Down) sprite_pos +=16; if(direction == Right) sprite_pos++; if(direction == Left) sprite_pos--; if(direction == Up) sprite_pos -=16; counter--; } } } //************************************************************************************************************************ void Fade_In_Level(void) // fades in level { int counter; static int red=0; static int green=0; static int blue=0; for(counter=0;counter<224;counter++) { Ice_Blocks[counter].r=red; // Fade up colour values Ice_Blocks[counter].g=green; Ice_Blocks[counter].b=blue; } red+=2; green+=2; blue+=2; if(red==130) // Have we reached our maximum values { // if so then reset colours and set the game mode red=0; green=0; blue=0; Game_Mode=Nearly_Ready; Ready_Counter=100; } } //************************************************************************************************************************ void Fade_Out_Level(void) // fades out level { int counter; static int red=128; static int green=128; static int blue=128; for(counter=0;counter<224;counter++) { Ice_Blocks[counter].r=red; // Fade up colour values Ice_Blocks[counter].g=green; Ice_Blocks[counter].b=blue; } red-=2; green-=2; blue-=2; if(red==0) // Have we reached our maximum values { // if so then reset colours and set the game mode red=128; green=128; blue=128; Game_Mode=Faded_Out; } } //************************************************************************************************************************ void Init_Player1(void) // Sets up Player 1 structure { P1.frame=0; P1.status=Flashing; P1.moving=0; P1.block_x=8; P1.block_y=7; P1.direction=Right; P1.move_counter=0; P1.lives=4; P1.speed=Slow; P1.run_energy=200; P1.Flash_counter=60; P1.anim_counter=0; P1.sprite.attribute = 0x01000000 ; P1.sprite.x=(P1.block_x*16)+24; // P1 sprite details. P1.sprite.y=(P1.block_y*16)+24; P1.sprite.w=16; P1.sprite.h=16; P1.sprite.tpage = GetTPage(1,0,Player_tim_data.px,Player_tim_data.py); P1.sprite.u=48; P1.sprite.v=0; P1.sprite.cx=Player_tim_data.cx; P1.sprite.cy=Player_tim_data.cy; P1.sprite.r=128; P1.sprite.g=128; P1.sprite.b=128; P1.sprite.mx=8; P1.sprite.my=8; P1.sprite.scalex=ONE; P1.sprite.scaley=ONE; P1.sprite.rotate=0; } //************************************************************************************************************************ int Move_Ok(int BlockX, int BlockY) // takes in x and y block coordinates and returns 0 if their is no ice block in that location { int temp; temp=BlockY*16; // calculate Y offset temp+=BlockX; // add X offset return(Movement[temp]); } //************************************************************************************************************************ void Move_Player1(void) { static int counter=0; static int Scale=0; // Used to hold the scaling value when the player dies static int Scale_Dir=Up; // used to hold the scaling direction ( Up or Down ) static int Rotate=0; // Holds rotation value when the player is dieing int temp; if(P1.lives>=0 && P1.status==Flashing) // Player is Invunerable { counter++; if(counter==1) { P1.sprite.r=0; // make sprite invisible to give the impression that the sprite is flashing P1.sprite.g=0; P1.sprite.b=0; } if(counter==2) { counter=0; //reset counter P1.sprite.r=128; // make sprite visable again P1.sprite.g=128; P1.sprite.b=128; P1.Flash_counter--; if(P1.Flash_counter==0) // Player can now be killed { P1.status=Ok; } } } if(P1.lives>=0 && (P1.status == Ok || P1.status==Flashing)) // check for remaining lives { if(P1.moving==0) // make sure the player is not moving between blocks { if(FSPadRead(PORT_ONE) & SPADright) // try and move right { if(P1.block_x <15) // keep within map boundaries. { if(Move_Ok(P1.block_x+1,P1.block_y)==0) // check to see if the block to the right is empty { if((FSPadRead(PORT_ONE) & SPADcr) && P1.run_energy !=0) { P1.speed=Fast; } else { P1.speed=Slow; } P1.direction=Right; // all checks complete so move sprite right P1.moving=1; P1.move_counter=0; P1.anim_counter=0; } else { P1.speed=Slow; P1.direction=Right; // stop moving right P1.sprite.u=P1_Right_Anim[0].x; P1.sprite.v=P1_Right_Anim[0].y; P1.moving=0; } } } if(FSPadRead(PORT_ONE) & SPADleft) // try and move left { if(P1.block_x >0) // keep within map boundaries. { if(Move_Ok(P1.block_x-1,P1.block_y)==0) // check to see if the block to the left is empty { if((FSPadRead(PORT_ONE) & SPADcr) && P1.run_energy !=0) // check to see if player should run or walk { P1.speed=Fast; } else { P1.speed=Slow; } P1.direction=Left; // all checks complete so move sprite left P1.moving=1; P1.move_counter=0; P1.anim_counter=0; } else { P1.speed=Slow; P1.direction=Left; // stop moving left P1.sprite.u=P1_Left_Anim[0].x; P1.sprite.v=P1_Left_Anim[0].y; P1.moving=0; } } } if(FSPadRead(PORT_ONE) & SPADup) // try and move up { if(P1.block_y >0) // keep within map boundaries. { if(Move_Ok(P1.block_x,P1.block_y-1)==0) // check to see if the block above is empty { if((FSPadRead(PORT_ONE) & SPADcr) && P1.run_energy !=0) { P1.speed=Fast; } else { P1.speed=Slow; } P1.direction=Up; // all checks complete so move sprite up P1.moving=1; P1.move_counter=0; P1.anim_counter=0; } else { P1.speed=Slow; P1.direction=Up; P1.sprite.u=P1_Up_Anim[0].x; P1.sprite.v=P1_Up_Anim[0].y; // stop moving up P1.moving=0; } } } if(FSPadRead(PORT_ONE) & SPADdown) // try and move down { if(P1.block_y <13) // keep within map boundaries. { if(Move_Ok(P1.block_x,P1.block_y+1)==0) // check to see if the block below is empty { if((FSPadRead(PORT_ONE) & SPADcr) && P1.run_energy !=0) { P1.speed=Fast; } else { P1.speed=Slow; } P1.direction=Down; // all checks complete so move sprite down P1.moving=1; P1.move_counter=0; P1.anim_counter=0; } else { P1.speed=Slow; P1.direction=Down; // stop moving down P1.sprite.u=P1_Down_Anim[0].x; P1.sprite.v=P1_Down_Anim[0].y; P1.moving=0; } } } } if(P1.moving==1) // this section moves and animates the sprite. { temp=P1.move_counter; if(P1.direction==Right) // Sprite is moving right { if((FSPadRead(PORT_ONE) & SPADcr) && P1.run_energy !=0 && (temp==0 || temp==2 ||temp==4 || temp==6 ||temp==8 ||temp==10 ||temp==12 || temp==14)) { P1.speed=Fast; } else { P1.speed=Slow; } if(P1.speed==Fast) { P1.run_energy--; } P1.move_counter+=P1.speed; P1.sprite.x+=P1.speed; P1.anim_counter++; if(P1.anim_counter==4) { P1.anim_counter=0; P1.frame++; } if(P1.frame==4) P1.frame=0; P1.sprite.u=P1_Right_Anim[P1.frame].x; P1.sprite.v=P1_Right_Anim[P1.frame].y; if(P1.move_counter==16) { P1.moving=0; // Sprite has moved required distance st stop moving P1.block_x++; // Increment block position P1.speed=Slow; } } if(P1.direction==Left) // Sprite is moving Left { if((FSPadRead(PORT_ONE) & SPADcr) && P1.run_energy !=0 &&(temp==0 || temp==2 ||temp==4 || temp==6 ||temp==8 ||temp==10 ||temp==12 || temp==14)) { P1.speed=Fast; } else { P1.speed=Slow; } if(P1.speed==Fast) { P1.run_energy--; } P1.move_counter+=P1.speed; P1.sprite.x-=P1.speed; P1.anim_counter++; if(P1.anim_counter==4) { P1.anim_counter=0; P1.frame++; } if(P1.frame==4) P1.frame=0; P1.sprite.u=P1_Left_Anim[P1.frame].x; P1.sprite.v=P1_Left_Anim[P1.frame].y; if(P1.move_counter==16) { P1.moving=0; // Sprite has moved required distance st stop moving P1.block_x--; // Decrement block position P1.speed=Slow; } } if(P1.direction==Up) // Sprite is moving upwards { if((FSPadRead(PORT_ONE) & SPADcr) && P1.run_energy !=0 &&(temp==0 || temp==2 ||temp==4 || temp==6 ||temp==8 ||temp==10 ||temp==12 || temp==14)) { P1.speed=Fast; } else { P1.speed=Slow; } if(P1.speed==Fast) { P1.run_energy--; } P1.move_counter+=P1.speed; P1.sprite.y-=P1.speed; P1.anim_counter++; if(P1.anim_counter==4) { P1.anim_counter=0; P1.frame++; } if(P1.frame==4) P1.frame=0; P1.sprite.u=P1_Up_Anim[P1.frame].x; P1.sprite.v=P1_Up_Anim[P1.frame].y; if(P1.move_counter==16) { P1.moving=0; // Sprite has moved required distance st stop moving P1.block_y--; // Decrement block position P1.speed=Slow; } } if(P1.direction==Down) // Sprite is moving downwards { if((FSPadRead(PORT_ONE) & SPADcr) && P1.run_energy >0 &&(temp==0 || temp==2 ||temp==4 || temp==6 ||temp==8 ||temp==10 ||temp==12 || temp==14)) { P1.speed=Fast; } else { P1.speed=Slow; } if(P1.speed==Fast) { P1.run_energy--; } P1.move_counter+=P1.speed; P1.sprite.y+=P1.speed; P1.anim_counter++; if(P1.anim_counter==4) { P1.anim_counter=0; P1.frame++; } if(P1.frame==4) P1.frame=0; P1.sprite.u=P1_Down_Anim[P1.frame].x; P1.sprite.v=P1_Down_Anim[P1.frame].y; if(P1.move_counter==16) { P1.moving=0; // Sprite has moved required distance st stop moving P1.block_y++; // Decrement block position P1.speed=Slow; } } } } if(P1.lives>=0 && P1.status==Dying) // Player is currently dying { P1.sprite.attribute= (1<<30)+(1<<28)+(1<<24); if(Scale_Dir==Up) { // sprite is scaling up Scale+=100; Rotate+=12; if(Scale==6000) // if scale has reached maximum value then scale back down to normal value { Scale_Dir=Down; } } if(Scale_Dir==Down) // sprite is scaling down { Scale-=100; Rotate-=12; if(Scale==0) // sprite has reached normal size { P1.status=Flashing; // make sprite invunerable P1.Flash_counter=60; Scale_Dir=Up; Rotate=0; P1.lives--; // subtract a life Add_Run_Energy(50); // give player some more run energy P1.sprite.attribute = 0x01000000; // reset sprite attributes if(P1.lives<0) { P1.lives=0; Game_Mode=Game_Over; // all lives have gone so it's game over Fade_Mode=Complete_Fade_Out; Game_Over_Timer=170; } } } P1.sprite.rotate=Rotate*4096; P1.sprite.scalex=4096+Scale; // Scale sprite P1.sprite.scaley=4096+Scale; } } //************************************************************************************************************************ void Init_Animation_Tables(void) // sets up all the animation structures { P1_Right_Anim[0].x=48; // X an Y pixel positions in the sprites TPage P1_Right_Anim[0].y=0; P1_Right_Anim[1].x=0; P1_Right_Anim[1].y=0; P1_Right_Anim[2].x=16; P1_Right_Anim[2].y=0; P1_Right_Anim[3].x=32; P1_Right_Anim[3].y=0; P1_Left_Anim[0].x=64; P1_Left_Anim[0].y=0; P1_Left_Anim[1].x=112; P1_Left_Anim[1].y=0; P1_Left_Anim[2].x=96; P1_Left_Anim[2].y=0; P1_Left_Anim[3].x=80; P1_Left_Anim[3].y=0; P1_Up_Anim[0].x=0; P1_Up_Anim[0].y=16; P1_Up_Anim[1].x=16; P1_Up_Anim[1].y=16; P1_Up_Anim[2].x=0; P1_Up_Anim[2].y=16; P1_Up_Anim[3].x=32; P1_Up_Anim[3].y=16; P1_Down_Anim[0].x=48; P1_Down_Anim[0].y=16; P1_Down_Anim[1].x=64; P1_Down_Anim[1].y=16; P1_Down_Anim[2].x=48; P1_Down_Anim[2].y=16; P1_Down_Anim[3].x=80; P1_Down_Anim[3].y=16; Enemy_Right[0].x=0; Enemy_Right[0].y=0; Enemy_Right[1].x=16; Enemy_Right[1].y=0; Enemy_Right[2].x=32; Enemy_Right[2].y=0; Enemy_Right[3].x=48; Enemy_Right[3].y=0; Enemy_Left[0].x=64; Enemy_Left[0].y=0; Enemy_Left[1].x=80; Enemy_Left[1].y=0; Enemy_Left[2].x=96; Enemy_Left[2].y=0; Enemy_Left[3].x=112; Enemy_Left[3].y=0; Enemy_Up[0].x=64; Enemy_Up[0].y=16; Enemy_Up[1].x=80; Enemy_Up[1].y=16; Enemy_Up[2].x=96; Enemy_Up[2].y=16; Enemy_Up[3].x=112; Enemy_Up[3].y=16; Enemy_Down[0].x=0; Enemy_Down[0].y=16; Enemy_Down[1].x=16; Enemy_Down[1].y=16; Enemy_Down[2].x=32; Enemy_Down[2].y=16; Enemy_Down[3].x=48; Enemy_Down[3].y=16; Bonus_Item[0].x=0; // Bonus Items offsets into the Tpage. Bonus_Item[0].y=0+96; Bonus_Item[1].x=16; Bonus_Item[1].y=0+96; Bonus_Item[2].x=32; Bonus_Item[2].y=0+96; Bonus_Item[3].x=48; Bonus_Item[3].y=0+96; Bonus_Item[4].x=64; Bonus_Item[4].y=0+96; Bonus_Item[5].x=80; Bonus_Item[5].y=0+96; Bonus_Item[6].x=96; Bonus_Item[6].y=0+96; Bonus_Item[7].x=112; Bonus_Item[7].y=0+96; Bonus_Item[8].x=0; Bonus_Item[8].y=16+96; } //************************************************************************************************************************ void Melt_This_Block(int sprite_number) // Melts the block refered to by sprite number { // can range from 0 to 223 int loop; // standard counter int block_added; // gets set to 1 when the block is added block_added=0; loop=0; while(block_added==0 && loop<50) { if(Melting[loop].avail==0) // is this position available { block_added=1; // block was added to melting list Melting[loop].avail=1; // slot is now taken Melting[loop].array_position=sprite_number; Melting[loop].frame_counter=0; Melting[loop].frame=0; Movement[sprite_number]=2; // 2 denotes that the block in this position is melting } loop++; } } //************************************************************************************************************************ void Animate_Melt(void) // animates all blocks that are melting. { int loop; for(loop=0;loop<50;loop++) { if(Melting[loop].avail==1) { Melting[loop].frame_counter++; if(Melting[loop].frame_counter==4) // next frame required now { Melting[loop].frame_counter=0; //reset frame counter Ice_Blocks[Melting[loop].array_position].v+=16; // change offset in TPage to animate sptite Melting[loop].frame++; if(Melting[loop].frame==5) // anim has finished { Melting[loop].avail=0; // slot is free again Movement[Melting[loop].array_position]=0; // block has melted so we can now move the this block position Melting[loop].frame=0; Melting[loop].frame_counter=0; Ice_Blocks[Melting[loop].array_position].attribute=0; // turn off Ice sprite } } } } } //************************************************************************************************************************ void Request_Block_Move(void) { if(P1.lives >=0 && (P1.status==Ok || P1.status==Flashing)) { if(P1.moving==0) // player must be stationary to push a block { if((P1.direction==Right) && Button_Check()==1) // player is facing right and has pushed the square button { if(P1.block_x==14 &&(Move_Ok(P1.block_x+1,P1.block_y)==1)) // there is a block to the right of the player { Melt_This_Block((P1.block_y*16)+(P1.block_x+1)); Add_To_Score(Block_Crush_Score); Add_Run_Energy(10); SsUtKeyOn(Main_Sfx_Vab_ID,7,0,60,0,80,80); } if(P1.block_x<14 && (Move_Ok(P1.block_x+1,P1.block_y)==1)) { if(Move_Ok(P1.block_x+2,P1.block_y)==1) { Melt_This_Block((P1.block_y*16)+(P1.block_x+1)); Add_To_Score(Block_Crush_Score); Add_Run_Energy(10); SsUtKeyOn(Main_Sfx_Vab_ID,7,0,60,0,80,80); } else { // function call to move block right goes here Move_This_Block((P1.block_y*16)+(P1.block_x+1),Right,2); } } } if((P1.direction==Left) && Button_Check()==1) // player is facing left and has pushed the square button { if(P1.block_x==1 &&(Move_Ok(P1.block_x-1,P1.block_y)==1)) // there is a block to the left of the player { Melt_This_Block((P1.block_y*16)+(P1.block_x-1)); Add_To_Score(Block_Crush_Score); Add_Run_Energy(10); SsUtKeyOn(Main_Sfx_Vab_ID,7,0,60,0,80,80); } if(P1.block_x>1 && (Move_Ok(P1.block_x-1,P1.block_y)==1)) { if(Move_Ok(P1.block_x-2,P1.block_y)==1) { Melt_This_Block((P1.block_y*16)+(P1.block_x-1)); Add_To_Score(Block_Crush_Score); Add_Run_Energy(10); SsUtKeyOn(Main_Sfx_Vab_ID,7,0,60,0,80,80); } else { // function call to move block left goes here Move_This_Block((P1.block_y*16)+(P1.block_x-1),Left,2); } } } if((P1.direction==Up) && Button_Check()==1) // player is facing up and has pushed the square button { if(P1.block_y==1 &&(Move_Ok(P1.block_x,P1.block_y-1)==1)) // there is a block above of the player { Melt_This_Block(((P1.block_y-1)*16)+(P1.block_x)); Add_To_Score(Block_Crush_Score); Add_Run_Energy(10); SsUtKeyOn(Main_Sfx_Vab_ID,7,0,60,0,80,80); } if(P1.block_y>1 && (Move_Ok(P1.block_x,P1.block_y-1)==1)) { if(Move_Ok(P1.block_x,P1.block_y-2)==1) { Melt_This_Block(((P1.block_y-1)*16)+(P1.block_x)); Add_To_Score(Block_Crush_Score); Add_Run_Energy(10); SsUtKeyOn(Main_Sfx_Vab_ID,7,0,60,0,80,80); } else { // function call to move block up goes here Move_This_Block(((P1.block_y*16)-16)+(P1.block_x),Up,2); } } } if((P1.direction==Down) && Button_Check()==1) // player is facing down and has pushed the square button { if(P1.block_y==12 &&(Move_Ok(P1.block_x,P1.block_y+1)==1)) // there is a block below of the player { Melt_This_Block(((P1.block_y+1)*16)+(P1.block_x)); Add_To_Score(Block_Crush_Score); Add_Run_Energy(10); SsUtKeyOn(Main_Sfx_Vab_ID,7,0,60,0,80,80); } if(P1.block_y<12 && (Move_Ok(P1.block_x,P1.block_y+1)==1)) { if(Move_Ok(P1.block_x,P1.block_y+2)==1) { Melt_This_Block(((P1.block_y+1)*16)+(P1.block_x)); Add_To_Score(Block_Crush_Score); Add_Run_Energy(10); SsUtKeyOn(Main_Sfx_Vab_ID,7,0,60,0,80,80); } else { // function call to down block Down goes here Move_This_Block(((P1.block_y*16)+16)+(P1.block_x),Down,2); } } } } } } //************************************************************************************************************************ int Button_Check(void) { if(FSPadRead(PORT_ONE) & SPADsq) { return(1); } return(-1); } //************************************************************************************************************************ void Select_Next_Level(void) // Starts the next level { static int clear_counter=0; if(All_Dead()==TRUE) // allows player to pick up bonus obejcts after killing all bad guys { clear_counter++; if(clear_counter==250) { clear_counter=0; Level_Complete=1; Game_Mode=Ready; } } if((Level_Complete==1) && Game_Mode==Ready &&(P1.status==Ok || P1.status==Flashing)) { P1.block_x=8; // Reset P1 sprite details P1.block_y=7; P1.direction=Right; P1.move_counter=0; P1.moving=0; P1.sprite.x=(P1.block_x*16)+24; // P1 sprite details. P1.sprite.y=(P1.block_y*16)+24; P1.sprite.u=48; P1.sprite.v=0; P1.Flash_counter=60; P1.status=Flashing; if(Current_Level ==0) { Game_Mode=Faded_Out; } else { Game_Mode=Fade_Out; // fade out level } } if(Game_Mode==Faded_Out) // Now that the level is faded do what is required to setup the next level { Clear_Melting_Blocks(); Clear_Moving_Blocks(); Level_Complete=0; // reset level complete Current_Level++; // increment level counter Character.status=Bonus_Letter_Off; // turn off bonus letter is its still displayed Bonus_Object.status=Bonus_Letter_Off; if(Current_Level==1) { Init_Ice(); Setup_Level(&Level1[0]); Init_Enemy(); Game_Mode=Fade_In; } if(Current_Level==2) { Init_Ice(); Setup_Level(&Level2[0]); Init_Enemy(); Game_Mode=Fade_In; } if(Current_Level==3) { Init_Ice(); Setup_Level(&Level3[0]); Init_Enemy(); Game_Mode=Fade_In; } if(Current_Level==4) { Init_Ice(); Setup_Level(&Level4[0]); Init_Enemy(); Game_Mode=Fade_In; } if(Current_Level==5) { Init_Ice(); Setup_Level(&Level5[0]); Init_Enemy(); Game_Mode=Fade_In; } if(Current_Level==6) { Init_Ice(); Setup_Level(&Level6[0]); Init_Enemy(); Game_Mode=Fade_In; } if(Current_Level==7) { Init_Ice(); Setup_Level(&Level7[0]); Init_Enemy(); Game_Mode=Fade_In; } if(Current_Level==8) { Init_Ice(); Setup_Level(&Level8[0]); Init_Enemy(); Game_Mode=Fade_In; } if(Current_Level==9) { Init_Ice(); Setup_Level(&Level9[0]); Init_Enemy(); Game_Mode=Fade_In; } if(Current_Level==10) { Init_Ice(); Setup_Level(&Level10[0]); Init_Enemy(); Game_Mode=Fade_In; } if(Current_Level==11) { Init_Ice(); Setup_Level(&Level11[0]); Init_Enemy(); Game_Mode=Fade_In; } if(Current_Level==12) { Init_Ice(); Setup_Level(&Level12[0]); Init_Enemy(); Game_Mode=Fade_In; } if(Current_Level==13) { Game_Mode=The_End; Add_To_Score(10000); } } } //************************************************************************************************************************ void Clear_Melting_Blocks(void) // Clears the array so the blocks don't keep melting when a new level is reached { int loop; for(loop=0;loop<50;loop++) { Melting[loop].avail=0; } } void Clear_Moving_Blocks(void) { int loop; for(loop=0;loop<50;loop++) { Block_Move[loop].avail=0; if(Block_Move[loop].sfx_on==TRUE) { SsUtKeyOff(Block_Move[loop].channel,Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note); // turn channel off } Block_Move[loop].sfx_on=FALSE; } } //************************************************************************************************************************ void Move_This_Block(int sprite_number, int dir, int speed) // Function that adds the specified sprite block to the Block_Move[] array { int loop; int block_added; block_added=0; loop=0; while(block_added==0 && loop<50) { if(Block_Move[loop].avail==0) { Block_Move[loop].prog=5; // slide sfx program number Block_Move[loop].note=60; Block_Move[loop].sfx_counter=0; Block_Move[loop].sfx_on=TRUE; Block_Move[loop].channel=SsUtKeyOn(Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note,0,Slide_Vol,Slide_Vol); block_added=1; Block_Move[loop].avail=1; // show that this position is taken Block_Move[loop].from=sprite_number; // block sprite to move Block_Move[loop].direction=dir; // direction block is moving Block_Move[loop].speed=speed; Block_Move[loop].move_counter=0; // reset the movement counter Block_Move[loop].old_x=Ice_Blocks[sprite_number].x; // take a copy of the x coordinate Block_Move[loop].old_y=Ice_Blocks[sprite_number].y; // take a copy of the old y coordinate Movement[sprite_number]=3; // 3 denotes that a block is moving from this map position if(dir==Right) Movement[sprite_number+1]=4; // 4 denotes that a block is moving into the specified map location if(dir==Left) Movement[sprite_number-1]=4; if(dir==Up) Movement[sprite_number-16]=4; if(dir==Down) Movement[sprite_number+16]=4; } loop++; } } //************************************************************************************************************************ void Move_Blocks(void) // Moves all blocks that have been put into the Block_move[] array { int loop; for(loop=0;loop<50;loop++) { if(Block_Move[loop].avail==1) // is there a block in this array position that needs moving { if(Block_Move[loop].direction==Right) // Is the block moving right { if(Block_Move[loop].sfx_on==TRUE) { if(Block_Move[loop].sfx_counter==56) { Block_Move[loop].sfx_counter=0; SsUtKeyOff(Block_Move[loop].channel,Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note); Block_Move[loop].channel=SsUtKeyOn(Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note,0,Slide_Vol,Slide_Vol); } else { Block_Move[loop].sfx_counter+=2; } } Block_Move[loop].move_counter+=Block_Move[loop].speed; // add to movment counter Ice_Blocks[Block_Move[loop].from].x+=Block_Move[loop].speed; // change coordinate of block if(Block_Move[loop].move_counter==16) // has the block moved its full distance, 16 pixels { Movement[Block_Move[loop].from]=0; Movement[Block_Move[loop].from+1]=1; Ice_Blocks[Block_Move[loop].from+1].u=Ice_Blocks[Block_Move[loop].from].u; Ice_Blocks[Block_Move[loop].from+1].v=Ice_Blocks[Block_Move[loop].from].v; Ice_Blocks[Block_Move[loop].from+1].attribute=0x01000000; Ice_Blocks[Block_Move[loop].from+1].attribute +=(1<<30)+(1<<28); Ice_Blocks[Block_Move[loop].from].x=Block_Move[loop].old_x; Ice_Blocks[Block_Move[loop].from].y=Block_Move[loop].old_y; Ice_Blocks[Block_Move[loop].from].attribute=0; Block_Move[loop].from=Block_Move[loop].from+1; if((Ice_Blocks[Block_Move[loop].from].x/16)-1 <15) // check to see it the block should stop or keep moving { if(Movement[Block_Move[loop].from+1]==0) // block keeps moving { Block_Move[loop].move_counter=0; Block_Move[loop].old_x=Ice_Blocks[Block_Move[loop].from].x; // reset counters so block keeps moving Block_Move[loop].old_y=Ice_Blocks[Block_Move[loop].from].y; Movement[Block_Move[loop].from]=3; //shows block is moving from this location Movement[Block_Move[loop].from+1]=4; // Shows block is moving to this location } else { Block_Move[loop].avail=0; // else stop block and free this position in the array SsUtKeyOff(Block_Move[loop].channel,Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note); Block_Move[loop].prog=6; Block_Move[loop].note=48; Block_Move[loop].channel=SsUtKeyOn(Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note,0,127,127); Block_Move[loop].sfx_on=FALSE; } } else { Block_Move[loop].avail=0; // End his blocks movement SsUtKeyOff(Block_Move[loop].channel,Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note); Block_Move[loop].prog=0; Block_Move[loop].note=31; Block_Move[loop].channel=SsUtKeyOn(Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note,0,127,127); Block_Move[loop].sfx_on=FALSE; } } } if(Block_Move[loop].direction==Left) // Is the block moving left { if(Block_Move[loop].sfx_counter==56) { Block_Move[loop].sfx_counter=0; SsUtKeyOff(Block_Move[loop].channel,Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note); Block_Move[loop].channel=SsUtKeyOn(Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note,0,Slide_Vol,Slide_Vol); } else { Block_Move[loop].sfx_counter+=2; } Block_Move[loop].move_counter+=Block_Move[loop].speed; // add to movment counter Ice_Blocks[Block_Move[loop].from].x-=Block_Move[loop].speed; // change coordinate of block if(Block_Move[loop].move_counter==16) { Movement[Block_Move[loop].from]=0; Movement[Block_Move[loop].from-1]=1; Ice_Blocks[Block_Move[loop].from-1].u=Ice_Blocks[Block_Move[loop].from].u; Ice_Blocks[Block_Move[loop].from-1].v=Ice_Blocks[Block_Move[loop].from].v; Ice_Blocks[Block_Move[loop].from-1].attribute=0x01000000; Ice_Blocks[Block_Move[loop].from-1].attribute +=(1<<30)+(1<<28); Ice_Blocks[Block_Move[loop].from].x=Block_Move[loop].old_x; Ice_Blocks[Block_Move[loop].from].y=Block_Move[loop].old_y; Ice_Blocks[Block_Move[loop].from].attribute=0; Block_Move[loop].from=Block_Move[loop].from-1; if((Ice_Blocks[Block_Move[loop].from].x/16)-1 >0) { if(Movement[Block_Move[loop].from-1]==0) { Block_Move[loop].move_counter=0; Block_Move[loop].old_x=Ice_Blocks[Block_Move[loop].from].x; Block_Move[loop].old_y=Ice_Blocks[Block_Move[loop].from].y; Movement[Block_Move[loop].from]=3; //shows block is moving from this location Movement[Block_Move[loop].from-1]=4; // Shows block is moving to this location } else { Block_Move[loop].avail=0; SsUtKeyOff(Block_Move[loop].channel,Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note); Block_Move[loop].prog=6; Block_Move[loop].note=48; Block_Move[loop].channel=SsUtKeyOn(Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note,0,127,127); Block_Move[loop].sfx_on=FALSE; } } else { Block_Move[loop].avail=0; // End his blocks movement SsUtKeyOff(Block_Move[loop].channel,Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note); Block_Move[loop].prog=0; Block_Move[loop].note=31; Block_Move[loop].channel=SsUtKeyOn(Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note,0,127,127); Block_Move[loop].sfx_on=FALSE; } } } if(Block_Move[loop].direction==Up) // Is the block moving Up { if(Block_Move[loop].sfx_counter==56) { Block_Move[loop].sfx_counter=0; SsUtKeyOff(Block_Move[loop].channel,Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note); Block_Move[loop].channel=SsUtKeyOn(Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note,0,Slide_Vol,Slide_Vol); } else { Block_Move[loop].sfx_counter+=2; } Block_Move[loop].move_counter+=Block_Move[loop].speed; // add to movment counter Ice_Blocks[Block_Move[loop].from].y-=Block_Move[loop].speed; // change coordinate of block if(Block_Move[loop].move_counter==16) { Movement[Block_Move[loop].from]=0; Movement[Block_Move[loop].from-16]=1; Ice_Blocks[Block_Move[loop].from-16].u=Ice_Blocks[Block_Move[loop].from].u; Ice_Blocks[Block_Move[loop].from-16].v=Ice_Blocks[Block_Move[loop].from].v; Ice_Blocks[Block_Move[loop].from-16].attribute=0x01000000; Ice_Blocks[Block_Move[loop].from-16].attribute +=(1<<30)+(1<<28); Ice_Blocks[Block_Move[loop].from].x=Block_Move[loop].old_x; Ice_Blocks[Block_Move[loop].from].y=Block_Move[loop].old_y; Ice_Blocks[Block_Move[loop].from].attribute=0; Block_Move[loop].from=Block_Move[loop].from-16; if((Ice_Blocks[Block_Move[loop].from].y/16)-1 >0) { if(Movement[Block_Move[loop].from-16]==0) { Block_Move[loop].move_counter=0; Block_Move[loop].old_x=Ice_Blocks[Block_Move[loop].from].x; Block_Move[loop].old_y=Ice_Blocks[Block_Move[loop].from].y; Movement[Block_Move[loop].from]=3; //shows block is moving from this location Movement[Block_Move[loop].from-16]=4; // Shows block is moving to this location } else { Block_Move[loop].avail=0; SsUtKeyOff(Block_Move[loop].channel,Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note); Block_Move[loop].prog=6; Block_Move[loop].note=48; Block_Move[loop].channel=SsUtKeyOn(Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note,0,127,127); Block_Move[loop].sfx_on=FALSE; } } else { Block_Move[loop].avail=0; // End his blocks movement SsUtKeyOff(Block_Move[loop].channel,Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note); Block_Move[loop].prog=0; Block_Move[loop].note=31; Block_Move[loop].channel=SsUtKeyOn(Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note,0,127,127); Block_Move[loop].sfx_on=FALSE; } } } if(Block_Move[loop].direction==Down) // Is the block moving Down { if(Block_Move[loop].sfx_counter==56) { Block_Move[loop].sfx_counter=0; SsUtKeyOff(Block_Move[loop].channel,Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note); Block_Move[loop].channel=SsUtKeyOn(Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note,0,Slide_Vol,Slide_Vol); } else { Block_Move[loop].sfx_counter+=2; } Block_Move[loop].move_counter+=Block_Move[loop].speed; // add to movment counter Ice_Blocks[Block_Move[loop].from].y+=Block_Move[loop].speed; // change coordinate of block if(Block_Move[loop].move_counter==16) { Movement[Block_Move[loop].from]=0; Movement[Block_Move[loop].from+16]=1; Ice_Blocks[Block_Move[loop].from+16].u=Ice_Blocks[Block_Move[loop].from].u; Ice_Blocks[Block_Move[loop].from+16].v=Ice_Blocks[Block_Move[loop].from].v; Ice_Blocks[Block_Move[loop].from+16].attribute=0x01000000; Ice_Blocks[Block_Move[loop].from+16].attribute +=(1<<30)+(1<<28); Ice_Blocks[Block_Move[loop].from].x=Block_Move[loop].old_x; Ice_Blocks[Block_Move[loop].from].y=Block_Move[loop].old_y; Ice_Blocks[Block_Move[loop].from].attribute=0; Block_Move[loop].from=Block_Move[loop].from+16; if((Ice_Blocks[Block_Move[loop].from].y/16)-1 <13) { if(Movement[Block_Move[loop].from+16]==0) { Block_Move[loop].move_counter=0; Block_Move[loop].old_x=Ice_Blocks[Block_Move[loop].from].x; Block_Move[loop].old_y=Ice_Blocks[Block_Move[loop].from].y; Movement[Block_Move[loop].from]=3; //shows block is moving from this location Movement[Block_Move[loop].from+16]=4; // Shows block is moving to this location } else { Block_Move[loop].avail=0; SsUtKeyOff(Block_Move[loop].channel,Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note); Block_Move[loop].prog=6; Block_Move[loop].note=48; Block_Move[loop].channel=SsUtKeyOn(Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note,0,127,127); Block_Move[loop].sfx_on=FALSE; } } else { Block_Move[loop].avail=0; // End his blocks movement SsUtKeyOff(Block_Move[loop].channel,Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note); Block_Move[loop].prog=0; Block_Move[loop].note=31; Block_Move[loop].channel=SsUtKeyOn(Main_Sfx_Vab_ID,Block_Move[loop].prog,0,Block_Move[loop].note,0,127,127); Block_Move[loop].sfx_on=FALSE; } } } }// } } //************************************************************************************************************************ void Adjust_Music_Vol(void) // Turns up or down the Music volume with L2 and R2 { if((FSPadRead(PORT_ONE) & SPADl1) && Music_Volume>0) Music_Volume--; if((FSPadRead(PORT_ONE) & SPADr1) && Music_Volume<256) Music_Volume++; } //************************************************************************************************************************ void Setup_Score_Display(void) // Sets up all the sprites for the score pannel { int counter; Command.attribute = 0+(1<<30)+(1<<28)+(1<<24); Command.x=160; // Default command sprite = PAUSED Command.y=128; Command.w=71; Command.h=15; Command.tpage = GetTPage(1,0,Command_tim_data.px,Command_tim_data.py); Command.u=0; Command.v=0; Command.cx=Command_tim_data.cx; Command.cy=Command_tim_data.cy; Command.r=128; Command.g=128; Command.b=128; Command.mx=35; Command.my=7; Command.rotate=0; Command.scalex=ONE; Command.scaley=ONE; Controller.attribute = 0+(1<<30)+(1<<28)+(1<<24); Controller.x=160; // Setup sprite that is displayed is controller in port 1 is removed Controller.y=128+20; Controller.w=104; Controller.h=9; Controller.tpage = GetTPage(1,0,Command_tim_data.px,Command_tim_data.py); Controller.u=0; Controller.v=48; Controller.cx=Command_tim_data.cx; Controller.cy=Command_tim_data.cy; Controller.r=128; Controller.g=128; Controller.b=128; Controller.mx=52; Controller.my=4; Controller.rotate=0; Controller.scalex=ONE; Controller.scaley=ONE; Life_Indicator.attribute = 0x01000000 ; Life_Indicator.x=288+8; // Life Indicator Sprite Details Life_Indicator.y=12; Life_Indicator.w=16; Life_Indicator.h=17; Life_Indicator.tpage = GetTPage(1,0,Player_tim_data.px,Player_tim_data.py); Life_Indicator.u=98; Life_Indicator.v=16; Life_Indicator.cx=Player_tim_data.cx; Life_Indicator.cy=Player_tim_data.cy; Life_Indicator.r=128; Life_Indicator.g=128; Life_Indicator.b=128; Life_Indicator.mx=8; Life_Indicator.my=8; Life_Indicator.rotate=0; Life_Indicator.scalex=ONE; Life_Indicator.scaley=ONE; Run_Indicator.attribute= 0x01000000; // sprite to show hol much longer p1 can run Run_Indicator.x=288+20; Run_Indicator.y=40; Run_Indicator.w=7; Run_Indicator.h=29; Run_Indicator.tpage=GetTPage(1,0,Player_tim_data.px,Player_tim_data.py); Run_Indicator.u=119; Run_Indicator.v=16; Run_Indicator.cx=Player_tim_data.cx; Run_Indicator.cy=Player_tim_data.cy; Run_Indicator.r=128; Run_Indicator.g=128; Run_Indicator.b=128; Run_Indicator.mx=0; Run_Indicator.my=0; Run_Indicator.rotate=0; Run_Indicator.scalex=ONE; Run_Indicator.scaley=ONE; Life_Counter.attribute = 0x01000000 ; Life_Counter.x=288+8+7+2; // Life Counter Sprite defaults.... Life_Counter.y=7; Life_Counter.w=7; Life_Counter.h=7; Life_Counter.tpage = GetTPage(1,0,Player_tim_data.px,Player_tim_data.py); Life_Counter.u=0; Life_Counter.v=32; Life_Counter.cx=Player_tim_data.cx; Life_Counter.cy=Player_tim_data.cy; Life_Counter.r=128; Life_Counter.g=128; Life_Counter.b=128; Life_Counter.mx=0; Life_Counter.my=0; Life_Counter.rotate=0; Life_Counter.scalex=ONE; Life_Counter.scaley=ONE; Lives[0].x=0; // Tpage graphic offset for lives counter Lives[0].y=32; Lives[0].width=7; Lives[1].x=8; Lives[1].y=32; Lives[1].width=2; Lives[2].x=11; Lives[2].y=32; Lives[2].width=7; Lives[3].x=19; Lives[3].y=32; Lives[3].width=7; Lives[4].x=27; Lives[4].y=32; Lives[4].width=7; Lives[5].x=35; Lives[5].y=32; Lives[5].width=7; Lives[6].x=43; Lives[6].y=32; Lives[6].width=7; Lives[7].x=51; Lives[7].y=32; Lives[7].width=7; Lives[8].x=59; Lives[8].y=32; Lives[8].width=7; Lives[9].x=67; Lives[9].y=32; Lives[9].width=7; for(counter=0;counter<7;counter++) // sets up the score sprites { Score_Sprite[counter].attribute = 0x01000000 ; Score_Sprite[counter].x=280; // Life Counter Sprite defaults.... Score_Sprite[counter].y=40+(counter*10); Score_Sprite[counter].w=7; Score_Sprite[counter].h=7; Score_Sprite[counter].tpage = GetTPage(1,0,Player_tim_data.px,Player_tim_data.py); Score_Sprite[counter].u=0; Score_Sprite[counter].v=40; Score_Sprite[counter].cx=Player_tim_data.cx; Score_Sprite[counter].cy=Player_tim_data.cy; Score_Sprite[counter].r=128; Score_Sprite[counter].g=128; Score_Sprite[counter].b=128; Score_Sprite[counter].mx=0; Score_Sprite[counter].my=0; Score_Sprite[counter].rotate=0; Score_Sprite[counter].scalex=ONE; Score_Sprite[counter].scaley=ONE; } for(counter=0;counter<5;counter++) // sets up the bonus characters { Bonus_Display[counter].status=Bonus_Letter_Off; Bonus_Display[counter].counter=0; Bonus_Display[counter].sprite.attribute = 0+(1<<30)+(1<<28)+(1<<24); Bonus_Display[counter].sprite.x=305; // BONUS characters on score display Bonus_Display[counter].sprite.y=135+(counter*18); Bonus_Display[counter].sprite.w=16; Bonus_Display[counter].sprite.h=16; Bonus_Display[counter].sprite.tpage = GetTPage(1,0,Bonus_tim_data.px,Bonus_tim_data.py); Bonus_Display[counter].sprite.u=(counter*16); Bonus_Display[counter].sprite.v=32+96; Bonus_Display[counter].sprite.cx=Bonus_tim_data.cx; Bonus_Display[counter].sprite.cy=Bonus_tim_data.cy; Bonus_Display[counter].sprite.r=45; Bonus_Display[counter].sprite.g=45; Bonus_Display[counter].sprite.b=45; Bonus_Display[counter].sprite.mx=8; Bonus_Display[counter].sprite.my=8; Bonus_Display[counter].sprite.rotate=0; Bonus_Display[counter].sprite.scalex=ONE; Bonus_Display[counter].sprite.scaley=ONE; } } //************************************************************************************************************************ void Draw_Score_Display(void) // Draws the score pannel and contents { static int Scale_Direction= Down; static int Scale_Counter=0; unsigned int Temp_Score; int Temp; if( Bonus_Display[0].status==Bonus_Letter_Collected && // start the bonus flashing if all characters have been collected Bonus_Display[1].status==Bonus_Letter_Collected && Bonus_Display[2].status==Bonus_Letter_Collected && Bonus_Display[3].status==Bonus_Letter_Collected && Bonus_Display[4].status==Bonus_Letter_Collected && Bonus_Flash==0) { Bonus_Flash=1; Bonus_Flash_Counter=0; Flash_Repeat=0; Add_To_Score(5000); Add_Run_Energy(200); Add_Life(); SsUtKeyOn(Main_Sfx_Vab_ID,11,0,50,0,100,100); } if(Bonus_Flash==1) // make bonus display flash on and off { Bonus_Flash_Counter++; if(Bonus_Flash_Counter==3) { Bonus_Flash_Counter=0; Flash_Repeat++; if(Bonus_Show==TRUE) { Bonus_Show=FALSE; } else { Bonus_Show=TRUE; } } if(Flash_Repeat>=30 && Bonus_Show==TRUE) // bonus has flashed enough { Bonus_Show=TRUE; Flash_Repeat=0; Bonus_Flash=0; Bonus_Flash_Counter=0; for(Temp=0;Temp<5;Temp++) { Bonus_Display[Temp].sprite.r=45; // reset bonus colours Bonus_Display[Temp].sprite.g=45; Bonus_Display[Temp].sprite.b=45; Bonus_Display[Temp].status=Bonus_Letter_Off; Bonus_Display[Temp].counter=0; } } }// end bonus flashing. // Decode the score digits from Player 1s score Temp_Score=P1_Score; // copy player 1s current score Temp=Temp_Score/1000000; Score_Sprite[0].u=Lives[Temp].x; // Decode all the digits Score_Sprite[0].v=Lives[Temp].y+8; Score_Sprite[0].w=Lives[Temp].width; Temp_Score-=Temp*1000000; Temp=Temp_Score/100000; Score_Sprite[1].u=Lives[Temp].x; // Decode all the digits Score_Sprite[1].v=Lives[Temp].y+8; Score_Sprite[1].w=Lives[Temp].width; Temp_Score-=Temp*100000; Temp=Temp_Score/10000; Score_Sprite[2].u=Lives[Temp].x; // Decode all the digits Score_Sprite[2].v=Lives[Temp].y+8; Score_Sprite[2].w=Lives[Temp].width; Temp_Score-=Temp*10000; Temp=Temp_Score/1000; Score_Sprite[3].u=Lives[Temp].x; // Decode all the digits Score_Sprite[3].v=Lives[Temp].y+8; Score_Sprite[3].w=Lives[Temp].width; Temp_Score-=Temp*1000; Temp=Temp_Score/100; Score_Sprite[4].u=Lives[Temp].x; // Decode all the digits Score_Sprite[4].v=Lives[Temp].y+8; Score_Sprite[4].w=Lives[Temp].width; Temp_Score-=Temp*100; Temp=Temp_Score/10; Score_Sprite[5].u=Lives[Temp].x; // Decode all the digits Score_Sprite[5].v=Lives[Temp].y+8; Score_Sprite[5].w=Lives[Temp].width; Temp_Score-=Temp*10; Temp=Temp_Score/1; Score_Sprite[6].u=Lives[Temp].x; // Decode all the digits Score_Sprite[6].v=Lives[Temp].y+8; Score_Sprite[6].w=Lives[Temp].width; Temp_Score-=Temp*1; for(Temp=0;Temp<7;Temp++) { if(Score_Sprite[Temp].u==8) { Score_Sprite[Temp].x=299; // Alter X coordinate if the sprite is a 1. } else { Score_Sprite[Temp].x=296; } } if(Scale_Direction==Down) // Scale Life marker up and down { Scale_Counter+=100; if(Scale_Counter==2000) { Scale_Direction=Up; } } if(Scale_Direction==Up) { Scale_Counter-=100; if(Scale_Counter==0) { Scale_Direction=Down; } } if(P1.run_energy==200) // makes the run energy bar decrease { Run_Indicator.h=29; } if(P1.run_energy<199 && P1.run_energy >=190) // makes the run energy bar decrease { Run_Indicator.h=27; } if(P1.run_energy<189 && P1.run_energy >=180) // makes the run energy bar decrease { Run_Indicator.h=26; } if(P1.run_energy<179 && P1.run_energy >=170) // makes the run energy bar decrease { Run_Indicator.h=25; } if(P1.run_energy<169 && P1.run_energy >=160) // makes the run energy bar decrease { Run_Indicator.h=24; } if(P1.run_energy<159 && P1.run_energy >=150) // makes the run energy bar decrease { Run_Indicator.h=23; } if(P1.run_energy<149 && P1.run_energy >=140) // makes the run energy bar decrease { Run_Indicator.h=21; } if(P1.run_energy<139 && P1.run_energy >=140) // makes the run energy bar decrease { Run_Indicator.h=19; } if(P1.run_energy<129 && P1.run_energy >=120) // makes the run energy bar decrease { Run_Indicator.h=18; } if(P1.run_energy<119 && P1.run_energy >=110) // makes the run energy bar decrease { Run_Indicator.h=17; } if(P1.run_energy<109 && P1.run_energy >=100) // makes the run energy bar decrease { Run_Indicator.h=16; } if(P1.run_energy<99 && P1.run_energy >=90) // makes the run energy bar decrease { Run_Indicator.h=15; } if(P1.run_energy<99 && P1.run_energy >=80) // makes the run energy bar decrease { Run_Indicator.h=14; } if(P1.run_energy<79 && P1.run_energy >=70) // makes the run energy bar decrease { Run_Indicator.h=13; } if(P1.run_energy<69 && P1.run_energy >=60) // makes the run energy bar decrease { Run_Indicator.h=11; } if(P1.run_energy<59 && P1.run_energy >=50) // makes the run energy bar decrease { Run_Indicator.h=10; } if(P1.run_energy<49 && P1.run_energy >=45) // makes the run energy bar decrease { Run_Indicator.h=9; } if(P1.run_energy<45 && P1.run_energy >=40) // makes the run energy bar decrease { Run_Indicator.h=8; } if(P1.run_energy<39 && P1.run_energy >=35) // makes the run energy bar decrease { Run_Indicator.h=7; } if(P1.run_energy<35 && P1.run_energy >=30) // makes the run energy bar decrease { Run_Indicator.h=6; } if(P1.run_energy<29 && P1.run_energy >=25) // makes the run energy bar decrease { Run_Indicator.h=5; } if(P1.run_energy<25 && P1.run_energy >=20) // makes the run energy bar decrease { Run_Indicator.h=4; } if(P1.run_energy<19 && P1.run_energy >=15) // makes the run energy bar decrease { Run_Indicator.h=3; } if(P1.run_energy<14 && P1.run_energy >=10) // makes the run energy bar decrease { Run_Indicator.h=2; } if(P1.run_energy<9 && P1.run_energy >=5) // makes the run energy bar decrease { Run_Indicator.h=1; } if(P1.run_energy==0) // makes the run energy bar decrease { Run_Indicator.h=0; } Life_Indicator.scalex=4096-Scale_Counter; // Apply scaling to sprite Life_Indicator.scaley=4096-Scale_Counter; Life_Counter.u=Lives[P1.lives].x; // set x Tpage offset for lives counter Life_Counter.v=Lives[P1.lives].y; // set y Tpage offset for lives counter Life_Counter.w=Lives[P1.lives].width; // set width of gfx GsSortSprite(&Life_Indicator,&WorldOT[activebuff],287); // put life indicator into the ordering table GsSortSprite(&Life_Counter,&WorldOT[activebuff],286); // put life counter into the ordering table GsSortSprite(&Score_Sprite[0],&WorldOT[activebuff],285); // put score sprite 0 into the ordering table GsSortSprite(&Score_Sprite[1],&WorldOT[activebuff],284); // put score sprite 1 into the ordering table GsSortSprite(&Score_Sprite[2],&WorldOT[activebuff],283); // put score sprite 2 into the ordering table GsSortSprite(&Score_Sprite[3],&WorldOT[activebuff],282); // put score sprite 3 into the ordering table GsSortSprite(&Score_Sprite[4],&WorldOT[activebuff],281); // put score sprite 4 into the ordering table GsSortSprite(&Score_Sprite[5],&WorldOT[activebuff],280); // put score sprite 5 into the ordering table GsSortSprite(&Score_Sprite[6],&WorldOT[activebuff],279); // put score sprite 6 into the ordering table GsSortSprite(&Run_Indicator,&WorldOT[activebuff],278); // put run indicator sprite into OT if(Bonus_Show==TRUE) { GsSortSprite(&Bonus_Display[0].sprite,&WorldOT[activebuff],277); // all the bonus characters GsSortSprite(&Bonus_Display[1].sprite,&WorldOT[activebuff],276); // all the bonus characters GsSortSprite(&Bonus_Display[2].sprite,&WorldOT[activebuff],275); // all the bonus characters GsSortSprite(&Bonus_Display[3].sprite,&WorldOT[activebuff],274); // all the bonus characters GsSortSprite(&Bonus_Display[4].sprite,&WorldOT[activebuff],273); // all the bonus characters } } //************************************************************************************************************************ void Add_To_Score(int value) // Adds the value to Player 1s score { P1_Score+=value; if(P1_Score >9999999) { P1_Score=9999999; } } //************************************************************************************************************************ int Enemy_Melt_Block(void) // checks to see if the enemy should melt a block or not { static int array_counter=0; int temp; temp=Enemy_Melt[array_counter]; // get the array item if(temp==-1) // end of array has been reached { array_counter=0; // reset the array counter temp=Enemy_Melt[array_counter]; // get the array item } array_counter++; // increment the array counter return(temp); // return the array value 1=block should be melted 0= leave block alone } //************************************************************************************************************************ //************************************************************************************************************************ int Select_Enemy_Move_Direction(void) // returns a number that coresponds to a direction to move { static int array_counter=0; int temp; temp=Enemy_Move[array_counter]; // get the array item if(temp==-1) // end of array has been reached { array_counter=0; // reset the array counter temp=Enemy_Move[array_counter]; // get the array item } array_counter++; // increment the array counter return(temp); // return the array value 1=block should be melted 0= leave block alone } //************************************************************************************************************************ void Init_Enemy(void) // sets up starting locations for the enemy dudes { int loop; Enemy_Count=0; for(loop=0;loop=4096) // check to see if we have reached the full scale value { Enemy[loop].scale_value=4096; Enemy[loop].status=Enemy_OK; // change ststus of enemy } Enemy[loop].sprite.scalex=Enemy[loop].scale_value; // asign current scaling value to sprite Enemy[loop].sprite.scaley=Enemy[loop].scale_value; } if(Enemy[loop].status==Enemy_Die) // enemy is currently going through its dieing anim { Enemy[loop].scale_value+=150; Enemy[loop].sprite.scalex=ONE+Enemy[loop].scale_value; // make sprite scale Enemy[loop].sprite.scaley=ONE+Enemy[loop].scale_value; Enemy[loop].sprite.rotate=(Enemy[loop].scale_value/25)*4096; Enemy[loop].sprite.r-=4; Enemy[loop].sprite.g-=4; Enemy[loop].sprite.b-=4; if(Enemy[loop].sprite.r==0) { Enemy[loop].status=Enemy_Dead; // enemy sprite is dead !!! Enemy[loop].sprite.attribute=0; } } if(Enemy[loop].status==Enemy_Wait) // makes the sprite wait for the block to melt { Enemy[loop].timer--; if(Enemy[loop].timer==0) { Enemy[loop].status=Enemy_OK; Enemy[loop].moving=0; } } if(Enemy[loop].status==Enemy_OK) // enemy sprite is ok to move { if(Enemy[loop].moving==0) // enemy is currently not moving { // Get the details of the blocks surrounding the enemy sprite if(Enemy[loop].block_x==0 && Enemy[loop].block_y==0) // top left corner { Enemy[loop].Bup=5; // can't move up Enemy[loop].Bleft=5; // can't move left Enemy[loop].Bright=Move_Ok(Enemy[loop].block_x+1,Enemy[loop].block_y); // get block to the right Enemy[loop].Bdown=Move_Ok(Enemy[loop].block_x,Enemy[loop].block_y+1); // get block below } if(Enemy[loop].block_x==0 && Enemy[loop].block_y==13) // bottom left corner { Enemy[loop].Bdown=5; // can't move down Enemy[loop].Bleft=5; // can't move left Enemy[loop].Bright=Move_Ok(Enemy[loop].block_x+1,Enemy[loop].block_y); // get block to the right Enemy[loop].Bup=Move_Ok(Enemy[loop].block_x,Enemy[loop].block_y-1); // get block above } if(Enemy[loop].block_x==15 && Enemy[loop].block_y==0) // top right corner { Enemy[loop].Bup=5; // can't move up Enemy[loop].Bright=5; // can't move left Enemy[loop].Bleft=Move_Ok(Enemy[loop].block_x-1,Enemy[loop].block_y); // get block to the left Enemy[loop].Bdown=Move_Ok(Enemy[loop].block_x,Enemy[loop].block_y+1); // get block below } if(Enemy[loop].block_x==15 && Enemy[loop].block_y==13) // bottom right corner { Enemy[loop].Bdown=5; // can't move down Enemy[loop].Bright=5; // can't move right Enemy[loop].Bleft=Move_Ok(Enemy[loop].block_x-1,Enemy[loop].block_y); // get block to the left Enemy[loop].Bup=Move_Ok(Enemy[loop].block_x,Enemy[loop].block_y-1); // get block above } if(Enemy[loop].block_x!=0 && Enemy[loop].block_y==0 && Enemy[loop].block_x!=15) // On top line { Enemy[loop].Bup=5; // can't move up Enemy[loop].Bleft=Move_Ok(Enemy[loop].block_x-1,Enemy[loop].block_y); // get block to the left Enemy[loop].Bright=Move_Ok(Enemy[loop].block_x+1,Enemy[loop].block_y); // get block to the right Enemy[loop].Bdown=Move_Ok(Enemy[loop].block_x,Enemy[loop].block_y+1); // get block below } if(Enemy[loop].block_x!=0 && Enemy[loop].block_y==13 && Enemy[loop].block_x!=15) // On bottom line { Enemy[loop].Bdown=5; // can't move down Enemy[loop].Bleft=Move_Ok(Enemy[loop].block_x-1,Enemy[loop].block_y); // get block to the left Enemy[loop].Bright=Move_Ok(Enemy[loop].block_x+1,Enemy[loop].block_y); // get block to the right Enemy[loop].Bup=Move_Ok(Enemy[loop].block_x,Enemy[loop].block_y-1); // get block above } if(Enemy[loop].block_y!=0 && Enemy[loop].block_x==0 && Enemy[loop].block_y!=13) // On left line { Enemy[loop].Bleft=5; // can't move left Enemy[loop].Bup=Move_Ok(Enemy[loop].block_x,Enemy[loop].block_y-1); // get block above Enemy[loop].Bright=Move_Ok(Enemy[loop].block_x+1,Enemy[loop].block_y); // get block to the right Enemy[loop].Bdown=Move_Ok(Enemy[loop].block_x,Enemy[loop].block_y+1); // get block below } if(Enemy[loop].block_y!=0 && Enemy[loop].block_x==15 && Enemy[loop].block_y!=13) // On right line { Enemy[loop].Bright=5; // can't move right Enemy[loop].Bup=Move_Ok(Enemy[loop].block_x,Enemy[loop].block_y-1); // get block above Enemy[loop].Bleft=Move_Ok(Enemy[loop].block_x-1,Enemy[loop].block_y); // get block to the left Enemy[loop].Bdown=Move_Ok(Enemy[loop].block_x,Enemy[loop].block_y+1); // get block below } if(Enemy[loop].block_y>0 && Enemy[loop].block_y<13 && Enemy[loop].block_x>0 && Enemy[loop].block_x<15) { Enemy[loop].Bup = Move_Ok(Enemy[loop].block_x,Enemy[loop].block_y-1); // block above Enemy[loop].Bdown = Move_Ok(Enemy[loop].block_x,Enemy[loop].block_y+1); // block below Enemy[loop].Bleft = Move_Ok(Enemy[loop].block_x-1,Enemy[loop].block_y); // block to the left Enemy[loop].Bright = Move_Ok(Enemy[loop].block_x+1,Enemy[loop].block_y); // block to the right } if(Enemy[loop].moving==0 && Enemy[loop].speed==1) // see if the enemy should melt a block { if(Enemy[loop].direction==Up && Enemy[loop].Bup==1 && Enemy_Melt_Block()==1) { Melt_This_Block(((Enemy[loop].block_y-1)*16)+Enemy[loop].block_x); Enemy[loop].status=Enemy_Wait; Enemy[loop].timer=20; Enemy[loop].moving=0; } if(Enemy[loop].direction==Down && Enemy[loop].Bdown==1 && Enemy_Melt_Block()==1) { Melt_This_Block(((Enemy[loop].block_y+1)*16)+Enemy[loop].block_x); Enemy[loop].status=Enemy_Wait; Enemy[loop].timer=20; Enemy[loop].moving=0; } if(Enemy[loop].direction==Left && Enemy[loop].Bleft==1 && Enemy_Melt_Block()==1) { Melt_This_Block(((Enemy[loop].block_y)*16)+(Enemy[loop].block_x-1)); Enemy[loop].status=Enemy_Wait; Enemy[loop].timer=20; Enemy[loop].moving=0; } if(Enemy[loop].direction==Right && Enemy[loop].Bright==1 && Enemy_Melt_Block()==1) { Melt_This_Block(((Enemy[loop].block_y)*16)+(Enemy[loop].block_x+1)); Enemy[loop].status=Enemy_Wait; Enemy[loop].timer=20; Enemy[loop].moving=0; } } if(Enemy[loop].Bup!=0 && Enemy[loop].Bdown !=0 && Enemy[loop].Bleft !=0 && Enemy[loop].Bright !=0) { // sprite is trapped so ingnore trying to move it } else { if(Enemy[loop].moving==0) // checks to see if enemy should chase player { if(Enemy[loop].block_y==P1.block_y && P1.status==Ok) // sprites are on the same y coordinates { if(Enemy[loop].block_x > P1.block_x && (Enemy[loop].block_x-P1.block_x <=Current_Level+1) && Enemy_Can_See_Player(P1.block_x,P1.block_y,Enemy[loop].block_x,Enemy[loop].block_y,Left)) { Enemy[loop].direction=Left; // move sprite left Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; } } if(Enemy[loop].block_y==P1.block_y && P1.status==Ok) // sprites are on the same y coordinates { if(Enemy[loop].block_x < P1.block_x && (P1.block_x-Enemy[loop].block_x <=Current_Level+1) && Enemy_Can_See_Player(Enemy[loop].block_x,Enemy[loop].block_y,P1.block_x,P1.block_y,Right)) { Enemy[loop].direction=Right; // move sprite left Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; } } if(Enemy[loop].block_x==P1.block_x && P1.status==Ok) // sprites are on the same X coordinates { if(Enemy[loop].block_y > P1.block_y && (Enemy[loop].block_y-P1.block_y <=Current_Level+1) && Enemy_Can_See_Player(P1.block_x,P1.block_y,Enemy[loop].block_x,Enemy[loop].block_y,Up)) { Enemy[loop].direction=Up; // move sprite left Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; } } if(Enemy[loop].block_x==P1.block_x && P1.status==Ok) // sprites are on the same X coordinates { if(Enemy[loop].block_y < P1.block_y && (P1.block_y-Enemy[loop].block_y <=Current_Level+1) && Enemy_Can_See_Player(Enemy[loop].block_x,Enemy[loop].block_y,P1.block_x,P1.block_y,Down)) { Enemy[loop].direction=Down; // move sprite left Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; } } } if(Enemy[loop].moving==0 && Enemy[loop].direction==Up && Enemy[loop].status==Enemy_OK) // makes enemy move in direction of player { random=rand()%15; if(random<4 && Enemy[loop].block_x < P1.block_x && Enemy[loop].Bright==0) { Enemy[loop].direction=Right; // move sprite right Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; } if(random<4 && Enemy[loop].block_x > P1.block_x && Enemy[loop].Bleft==0) { Enemy[loop].direction=Left; // move sprite left Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; } } if(Enemy[loop].moving==0 && Enemy[loop].direction==Down && Enemy[loop].status==Enemy_OK) // makes enemy move in direction of player { random=rand()%15; if(random<4 && Enemy[loop].block_x < P1.block_x && Enemy[loop].Bright==0) { Enemy[loop].direction=Right; // move sprite right Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; } if(random<4 && Enemy[loop].block_x > P1.block_x && Enemy[loop].Bleft==0) { Enemy[loop].direction=Left; // move sprite left Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; } } if(Enemy[loop].moving==0 && Enemy[loop].direction==Left && Enemy[loop].status==Enemy_OK) // makes enemy move in direction of player { random=rand()%15; if(random<4 && Enemy[loop].block_y < P1.block_y && Enemy[loop].Bdown==0) { Enemy[loop].direction=Down; // move sprite down Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; } if(random<4 && Enemy[loop].block_y > P1.block_y && Enemy[loop].Bup==0) { Enemy[loop].direction=Up; // move sprite up Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; } } if(Enemy[loop].moving==0 && Enemy[loop].direction==Right && Enemy[loop].status==Enemy_OK) // makes enemy move in direction of player { random=rand()%15; if(random<4 && Enemy[loop].block_y < P1.block_y && Enemy[loop].Bdown==0) { Enemy[loop].direction=Down; // move sprite down Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; } if(random<4 && Enemy[loop].block_y > P1.block_y && Enemy[loop].Bup==0) { Enemy[loop].direction=Up; // move sprite up Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; } } if(Enemy[loop].direction==Up && Enemy[loop].moving==0 && Enemy[loop].status==Enemy_OK) // sprite is currently moving up { random=rand()%10; if(Enemy[loop].Bup==0) // can we still move up { Enemy[loop].direction=Up; // yes Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; } else // if no then we need to select a new direction { move_ok=0; do { random=rand()%10; new_direction=Select_Enemy_Move_Direction(); // select a new direction if(new_direction==Down && Enemy[loop].Bdown==0 && move_ok==0 && random<3) { Enemy[loop].direction=Down; Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; move_ok=1; } if(new_direction==Left && Enemy[loop].Bleft==0 && move_ok==0 ) { Enemy[loop].direction=Left; Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; move_ok=1; } if(new_direction==Right && Enemy[loop].Bright==0 && move_ok==0 ) { Enemy[loop].direction=Right; Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; move_ok=1; } }while(move_ok==0); } }// End moving up section if(Enemy[loop].direction==Down && Enemy[loop].moving==0 && Enemy[loop].status==Enemy_OK) // sprite is currently moving down { random=rand()%10; if(Enemy[loop].Bdown==0) // can we still move down { Enemy[loop].direction=Down; // yes Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; } else // if no then we need to select a new direction { move_ok=0; do { random=rand()%10; new_direction=Select_Enemy_Move_Direction(); // select a new direction if(new_direction==Up && Enemy[loop].Bup==0 && move_ok==0 && random<3) { Enemy[loop].direction=Up; Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; move_ok=1; } if(new_direction==Left && Enemy[loop].Bleft==0 && move_ok==0 ) { Enemy[loop].direction=Left; Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; move_ok=1; } if(new_direction==Right && Enemy[loop].Bright==0 && move_ok==0 ) { Enemy[loop].direction=Right; Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; move_ok=1; } }while(move_ok==0); } }// End moving down section if(Enemy[loop].direction==Left && Enemy[loop].moving==0 && Enemy[loop].status==Enemy_OK) // sprite is currently moving left { random=rand()%10; if(Enemy[loop].Bleft==0 ) // can we still move left { Enemy[loop].direction=Left; // yes Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; } else // if no then we need to select a new direction { move_ok=0; do { random=rand()%10; new_direction=Select_Enemy_Move_Direction(); // select a new direction if(new_direction==Up && Enemy[loop].Bup==0 && move_ok==0 ) { Enemy[loop].direction=Up; Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; move_ok=1; } if(new_direction==Down && Enemy[loop].Bdown==0 && move_ok==0 ) { Enemy[loop].direction=Down; Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; move_ok=1; } if(new_direction==Right && Enemy[loop].Bright==0 && move_ok==0 && random<3) { Enemy[loop].direction=Right; Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; move_ok=1; } }while(move_ok==0); } }// End moving left section if(Enemy[loop].direction==Right && Enemy[loop].moving==0 && Enemy[loop].status==Enemy_OK) // sprite is currently moving right { random=rand()%10; if(Enemy[loop].Bright==0) // can we still move right { Enemy[loop].direction=Right; // yes Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; } else // if no then we need to select a new direction { move_ok=0; do { random=rand()%10; new_direction=Select_Enemy_Move_Direction(); // select a new direction if(new_direction==Up && Enemy[loop].Bup==0 && move_ok==0 ) { Enemy[loop].direction=Up; Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; move_ok=1; } if(new_direction==Down && Enemy[loop].Bdown==0 && move_ok==0 ) { Enemy[loop].direction=Down; Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; move_ok=1; } if(new_direction==Left && Enemy[loop].Bleft==0 && move_ok==0 && random <3) { Enemy[loop].direction=Left; Enemy[loop].move_counter=0; Enemy[loop].moving=1; Enemy[loop].frame_counter=0; Enemy[loop].frame=0; move_ok=1; } }while(move_ok==0); } }// End moving Right section }// Comes here is the sprite can't move anywhere }//End movment=0 section if(Enemy[loop].moving==1) // enemy sprite is in motion between 2 locations { if(Enemy[loop].direction==Up) { Enemy[loop].move_counter+=Enemy[loop].speed; // Increment movment counter Enemy[loop].sprite.y-=Enemy[loop].speed; // change sprite screen coordinate Enemy[loop].frame_counter++; if(Enemy[loop].frame_counter==4) { Enemy[loop].frame_counter=0; // change animation frames Enemy[loop].frame++; } if(Enemy[loop].frame==4) Enemy[loop].frame=0; Enemy[loop].sprite.u=Enemy_Up[Enemy[loop].frame].x; Enemy[loop].sprite.v=Enemy_Up[Enemy[loop].frame].y+48; if(Enemy[loop].move_counter==16) // sprite has moved to the desired location { Enemy[loop].moving=0; Enemy[loop].move_counter=0; Enemy[loop].block_y--; } } if(Enemy[loop].direction==Down) { Enemy[loop].move_counter+=Enemy[loop].speed; // Increment movment counter Enemy[loop].sprite.y+=Enemy[loop].speed; // change sprite screen coordinate Enemy[loop].frame_counter++; if(Enemy[loop].frame_counter==4) { Enemy[loop].frame_counter=0; // change animation frames Enemy[loop].frame++; } if(Enemy[loop].frame==4) Enemy[loop].frame=0; Enemy[loop].sprite.u=Enemy_Down[Enemy[loop].frame].x; Enemy[loop].sprite.v=Enemy_Down[Enemy[loop].frame].y+48; if(Enemy[loop].move_counter==16) { Enemy[loop].moving=0; Enemy[loop].move_counter=0; Enemy[loop].block_y++; } } if(Enemy[loop].direction==Left) { Enemy[loop].move_counter+=Enemy[loop].speed; // Increment movment counter Enemy[loop].sprite.x-=Enemy[loop].speed; // change sprite screen coordinate Enemy[loop].frame_counter++; if(Enemy[loop].frame_counter==4) { Enemy[loop].frame_counter=0; // change animation frames Enemy[loop].frame++; } if(Enemy[loop].frame==4) Enemy[loop].frame=0; Enemy[loop].sprite.u=Enemy_Left[Enemy[loop].frame].x; Enemy[loop].sprite.v=Enemy_Left[Enemy[loop].frame].y+48; if(Enemy[loop].move_counter==16) { Enemy[loop].moving=0; Enemy[loop].move_counter=0; Enemy[loop].block_x--; } } if(Enemy[loop].direction==Right) { Enemy[loop].move_counter+=Enemy[loop].speed; // Increment movment counter Enemy[loop].sprite.x+=Enemy[loop].speed; // change sprite screen coordinate Enemy[loop].frame_counter++; if(Enemy[loop].frame_counter==4) { Enemy[loop].frame_counter=0; // change animation frames Enemy[loop].frame++; } if(Enemy[loop].frame==4) Enemy[loop].frame=0; Enemy[loop].sprite.u=Enemy_Right[Enemy[loop].frame].x; Enemy[loop].sprite.v=Enemy_Right[Enemy[loop].frame].y+48; if(Enemy[loop].move_counter==16) { Enemy[loop].moving=0; Enemy[loop].move_counter=0; Enemy[loop].block_x++; } } }// End movement=1 section }// End Enemy_Ok section } // End Main loop } //************************************************************************************************************************ void Add_Run_Energy(int ammount) // Adds the value to Player 1s run energy { P1.run_energy+=ammount; if(P1.run_energy >200) { P1.run_energy=200; } } //************************************************************************************************************************ /* Sets up the low-level port buffers */ void FSetPortBuffers(void) { GetPadBuf(&X_fcontportbuf[0], &X_fcontportbuf[1]); } //************************************************************************************************************************ /* Checks the specified port for the connection of a controller Logical FALSE is returned (0) if no controller is connected, Logical TRUE is returned (1) if a controller is connected. */ unsigned char FControllerConnected(unsigned char port) { unsigned char connected_val = *(X_fcontportbuf[port]); switch(connected_val){ case 0: return TRUE; default: return FALSE; } } //************************************************************************************************************************ /* Returns the upper 4 bits of [buffer_address+1 byte], which indicates the controller type. The returned result should match one of CONTYPE_xxx */ unsigned char FControllerType(unsigned char port) { return (*(X_fcontportbuf[port]+1)>>4); } //************************************************************************************************************************ /* Returns the input data from a STANDARD PAD attached to the specified port */ unsigned short FSPadRead (unsigned char port) { return ~(*(X_fcontportbuf[port]+2)<<8|*(X_fcontportbuf[port]+3)); } //************************************************************************************************************************ void Check_For_Pause(void) // checks to see if game should be paused { static int Start_Status=0; if(Game_Mode==Ready || Game_Mode==Paused) { if(Start_Status==0 && (FSPadRead(PORT_ONE) & SPADstart)) // pause game { Start_Status=1; Game_Mode=Paused; } if(FSPadRead(PORT_ONE) & SPADstart) { } else { if(Start_Status==1) { Start_Status=2; // start button has been released } } if(Start_Status==2 && (FSPadRead(PORT_ONE) & SPADstart)) { Game_Mode=Ready; // un pause game Start_Status=3; } if(FSPadRead(PORT_ONE) & SPADstart) { } else { if(Start_Status==3) { Start_Status=0; // start button has been released } } } if(FControllerConnected(PORT_ONE)==FALSE &&(Game_Mode==Ready || Game_Mode==Paused)) // check to make sure there is a controller connected to port one { GsSortSprite(&Controller,&WorldOT[activebuff],8); // Place sprite into OT do show that the pad is not connected Game_Mode=Paused; Start_Status=1; } } //************************************************************************************************************************ void Fade_Out_Screen(void) // fades the complete screen out { static int counter=0; Fade_Box.attribute=0+(1<<30)+(2<<28); // Rectangle attributes used for fading Fade_Box.x=0; Fade_Box.y=0; Fade_Box.w=320; Fade_Box.h=256; if(counter <256) counter+=4; if(counter>=256) { if(Game_Over_Timer <=0) { Fade_Mode=No_Fade; // Fade out has completed counter=0; } Fade_Box.r=255; Fade_Box.g=255; Fade_Box.b=255; } else { if(counter==256) counter=255; Fade_Box.r=counter; Fade_Box.g=counter; Fade_Box.b=counter; } GsSortBoxFill(&Fade_Box,&WorldOT[activebuff],9); // place box in OT if(Fade_Mode==No_Fade) { counter=0; } } //************************************************************************************************************************ //************************************************************************************************************************ void Fade_In_Screen(void) // fades the complete screen in { static int counter=255; Fade_Box.attribute=0+(1<<30)+(2<<28); // Rectangle attributes used for fading Fade_Box.x=0; Fade_Box.y=0; Fade_Box.w=320; Fade_Box.h=256; Music_Volume=170; // set default music volume counter-=4; if(counter<=0) { Fade_Mode=No_Fade; // Fade in has completed counter=0; Fade_Box.r=0; Fade_Box.g=0; Fade_Box.b=0; Game_Mode=Faded_Out; P1.block_x=8; // Reset P1 sprite details P1.block_y=7; P1.direction=Right; P1.move_counter=0; P1.moving=0; P1.sprite.x=(P1.block_x*16)+24; // P1 default sprite details. P1.sprite.y=(P1.block_y*16)+24; P1.sprite.u=48; P1.sprite.v=0; P1.Flash_counter=60; P1.status=Flashing; } else { Fade_Box.r=counter; Fade_Box.g=counter; Fade_Box.b=counter; } GsSortBoxFill(&Fade_Box,&WorldOT[activebuff],9); // place box in OT if(Fade_Mode==No_Fade) { counter=255; } } //************************************************************************************************************************ int Enemy_Can_See_Player(int bx,int by,int ex,int ey,int direction) // checks if enemy sprite can see the player { // returns 1 if enemy can see the player int result; int Blow; int Bhigh; int loop; result=0; Blow=(by*16)+bx; // Get array offsets Bhigh=(ey*16)+ex; if(direction==Left || direction==Right) // check for blocks on the horizontal plane { for(loop=Blow;loop<=Bhigh;loop++) { if(Movement[loop]==1) { return(FALSE); } } return(TRUE); } if(direction==Up || direction==Down) // check for blocks on the vertical plane { for(loop=Blow;loop<=Bhigh;loop+=16) { if(Movement[loop]==1) { return(FALSE); } } return(TRUE); } } //************************************************************************************************************************ void Check_For_Collisions(void) // checks for all game collisions { int loop; int count; for(loop=0;loop ((Enemy[loop].sprite.x-4) + 8) || Enemy[loop].sprite.x-4 > (P1.sprite.x-4 + 8) || P1.sprite.y-4 > (Enemy[loop].sprite.y-4 + 8) || Enemy[loop].sprite.y-4 > (P1.sprite.y-4 + 8) ) { // No collision } else { P1.status=Dying; // collision took place SsUtKeyOn(Main_Sfx_Vab_ID,2,0,20,0,90,90); } } }// End collision with the player // test for collisions between enemies and blocks for(loop=0;loop9) P1.lives=9; } //************************************************************************************************************************ void Do_HighScore(void) // checks players score to see if a new highscore has been set { GsLINE Gradient1[256]; GsSPRITE High_Score_Logo[6]; // 2 sprites to hold the High score gfx logo GsSPRITE Box; // flashing box to denote the current letter GsSPRITE Text[4]; // spells PERSS SELECT WHEN FINISHED GsBOXF Fading; // box used for fading anim_frame Letters[27]; // A through Z + . int loop,G1_colour,G2_direction,G2_position,current_letter,current_anim_frame,change_counter,finished,box_show,box_count; int score_fade_mode,fade_counter; G1_colour=0; G2_direction=Down; G2_position=0; current_letter=0; // 0->5 current_anim_frame=0; //0->26 change_counter=0; finished=0; box_show=TRUE; box_count=0; score_fade_mode=1; // fade in screen fade_counter=255; // starting colour of box Fading.attribute=0+(1<<30)+(2<<28); Fading.x=0; Fading.y=0; Fading.w=320; Fading.h=256; Fading.r=255; Fading.g=255; Fading.b=255; for(loop=0;loop<4;loop++) // setup text sptites { Text[loop].attribute = 0+(1<<30)+(1<<28)+(1<<24); Text[loop].x=160; // Setup High sprite logo Text[loop].y=30; Text[loop].w=86; Text[loop].h=23; Text[loop].tpage = GetTPage(1,0,High_Score_tim_data.px,High_Score_tim_data.py); Text[loop].u=0; Text[loop].v=0; Text[loop].cx=High_Score_tim_data.cx; Text[loop].cy=High_Score_tim_data.cy; Text[loop].r=128; Text[loop].g=128; Text[loop].b=128; Text[loop].mx=0; Text[loop].my=0; Text[loop].rotate=0; Text[loop].scalex=ONE; Text[loop].scaley=ONE; } Text[0].x=60; // Setup text Sprites Text[0].y=230; Text[0].w=39; Text[0].h=7; Text[0].u=0; Text[0].v=160; Text[1].x=109; Text[1].y=230; Text[1].w=47; Text[1].h=7; Text[1].u=48; Text[1].v=160; Text[2].x=166; Text[2].y=230; Text[2].w=31; Text[2].h=7; Text[2].u=0; Text[2].v=169; Text[3].x=207; // Setup High sprite logo Text[3].y=230; Text[3].w=53; Text[3].h=7; Text[3].u=48; Text[3].v=169; for(loop=0;loop<=7;loop++) // setup the 27 character offsets offsets within the TPage { Letters[loop].x=loop*16; Letters[loop].y=96; } for(loop=0;loop<=7;loop++) { Letters[loop+8].x=loop*16; Letters[loop+8].y=112; } for(loop=0;loop<=7;loop++) { Letters[loop+16].x=loop*16; Letters[loop+16].y=128; } for(loop=0;loop<=2;loop++) { Letters[loop+24].x=loop*16; Letters[loop+24].y=144; } High_Score_Logo[0].attribute = 0+(1<<30)+(1<<28)+(1<<24); High_Score_Logo[0].x=160; // Setup High sprite logo High_Score_Logo[0].y=30; High_Score_Logo[0].w=86; High_Score_Logo[0].h=23; High_Score_Logo[0].tpage = GetTPage(1,0,High_Score_tim_data.px,High_Score_tim_data.py); High_Score_Logo[0].u=0; High_Score_Logo[0].v=0; High_Score_Logo[0].cx=High_Score_tim_data.cx; High_Score_Logo[0].cy=High_Score_tim_data.cy; High_Score_Logo[0].r=128; High_Score_Logo[0].g=128; High_Score_Logo[0].b=128; High_Score_Logo[0].mx=43; High_Score_Logo[0].my=12; High_Score_Logo[0].rotate=0; High_Score_Logo[0].scalex=ONE; High_Score_Logo[0].scaley=ONE; High_Score_Logo[1].attribute = 0+(1<<30)+(1<<28)+(1<<24); High_Score_Logo[1].x=160; // Setup SCORE sprite logo High_Score_Logo[1].y=55; High_Score_Logo[1].w=112; High_Score_Logo[1].h=23; High_Score_Logo[1].tpage = GetTPage(1,0,High_Score_tim_data.px,High_Score_tim_data.py); High_Score_Logo[1].u=0; High_Score_Logo[1].v=32; High_Score_Logo[1].cx=High_Score_tim_data.cx; High_Score_Logo[1].cy=High_Score_tim_data.cy; High_Score_Logo[1].r=128; High_Score_Logo[1].g=128; High_Score_Logo[1].b=128; High_Score_Logo[1].mx=56; High_Score_Logo[1].my=12; High_Score_Logo[1].rotate=0; High_Score_Logo[1].scalex=ONE; High_Score_Logo[1].scaley=ONE; High_Score_Logo[2].attribute = 0+(1<<30)+(1<<28)+(1<<24); High_Score_Logo[2].x=91; // Setup PLEASE sprite logo High_Score_Logo[2].y=90; High_Score_Logo[2].w=47; High_Score_Logo[2].h=7; High_Score_Logo[2].tpage = GetTPage(1,0,High_Score_tim_data.px,High_Score_tim_data.py); High_Score_Logo[2].u=0; High_Score_Logo[2].v=64; High_Score_Logo[2].cx=High_Score_tim_data.cx; High_Score_Logo[2].cy=High_Score_tim_data.cy; High_Score_Logo[2].r=128; High_Score_Logo[2].g=128; High_Score_Logo[2].b=128; High_Score_Logo[2].mx=23; High_Score_Logo[2].my=4; High_Score_Logo[2].rotate=0; High_Score_Logo[2].scalex=ONE; High_Score_Logo[2].scaley=ONE; High_Score_Logo[3].attribute = 0+(1<<30)+(1<<28)+(1<<24); High_Score_Logo[3].x=148; // Setup ENTER sprite logo High_Score_Logo[3].y=90; High_Score_Logo[3].w=39; High_Score_Logo[3].h=7; High_Score_Logo[3].tpage = GetTPage(1,0,High_Score_tim_data.px,High_Score_tim_data.py); High_Score_Logo[3].u=48; High_Score_Logo[3].v=64; High_Score_Logo[3].cx=High_Score_tim_data.cx; High_Score_Logo[3].cy=High_Score_tim_data.cy; High_Score_Logo[3].r=128; High_Score_Logo[3].g=128; High_Score_Logo[3].b=128; High_Score_Logo[3].mx=20; High_Score_Logo[3].my=4; High_Score_Logo[3].rotate=0; High_Score_Logo[3].scalex=ONE; High_Score_Logo[3].scaley=ONE; High_Score_Logo[4].attribute = 0+(1<<30)+(1<<28)+(1<<24); High_Score_Logo[4].x=189; // Setup YOUR sprite logo High_Score_Logo[4].y=90; High_Score_Logo[4].w=31; High_Score_Logo[4].h=7; High_Score_Logo[4].tpage = GetTPage(1,0,High_Score_tim_data.px,High_Score_tim_data.py); High_Score_Logo[4].u=96; High_Score_Logo[4].v=64; High_Score_Logo[4].cx=High_Score_tim_data.cx; High_Score_Logo[4].cy=High_Score_tim_data.cy; High_Score_Logo[4].r=128; High_Score_Logo[4].g=128; High_Score_Logo[4].b=128; High_Score_Logo[4].mx=15; High_Score_Logo[4].my=4; High_Score_Logo[4].rotate=0; High_Score_Logo[4].scalex=ONE; High_Score_Logo[4].scaley=ONE; High_Score_Logo[5].attribute = 0+(1<<30)+(1<<28)+(1<<24); High_Score_Logo[5].x=230; // Setup Name sprite logo High_Score_Logo[5].y=90; High_Score_Logo[5].w=31; High_Score_Logo[5].h=7; High_Score_Logo[5].tpage = GetTPage(1,0,High_Score_tim_data.px,High_Score_tim_data.py); High_Score_Logo[5].u=0; High_Score_Logo[5].v=73; High_Score_Logo[5].cx=High_Score_tim_data.cx; High_Score_Logo[5].cy=High_Score_tim_data.cy; High_Score_Logo[5].r=128; High_Score_Logo[5].g=128; High_Score_Logo[5].b=128; High_Score_Logo[5].mx=15; High_Score_Logo[5].my=4; High_Score_Logo[5].rotate=0; High_Score_Logo[5].scalex=ONE; High_Score_Logo[5].scaley=ONE; Box.attribute = 0+(1<<24)+(1<<30)+(1<<28); Box.x=120; // Setup Name sprite logo Box.y=150; Box.w=16; Box.h=16; Box.tpage = GetTPage(1,0,High_Score_tim_data.px,High_Score_tim_data.py); Box.u=48; Box.v=144; Box.cx=High_Score_tim_data.cx; Box.cy=High_Score_tim_data.cy; Box.r=128; Box.g=128; Box.b=128; Box.mx=8; Box.my=8; Box.rotate=0; Box.scalex=ONE; Box.scaley=ONE; for(loop=0;loop<128;loop++) // setup the background line structures { Gradient1[loop].attribute=(1<<30)+(1<<28); Gradient1[loop].x0=0; Gradient1[loop].y0=loop; Gradient1[loop].x1=320; Gradient1[loop].y1=loop; Gradient1[loop].b=G1_colour; Gradient1[loop].g=0; Gradient1[loop].r=0; G1_colour+=2; } for(loop=128;loop<256;loop++) // setup the background line structures { G1_colour-=2; Gradient1[loop].attribute=(1<<30)+(1<<28); Gradient1[loop].x0=0; Gradient1[loop].y0=loop; Gradient1[loop].x1=320; Gradient1[loop].y1=loop; Gradient1[loop].b=G1_colour; Gradient1[loop].g=0; Gradient1[loop].r=0; } DMSSongReset(&High_Module); GsClearOt(0,0,&WorldOT[0]); // clear the 2 ordering tables GsClearOt(0,0,&WorldOT[1]); if(P1_Score >Highscore) { Highscore=P1_Score; // set the new highscore value DMSSetMasterVol(&High_Module,210); // set volume of music for(loop=0;loop<6;loop++) // reset highscore name to all A { High_Score_Name[loop].attribute = 0+(1<<24); High_Score_Name[loop].x=110+10+(loop*16); // Setup High sprite logo High_Score_Name[loop].y=150; High_Score_Name[loop].w=16; High_Score_Name[loop].h=16; High_Score_Name[loop].tpage = GetTPage(1,0,High_Score_tim_data.px,High_Score_tim_data.py); High_Score_Name[loop].u=0; High_Score_Name[loop].v=96; High_Score_Name[loop].cx=High_Score_tim_data.cx; High_Score_Name[loop].cy=High_Score_tim_data.cy; High_Score_Name[loop].r=128; High_Score_Name[loop].g=128; High_Score_Name[loop].b=128; High_Score_Name[loop].mx=8; High_Score_Name[loop].my=8; High_Score_Name[loop].rotate=0; High_Score_Name[loop].scalex=ONE; High_Score_Name[loop].scaley=ONE; } do { activebuff = GsGetActiveBuff(); // get active buffer GsSetWorkBase((PACKET *)GpuPacketArea[activebuff]); GsClearOt(0,0,&WorldOT[activebuff]); if(FSPadRead(PORT_ONE)&SPADselect && finished==0 && score_fade_mode==0) // finished entering name, continue with game. { score_fade_mode=2; // fade screen out Fading.attribute=0+(1<<30)+(2<<28); Fading.r=0; Fading.g=0; Fading.b=0; fade_counter=0; SsUtKeyOn(Main_Sfx_Vab_ID,10,0,60,0,120,120); } if(change_counter<7) change_counter++; if(FSPadRead(PORT_ONE)&SPADup && change_counter==7 && score_fade_mode==0) // change letters by pushing up and down on controller { current_anim_frame++; change_counter=0; SsUtKeyOn(Main_Sfx_Vab_ID,3,0,60,0,120,120); if(current_anim_frame>26) current_anim_frame=0; } if(FSPadRead(PORT_ONE)&SPADdown && change_counter==7 && score_fade_mode==0) // change letters by pushing up and down on controller { current_anim_frame--; change_counter=0; SsUtKeyOn(Main_Sfx_Vab_ID,3,0,60,0,120,120); if(current_anim_frame<0) current_anim_frame=26; } if(FSPadRead(PORT_ONE)&SPADright && change_counter==7 && score_fade_mode==0) // move along the letters to the right { current_letter++; change_counter=0; SsUtKeyOn(Main_Sfx_Vab_ID,4,0,60,0,120,120); Box.x+=16; current_anim_frame=0; if(current_letter==6) { current_letter=0; Box.x=120; } } if(FSPadRead(PORT_ONE)&SPADleft && change_counter==7 && score_fade_mode==0) // move along the letters to the right { current_letter--; change_counter=0; SsUtKeyOn(Main_Sfx_Vab_ID,4,0,60,0,120,120); Box.x-=16; current_anim_frame=0; if(current_letter==-1) { current_letter=5; Box.x=200; } } High_Score_Name[current_letter].u=Letters[current_anim_frame].x; // assign current anim frame to the current letter High_Score_Name[current_letter].v=Letters[current_anim_frame].y; box_count++; if(box_count==5 && box_show==TRUE) // make white box flash { box_show=FALSE; box_count=0; } if(box_count==5 && box_show==FALSE) { box_show=TRUE; box_count=0; } if(score_fade_mode==1) // currently fading in { fade_counter-=4; if(fade_counter<=0) { Fading.r=0; Fading.g=0; Fading.b=0; score_fade_mode=0; fade_counter=0; } else { Fading.r=fade_counter; Fading.g=fade_counter; Fading.b=fade_counter; } } if(score_fade_mode==2) // currently fading out { fade_counter+=4; if(fade_counter>=255) { Fading.r=255; Fading.g=255; Fading.b=255; fade_counter=255; finished=1; } else { Fading.r=fade_counter; Fading.g=fade_counter; Fading.b=fade_counter; } } if(High_OK == DMS_OK) // Play the music module { DMSPoll(&High_Module); } if(score_fade_mode !=0) GsSortBoxFill(&Fading,&WorldOT[activebuff],0); // put box into OT if required GsSortSprite(&High_Score_Logo[0],&WorldOT[activebuff],100); // draw HIGH logo GsSortSprite(&High_Score_Logo[1],&WorldOT[activebuff],99); // draw SCORE logo GsSortSprite(&High_Score_Logo[2],&WorldOT[activebuff],98); // draw PLEASE logo GsSortSprite(&High_Score_Logo[3],&WorldOT[activebuff],97); // draw ENTER logo GsSortSprite(&High_Score_Logo[4],&WorldOT[activebuff],96); // draw YOUR logo GsSortSprite(&High_Score_Logo[5],&WorldOT[activebuff],95); // draw NAME logo if(box_show==TRUE) GsSortSprite(&Box,&WorldOT[activebuff],80); // Box sprite for(loop=0;loop<4;loop++) { GsSortSprite(&Text[loop],&WorldOT[activebuff],79-loop); } for(loop=0;loop<6;loop++) { GsSortSprite(&High_Score_Name[loop],&WorldOT[activebuff],94-loop); // draw new name characters } for(loop=0;loop<256;loop++) // Draw background lines into the OT. { GsSortLine(&Gradient1[loop],&WorldOT[activebuff],1023-loop); } DrawSync(0); // wait for all drawing to finish VSync(0); // wait for vertical blank interrupt GsSwapDispBuff(); // swap display buffers GsSortClear(0,0,0,&WorldOT[activebuff]); GsDrawOt(&WorldOT[activebuff]); }while(finished==0); Clear_Display_Buffers(); // clear Vram display area GsClearOt(0,0,&WorldOT[0]); // clear both OTs GsClearOt(0,0,&WorldOT[1]); SsUtAllKeyOff(0); } } //************************************************************************************************************************ void Do_Titles(void) // Title screen routine { int Continue; GsSPRITE X_gfx; // sprite structure to hold the big X graphics GsSPRITE Penguin_gfx; // sprite structure to hold the penguin logo GsSPRITE Text1; // Press start text GsSPRITE Player; GsSPRITE Baddy; GsSPRITE Player_Text; GsSPRITE Baddy_Text; GsSPRITE High_Text; GsSPRITE Story_Left; GsSPRITE Story_Right; GsBOXF Fade; int Player_Anim; int Baddy_Anim; int Anim_Counter; int X_scale; // ammount to scale big X logo int X_scale_dir; // current scaling direction; int Mode; int Mode_Temp; int Show_Bottom_Text; int Bottom_Text_Timer; int Loop; int Temp,Temp_Score; int Music_Vol; int Fade_Count; int Story_Counter; Fade.attribute=0+(1<<30)+(2<<28); // Rectangle attributes used for fading Fade.x=0; Fade.y=0; Fade.w=320; Fade.h=256; X_gfx.attribute = 0+(1<<30)+(1<<28)+(1<<24); X_gfx.x=160; // Setup the big X logo X_gfx.y=128; X_gfx.w=142; X_gfx.h=150; X_gfx.tpage = GetTPage(1,0,Titles_tim_data.px,Titles_tim_data.py); X_gfx.u=0; X_gfx.v=0; X_gfx.cx=Titles_tim_data.cx; X_gfx.cy=Titles_tim_data.cy; X_gfx.r=0; X_gfx.g=0; X_gfx.b=0; X_gfx.mx=142/2; X_gfx.my=75; X_gfx.rotate=0; X_gfx.scalex=ONE; X_gfx.scaley=ONE; Penguin_gfx.attribute = 0+(1<<24); Penguin_gfx.x=-63; // Setup the big penguin logo Penguin_gfx.y=128; Penguin_gfx.w=126; Penguin_gfx.h=19; Penguin_gfx.tpage = GetTPage(1,0,Titles_tim_data.px,Titles_tim_data.py); Penguin_gfx.u=0; Penguin_gfx.v=160; Penguin_gfx.cx=Titles_tim_data.cx; Penguin_gfx.cy=Titles_tim_data.cy; Penguin_gfx.r=128; Penguin_gfx.g=128; Penguin_gfx.b=128; Penguin_gfx.mx=126/2; Penguin_gfx.my=10; Penguin_gfx.rotate=0; Penguin_gfx.scalex=ONE; Penguin_gfx.scaley=ONE; Text1.attribute = 0+(1<<30)+(1<<28)+(1<<24); Text1.x=160; // Setup the text logo PRESS START Text1.y=256+10; Text1.w=136; Text1.h=7; Text1.tpage = GetTPage(1,0,Titles_tim_data.px,Titles_tim_data.py); Text1.u=0; Text1.v=192; Text1.cx=Titles_tim_data.cx; Text1.cy=Titles_tim_data.cy; Text1.r=128; Text1.g=128; Text1.b=128; Text1.mx=136/2; Text1.my=4; Text1.rotate=0; Text1.scalex=ONE; Text1.scaley=ONE; Player.attribute = 0+(1<<30)+(1<<28)+(1<<24); Player.x=-20; // Sprite image that represents the player Player.y=200; Player.w=16; Player.h=16; Player.tpage = GetTPage(1,0,Player_tim_data.px,Player_tim_data.py); Player.u=0; Player.v=0; Player.cx=Player_tim_data.cx; Player.cy=Player_tim_data.cy; Player.r=128; Player.g=128; Player.b=128; Player.mx=8; Player.my=8; Player.rotate=0; Player.scalex=ONE; Player.scaley=ONE; Baddy.attribute = 0+(1<<30)+(1<<28)+(1<<24); Baddy.x=-20; // Sprite image that represents the Enemy Baddy.y=200; Baddy.w=16; Baddy.h=16; Baddy.tpage = GetTPage(1,0,Enemy_tim_data.px,Enemy_tim_data.py); Baddy.u=0; Baddy.v=0; Baddy.cx=Enemy_tim_data.cx; Baddy.cy=Enemy_tim_data.cy; Baddy.r=128; Baddy.g=128; Baddy.b=128; Baddy.mx=8; Baddy.my=8; Baddy.rotate=0; Baddy.scalex=ONE; Baddy.scaley=ONE; Player_Text.attribute = 0+(1<<30)+(1<<28)+(1<<24); Player_Text.x=160; // Text line THE GOOD GUY Player_Text.y=215; Player_Text.w=87; Player_Text.h=7; Player_Text.tpage = GetTPage(1,0,Titles_tim_data.px,Titles_tim_data.py); Player_Text.u=0; Player_Text.v=217; Player_Text.cx=Titles_tim_data.cx; Player_Text.cy=Titles_tim_data.cy; Player_Text.r=0; Player_Text.g=0; Player_Text.b=0; Player_Text.mx=88/2; Player_Text.my=4; Player_Text.rotate=0; Player_Text.scalex=ONE; Player_Text.scaley=ONE; Baddy_Text.attribute = 0+(1<<30)+(1<<28)+(1<<24); Baddy_Text.x=160; // Text line THE GOOD GUY Baddy_Text.y=215; Baddy_Text.w=79; Baddy_Text.h=7; Baddy_Text.tpage = GetTPage(1,0,Titles_tim_data.px,Titles_tim_data.py); Baddy_Text.u=0; Baddy_Text.v=224; Baddy_Text.cx=Titles_tim_data.cx; Baddy_Text.cy=Titles_tim_data.cy; Baddy_Text.r=0; Baddy_Text.g=0; Baddy_Text.b=0; Baddy_Text.mx=40; Baddy_Text.my=4; Baddy_Text.rotate=0; Baddy_Text.scalex=ONE; Baddy_Text.scaley=ONE; High_Text.attribute = 0+(1<<30)+(1<<28)+(1<<24); High_Text.x=160; // Text line High SCORE High_Text.y=180; High_Text.w=70; High_Text.h=7; High_Text.tpage = GetTPage(1,0,Titles_tim_data.px,Titles_tim_data.py); High_Text.u=0; High_Text.v=208; High_Text.cx=Titles_tim_data.cx; High_Text.cy=Titles_tim_data.cy; High_Text.r=0; High_Text.g=0; High_Text.b=0; High_Text.mx=35; High_Text.my=4; High_Text.rotate=0; High_Text.scalex=ONE; High_Text.scaley=ONE; Story_Left.attribute = 0+(1<<24); Story_Left.x=-170; // Setup left side of story screen Story_Left.y=0; Story_Left.w=160; Story_Left.h=256; Story_Left.tpage = GetTPage(1,0,Story1_tim_data.px,Story1_tim_data.py); Story_Left.u=0; Story_Left.v=0; Story_Left.cx=Story1_tim_data.cx; Story_Left.cy=Story1_tim_data.cy; Story_Left.r=128; Story_Left.g=128; Story_Left.b=128; Story_Left.mx=0; Story_Left.my=0; Story_Left.rotate=0; Story_Left.scalex=ONE; Story_Left.scaley=ONE; Story_Right.attribute = 0+(1<<24); Story_Right.x=330; // Setup left side of story screen Story_Right.y=0; Story_Right.w=160; Story_Right.h=256; Story_Right.tpage = GetTPage(1,0,Story2_tim_data.px,Story2_tim_data.py); Story_Right.u=0; Story_Right.v=0; Story_Right.cx=Story2_tim_data.cx; Story_Right.cy=Story2_tim_data.cy; Story_Right.r=128; Story_Right.g=128; Story_Right.b=128; Story_Right.mx=0; Story_Right.my=0; Story_Right.rotate=0; Story_Right.scalex=ONE; Story_Right.scaley=ONE; High_Score_Name[0].x=(160-40)-220; High_Score_Name[0].y=200; High_Score_Name[1].x=(160-24)-220; High_Score_Name[1].y=200; High_Score_Name[2].x=(160-8)-220; High_Score_Name[2].y=200; High_Score_Name[3].x=(160+8)-220; High_Score_Name[3].y=200; High_Score_Name[4].x=(160+24)-220; High_Score_Name[4].y=200; High_Score_Name[5].x=(160+40)-220; High_Score_Name[5].y=200; Score_Sprite[0].x=(160-32)+220; Score_Sprite[0].y=220; Score_Sprite[1].x=(160-22)+220; Score_Sprite[1].y=220; Score_Sprite[2].x=(160-12)+220; Score_Sprite[2].y=220; Score_Sprite[3].x=(160-2)+220; Score_Sprite[3].y=220; Score_Sprite[4].x=(160+8)+220; Score_Sprite[4].y=220; Score_Sprite[5].x=(160+18)+220; Score_Sprite[5].y=220; Score_Sprite[6].x=(160+28)+220; Score_Sprite[6].y=220; Temp_Score=Highscore; // copy the current highscore Temp=Temp_Score/1000000; Score_Sprite[0].u=Lives[Temp].x; // Decode all the digits Score_Sprite[0].v=Lives[Temp].y+8; Score_Sprite[0].w=Lives[Temp].width; Temp_Score-=Temp*1000000; Temp=Temp_Score/100000; Score_Sprite[1].u=Lives[Temp].x; // Decode all the digits Score_Sprite[1].v=Lives[Temp].y+8; Score_Sprite[1].w=Lives[Temp].width; Temp_Score-=Temp*100000; Temp=Temp_Score/10000; Score_Sprite[2].u=Lives[Temp].x; // Decode all the digits Score_Sprite[2].v=Lives[Temp].y+8; Score_Sprite[2].w=Lives[Temp].width; Temp_Score-=Temp*10000; Temp=Temp_Score/1000; Score_Sprite[3].u=Lives[Temp].x; // Decode all the digits Score_Sprite[3].v=Lives[Temp].y+8; Score_Sprite[3].w=Lives[Temp].width; Temp_Score-=Temp*1000; Temp=Temp_Score/100; Score_Sprite[4].u=Lives[Temp].x; // Decode all the digits Score_Sprite[4].v=Lives[Temp].y+8; Score_Sprite[4].w=Lives[Temp].width; Temp_Score-=Temp*100; Temp=Temp_Score/10; Score_Sprite[5].u=Lives[Temp].x; // Decode all the digits Score_Sprite[5].v=Lives[Temp].y+8; Score_Sprite[5].w=Lives[Temp].width; Temp_Score-=Temp*10; Temp=Temp_Score/1; Score_Sprite[6].u=Lives[Temp].x; // Decode all the digits Score_Sprite[6].v=Lives[Temp].y+8; Score_Sprite[6].w=Lives[Temp].width; for(Temp=0;Temp<7;Temp++) { if(Score_Sprite[Temp].u==8) { Score_Sprite[Temp].x+=3; // Alter X coordinate if the sprite is a 1. } } Continue=FALSE; X_scale_dir=Down; // scale logo down to start with X_scale=0; Mode=0; Mode_Temp=0; Show_Bottom_Text=TRUE; Bottom_Text_Timer=0; Player_Anim=0; Baddy_Anim=0; Anim_Counter=0; Music_Vol=170; Fade_Count=0; Story_Counter=0; DMSSongReset(&Title_Music); do { activebuff = GsGetActiveBuff(); // get active buffer GsSetWorkBase((PACKET *)GpuPacketArea[activebuff]); GsClearOt(0,0,&WorldOT[activebuff]); Anim_Counter++; if(Anim_Counter==6) { Player_Anim++; Baddy_Anim++; Anim_Counter=0; if(Player_Anim==4) // Animate player and Enemy sprites { Player_Anim=0; Baddy_Anim=0; } } Player.u=P1_Right_Anim[Player_Anim].x; Player.v=P1_Right_Anim[Player_Anim].y; Baddy.u=Enemy_Right[Baddy_Anim].x; Baddy.v=Enemy_Right[Baddy_Anim].y+48; if(X_scale_dir==Down) // Scale X logo { X_scale+=50; if(X_scale==1000) { X_scale_dir=Up; } } if(X_scale_dir==Up) { X_scale-=50; if(X_scale==0) { X_scale_dir=Down; } }//end scaling X graphic X_gfx.scalex=ONE-X_scale; // Apply scaling factor the the sprite X_gfx.scaley=ONE-X_scale; if(Mode==0) // Mode 0 is the penguin logo moving onto the screen { Penguin_gfx.x+=8; if(Penguin_gfx.x>=160) { Penguin_gfx.x=160; Mode=1; } } if(Mode==1) // Mode 1 fades in the big X logo { Mode_Temp+=1; if(Mode_Temp>=128) { Mode=2; Mode_Temp=128; X_gfx.r=X_gfx.g=X_gfx.b=Mode_Temp; Mode_Temp=0; } else { X_gfx.r=X_gfx.g=X_gfx.b=Mode_Temp; } } if(Mode==2) // Mode 2 is just a delay { Mode_Temp++; if(Mode_Temp==50) { Mode++; Mode_Temp=0; } } if(Mode==3) // Mode 3 moves the penguin and the X logo to the top of the screen { Mode_Temp++; X_gfx.y--; Penguin_gfx.y--; if(Mode_Temp==50) { Mode++; Mode_Temp=0; } } if(Mode==4) // mode 4 brings the PRESS START text onto the screen { Mode_Temp++; Text1.y--; if(Mode_Temp==15) { Mode++; Mode_Temp=0; } } if(Mode==5) // mode 5 brings the player and sprite onto the screen { Player.x++; if(Player.x==160) { Mode_Temp=0; Mode++; } } if(Mode==6) // Mode 6 fades up the player text { Mode_Temp+=2; if(Mode_Temp>128) { Mode_Temp=0; Mode++; } else { Player_Text.r=Player_Text.g=Player_Text.b=Mode_Temp; } } if(Mode==7) // just a short delay { Mode_Temp++; if(Mode_Temp==100) { Mode++; Mode_Temp=128; } } if(Mode==8) // player sprite leaves the screen { if(Mode_Temp>0) Mode_Temp-=2; Player_Text.r=Player_Text.g=Player_Text.b=Mode_Temp; Player.x++; if(Player.x==330) { Mode++; Mode_Temp=0; } } if(Mode==9) // Enemy sprite enters screen { Baddy.x++; if(Baddy.x==160) { Mode_Temp=0; Mode++; } } if(Mode==10) // fades in the baddy text { Mode_Temp+=2; if(Mode_Temp>128) { Mode_Temp=0; Mode++; } else { Baddy_Text.r=Baddy_Text.g=Baddy_Text.b=Mode_Temp; } } if(Mode==11) // just a short delay { Mode_Temp++; if(Mode_Temp==100) { Mode++; Mode_Temp=128; } } if(Mode==12) // enemy sprite leaves the screen { if(Mode_Temp>0) Mode_Temp-=2; Baddy_Text.r=Baddy_Text.g=Baddy_Text.b=Mode_Temp; Baddy.x++; if(Baddy.x==330) { Mode++; Mode_Temp=0; } } if(Mode==13) // Fades in High Score text { Mode_Temp+=2; if(Mode_Temp>128) { Mode_Temp=0; Mode++; } else { High_Text.r=High_Text.g=High_Text.b=Mode_Temp; } } if(Mode==14) // Moves highscore value and name into view { Mode_Temp+=10; for(Temp=0;Temp<6;Temp++) { High_Score_Name[Temp].x+=10; } for(Temp=0;Temp<7;Temp++) { Score_Sprite[Temp].x-=10; } if(Mode_Temp==220) { Mode++; Mode_Temp=0; } } if(Mode==15) // Just a delay { Mode_Temp++; if(Mode_Temp==900) { Mode++; Mode_Temp=0; Story_Left.x=-170; Story_Left.y=0; Story_Right.x=330; Story_Right.y=0; } } if(Mode==16) // Moves the story screen into display { Mode_Temp++; Story_Left.x+=5; Story_Right.x-=5; if(Mode_Temp==34) { Mode++; Mode_Temp=0; } } if(Mode==17) // Just a delay { Mode_Temp++; if(Mode_Temp==700) { Mode++; Mode_Temp=0; } } if(Mode==18) // moves story off the screen { Mode_Temp++; Story_Left.y+=10; Story_Right.y-=10; if(Mode_Temp==26) { Mode_Temp=0; Mode=15; } } if(Mode>4) // flashes bottom text { Bottom_Text_Timer++; if(Bottom_Text_Timer==10) { if(Show_Bottom_Text==TRUE) { Show_Bottom_Text=FALSE; Bottom_Text_Timer=0; } else { Show_Bottom_Text=TRUE; Bottom_Text_Timer=0; } } } GsSortFastSprite(&Story_Left,&WorldOT[activebuff],2); // draw left side of story screen GsSortFastSprite(&Story_Right,&WorldOT[activebuff],3); // draw Right side of story screen if(Show_Bottom_Text==TRUE) GsSortSprite(&Text1,&WorldOT[activebuff],1); // draw Bottom text logo PRESS START GsSortSprite(&X_gfx,&WorldOT[activebuff],10); // draw big X logo GsSortSprite(&Penguin_gfx,&WorldOT[activebuff],9); // draw big penguin logo GsSortSprite(&Player,&WorldOT[activebuff],12); // draw Player sprite GsSortSprite(&Baddy,&WorldOT[activebuff],13); // draw enemy sprite GsSortSprite(&Player_Text,&WorldOT[activebuff],14); GsSortSprite(&Baddy_Text,&WorldOT[activebuff],15); for(Loop=0;Loop<6;Loop++) { GsSortSprite(&High_Score_Name[Loop],&WorldOT[activebuff],16+Loop); } GsSortSprite(&High_Text,&WorldOT[activebuff],21); // draw text that says HIGH SCORE for(Loop=0;Loop<7;Loop++) // draw high score value { GsSortSprite(&Score_Sprite[Loop],&WorldOT[activebuff],22+Loop); } if(Continue==TRUE) { // Fade out title music Music_Vol-=2; if(Music_Vol <=0) { Music_Vol=0; } if(Fade_Count <256) // Fade out screen Fade_Count+=4; if(Fade_Count>=256) Fade_Count=255; Fade.r=Fade.g=Fade.b=Fade_Count; GsSortBoxFill(&Fade,&WorldOT[activebuff],0); // place box in OT } if(Title_OK == DMS_OK) // Play the music module { DMSSetMasterVol(&Title_Music,Music_Vol); // set volume of music DMSPoll(&Title_Music); } if(FSPadRead(PORT_ONE)&SPADstart && Continue==FALSE && Mode >4) // detect when the user has pressed the start button { Continue=TRUE; } DrawSync(0); // wait for all drawing to finish VSync(0); // wait for vertical blank interrupt GsSwapDispBuff(); // swap display buffers GsSortClear(0,0,0,&WorldOT[activebuff]); GsDrawOt(&WorldOT[activebuff]); // Draw the contents of the OT. }while(Music_Vol !=0); Clear_Display_Buffers(); // clear Vram display area GsClearOt(0,0,&WorldOT[0]); // clear both OTs GsClearOt(0,0,&WorldOT[1]); SsUtAllKeyOff(0); } //************************************************************************************************************************ void Show_Credits(void) // shows credits { int Display_Timer; int Colour; int Counter; int Scale; GsSPRITE Credits_Left; GsSPRITE Credits_Right; GsBOXF Fade; Fade.attribute=0+(1<<30)+(2<<28); // Rectangle attributes used for fading Fade.x=0; Fade.y=0; Fade.w=320; Fade.h=256; Credits_Left.attribute = 0+(1<<24); Credits_Left.x=80; // Setup the big penguin logo Credits_Left.y=128; Credits_Left.w=160; Credits_Left.h=256; Credits_Left.tpage = GetTPage(1,0,Credits1_tim_data.px,Credits1_tim_data.py); Credits_Left.u=0; Credits_Left.v=0; Credits_Left.cx=Credits1_tim_data.cx; Credits_Left.cy=Credits1_tim_data.cy; Credits_Left.r=128; Credits_Left.g=128; Credits_Left.b=128; Credits_Left.mx=80; Credits_Left.my=128; Credits_Left.rotate=0; Credits_Left.scalex=ONE; Credits_Left.scaley=ONE; Credits_Right.attribute = 0+(1<<24); Credits_Right.x=240; // Setup the big penguin logo Credits_Right.y=128; Credits_Right.w=160; Credits_Right.h=256; Credits_Right.tpage = GetTPage(1,0,Credits2_tim_data.px,Credits2_tim_data.py); Credits_Right.u=0; Credits_Right.v=0; Credits_Right.cx=Credits2_tim_data.cx; Credits_Right.cy=Credits2_tim_data.cy; Credits_Right.r=128; Credits_Right.g=128; Credits_Right.b=128; Credits_Right.mx=80; Credits_Right.my=128; Credits_Right.rotate=0; Credits_Right.scalex=ONE; Credits_Right.scaley=ONE; Display_Timer=0; Colour=0; Counter=0; Scale=0; do { activebuff = GsGetActiveBuff(); // get active buffer GsSetWorkBase((PACKET *)GpuPacketArea[activebuff]); GsClearOt(0,0,&WorldOT[activebuff]); Display_Timer++; if(Display_Timer>700) { Scale+=100; if(Scale>=4096) Scale=4096; Credits_Right.scaley=ONE-Scale; Credits_Left.scaley=ONE-Scale; if(Counter <256) Counter+=4; if(Counter>=256) { Fade.r=255; Fade.g=255; Fade.b=255; } else { if(Counter==256) Counter=255; Fade.r=Counter; Fade.g=Counter; Fade.b=Counter; } GsSortBoxFill(&Fade,&WorldOT[activebuff],0); // place box in OT } GsSortSprite(&Credits_Left,&WorldOT[activebuff],10); GsSortSprite(&Credits_Right,&WorldOT[activebuff],11); DrawSync(0); VSync(0); GsSwapDispBuff(); if(Display_Timer<700) GsSortClear(0,0,0,&WorldOT[activebuff]); GsDrawOt(&WorldOT[activebuff]); // Draw all Gfx to the screen }while(Counter<256); Clear_Display_Buffers(); // clear Vram display area GsClearOt(0,0,&WorldOT[0]); // clear both OTs GsClearOt(0,0,&WorldOT[1]); } //************************************************************************************************************************