/* !!!!!!!DISCLAIMER!!!!!!!!!!! THIS SOURCE CODE IS AN ABSOLUTE MESS AND I DOUBT IT'LL HELP YOU MUCH. I PLAN ON TIDYING IT, ADDING COMMENTS ETC AFTER A FEW WEEKS BREAK - THIS WAS THE MOST KER-AY-ZEE MONTH! MADE AVAILABLE ON PRINCIPLE ALONE, THEN! PS TAB LENGTH IS SET TO 4 SPACES ON MY TXT VIEWER... */ /********************************* - C H E M I C A L W A R F A R E - ********************************** GDUK 98 Best Net Yaroze Game entry! Design, code, graphics and sound by Nick Ferguson Ideas/design: July '98 Code started: 5 August '98 (15:35) GDUK version: 31 August '98 (23:00) WRITTEN FOR PAL (revenge! revenge!) ---------------------------------- CONTACT DETAILS: nickf@saqnet.co.uk http://www.netyaroze-europe.com/~rookie1 http://www.saqnet.co.uk/users/nickf http://www.n64gazetta.com ---------------------------------- Mini-Diary: (I like my diaries!) 12/7/98 Stripped old AMATEUR WARS source to bare bones - get ready for CHEMICAL WARFARE!!! 13/7/98 - 5/8/98 Numerous false starts. Still, I learnt a fair bit :-) Also played too much Quake 2 vs. my bro'. Many hours. 5/8/98 -10/8/98 Girlfriend on 8-week backpacking trip - I may now begin coding! Basic player graphics, animation and movement. 10 hours. 11/8/98 Rewritten to take advantage of pointers and enum. stuff. Started adding sniper mode. 3 hours. 14/8/98 Added first two death animations. Pondered writing sniper mode, but put it off again. 2 hours. 15/8/98 Wrote the goddam sniper mode. Well, 90% of it. Re-learnt maths I used to know! Did another death animation (hey - they're fun!). 8 hours of coding. 16/8/98 Fixed 'flicker' bug. Boned up on custom fonts. Added 'standfirm' mode (oo-er) and decelerate function. Spent rest of the evening hunting resultant bugs (the fixes are NOT elegant). 6 bloody hours. 17/8/98 Drew the initial power-up icons and got basic power-ups appearing at 'random' every blah-de-blah Vsyncs. A relatively painless 3 1/2 hours. I'm beginning to wish I'd started this game earlier!!! 18/8/98 Tidied up power-up code, added collision detection and let the player 'pick up' power ups and what's in them. Then fixed a few bugs and made the icons *much* nicer. 6 hours of coding (not bad considering I got 'Sonic Jam' today)! 19/8/98 Added mine-dropping animation (took so loooong!) and keyed it in. Getting fed up of fixing bugs! Maybe next time I shall plan the program before starting... 5 hours. 20/8/98 Tidied up animation and frame stuff. Connected Yaroze to TV (rather than PC TV card) for the rest of the project! Polished off mines functions and got started on explosions! 8 hours (lots of graphics tweaking). 21/8/98 Added player-explosion interaction, did explosion sprites, bunked off a bit... 4 hours. 22/8/98 Tweaked bloody explosion sprites, did sniper shot graphics and code. Managed to balls-up TIM positions in memory and spent an hour sorting that out... Added bare bones of two player mode. 7 hours. 23/8/98 Added dubious collision detection and generally bugfixed two-player mode. Added bullet collision detection and hit effects. Would have done more but locked myself OUT MY FUCKING FLAT for 4 hours >:-( So, only managed 6 hours, then. 24/8/98 Did status screen graphics and started to code them in. Was a bit lazy. 4 hours. 25/8/98 Added damage from weapons, fixed a few bugs and found a few others. Oh well. Added energy bars, tied status screen numbers to "real" ones... 2 hrs. 26/8/98 Slacked off badly. Finished status bars and that's about it... Stupid git! 2 hours. 27/8/98 Well, I feel like shit but I carry on. How manly is that? Don't get much done, as I have the flu (mildly). 2 hrs. 28/8/98 How well-timed is this illness? Bloody hell... Get the game/round death animations and victory stuff done. It's going to be very messy, but I only have 3 days!!! 4 hrs. 29/8/98 Add the dinky custom font. Menu screens are a bit dull, but it kinda works... 4 hrs. 30/8/98 Aiee! 24 hrs to go! Added scrolling text on menu screens, pause mode, general bugfixes, main logo, graphics tweaking, contemplated adding sound etc. 8 hrs. 31/8/98 Absolute f***ing panic. Add ALL sounds and general gameplay tweaks. FINISHED AT LAST! Should have worked harder this week... 12 hrs. KNOWN BUGS/QUIRKS: Occasional direction-facing problems (when releasing sniper sight...) Sticky collision detection between players. Sound mess-ups (not bad tho' - considering it was all done in one day) THANKS TO: (SCEE) Ira Rainey (~shadow) & Scott Campbell (~escotia) for their sprite tutorials. John Ward for his "Spacies" source. James Russell for the Net Yaroze FAQ. DEnnis Brinkhuis (~madmac) for the profile list and his Middlesex journal. & every other NY member who's encouraged or inspired me (a lot of you)! EXTRA-SPECIAL THANKS (with a cherry on top!): (SCEE) James Rutherford (~mrfrosty) for coding tips, peeks at his old source, and the awesome FCONTROL controller library. James Shaugnessy (~shaughnj) for his brill Gravitation source and personal help. James Russell & Craig Graham for their newsgroup comments on custom fonts. Pete Dollochan for advice on stopping the compiler from barfing! Whoever wrote the "Sound Programming for Dummies" tutorial (?)- I added sound in the last 12 hours thanks to you! (SCEA) Darco for the mega 'combine' utility! (OUTSIDERS!!!!) Ross Anderson (flatmate) for the 'Line-Of-Sight Algorithm' ;-) Chris Ferguson (brother) for occasionally popping his head round my door and saying "That's shit"... *********************************/ /* HEADER FILES */ #include // Hooray for LIBPS! #include "fcont1_5.h" // fcontrol v1.5 (from Mr Frosty) #define SPRITE_CNT (1500) // sprite count #define SCREEN_W (320) // setup screen stuff. Dur. #define SCREEN_H (256) #include "mem_add.h" // Darco's 'Combine' utility creates this header file // It contains the *individual* memory addresses for // the combined data! And it's classified ;-) #define ROTATE_UP (0) // Rotation definitions #define ROTATE_DOWN (0+ONE*180) #define ROTATE_LEFT (0+ONE*270) #define ROTATE_RIGHT (0+ONE*90) #define OT_LENGTH (2) //Ordering Table length. 2 means I can cover mistakes easier! /*GAME CONTROL DEFINITIONS */ #define NUM_LIVES (3) // Number of lives players start with! #define MAX_ENERGY (376832) // Max energy level (pixel width of energy bar * 4096) #define BULLET_DAMAGE (4096) // Damage to energy level done by bullet #define SNIPER_HEAD_DAMAGE (36864) // Ditto for sniper rifle! #define SNIPER_BODY_DAMAGE (20480) // Ditto for sniper rifle! #define EXPLOSION_DAMAGE (12288) // Ditto for explosive! #define PLAYER_FRAME_RATE (5) // Animation rate of player... #define PLAYER_MAXSPEED (6144) // MAX speed of player (4096) #define PLAYER_ACCELERATE (384) // ACC. RATE of player (192) #define PLAYER_DECELERATE (576) // DEC. RATE of player (384) #define BLAST_FORCE (9216) // Power of explosive BLAST!!! :-) #define BULLET_SPEED (15360) // speed of bullets (*4096) #define BULLET_GAP (6) // Vsyncs between bullets #define BULLET_TIMER (12) // Time for bullet hit animation! #define MAX_BULLETS_ONSCREEN (50) // Max no bullets onscreen at a time (per player). #define MAX_MINES_ONSCREEN (20) // Max no. of mines possible onscreen (limited by powerup code) #define MAX_EXPLOSIONS_ONSCREEN (40) // Geddit? #define MAX_BULLET_HITS (15) // Max no. of bullet hits onscreen per player! #define DROP_MINE_TIMER (65) // Time taken to drop mine (in VSyncs) was 78 #define MINE_TIMER (150) // Time for a dropped mine to "prime" (VSyncs*2)due to looping #define MAX_BULLETS (50) // max no. of one item possibly held by a player #define MAX_SNIPER (25) // etc #define MAX_MINES (10) #define MAX_GRENADES (10) #define MAX_POWERUPS (4) // max no. powerups onscreen at once #define POWERUP_LENGTH (300) // Length powerup on screen (in VSyncs) (750) #define POWERUP_FREQ (100) // Frequency of powerups (in VSyncs) (500) #define NUM_BULLETS (25) // players' starting no. of bullets, #define NUM_SNIPER_SHOTS (10) // sniper rounds, #define NUM_GRENADES (5) // grenades, #define NUM_MINES (5) // and mines! #define POWERUP_BULLETS (25) // How many of each given item powerups contain... #define POWERUP_SNIPER (10) #define POWERUP_MINES (5) #define POWERUP_HEALTH (61440) #define SIGHT_MAXSPEED (10240) // MAX speed of sniper sight #define SIGHT_ACCELERATE (384) // ACC. RATE of sniper sight #define SIGHT_DECCELERATE (312) // DEC. RATE of sniper sight #define SIGHTSHOT_TIMER (24) //length of sight shot animation #define EXPLOSION_TIMER (48) // Length explosion onscreen (in seconds)! #define BLAST_TIMER (20) // Time for player to recover from blast! #define PLAYER_TOP_WALL (26<<12) // screen edge boundaries for the players! #define PLAYER_BOTTOM_WALL (232<<12) #define PLAYER_LEFT_WALL (0<<12) #define PLAYER_RIGHT_WALL (304<<12) #define BULLET_TOP_WALL (27<<12) // screen edge collision boundaries for bullets (*4096) #define BULLET_BOTTOM_WALL (256<<12) #define BULLET_LEFT_WALL (0<<12) #define BULLET_RIGHT_WALL (320<<12) #define SIGHT_TOP_WALL (26<<12) // screen edge collision boundaries for sights (*4096) #define SIGHT_BOTTOM_WALL (246<<12) #define SIGHT_LEFT_WALL (0<<12) #define SIGHT_RIGHT_WALL (310<<12) /* ENUMERATION TYPES */ enum PAD_DIR { PDnull, PDup, PDdown, PDleft, PDright, PDup_left, PDup_right, PDdown_left, PDdown_right }; enum PLAYER_MODE { PMtrench=1, PMbattle, PMsniper, PMstandfirm, PMmine, PMblast }; enum PU_ITEM { PUbullets=1, PUsniper, PUgasmask, PUmines, PUhealth }; enum EXP_TYPE { EXPinactive, EXPmine, EXPgrenade }; enum CURRENT_GAME_STATE { GSintro, GStitle, GSoptions, GScredits, GSbattle, GSfadeout, GSgameover, GSroundintro, GSroundover, GSpause }; enum BATTLE_EVENTS { BEnormal, BEgasmask, BEgameover }; enum CAUSE_OF_DEATH { CDnull, CDbullet, CDexplosion, CDsniperhead, CDsniperbody }; enum SIGHTSHOT_TYPE { STmiss, SThit }; /* GLOBAL VARIABLES, STRUCTS 'N STUFF */ GsOT WorldOT[2]; GsOT_TAG OTTags[2][1<250) printString(credits, (320-text_scroll*3),220); else printString(version, 92, 220); if(screen_timer>5575) screen_timer=0; break; case GSgameover: if(player1.lives_left > player2.lives_left) { printString(p1wins, 34, 80); printString(start, 72, 120); } if(player1.lives_left < player2.lives_left) { printString(p2wins, 33, 80); printString(start, 72, 120); } if(player1.lives_left == player2.lives_left) { printString(draw, 68, 80); printString(start, 72, 120); } break; default: break; } DrawSync(0); VSync(0); GsSwapDispBuff(); GsSortClear(0,0,0,&WorldOT[activeBuff]); //clear screen GsDrawOt(&WorldOT[activeBuff]); switch(state) { case GSoptions: break; case GScredits: break; case GSfadeout: break; case GSpause: if(((FSPadRead(PORT_ONE) & SPADstart) || (FSPadRead(PORT_TWO) & SPADstart)) && (screen_timer > 33)) { state=GSbattle; screen_timer=0; } else screen_timer++; if(screen_timer > 500) screen_timer=100; break; case GSgameover: SsVabClose(gore_vab_id); // close vab data SsVabClose(agony_vab_id); // close vab data if(screen_timer==0) { if(player1.lives_left > player2.lives_left) { p1wins_vab_id = SsVabTransfer( (u_char *) DATA_P1WINS_VH, (u_char *) DATA_P1WINS_VB, -1, 1); SsUtKeyOn(p1wins_vab_id, 0, 0, 48, 0, 127, 127); } if(player1.lives_left < player2.lives_left) { p2wins_vab_id = SsVabTransfer( (u_char *) DATA_P2WINS_VH, (u_char *) DATA_P2WINS_VB, -1, 1); SsUtKeyOn(p2wins_vab_id, 0, 0, 48, 0, 127, 127); } if(player1.lives_left == player2.lives_left) { nowins_vab_id = SsVabTransfer( (u_char *) DATA_NOWINS_VH, (u_char *) DATA_NOWINS_VB, -1, 1); SsUtKeyOn(nowins_vab_id, 0, 0, 48, 0, 127, 127); } } screen_timer++; if((FSPadRead(PORT_ONE) & SPADstart) && screen_timer > 40) { screen_timer=0; state=GStitle; if(player1.lives_left > player2.lives_left) SsVabClose(p1wins_vab_id); if(player1.lives_left < player2.lives_left) SsVabClose(p2wins_vab_id); if(player1.lives_left == player2.lives_left) SsVabClose(nowins_vab_id); } break; case GSroundintro: SsVabClose(gore_vab_id); // close vab data SsVabClose(agony_vab_id); // close vab data if(screen_timer==0) { switch(round) { case 1: round1_vab_id = SsVabTransfer( (u_char *) DATA_ROUND1_VH, (u_char *) DATA_ROUND1_VB, -1, 1); SsUtKeyOn(round1_vab_id, 0, 0, 48, 0, 127, 127); //45 was 60 break; case 2: round2_vab_id = SsVabTransfer( (u_char *) DATA_ROUND2_VH, (u_char *) DATA_ROUND2_VB, -1, 1); SsUtKeyOn(round2_vab_id, 0, 0, 48, 0, 127, 127); break; case 3: round3_vab_id = SsVabTransfer( (u_char *) DATA_ROUND3_VH, (u_char *) DATA_ROUND3_VB, -1, 1); SsUtKeyOn(round3_vab_id, 0, 0, 48, 0, 127, 127); break; case 4: round4_vab_id = SsVabTransfer( (u_char *) DATA_ROUND4_VH, (u_char *) DATA_ROUND4_VB, -1, 1); SsUtKeyOn(round4_vab_id, 0, 0, 48, 0, 127, 127); break; case 5: round5_vab_id = SsVabTransfer( (u_char *) DATA_ROUND5_VH, (u_char *) DATA_ROUND5_VB, -1, 1); SsUtKeyOn(round5_vab_id, 0, 0, 48, 0, 127, 127); break; default: break; } } if(screen_timer<125) { screen_timer++; player=&player1; status=&status1; DoStatusBars(status, player); player=&player2; status=&status2; DoStatusBars(status, player); } else { state=GSbattle; switch(round) { case 1: SsVabClose(round1_vab_id); break; case 2: SsVabClose(round2_vab_id); break; case 3: SsVabClose(round3_vab_id); break; case 4: SsVabClose(round4_vab_id); break; case 5: SsVabClose(round5_vab_id); break; default: break; } } break; case GSroundover: if((player1.x_speed==0) && (player1.y_speed==0) && (player2.x_speed==0) && (player2.y_speed==0)) { player=&player1; switch(player1.death) { case CDbullet: switch(death_animation1) { case 0: if(player->death_timer==0) SsUtKeyOn(agony_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 160); break; case 1: if(player->death_timer==0) SsUtKeyOn(gore_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 176); break; case 2: if(player->death_timer==0) SsUtKeyOn(agony_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 192); break; case 3: if(player->death_timer==0) SsUtKeyOn(agony_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 160); break; default: if(player->death_timer==0) SsUtKeyOn(gore_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 176); break; } break; case CDexplosion: switch(death_animation1) { case 0: if(player->death_timer==0) SsUtKeyOn(agony_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 144); break; case 1: if(player->death_timer==0) SsUtKeyOn(gore_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 176); break; case 2: if(player->death_timer==0) SsUtKeyOn(agony_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 192); break; case 3: if(player->death_timer==0) SsUtKeyOn(gore_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 208); break; default: if(player->death_timer==0) SsUtKeyOn(gore_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 176); break; } break; case CDsniperhead: if(player->death_timer==0) SsUtKeyOn(gore_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 128); break; case CDsniperbody: if(player->death_timer==0) SsUtKeyOn(gore_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 208); break; case CDnull: switch(death_animation1) { case 0: AnimateVictory(player,224); break; case 1: AnimateVictory(player,240); break; case 2: AnimateVictory(player,224); break; case 3: AnimateVictory(player,240); break; default: AnimateVictory(player,224); break; } break; default: break; } player=&player2; switch(player2.death) { case CDbullet: switch(death_animation2) { case 0: if(player->death_timer==0) SsUtKeyOn(agony_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 160); break; case 1: if(player->death_timer==0) SsUtKeyOn(gore_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 176); break; case 2: if(player->death_timer==0) SsUtKeyOn(agony_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 192); break; case 3: if(player->death_timer==0) SsUtKeyOn(agony_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 160); break; default: if(player->death_timer==0) SsUtKeyOn(gore_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 176); break; } break; case CDexplosion: switch(death_animation2) { case 0: if(player->death_timer==0) SsUtKeyOn(agony_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 144); break; case 1: if(player->death_timer==0) SsUtKeyOn(gore_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 176); break; case 2: if(player->death_timer==0) SsUtKeyOn(agony_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 192); break; case 3: if(player->death_timer==0) SsUtKeyOn(gore_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 208); break; default: if(player->death_timer==0) SsUtKeyOn(gore_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 176); break; } break; case CDsniperhead: if(player->death_timer==0) SsUtKeyOn(gore_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 128); break; case CDsniperbody: if(player->death_timer==0) SsUtKeyOn(gore_vab_id, 0, 0, 36, 0, 127, 127); AnimateDeath(player, 208); break; case CDnull: switch(death_animation2) { case 0: AnimateVictory(player,224); break; case 1: AnimateVictory(player,240); break; case 2: AnimateVictory(player,224); break; case 3: AnimateVictory(player,240); break; default: AnimateVictory(player,224); break; } break; default: break; } screen_timer++; } else { player=&player1; DeceleratePlayer(player); player=&player2; DeceleratePlayer(player); } explode=&explosion[0]; for(i=0;itimer) DoExplosions(explode); } sightshot=&sightshot1[0]; bullet_hit=&bullet_hit1[0]; vs_player=&player2; bullet=&bullet1[0]; for(i=0;i<3;i++,sightshot++) { if(sightshot->timer) DoSightShot(sightshot, vs_player); } for(i=0;itimer) DoBulletHit(bullet_hit, vs_player); } for(i=0;ilaunched) MoveBullet(bullet); } bullet_hit=&bullet_hit1[0]; vs_player=&player2; bullet=&bullet1[0]; for(i=0;ilaunched) DoBullets(bullet, vs_player, bullet_hit); } sightshot=&sightshot2[0]; bullet_hit=&bullet_hit2[0]; vs_player=&player1; bullet=&bullet2[0]; for(i=0;i<3;i++,sightshot++) { if(sightshot->timer) DoSightShot(sightshot, vs_player); } for(i=0;itimer) DoBulletHit(bullet_hit, vs_player); } for(i=0;ilaunched) MoveBullet(bullet); } bullet_hit=&bullet_hit2[0]; vs_player=&player1; bullet=&bullet2[0]; for(i=0;ilaunched) DoBullets(bullet, vs_player, bullet_hit); } player=&player1; status=&status1; DoStatusBars(status, player); player=&player2; status=&status2; DoStatusBars(status, player); for(i=0;i40) { srand(screen_timer); // seed random number generator! InitialiseBattle(); state=GSroundintro; screen_timer=0; round=1; SsVabClose(welcome_vab_id); // close vab data ammo_vab_id = SsVabTransfer( (u_char *) DATA_AMMO_VH, (u_char *) DATA_AMMO_VB, -1, 1); bullet_vab_id = SsVabTransfer( (u_char *) DATA_BULLET_VH, (u_char *) DATA_BULLET_VB, -1, 1); explode_vab_id = SsVabTransfer( (u_char *) DATA_EXPLODE_VH, (u_char *) DATA_EXPLODE_VB, -1, 1); sniper_vab_id = SsVabTransfer( (u_char *) DATA_SNIPER_VH, (u_char *) DATA_SNIPER_VB, -1, 1); } break; case GSbattle: DoPowerUps(); explode=&explosion[0]; for(i=0;itimer) DoExplosions(explode); } // PLAYER ONE GAME CONTROLS!!!! for(mainloop=0;mainloop<2;mainloop++) { switch(mainloop) { case 0: player=&player1; vs_player=&player2; bullet=&bullet1[0]; sightshot=&sightshot1[0]; bullet_hit=&bullet_hit1[0]; sight=&sight1; break; case 1: player=&player2; vs_player=&player1; bullet=&bullet2[0]; sightshot=&sightshot2[0]; bullet_hit=&bullet_hit2[0]; sight=&sight2; break; default: break; } for(i=0;i<3;i++,sightshot++) { if(sightshot->timer) DoSightShot(sightshot, vs_player); } for(i=0;itimer) DoBulletHit(bullet_hit, vs_player); } if(mainloop==0) GetPadDirection(player, PORT_ONE); else GetPadDirection(player, PORT_TWO); if(player->blast_timer) player->mode=PMblast; if((player->mode==PMbattle) && (player->prev_mode!=PMbattle)) { sight->x_speed=0; //reset sight speed variables to zero sight->y_speed=0; sight->timer=0; //reset timer so sight position is reset } switch(player->mode) { case PMsniper: if(player->fire) //if fire held { if((player->sniper_timer==0) && (player->sniper_shots>0)) { if(mainloop==0) sightshot=&sightshot1[0]; else sightshot=&sightshot2[0]; while(sightshot->timer) sightshot++; FireSniper(sightshot,vs_player,sight); player->sniper_timer=PLAYER_FRAME_RATE*6; player->sniper_shots--; SsUtKeyOn(sniper_vab_id, 0, 0, 36, 0, 127, 127); } } MoveSight(sight, player); AnimateSniper(player,sight); if(player->sniper_timer>PLAYER_FRAME_RATE*5) player->sprite.v+=24; if(player->sniper_timer) //decrement timer if over zero player->sniper_timer--; break; case PMbattle: MovePlayer(player, vs_player); //swapped round if(player->fire) //if fire held { if((player->bullet_gap==0) && (player->bullets>0)) { FireNormal(bullet,player); player->bullets--; SsUtKeyOn(bullet_vab_id, 0, 0, 36, 0, 127, 127); } } AnimateBattle(player); break; case PMstandfirm: if((player->x_speed==0) && (player->y_speed==0)) { AnimateStandFirm(player); } else DeceleratePlayer(player); if(player->fire) //if fire held { if((player->bullet_gap==0) && (player->bullets>0)) { FireNormal(bullet,player); player->bullets--; SsUtKeyOn(bullet_vab_id, 0, 0, 36, 0, 127, 127); } } break; case PMmine: if((player->x_speed==0) && (player->y_speed==0)) PlayerDropMine(player); else DeceleratePlayer(player); break; case PMblast: DeceleratePlayer(player); player->mode=PMblast; player->blast_timer--; break; default: break; } if(mainloop==0) bullet=&bullet1[0]; else bullet=&bullet2[0]; for(i=0;ilaunched) MoveBullet(bullet); } if(mainloop==0) { bullet=&bullet1[0]; bullet_hit=&bullet_hit1[0]; } else { bullet=&bullet2[0]; bullet_hit=&bullet_hit2[0]; } for(i=0;ilaunched) DoBullets(bullet, vs_player, bullet_hit); } powerup=&p_up[0]; CollectPowerUp(player); for(i=0, mine=&mines[0];idisplay) DoMines(mine, player); } for(i=0, explode=&explosion[0];itimer) DoPlayerExplosion(player, explode); } if(player->bullet_gap>0) player->bullet_gap--; if(player->fire_timer>0) player->fire_timer--; player->prev_mode=player->mode; //player->prev_face=player->dir_face; } DoPlayerCollision(player, vs_player); player=&player1; status=&status1; DoStatusBars(status, player); player=&player2; status=&status2; DoStatusBars(status, player); if(player1.energy_left!=0) player1.death=CDnull; if(player2.energy_left!=0) player2.death=CDnull; /* FntPrint("CHEMICAL WARFARE so far...\n"); FntPrint("BULLETS: %d\n",player1.bullets); FntPrint("SNIPER SHOTS: %d\n",player1.sniper_shots); FntPrint("GRENADES: %d\n",player1.grenades); FntPrint("MINES: %d\n",player1.mines); FntFlush(-1); */ if(player1.energy_left==0) { player1.lives_left--; death_animation1=rand()%4; death_animation2=rand()%4; screen_timer=0; gore_vab_id = SsVabTransfer( (u_char *) DATA_GORE_VH, (u_char *) DATA_GORE_VB, -1, 1); agony_vab_id = SsVabTransfer( (u_char *) DATA_AGONY_VH, (u_char *) DATA_AGONY_VB, -1, 1); state=GSroundover; } if(player2.energy_left==0) { player2.lives_left--; death_animation1=rand()%4; death_animation2=rand()%4; screen_timer=0; gore_vab_id = SsVabTransfer( (u_char *) DATA_GORE_VH, (u_char *) DATA_GORE_VB, -1, 1); agony_vab_id = SsVabTransfer( (u_char *) DATA_AGONY_VH, (u_char *) DATA_AGONY_VB, -1, 1); state=GSroundover; } if(((FSPadRead(PORT_ONE) & SPADstart) || (FSPadRead(PORT_TWO) & SPADstart)) && (screen_timer > 33)) { state=GSpause; screen_timer=0; } else screen_timer++; if(screen_timer > 500) screen_timer=100; break; } //end of switch-case } ResetGraph(3); } /************************************** INITIALISE REALLY DULL STUFF **************************************/ void InitialiseGraphics() { SetVideoMode(MODE_PAL); GsInitGraph(SCREEN_W, SCREEN_H, GsOFSGPU, 0, 0); GsDefDispBuff(0,0,0,SCREEN_H); //GsDISPENV.screen.w = 320; GsDISPENV.screen.h = 256; // Height can now be properly set to full PAL screen /* GsDISPENV.screen.x = ?; // These values set the screen offset position GsDISPENV.screen.y = ?; */ } void InitialiseOTs() { int i; for(i=0;i<2;i++) { WorldOT[i].length = OT_LENGTH; WorldOT[i].org = OTTags[i]; } } void InitialiseText() { FntLoad(960, 256); FntOpen( 100, 100, 320, 256, 0, 1024); } /*********************** CUSTOM FONT STUFF ***********************/ void printString(char *string, short x, short y) { FontSprite.x=x; FontSprite.y=y; while (*string) { if((*string!=' ') && (FontSprite.x > -25) && (FontSprite.x < 321)) //only draws onscreen chars - stops overwriting due to long char string { CharToUV(*string, &FontSprite.u, &FontSprite.v); // Get UV FontSprite.w=GetFontSpacing(*string); GsSortFastSprite(&FontSprite,&WorldOT[activeBuff],0); } FontSprite.x+=GetFontSpacing(*string); string++; } } void CharToUV(char s, char *u, char *v) { switch(s) { case 'A': *u=0; *v=0; break; case 'B': *u=17; *v=0; break; case 'C': *u=33; *v=0; break; case 'D': *u=48; *v=0; break; case 'E': *u=65; *v=0; break; case 'F': *u=80; *v=0; break; case 'G': *u=95; *v=0; break; case 'H': *u=0; *v=19; break; case 'I': *u=18; *v=19; break; case 'J': *u=28; *v=19; break; case 'K': *u=43; *v=19; break; case 'L': *u=62; *v=19; break; case 'M': *u=76; *v=19; break; case 'N': *u=95; *v=19; break; case 'O': *u=0; *v=38; break; case 'P': *u=16; *v=38; break; case 'Q': *u=32; *v=38; break; case 'R': *u=49; *v=38; break; case 'S': *u=66; *v=38; break; case 'T': *u=80; *v=38; break; case 'U': *u=96; *v=38; break; case 'V': *u=0; *v=58; break; case 'W': *u=16; *v=58; break; case 'X': *u=38; *v=58; break; case 'Y': *u=55; *v=58; break; case 'Z': *u=71; *v=58; break; case '0': *u=0; *v=77; break; case '1': *u=15; *v=77; break; case '2': *u=25; *v=77; break; case '3': *u=38; *v=77; break; case '4': *u=52; *v=77; break; case '5': *u=67; *v=77; break; case '6': *u=0; *v=97; break; case '7': *u=14; *v=97; break; case '8': *u=26; *v=97; break; case '9': *u=40; *v=97; break; case '!': *u=0; *v=117; break; case '"': *u=9; *v=117; break; case '-': *u=20; *v=117; break; case ':': *u=33; *v=117; break; case '?': *u=43; *v=117; break; case '&': *u=57; *v=117; break; default: break; } } short GetFontSpacing(char s) { switch(s) { case 'A': return(17); break; case 'B': return(16); break; case 'C': return(15); break; case 'D': return(17); break; case 'E': return(15); break; case 'F': return(15); break; case 'G': return(15); break; case 'H': return(18); break; case 'I': return(10); break; case 'J': return(15); break; case 'K': return(19); break; case 'L': return(14); break; case 'M': return(19); break; case 'N': return(17); break; case 'O': return(16); break; case 'P': return(16); break; case 'Q': return(17); break; case 'R': return(17); break; case 'S': return(14); break; case 'T': return(16); break; case 'U': return(17); break; case 'V': return(16); break; case 'W': return(22); break; case 'X': return(17); break; case 'Y': return(16); break; case 'Z': return(14); break; case '1': return(10); break; case '2': return(13); break; case '3': return(14); break; case '4': return(14); break; case '5': return(13); break; case '6': return(14); break; case '7': return(12); break; case '8': return(14); break; case '9': return(15); break; case '0': return(15); break; case ' ': return(15); break; case '!': return(8); break; case '"': return(11); break; case '-': return(14); break; case ':': return(9); break; case '?': return(13); break; case '&': return(20); break; default: break; } } /*********************** MAIN FUNCTIONS ***********************/ void InitialiseBattle(void) { // Init background! InitBG(); // Init small logo InitSmallLogo(); //Init Status screens status=&status1; InitStatus1(status); status=&status2; InitStatus2(status); // Init players player=&player1; InitPlayer1(player, 105, 120); player=&player2; InitPlayer2(player, 205, 120); //Init bullets bullet=&bullet1[0]; InitBullets(bullet); bullet=&bullet2[0]; InitBullets(bullet); //Init bullet hits bullet_hit=&bullet_hit1[0]; InitBulletHits(bullet_hit); bullet_hit=&bullet_hit2[0]; InitBulletHits(bullet_hit); //Init sights sight=&sight1; InitSight1(sight); sight=&sight2; InitSight2(sight); //Init mines mine=&mines[0]; InitMines(mine); //Init explosions explode=&explosion[0]; InitExplosions(explode); // Init Sightshot sightshot=&sightshot1[0]; InitSightShot(sightshot); sightshot=&sightshot2[0]; InitSightShot(sightshot); } /***************************/ void DrawBattleScreen(void) { int i; //for loops /*SORT SPRITES INTO ORDERING TABLE (items at bottom of list are drawn first) */ GsSortFastSprite(&SmallLogo,&WorldOT[activeBuff],0); //STATUS SCREENS STUFF for P1 GsSortFastSprite(&status1.lives,&WorldOT[activeBuff],0); GsSortFastSprite(&status1.ammo1,&WorldOT[activeBuff],0); GsSortFastSprite(&status1.ammo2,&WorldOT[activeBuff],0); GsSortFastSprite(&status1.sniper1,&WorldOT[activeBuff],0); GsSortFastSprite(&status1.sniper2,&WorldOT[activeBuff],0); GsSortFastSprite(&status1.mines1,&WorldOT[activeBuff],0); GsSortFastSprite(&status1.mines2,&WorldOT[activeBuff],0); GsSortFastSprite(&status1.menubar,&WorldOT[activeBuff],0); GsSortBoxFill(&status1.energy,&WorldOT[activeBuff],0); //STATUS SCREENS STUFF for P2 GsSortFastSprite(&status2.lives,&WorldOT[activeBuff],0); GsSortFastSprite(&status2.ammo1,&WorldOT[activeBuff],0); GsSortFastSprite(&status2.ammo2,&WorldOT[activeBuff],0); GsSortFastSprite(&status2.sniper1,&WorldOT[activeBuff],0); GsSortFastSprite(&status2.sniper2,&WorldOT[activeBuff],0); GsSortFastSprite(&status2.mines1,&WorldOT[activeBuff],0); GsSortFastSprite(&status2.mines2,&WorldOT[activeBuff],0); GsSortFastSprite(&status2.menubar,&WorldOT[activeBuff],0); GsSortBoxFill(&status2.energy,&WorldOT[activeBuff],0); // EXPLOSIONS! for(i=0,explode=&explosion[0];itimer) GsSortFastSprite(&explode->sprite,&WorldOT[activeBuff],0); //if explosion 'on', display! } //SIGHT "SHOT" EFFECTS for(i=0;i<3;i++) { if(sightshot1[i].timer) GsSortFastSprite(&sightshot1[i].sprite,&WorldOT[activeBuff],0); } for(i=0;i<3;i++) { if(sightshot2[i].timer) GsSortFastSprite(&sightshot2[i].sprite,&WorldOT[activeBuff],0); } //BULLET HIT EFFECTS! for(i=0;itimer) GsSortFastSprite(&explode->sprite,&WorldOT[activeBuff],0); //if explosion 'on', display! } //SIGHT "SHOT" EFFECTS for(i=0;i<3;i++) { if(sightshot1[i].timer) GsSortFastSprite(&sightshot1[i].sprite,&WorldOT[activeBuff],0); } for(i=0;i<3;i++) { if(sightshot2[i].timer) GsSortFastSprite(&sightshot2[i].sprite,&WorldOT[activeBuff],0); } //BULLET HIT EFFECTS! for(i=0;ifire=1; else player->fire=0; if((fpadstatus & SPADl1) || (player->sniper_timer>PLAYER_FRAME_RATE*5))//hold L1 for sniper mode (change it to toggle?) { if(player->drop_mine==0) player->mode=PMsniper; } else if(fpadstatus & SPADr1) { player->mode=PMstandfirm; } else { player->mode=PMbattle; player->death_timer=0; if (player->prev_mode==PMstandfirm) // Fixes "sliding" problem { player->prev_face=PDnull; } } // Do player_mine thing! if((fpadstatus & SPADtr) && (player->drop_mine==0) && (player->mines>0)) player->drop_mine=DROP_MINE_TIMER; if(player->drop_mine>0) player->mode=PMmine; //Assign PAD_DIR enum values depending on the stick direction (oo-er) if((xjoy==0) && (yjoy==0)) player->dir_move = PDnull; if((xjoy==0) && (yjoy==1)) player->dir_move = PDup; if((xjoy==0) && (yjoy==-1)) player->dir_move = PDdown; if((xjoy==-1) && (yjoy==0)) player->dir_move = PDleft; if((xjoy==1) && (yjoy==0)) player->dir_move = PDright; if((xjoy==-1) && (yjoy==1)) player->dir_move = PDup_left; if((xjoy==1) && (yjoy==1)) player->dir_move = PDup_right; if((xjoy==-1) && (yjoy==-1)) player->dir_move = PDdown_left; if((xjoy==1) && (yjoy==-1)) player->dir_move = PDdown_right; } /********************************/ void DoStatusBars(STATUS *status, PLAYER *player) { short energy, u1, v1, *u, *v; short green[] = {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 250, 245, 239, 234, 228, 223, 217, 211, 206, 200, 195, 189, 184, 178, 173, 167, 161, 156, 150, 145, 139, 134, 128, 122, 117, 111, 106, 100, 95, 89, 83, 78, 72, 67, 61, 56, 50, 45, 39, 34, 28, 22, 17, 11, 6, 0, 0}; short blue[] = {250, 245, 239, 234, 228, 223, 217, 211, 206, 200, 195, 189, 184, 178, 173, 167, 161, 156, 150, 145, 139, 134, 128, 122, 117, 111, 106, 100, 95, 89, 83, 78, 72, 67, 61, 56, 50, 45, 39, 34, 28, 22, 17, 11, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Init pointers u=&u1; v=&v1; //Keep bar empty if(player->energy_left>MAX_ENERGY) player->energy_left=0; status->bullets=player->bullets; status->sniper_shots=player->sniper_shots; status->mines=player->mines; status->lives_left=player->lives_left; status->energy_left=player->energy_left; GetStatusUV((status->bullets/10), u, v); status->ammo1.u=*u; status->ammo1.v=*v; GetStatusUV((status->bullets%10), u, v); status->ammo2.u=*u; status->ammo2.v=*v; GetStatusUV((status->sniper_shots/10), u, v); status->sniper1.u=*u; status->sniper1.v=*v; GetStatusUV((status->sniper_shots%10), u, v); status->sniper2.u=*u; status->sniper2.v=*v; GetStatusUV((status->mines/10), u, v); status->mines1.u=*u; status->mines1.v=*v; GetStatusUV((status->mines%10), u, v); status->mines2.u=*u; status->mines2.v=*v; GetStatusUV((status->lives_left), u, v); status->lives.u=*u; status->lives.v=*v; status->energy.w=(status->energy_left>>12); energy=92-status->energy.w; // RGB valuse depend on amount of NRG left... status->energy.g=green[energy]; status->energy.b=blue[energy]; } /**********************************/ void GetStatusUV(short item, short *u, short *v) { switch(item) { case 0: *u=0; *v=0; break; case 1: *u=10; *v=0; break; case 2: *u=20; *v=0; break; case 3: *u=30; *v=0; break; case 4: *u=40; *v=0; break; case 5: *u=50; *v=0; break; case 6: *u=60; *v=0; break; case 7: *u=70; *v=0; break; case 8: *u=80; *v=0; break; case 9: *u=90; *v=0; break; default: break; } } /********************************/ void DoPlayerCollision(PLAYER *player, PLAYER *vs_player) { int new_x_speed, new_y_speed; if(CheckPlayerCollision(player, vs_player)) { new_x_speed=(player->x_speed + vs_player->x_speed)/2; new_y_speed=(player->y_speed + vs_player->y_speed)/2; player->x_speed=new_x_speed; player->y_speed=new_y_speed; vs_player->x_speed=new_x_speed; vs_player->y_speed=new_y_speed; playercollide=1; } else playercollide=0; } /********************************/ void DoBullets(BULLET *bullet, PLAYER *vs_player, BULLET_HIT *bullet_hit) { if(CheckPlayerBullet(vs_player, bullet)) { bullet->launched=0; vs_player->energy_left-=BULLET_DAMAGE; vs_player->death=CDbullet; while(bullet_hit->timer) bullet_hit++; bullet_hit->sprite.x=(bullet->sprite.x-4); // prob. needs fixed bullet_hit->sprite.y=(bullet->sprite.y-4); // ditto bullet_hit->timer=BULLET_TIMER; bullet_hit->sprite.u=0; bullet_hit->sprite.v=22; bullet_hit->x_diff=(bullet_hit->sprite.x)-(vs_player->sprite.x); bullet_hit->y_diff=(bullet_hit->sprite.y)-(vs_player->sprite.y); } } /********************************/ DoBulletHit(BULLET_HIT *bullet_hit, PLAYER *vs_player) { switch(bullet_hit->timer) { case 10: bullet_hit->sprite.u+=11; bullet_hit->timer--; break; case 8: bullet_hit->sprite.u+=11; bullet_hit->timer--; break; case 6: bullet_hit->sprite.u=0; bullet_hit->sprite.v+=11; bullet_hit->timer--; break; case 4: bullet_hit->sprite.u+=11; bullet_hit->timer--; break; case 2: bullet_hit->sprite.u+=11; bullet_hit->timer--; break; default: bullet_hit->timer--; break; } bullet_hit->sprite.x=(vs_player->sprite.x)+(bullet_hit->x_diff); bullet_hit->sprite.y=(vs_player->sprite.y)+(bullet_hit->y_diff); } /********************************/ void DoSightShot(SIGHTSHOT *sightshot, PLAYER *vs_player) { switch(sightshot->timer) { case 20: sightshot->sprite.u+=11; sightshot->timer--; break; case 16: sightshot->sprite.u+=11; sightshot->timer--; break; case 12: sightshot->sprite.u=0; sightshot->sprite.v+=11; sightshot->timer--; break; case 8: sightshot->sprite.u+=11; sightshot->timer--; break; case 4: sightshot->sprite.u+=11; sightshot->timer--; break; default: sightshot->timer--; break; } if(sightshot->type==SThit) { sightshot->sprite.x=(vs_player->sprite.x)+(sightshot->x_diff); sightshot->sprite.y=(vs_player->sprite.y)+(sightshot->y_diff); } } /********************************/ void DoPowerUps(void) { short i, a, random; // 'a' holds the current powerup's number, 'random' the random no.! //These arrays hold the X and Y positions for dumping random powerups... short random_x_axis[18]= { 16,32,48,64,80,96,112,128,144,160,176,192,208,224,240,256,282,298 }; short random_y_axis[14]= { 32,48,64,80,96,112,128,144,160,176,192,208,224, 240 }; if(powerup_cntr) //if powerup countdown is over zero, powerup_cntr--; //decrement counter //Decrement powerup structs' timers if over zero for(i=0;itimer) powerup++; random=rand()%20; switch(random) { case 0: powerup->contents=PUbullets; break; case 1: powerup->contents=PUsniper; break; case 2: powerup->contents=PUbullets; break; case 3: powerup->contents=PUmines; break; case 4: powerup->contents=PUhealth; break; case 5: powerup->contents=PUbullets; break; case 6: powerup->contents=PUbullets; break; case 7: powerup->contents=PUbullets; break; case 8: // CHANGE TO BOOBY-TRAPPED ICON..? powerup->contents=PUbullets; break; case 9: powerup->contents=PUsniper; break; case 10: powerup->contents=PUbullets; break; case 11: powerup->contents=PUhealth; break; case 12: powerup->contents=PUmines; break; case 13: powerup->contents=PUbullets; break; case 14: powerup->contents=PUsniper; break; case 15: powerup->contents=PUbullets; break; case 16: powerup->contents=PUhealth; break; case 17: powerup->contents=PUbullets; break; case 18: powerup->contents=PUsniper; break; case 19: powerup->contents=PUsniper; break; default: powerup->contents=PUbullets; break; } random=rand()%18; powerup->sprite.x=random_x_axis[random]; random=rand()%14; powerup->sprite.y=random_y_axis[random]; // This part stops powerups appearing on the same X OR Y axis! for(i=0;isprite.x) && (p_up[i].sprite.y==powerup->sprite.y) && (p_up[i].timer>0)) { random=rand()%18; powerup->sprite.x=random_x_axis[random]; random=rand()%14; powerup->sprite.y=random_y_axis[random]; } } } InitPowerup(powerup); powerup_cntr=POWERUP_FREQ; } } /********************************/ void CollectPowerUp(PLAYER *player) { int i; for (i=0;i0) { powerup=&p_up[i]; if(CheckPlayerPowerup(player, powerup)) { switch(powerup->contents) { case PUbullets: if(player->bulletsbullets+=POWERUP_BULLETS; if(player->bullets>MAX_BULLETS) player->bullets=MAX_BULLETS; powerup->timer=0; } break; case PUsniper: if(player->sniper_shotssniper_shots+=POWERUP_SNIPER; if(player->sniper_shots>MAX_SNIPER) player->sniper_shots=MAX_SNIPER; powerup->timer=0; } break; case PUmines: if(player->minesmines+=POWERUP_MINES; if(player->mines>MAX_MINES) player->mines=MAX_MINES; powerup->timer=0; } break; case PUhealth: if(player->energy_leftenergy_left+=POWERUP_HEALTH; if(player->energy_left>MAX_ENERGY) player->energy_left=MAX_ENERGY; powerup->timer=0; } break; case PUgasmask: //DO some funky gasmask thing! break; default: break; } } } } } int CheckPlayerPowerup(PLAYER *player,POWERUP *powerup) { if(Check((player->sprite.x + 8) - 7, (player->sprite.y + 12) - 11, (player->sprite.x + 8) + 7, (player->sprite.y + 12) + 11, (powerup->sprite.x + 8) - powerup->sprite.w/2, (powerup->sprite.y + 8) - powerup->sprite.h/2, (powerup->sprite.x + 8) + powerup->sprite.w/2, (powerup->sprite.y + 8) + powerup->sprite.h/2 )) return(1); else return(0); } int CheckPlayerMine(PLAYER *player, MINE *mine) { if(Check((player->sprite.x + 8) - 6, (player->sprite.y + 20) - 4, (player->sprite.x + 8) + 6, (player->sprite.y + 20) + 4, (mine->sprite.x + 6) - 5, (mine->sprite.y + 4) - 3, (mine->sprite.x + 6) + 5, (mine->sprite.y + 4) + 3 )) return(1); else return(0); } int CheckPlayerExplosion(PLAYER *player, EXPLOSION *explode) { if(Check((player->sprite.x + 8) - 7, (player->sprite.y + 12) - 11, (player->sprite.x + 8) + 7, (player->sprite.y + 12) + 11, (explode->sprite.x+30) - 28, (explode->sprite.y+30) - 28, (explode->sprite.x+30) + 28, (explode->sprite.y+30) + 28 )) return(1); else return(0); } /*************************/ CheckPlayerSniperBodyshot(PLAYER *vs_player, SIGHT *sight) // DO A FIX FOR PLAYER DROPPING MINE ANIMATION (using mine_timer numbers?) { if(Check((vs_player->sprite.x + 8) - 6, (vs_player->sprite.y + 13) - 5, (vs_player->sprite.x + 8) + 3, (vs_player->sprite.y + 13) + 6, (sight->sprite.x+5) - 2, (sight->sprite.y+5) - 2, (sight->sprite.x+5) + 2, (sight->sprite.y+5) + 2 )) return(1); else return(0); } CheckPlayerSniperHeadshot(PLAYER *vs_player, SIGHT *sight) // DO A FIX FOR PLAYER DROPPING MINE ANIMATION (using mine_timer numbers?) { if(Check((vs_player->sprite.x + 8) - 3, (vs_player->sprite.y + 6) - 3, (vs_player->sprite.x + 8) + 3, (vs_player->sprite.y + 6) + 3, (sight->sprite.x+5) - 2, (sight->sprite.y+5) - 2, (sight->sprite.x+5) + 2, (sight->sprite.y+5) + 2 )) return(1); else return(0); } int CheckPlayerCollision(PLAYER *player, PLAYER *vs_player) { if(Check((player->sprite.x + 8) - 5, (player->sprite.y + 12) - 11, (player->sprite.x + 8) + 5, (player->sprite.y + 12) + 11, (vs_player->sprite.x + 8) - 5, (vs_player->sprite.y + 12) - 11, (vs_player->sprite.x + 8) + 5, (vs_player->sprite.y + 12) + 11 )) return(1); else return(0); } int CheckPlayerBullet(PLAYER *vs_player, BULLET *bullet) { if(Check((bullet->sprite.x + 1) - 1, (bullet->sprite.y + 1) - 1, (bullet->sprite.x + 1) + 1, (bullet->sprite.y + 1) + 1, (vs_player->sprite.x + 8) - 5, (vs_player->sprite.y + 12) - 11, (vs_player->sprite.x + 8) + 5, (vs_player->sprite.y + 12) + 11 )) return(1); else return(0); } int CheckSniperMine(MINE *mine, SIGHT *sight) { if(Check((mine->sprite.x + 6) - 5, (mine->sprite.y + 4) - 3, (mine->sprite.x + 6) + 5, (mine->sprite.y + 4) + 3, (sight->sprite.x+5) - 2, (sight->sprite.y+5) - 2, (sight->sprite.x+5) + 2, (sight->sprite.y+5) + 2 )) return(1); else return(0); } /******************************************************************** CORE COLLISION DETECTION FUNCTION - all the various collision detection routines point to this puppy! - ********************************************************************/ int Check(short One_x_minus, short One_y_minus, short One_x_plus, short One_y_plus, short Two_x_minus, short Two_y_minus, short Two_x_plus, short Two_y_plus) { if((Two_x_minus <= One_x_plus) & (Two_x_plus >= One_x_minus) & (Two_y_minus <= One_y_plus) & (Two_y_plus >= One_y_minus)) return(1); else return(0); } /************************** EXPLOSION STUFF **************************/ void StartExplosion(short x, short y, enum EXP_TYPE type) { explode=&explosion[0]; while(explode->timer) explode++; explode->sprite.x=x; explode->sprite.y=y; explode->timer=EXPLOSION_TIMER; explode->type=type; SsUtKeyOn(explode_vab_id, 0, 0, 36, 0, 127, 127); } void DoExplosions(EXPLOSION *explode) { switch(explode->timer) { case 44: explode->sprite.u=60; explode->sprite.v=0; explode->timer--; break; case 40: explode->sprite.u=120; explode->sprite.v=0; explode->timer--; break; case 36: explode->sprite.u=180; explode->sprite.v=0; explode->timer--; break; case 32: explode->sprite.u=0; explode->sprite.v=60; explode->timer--; break; case 28: explode->sprite.u=60; explode->sprite.v=60; explode->timer--; break; case 24: explode->sprite.u=120; explode->sprite.v=60; explode->timer--; break; case 20: explode->sprite.u=180; explode->sprite.v=60; explode->timer--; break; case 16: explode->sprite.u=0; explode->sprite.v=120; explode->timer--; break; case 12: explode->sprite.u=60; explode->sprite.v=120; explode->timer--; break; case 8: explode->sprite.u=120; explode->sprite.v=120; explode->timer--; break; case 4: explode->sprite.u=180; explode->sprite.v=120; explode->timer--; break; case 1: explode->sprite.u=0; explode->sprite.v=0; explode->timer--; break; default: explode->timer--; break; } } void DoPlayerExplosion(PLAYER *player, EXPLOSION *explode) // Checks if player is in explosion and 'blasts' them! { short x; short y; if(CheckPlayerExplosion(player, explode)) { short x_diff=(player->sprite.x+8)-(explode->sprite.x+30); short y_diff=(player->sprite.y+20)-(explode->sprite.y+30); x=x_diff; y=y_diff; if((x_diff<0) && (y_diff<0)) //up-left corner { if(y>=(x/2)) // player blown left { player->x_speed=-BLAST_FORCE; } else if(y>=(x*2)) //player blown up-left { player->x_speed=-BLAST_FORCE; player->y_speed=-BLAST_FORCE; } else //player blown up { player->y_speed=-BLAST_FORCE; } } if((x_diff>=0) && (y_diff<0)) //up right corner { if((-y)>=(x*2)) //player blown up { player->y_speed=-BLAST_FORCE; } else if((-y)>=(x/2)) //player blown up-right { player->x_speed=BLAST_FORCE; player->y_speed=-BLAST_FORCE; } else //player blown right { player->x_speed=BLAST_FORCE; } } if((x_diff<0) && (y_diff>=0)) //down left corner { if((-y)>=(x/2)) //player blown left { player->x_speed=-BLAST_FORCE; } else if((-y)>=(x*2)) //player blown down_left { player->x_speed=-BLAST_FORCE; player->y_speed=BLAST_FORCE; } else //player blown down { player->y_speed=BLAST_FORCE; } } if((x_diff>=0) && (y_diff>=0)) //down right corner { if(y<=(x/2)) //player blown right { player->x_speed=BLAST_FORCE; } else if(y<=(x*2)) //player blown down-right { player->x_speed=BLAST_FORCE; player->y_speed=BLAST_FORCE; } else // player blown down { player->y_speed=BLAST_FORCE; } } // Sort out player animation for blast effect if(player->sprite.u>112) //if in sniper mode, reset sprite animation to equiv. normal. player->sprite.u-=128; if(player->sprite.v>168) //if dropping mine, reset anim. to normal { player->sprite.u=64; player->sprite.v=0; } if(player->sprite.v>72) //if firing, reset animation to not firing player->sprite.v-=96; player->timer=0; player->bullet_gap=0; player->sniper_timer=0; player->death=CDexplosion; player->blast_timer=BLAST_TIMER; player->energy_left-=EXPLOSION_DAMAGE; } } /************************** MINE STUFF **************************/ void PlayerDropMine(PLAYER *player) { mine=&mines[0]; while(mine->display) mine++; switch(player->drop_mine) //NOTE: replace sums with integers for final version { case DROP_MINE_TIMER: player->sprite.u=0; player->sprite.v=192; break; case (DROP_MINE_TIMER-5): player->sprite.u=16; break; case (DROP_MINE_TIMER-10): player->sprite.u+=16; break; case (DROP_MINE_TIMER-15): player->sprite.u+=16; break; case (DROP_MINE_TIMER-20): player->sprite.u+=16; break; case (DROP_MINE_TIMER-25): player->sprite.u+=16; break; case (DROP_MINE_TIMER-30): player->sprite.u+=16; break; case (DROP_MINE_TIMER-35): player->sprite.u+=16; break; case (DROP_MINE_TIMER-40): //MINE is actually dropped HERE!!!! player->sprite.u+=16; mine->sprite.x=(player->sprite.x+2); mine->sprite.y=(player->sprite.y+16); mine->timer=MINE_TIMER; mine->display=1; player->mines-=1; break; case (DROP_MINE_TIMER-45): player->sprite.u+=16; break; case (DROP_MINE_TIMER-50): player->sprite.u+=16; break; case (DROP_MINE_TIMER-55): player->sprite.u+=16; break; case (DROP_MINE_TIMER-60): player->sprite.u+=16; break; case 1: switch(player->dir_move) { case PDup: player->sprite.u=0; break; case PDdown: player->sprite.u=64; break; case PDleft: player->sprite.u=96; break; case PDright: player->sprite.u=32; break; case PDup_left: player->sprite.u=112; break; case PDup_right: player->sprite.u=16; break; case PDdown_left: player->sprite.u=80; break; case PDdown_right: player->sprite.u=48; break; case PDnull: player->sprite.u=64; break; default: player->sprite.u=64; break; } player->mode=PMbattle; player->sprite.v=0; player->dir_face=PDdown; player->timer=0; player->dir_move=PDnull; player->prev_face=PDnull; break; default: break; } if(player->drop_mine>0) // This can prob. go at cleanup stage player->drop_mine--; } /*******************************/ void DoMines(MINE *mine, PLAYER *player) { if(mine->timer>0) mine->timer--; else { if(CheckPlayerMine(player, mine)) { mine->display=0; StartExplosion((mine->sprite.x-24), (mine->sprite.y-26), EXPmine); //fix positions so in middle! } } } /***************************** ANIMATION FUNCTIONS *****************************/ void AnimateBattle(PLAYER *player) //animate player in regular (battle) mode { if(player->sprite.v > 72) player->sprite.v-=96; if(player->sprite.u > 112) //if previously in sniper mode... player->sprite.u-=128; //move back to battle mode switch(player->dir_move) { case PDup: player->dir_face=PDup; if(player->dir_move!=player->prev_face) { player->prev_face=player->dir_move; player->timer=0; player->sprite.u=0; player->sprite.v=24; } else if(player->timer==PLAYER_FRAME_RATE) player->sprite.v+=24; else if(player->timer==PLAYER_FRAME_RATE*2) player->sprite.v+=24; else if(player->timer==PLAYER_FRAME_RATE*3) player->sprite.v=0; else if(player->timer==PLAYER_FRAME_RATE*4) { player->sprite.v=24; player->timer=0; } if((player->fire) && (player->bullets>0)) player->sprite.v+=96; player->timer++; break; case PDdown: player->dir_face=PDdown; if(player->dir_move!=player->prev_face) { player->prev_face=player->dir_move; player->timer=0; player->sprite.u=64; player->sprite.v=24; } else if(player->timer==PLAYER_FRAME_RATE) player->sprite.v+=24; else if(player->timer==PLAYER_FRAME_RATE*2) player->sprite.v+=24; else if(player->timer==PLAYER_FRAME_RATE*3) player->sprite.v=0; else if(player->timer==PLAYER_FRAME_RATE*4) { player->sprite.v=24; player->timer=0; } if((player->fire) && (player->bullets>0)) player->sprite.v+=96; player->timer++; break; case PDleft: player->dir_face=PDleft; if(player->dir_move!=player->prev_face) { player->prev_face=player->dir_move; player->timer=0; player->sprite.u=96; player->sprite.v=24; } else if(player->timer==PLAYER_FRAME_RATE) player->sprite.v+=24; else if(player->timer==PLAYER_FRAME_RATE*2) player->sprite.v+=24; else if(player->timer==PLAYER_FRAME_RATE*3) player->sprite.v=0; else if(player->timer==PLAYER_FRAME_RATE*4) { player->sprite.v=24; player->timer=0; } if((player->fire) && (player->bullets>0)) player->sprite.v+=96; player->timer++; break; case PDright: player->dir_face=PDright; if(player->dir_move!=player->prev_face) { player->prev_face=player->dir_move; player->timer=0; player->sprite.u=32; player->sprite.v=24; } else if(player->timer==PLAYER_FRAME_RATE) player->sprite.v+=24; else if(player->timer==PLAYER_FRAME_RATE*2) player->sprite.v+=24; else if(player->timer==PLAYER_FRAME_RATE*3) player->sprite.v=0; else if(player->timer==PLAYER_FRAME_RATE*4) { player->sprite.v=24; player->timer=0; } if((player->fire) && (player->bullets>0)) player->sprite.v+=96; player->timer++; break; case PDup_left: player->dir_face=PDup_left; if(player->dir_move!=player->prev_face) { player->prev_face=player->dir_move; player->timer=0; player->sprite.u=112; player->sprite.v=24; } else if(player->timer==PLAYER_FRAME_RATE) player->sprite.v+=24; else if(player->timer==PLAYER_FRAME_RATE*2) player->sprite.v+=24; else if(player->timer==PLAYER_FRAME_RATE*3) player->sprite.v=0; else if(player->timer==PLAYER_FRAME_RATE*4) { player->sprite.v=24; player->timer=0; } if((player->fire) && (player->bullets>0)) player->sprite.v+=96; player->timer++; break; case PDup_right: player->dir_face=PDup_right; if(player->dir_move!=player->prev_face) { player->prev_face=player->dir_move; player->timer=0; player->sprite.u=16; player->sprite.v=24; } else if(player->timer==PLAYER_FRAME_RATE) player->sprite.v+=24; else if(player->timer==PLAYER_FRAME_RATE*2) player->sprite.v+=24; else if(player->timer==PLAYER_FRAME_RATE*3) player->sprite.v=0; else if(player->timer==PLAYER_FRAME_RATE*4) { player->sprite.v=24; player->timer=0; } if((player->fire) && (player->bullets>0)) player->sprite.v+=96; player->timer++; break; case PDdown_left: player->dir_face=PDdown_left; if(player->dir_move!=player->prev_face) { player->prev_face=player->dir_move; player->timer=0; player->sprite.u=80; player->sprite.v=24; } else if(player->timer==PLAYER_FRAME_RATE) player->sprite.v+=24; else if(player->timer==PLAYER_FRAME_RATE*2) player->sprite.v+=24; else if(player->timer==PLAYER_FRAME_RATE*3) player->sprite.v=0; else if(player->timer==PLAYER_FRAME_RATE*4) { player->sprite.v=24; player->timer=0; } if((player->fire) && (player->bullets>0)) player->sprite.v+=96; player->timer++; break; case PDdown_right: player->dir_face=PDdown_right; if(player->dir_move!=player->prev_face) { player->prev_face=player->dir_move; player->timer=0; player->sprite.u=48; player->sprite.v=24; } else if(player->timer==PLAYER_FRAME_RATE) player->sprite.v+=24; else if(player->timer==PLAYER_FRAME_RATE*2) player->sprite.v+=24; else if(player->timer==PLAYER_FRAME_RATE*3) player->sprite.v=0; else if(player->timer==PLAYER_FRAME_RATE*4) { player->sprite.v=24; player->timer=0; } if((player->fire) && (player->bullets>0)) player->sprite.v+=96; player->timer++; break; case PDnull: if(player->dir_move!=player->prev_face) { player->prev_face=player->dir_move; player->timer=0; player->sprite.v=0; } else if(player->timer==PLAYER_FRAME_RATE) player->sprite.v+=48; else if(player->timer==PLAYER_FRAME_RATE*2) { player->sprite.v=0; player->timer=0; } if((player->fire) && (player->bullets>0)) { player->sprite.v+=96; player->timer++; } if(!player->fire) { player->timer=0; player->sprite.v=0; } break; default: break; } if(player->sniper_timer) //stops "cheating" by tapping L1! player->sniper_timer--; } /**************************************/ void AnimateStandFirm(PLAYER *player) //animate player in still (standfirm) mode { if(player->sprite.v > 72) //if previously firing, stop firing player->sprite.v-=96; if(player->sprite.u > 112) //if previously in sniper mode... player->sprite.u-=128; //move back to battle mode if (player->prev_mode==PMbattle) //fixes "pausing animation" problem { player->prev_face=PDnull; } switch(player->dir_move) { case PDup: player->dir_face=PDup; if(player->dir_move!=player->prev_face) { player->prev_face=player->dir_move; player->timer=0; player->sprite.u=0; player->sprite.v=0; } else if(player->timer==PLAYER_FRAME_RATE) player->sprite.v+=48; else if(player->timer==PLAYER_FRAME_RATE*2) { player->sprite.v=0; player->timer=0; } if((player->fire) && (player->bullets>0)) player->sprite.v+=96; player->timer++; break; case PDdown: player->dir_face=PDdown; if(player->dir_move!=player->prev_face) { player->prev_face=player->dir_move; player->timer=0; player->sprite.u=64; player->sprite.v=0; } else if(player->timer==PLAYER_FRAME_RATE) player->sprite.v+=48; else if(player->timer==PLAYER_FRAME_RATE*2) { player->sprite.v=0; player->timer=0; } if((player->fire) && (player->bullets>0)) player->sprite.v+=96; player->timer++; break; case PDleft: player->dir_face=PDleft; if(player->dir_move!=player->prev_face) { player->prev_face=player->dir_move; player->timer=0; player->sprite.u=96; player->sprite.v=0; } else if(player->timer==PLAYER_FRAME_RATE) player->sprite.v+=48; else if(player->timer==PLAYER_FRAME_RATE*2) { player->sprite.v=0; player->timer=0; } if((player->fire) && (player->bullets>0)) player->sprite.v+=96; player->timer++; break; case PDright: player->dir_face=PDright; if(player->dir_move!=player->prev_face) { player->prev_face=player->dir_move; player->timer=0; player->sprite.u=32; player->sprite.v=0; } else if(player->timer==PLAYER_FRAME_RATE) player->sprite.v+=48; else if(player->timer==PLAYER_FRAME_RATE*2) { player->sprite.v=0; player->timer=0; } if((player->fire) && (player->bullets>0)) player->sprite.v+=96; player->timer++; break; case PDup_left: player->dir_face=PDup_left; if(player->dir_move!=player->prev_face) { player->prev_face=player->dir_move; player->timer=0; player->sprite.u=112; player->sprite.v=0; } else if(player->timer==PLAYER_FRAME_RATE) player->sprite.v+=48; else if(player->timer==PLAYER_FRAME_RATE*2) { player->sprite.v=0; player->timer=0; } if((player->fire) && (player->bullets>0)) player->sprite.v+=96; player->timer++; break; case PDup_right: player->dir_face=PDup_right; if(player->dir_move!=player->prev_face) { player->prev_face=player->dir_move; player->timer=0; player->sprite.u=16; player->sprite.v=0; } else if(player->timer==PLAYER_FRAME_RATE) player->sprite.v+=48; else if(player->timer==PLAYER_FRAME_RATE*2) { player->sprite.v=0; player->timer=0; } if((player->fire) && (player->bullets>0)) player->sprite.v+=96; player->timer++; break; case PDdown_left: player->dir_face=PDdown_left; if(player->dir_move!=player->prev_face) { player->prev_face=player->dir_move; player->timer=0; player->sprite.u=80; player->sprite.v=0; } else if(player->timer==PLAYER_FRAME_RATE) player->sprite.v+=48; else if(player->timer==PLAYER_FRAME_RATE*2) { player->sprite.v=0; player->timer=0; } if((player->fire) && (player->bullets>0)) player->sprite.v+=96; player->timer++; break; case PDdown_right: player->dir_face=PDdown_right; if(player->dir_move!=player->prev_face) { player->prev_face=player->dir_move; player->timer=0; player->sprite.u=48; player->sprite.v=0; } else if(player->timer==PLAYER_FRAME_RATE) player->sprite.v+=48; else if(player->timer==PLAYER_FRAME_RATE*2) { player->sprite.v=0; player->timer=0; } if((player->fire) && (player->bullets>0)) player->sprite.v+=96; player->timer++; break; case PDnull: if(player->dir_move!=player->prev_face) { player->prev_face=player->dir_move; player->timer=0; player->sprite.v=0; } else if(player->timer==PLAYER_FRAME_RATE) player->sprite.v+=48; else if(player->timer==PLAYER_FRAME_RATE*2) { player->sprite.v=0; player->timer=0; } if((player->fire) && (player->bullets>0)) { player->sprite.v+=96; player->timer++; } if(!player->fire) { player->timer=0; player->sprite.v=0; } break; default: break; } if(player->sniper_timer) //stops "cheating" by tapping L1! player->sniper_timer--; } /**********************************/ void AnimateSniper(PLAYER *player,SIGHT *sight) //Animate player if in sniper mode { short x=0; short y=0; //These 2 lines find the difference between the sight and the player sprite... sight->x_diff=(sight->sprite.x+5)-(player->sprite.x+8); sight->y_diff=(sight->sprite.y+5)-(player->sprite.y+12); x=sight->x_diff; y=sight->y_diff; /* The first set of IF statements divide the screen into quarters - above left, above-right, below-left, below right. Then the relevant line equations from the following 4 are tested to determine which of the 3 directions in the relevant IF statement's quarter the player should point... 1. (-y=2*x) 2. (-y=x/2) 3. (y=x/2) 4. (y=2*x) Pretty simple, really, if you can be bothered to work it out. Thanks to Ross Anderson (my flatmate) for reminding me of maths I learnt at GCSE level five years ago!!! */ if((sight->x_diff<0) && (sight->y_diff<0)) //up-left corner { if(y>=(x/2)) player->dir_move=PDleft; else if(y>=(x*2)) player->dir_move=PDup_left; else player->dir_move=PDup; } if((sight->x_diff>=0) && (sight->y_diff<0)) //up right corner { if((-y)>=(x*2)) player->dir_move=PDup; else if((-y)>=(x/2)) player->dir_move=PDup_right; else player->dir_move=PDright; } if((sight->x_diff<0) && (sight->y_diff>=0)) //down left corner { if((-y)>=(x/2)) player->dir_move=PDleft; else if((-y)>=(x*2)) player->dir_move=PDdown_left; else player->dir_move=PDdown; } if((sight->x_diff>=0) && (sight->y_diff>=0)) //down right corner { if(y<=(x/2)) player->dir_move=PDright; else if(y<=(x*2)) player->dir_move=PDdown_right; else player->dir_move=PDdown; } // Animate player depending on the direction they are now facing... player->sprite.v=0; // reset the "fire" sprite to not firing. switch(player->dir_move) { case PDup: player->dir_face=PDup; //player is facing up (doh) player->sprite.u=128; player->sprite.v=0; break; case PDdown: player->dir_face=PDdown; player->sprite.u=192; player->sprite.v=0; break; case PDleft: player->dir_face=PDleft; player->sprite.u=224; player->sprite.v=0; break; case PDright: player->dir_face=PDright; player->sprite.u=160; player->sprite.v=0; break; case PDup_left: player->dir_face=PDup_left; player->sprite.u=240; player->sprite.v=0; break; case PDup_right: player->dir_face=PDup_right; player->sprite.u=144; player->sprite.v=0; break; case PDdown_left: player->dir_face=PDdown_left; player->sprite.u=208; player->sprite.v=0; break; case PDdown_right: player->dir_face=PDdown_right; player->sprite.u=176; player->sprite.v=0; break; case PDnull: if(player->sprite.u<128) player->sprite.u+=128; break; default: break; } } /******************************************/ void AnimateDeath(PLAYER *player, short u_axis) { switch(player->death_timer) { case 0: player->sprite.u=u_axis; player->sprite.v=48; player->death_timer++; break; case 5: player->sprite.v+=24; player->death_timer++; break; case 10: player->sprite.v+=24; player->death_timer++; break; case 15: player->sprite.v+=24; player->death_timer++; break; case 20: player->sprite.v+=24; player->death_timer++; break; case 27: player->sprite.v+=24; player->death_timer++; break; case 34: player->sprite.v=144; player->death_timer=21; break; default: player->death_timer++; break; } } /*************************/ void AnimateVictory(PLAYER *player, short u_axis) { switch(player->death_timer) { case 0: player->sprite.u=u_axis; player->sprite.v=48; player->death_timer++; break; case 5: player->sprite.v+=24; player->death_timer++; break; case 10: player->sprite.v+=24; player->death_timer++; break; case 15: player->sprite.v+=24; player->death_timer++; break; case 20: player->sprite.v+=24; player->death_timer++; break; case 25: player->sprite.v+=24; player->death_timer++; break; case 30: player->sprite.v+=24; player->death_timer++; break; case 35: player->sprite.v+=24; player->death_timer++; break; case 40: player->sprite.v-=24; player->death_timer++; break; case 45: player->sprite.v-=24; player->death_timer++; break; case 50: player->sprite.v-=24; player->death_timer++; break; case 55: player->sprite.v-=24; player->death_timer++; break; case 60: player->sprite.v=144; player->death_timer=21; break; default: player->death_timer++; break; } } /************************* MOVEMENT FUNCTIONS *************************/ void MovePlayer(PLAYER *player, PLAYER *vs_player) { long prev_player_x=player->x; //for backing up player position! long prev_player_y=player->y; //ditto // If player within bounds of game if (player->x >= PLAYER_LEFT_WALL && player->x <= PLAYER_RIGHT_WALL && player->y >= PLAYER_TOP_WALL && player->y <= PLAYER_BOTTOM_WALL) { switch(player->dir_move) { case PDup: player->y_speed-=PLAYER_ACCELERATE; if(player->y_speed<-PLAYER_MAXSPEED) player->y_speed=-PLAYER_MAXSPEED; if(player->x_speed!=0) { if(player->x_speed>0) { player->x_speed-=PLAYER_DECELERATE; if(player->x_speed<0) player->x_speed=0; } if(player->x_speed<0) { player->x_speed+=PLAYER_DECELERATE; if(player->x_speed>0) player->x_speed=0; } } break; case PDdown: player->y_speed+=PLAYER_ACCELERATE; if(player->y_speed>PLAYER_MAXSPEED) player->y_speed=PLAYER_MAXSPEED; if(player->x_speed!=0) { if(player->x_speed>0) { player->x_speed-=PLAYER_DECELERATE; if(player->x_speed<0) player->x_speed=0; } if(player->x_speed<0) { player->x_speed+=PLAYER_DECELERATE; if(player->x_speed>0) player->x_speed=0; } } break; case PDleft: player->x_speed-=PLAYER_ACCELERATE; if(player->x_speed<-PLAYER_MAXSPEED) player->x_speed=-PLAYER_MAXSPEED; if(player->y_speed!=0) { if(player->y_speed>0) { player->y_speed-=PLAYER_DECELERATE; if(player->y_speed<0) player->y_speed=0; } if(player->y_speed<0) { player->y_speed+=PLAYER_DECELERATE; if(player->y_speed>0) player->y_speed=0; } } break; case PDright: player->x_speed+=PLAYER_ACCELERATE; if(player->x_speed>PLAYER_MAXSPEED) player->x_speed=PLAYER_MAXSPEED; if(player->y_speed!=0) { if(player->y_speed>0) { player->y_speed-=PLAYER_DECELERATE; if(player->y_speed<0) player->y_speed=0; } if(player->y_speed<0) { player->y_speed+=PLAYER_DECELERATE; if(player->y_speed>0) player->y_speed=0; } } break; case PDup_left: player->y_speed-=PLAYER_ACCELERATE; if(player->y_speed<-PLAYER_MAXSPEED) player->y_speed=-PLAYER_MAXSPEED; player->x_speed-=PLAYER_ACCELERATE; if(player->x_speed<-PLAYER_MAXSPEED) player->x_speed=-PLAYER_MAXSPEED; break; case PDup_right: player->y_speed-=PLAYER_ACCELERATE; if(player->y_speed<-PLAYER_MAXSPEED) player->y_speed=-PLAYER_MAXSPEED; player->x_speed+=PLAYER_ACCELERATE; if(player->x_speed>PLAYER_MAXSPEED) player->x_speed=PLAYER_MAXSPEED; break; case PDdown_left: player->y_speed+=PLAYER_ACCELERATE; if(player->y_speed>PLAYER_MAXSPEED) player->y_speed=PLAYER_MAXSPEED; player->x_speed-=PLAYER_ACCELERATE; if(player->x_speed<-PLAYER_MAXSPEED) player->x_speed=-PLAYER_MAXSPEED; break; case PDdown_right: player->y_speed+=PLAYER_ACCELERATE; if(player->y_speed>PLAYER_MAXSPEED) player->y_speed=PLAYER_MAXSPEED; player->x_speed+=PLAYER_ACCELERATE; if(player->x_speed>PLAYER_MAXSPEED) player->x_speed=PLAYER_MAXSPEED; break; case PDnull: if(player->y_speed!=0) { if(player->y_speed>0) { player->y_speed-=PLAYER_DECELERATE; if(player->y_speed<0) player->y_speed=0; } if(player->y_speed<0) { player->y_speed+=PLAYER_DECELERATE; if(player->y_speed>0) player->y_speed=0; } } if(player->x_speed!=0) { if(player->x_speed>0) { player->x_speed-=PLAYER_DECELERATE; if(player->x_speed<0) player->x_speed=0; } if(player->x_speed<0) { player->x_speed+=PLAYER_DECELERATE; if(player->x_speed>0) player->x_speed=0; } } break; default: break; } player->x+=player->x_speed; player->y+=player->y_speed; if(playercollide) //if players colliding { if(player->x_speed > 0) // if player going right { if(vs_player->x > player->x) // and vs_player is to the right player->x=prev_player_x; // player stays in prev. position } if(player->x_speed < 0) // if player going left { if(vs_player->x < player->x) // and vs. player to left player->x=prev_player_x; // player stays in prev. position } if(player->y_speed > 0) // if player going down { if(vs_player->y > player->y) // and vs_player is below player->y=prev_player_y; // player stays in prev. position } if(player->y_speed < 0) // if player going up { if(vs_player->y < player->y) // and vs. player above player->y=prev_player_y; // player stays in prev. position } } } else // hit sides { if((player->x <= PLAYER_LEFT_WALL) || (player->x >= PLAYER_RIGHT_WALL)) player->x_speed=0; if((player->y <= PLAYER_TOP_WALL) || (player->y >= PLAYER_BOTTOM_WALL)) player->y_speed=0; } limitRange(player->x, PLAYER_LEFT_WALL, PLAYER_RIGHT_WALL); limitRange(player->y, PLAYER_TOP_WALL, PLAYER_BOTTOM_WALL); player->sprite.x=(player->x>>12); player->sprite.y=(player->y>>12); } /****************************************/ void MoveSight(SIGHT *sight, PLAYER *player) { if(player->prev_mode!=PMsniper) { switch(player->dir_face) { case PDup: sight->x=player->x+(3<<12); sight->y=player->y-(15<<12); break; case PDdown: sight->x=player->x+(3<<12); sight->y=player->y+(29<<12); break; case PDleft: sight->x=player->x-(15<<12); sight->y=player->y+(4<<12); break; case PDright: sight->x=player->x+(21<<12); sight->y=player->y+(4<<12); break; case PDup_left: sight->x=player->x-(12<<12); sight->y=player->y-(11<<12); break; case PDup_right: sight->x=player->x+(24<<12); sight->y=player->y-(11<<12); break; case PDdown_left: sight->x=player->x-(12<<12); sight->y=player->y+(33<<12); break; case PDdown_right: sight->x=player->x+(24<<12); sight->y=player->y+(33<<12); break; default: break; } player->x_speed=0; // reset player movement (stops weird drift when player->y_speed=0; // sniper button is let go)! } if (sight->x >= SIGHT_LEFT_WALL && sight->x <= SIGHT_RIGHT_WALL && sight->y >= SIGHT_TOP_WALL && sight->y <= SIGHT_BOTTOM_WALL) { switch(player->dir_move) { case PDup: player->dir_face=PDup; sight->y_speed-=SIGHT_ACCELERATE; if(sight->y_speed<-SIGHT_MAXSPEED) sight->y_speed=-SIGHT_MAXSPEED; if(sight->x_speed!=0) { if(sight->x_speed>0) { sight->x_speed-=SIGHT_DECCELERATE; if(sight->x_speed<0) sight->x_speed=0; } if(sight->x_speed<0) { sight->x_speed+=SIGHT_DECCELERATE; if(sight->x_speed>0) sight->x_speed=0; } } break; case PDdown: player->dir_face=PDdown; sight->y_speed+=SIGHT_ACCELERATE; if(sight->y_speed>SIGHT_MAXSPEED) sight->y_speed=SIGHT_MAXSPEED; if(sight->x_speed!=0) { if(sight->x_speed>0) { sight->x_speed-=SIGHT_DECCELERATE; if(sight->x_speed<0) sight->x_speed=0; } if(sight->x_speed<0) { sight->x_speed+=SIGHT_DECCELERATE; if(sight->x_speed>0) sight->x_speed=0; } } break; case PDleft: player->dir_face=PDleft; sight->x_speed-=SIGHT_ACCELERATE; if(sight->x_speed<-SIGHT_MAXSPEED) sight->x_speed=-SIGHT_MAXSPEED; if(sight->y_speed!=0) { if(sight->y_speed>0) { sight->y_speed-=SIGHT_DECCELERATE; if(sight->y_speed<0) sight->y_speed=0; } if(sight->y_speed<0) { sight->y_speed+=SIGHT_DECCELERATE; if(sight->y_speed>0) sight->y_speed=0; } } break; case PDright: player->dir_face=PDright; sight->x_speed+=SIGHT_ACCELERATE; if(sight->x_speed>SIGHT_MAXSPEED) sight->x_speed=SIGHT_MAXSPEED; if(sight->y_speed!=0) { if(sight->y_speed>0) { sight->y_speed-=SIGHT_DECCELERATE; if(sight->y_speed<0) sight->y_speed=0; } if(sight->y_speed<0) { sight->y_speed+=SIGHT_DECCELERATE; if(sight->y_speed>0) sight->y_speed=0; } } break; case PDup_left: player->dir_face=PDup_left; sight->y_speed-=SIGHT_ACCELERATE; if(sight->y_speed<-SIGHT_MAXSPEED) sight->y_speed=-SIGHT_MAXSPEED; sight->x_speed-=SIGHT_ACCELERATE; if(sight->x_speed<-SIGHT_MAXSPEED) sight->x_speed=-SIGHT_MAXSPEED; break; case PDup_right: player->dir_face=PDup_right; sight->y_speed-=SIGHT_ACCELERATE; if(sight->y_speed<-SIGHT_MAXSPEED) sight->y_speed=-SIGHT_MAXSPEED; sight->x_speed+=SIGHT_ACCELERATE; if(sight->x_speed>SIGHT_MAXSPEED) sight->x_speed=SIGHT_MAXSPEED; break; case PDdown_left: player->dir_face=PDdown_left; sight->y_speed+=SIGHT_ACCELERATE; if(sight->y_speed>SIGHT_MAXSPEED) sight->y_speed=SIGHT_MAXSPEED; sight->x_speed-=SIGHT_ACCELERATE; if(sight->x_speed<-SIGHT_MAXSPEED) sight->x_speed=-SIGHT_MAXSPEED; break; case PDdown_right: player->dir_face=PDdown_right; sight->y_speed+=SIGHT_ACCELERATE; if(sight->y_speed>SIGHT_MAXSPEED) sight->y_speed=SIGHT_MAXSPEED; sight->x_speed+=SIGHT_ACCELERATE; if(sight->x_speed>SIGHT_MAXSPEED) sight->x_speed=SIGHT_MAXSPEED; break; case PDnull: if(sight->y_speed!=0) { if(sight->y_speed>0) { sight->y_speed-=SIGHT_DECCELERATE; if(sight->y_speed<0) sight->y_speed=0; } if(sight->y_speed<0) { sight->y_speed+=SIGHT_DECCELERATE; if(sight->y_speed>0) sight->y_speed=0; } } if(sight->x_speed!=0) { if(sight->x_speed>0) { sight->x_speed-=SIGHT_DECCELERATE; if(sight->x_speed<0) sight->x_speed=0; } if(sight->x_speed<0) { sight->x_speed+=SIGHT_DECCELERATE; if(sight->x_speed>0) sight->x_speed=0; } } break; default: break; } sight->x+=sight->x_speed; sight->y+=sight->y_speed; } else // HIT wall { if((sight->x <= SIGHT_LEFT_WALL) || (sight->x >= SIGHT_RIGHT_WALL)) sight->x_speed=0; if((sight->y <= SIGHT_TOP_WALL) || (sight->y >= SIGHT_BOTTOM_WALL)) sight->y_speed=0; } limitRange(sight->x, SIGHT_LEFT_WALL, SIGHT_RIGHT_WALL); limitRange(sight->y, SIGHT_TOP_WALL, SIGHT_BOTTOM_WALL); sight->sprite.x=(sight->x>>12); sight->sprite.y=(sight->y>>12); } /********************************/ void MoveBullet(BULLET *bullet) { if((bullet->x>(BULLET_LEFT_WALL) && bullet->x<(BULLET_RIGHT_WALL)) && (bullet->y>(BULLET_TOP_WALL) && bullet->y<(BULLET_BOTTOM_WALL))) { switch(bullet->direction) { case PDup: bullet->x+=0; bullet->y-=BULLET_SPEED; break; case PDdown: bullet->x+=0; bullet->y+=BULLET_SPEED; break; case PDleft: bullet->x-=BULLET_SPEED; bullet->y+=0; break; case PDright: bullet->x+=BULLET_SPEED; bullet->y+=0; break; case PDup_left: bullet->x-=BULLET_SPEED; bullet->y-=BULLET_SPEED; break; case PDup_right: bullet->x+=BULLET_SPEED; bullet->y-=BULLET_SPEED; break; case PDdown_left: bullet->x-=BULLET_SPEED; bullet->y+=BULLET_SPEED; break; case PDdown_right: bullet->x+=BULLET_SPEED; bullet->y+=BULLET_SPEED; break; default: break; } bullet->sprite.x=(bullet->x>>12); bullet->sprite.y=(bullet->y>>12); } else { bullet->launched=0; } } /*******************************/ void DeceleratePlayer(PLAYER *player) //NOTE!!! Changes whatever active PLAYER_MODE TO 'PMbattle' { if (player->x >= PLAYER_LEFT_WALL && player->x <= PLAYER_RIGHT_WALL && player->y >= PLAYER_TOP_WALL && player->y <= PLAYER_BOTTOM_WALL) { if(player->y_speed!=0) { if(player->y_speed>0) { player->y_speed-=PLAYER_DECELERATE; if(player->y_speed<0) player->y_speed=0; } if(player->y_speed<0) { player->y_speed+=PLAYER_DECELERATE; if(player->y_speed>0) player->y_speed=0; } } if(player->x_speed!=0) { if(player->x_speed>0) { player->x_speed-=PLAYER_DECELERATE; if(player->x_speed<0) player->x_speed=0; } if(player->x_speed<0) { player->x_speed+=PLAYER_DECELERATE; if(player->x_speed>0) player->x_speed=0; } } player->x+=player->x_speed; player->y+=player->y_speed; } else // hit sides { if((player->x <= PLAYER_LEFT_WALL) || (player->x >= PLAYER_RIGHT_WALL)) player->x_speed=0; if((player->y <= PLAYER_TOP_WALL) || (player->y >= PLAYER_BOTTOM_WALL)) player->y_speed=0; } limitRange(player->x, PLAYER_LEFT_WALL, PLAYER_RIGHT_WALL); limitRange(player->y, PLAYER_TOP_WALL, PLAYER_BOTTOM_WALL); player->sprite.x=(player->x>>12); player->sprite.y=(player->y>>12); player->mode=PMbattle; } /************************************************ FIRING STUFF (stuff wot dun the vi-lunce) ************************************************/ void FireNormal(BULLET *bullet, PLAYER *player) { while(bullet->launched) //find 'first' unlaunched bullet bullet++; bullet->x=(player->x+(8<<12)); bullet->y=(player->y+(12<<12)); bullet->launched=1; bullet->direction=player->dir_face; player->bullet_gap=BULLET_GAP; } void FireSniper(SIGHTSHOT *sightshot, PLAYER *vs_player, SIGHT *sight) { int i; sightshot->sprite.x=sight->sprite.x; sightshot->sprite.y=sight->sprite.y; sightshot->timer=SIGHTSHOT_TIMER; if(CheckPlayerSniperHeadshot(vs_player, sight)) { sightshot->sprite.u=0; sightshot->sprite.v=22; sightshot->type=SThit; vs_player->energy_left-=SNIPER_HEAD_DAMAGE; vs_player->death=CDsniperhead; } else if(CheckPlayerSniperBodyshot(vs_player, sight)) { sightshot->sprite.u=0; sightshot->sprite.v=22; sightshot->type=SThit; vs_player->energy_left-=SNIPER_BODY_DAMAGE; vs_player->death=CDsniperbody; } else { sightshot->sprite.u=0; sightshot->sprite.v=0; // 22 sightshot->type=STmiss; } if(sightshot->type==SThit) { sightshot->x_diff=(sightshot->sprite.x)-(vs_player->sprite.x); sightshot->y_diff=(sightshot->sprite.y)-(vs_player->sprite.y); } //new bit for(i=0, mine=&mines[0];idisplay) && (mine->timer == 0)) { if(CheckSniperMine(mine, sight)) { mine->display=0; StartExplosion((mine->sprite.x-24), (mine->sprite.y-26), EXPmine); } } } // new bit over } /************************ INITIALISE GAME GRAPHICS STUFF (yawn) ************************/ void InitBigLogo(void) { RECT rect; GsIMAGE timData; GsGetTimInfo((u_long *)(DATA_LOGO_TIM+4),&timData); rect.x = timData.px; rect.y = timData.py; rect.w = timData.pw; rect.h = timData.ph; LoadImage(&rect, timData.pixel); rect.x=timData.cx; rect.y=timData.cy; rect.w=timData.cw; rect.h=timData.ch; LoadImage(&rect, timData.clut); // Initialise Sprite Structure! BigLogo.attribute = (1<<24); // middling 8-bitter BigLogo.x = 100; BigLogo.y = 20; BigLogo.w = 120; BigLogo.h = 52; BigLogo.tpage = GetTPage(1,0,timData.px,timData.py); BigLogo.u = 0; BigLogo.v = 0; BigLogo.r = 128; BigLogo.g = 128; BigLogo.b = 128; BigLogo.mx = 0; BigLogo.my = 0; BigLogo.scalex = ONE; BigLogo.scaley = ONE; BigLogo.rotate = 0; BigLogo.cx = timData.cx; BigLogo.cy = timData.cy; DrawSync(0); } void InitSmallLogo(void) { RECT rect; GsIMAGE timData; GsGetTimInfo((u_long *)(DATA_LOGO_TIM+4),&timData); rect.x = timData.px; rect.y = timData.py; rect.w = timData.pw; rect.h = timData.ph; LoadImage(&rect, timData.pixel); rect.x=timData.cx; rect.y=timData.cy; rect.w=timData.cw; rect.h=timData.ch; LoadImage(&rect, timData.clut); // Initialise Sprite Structure! SmallLogo.attribute = (1<<24); // middling 8-bitter SmallLogo.x = 130; SmallLogo.y = 0; SmallLogo.w = 60; SmallLogo.h = 26; SmallLogo.tpage = GetTPage(1,0,timData.px,timData.py); SmallLogo.u = 0; SmallLogo.v = 52; SmallLogo.r = 128; SmallLogo.g = 128; SmallLogo.b = 128; SmallLogo.mx = 0; SmallLogo.my = 0; SmallLogo.scalex = ONE; SmallLogo.scaley = ONE; SmallLogo.rotate = 0; SmallLogo.cx = timData.cx; SmallLogo.cy = timData.cy; DrawSync(0); } void InitFontSprite(void) { //Setup flash demo screen RECT rect; GsIMAGE timData; GsGetTimInfo((u_long *)(DATA_FONT_TIM+4),&timData); rect.x = timData.px; rect.y = timData.py; rect.w = timData.pw; rect.h = timData.ph; LoadImage(&rect, timData.pixel); rect.x=timData.cx; rect.y=timData.cy; rect.w=timData.cw; rect.h=timData.ch; LoadImage(&rect, timData.clut); // Initialise Sprite Structure! FontSprite.attribute = (1<<24); // middling 8-bitter FontSprite.x = 0; FontSprite.y = 0; FontSprite.w = 22; FontSprite.h = 19; FontSprite.tpage = GetTPage(1,0,timData.px,timData.py); FontSprite.u = 0; FontSprite.v = 0; FontSprite.r = 128; FontSprite.g = 128; FontSprite.b = 128; FontSprite.mx = 0; FontSprite.my = 0; FontSprite.scalex = ONE; FontSprite.scaley = ONE; FontSprite.rotate = 0; FontSprite.cx = timData.cx; FontSprite.cy = timData.cy; DrawSync(0); } void InitDemo(void) { //Setup flash demo screen RECT rect; GsIMAGE timData; GsGetTimInfo((u_long *)(DATA_DEMO_TIM+4),&timData); rect.x = 832; rect.y = 256; rect.w = timData.pw; rect.h = timData.ph; LoadImage(&rect, timData.pixel); rect.x=timData.cx; rect.y=timData.cy; rect.w=timData.cw; rect.h=timData.ch; LoadImage(&rect, timData.clut); // Initialise Sprite Structure! // First half of the demo sprite (sprites can only be 256x256) demo_left.attribute = (1<<24); // middling 8-bitter demo_left.x = 0; demo_left.y = 0; demo_left.w = timData.pw; demo_left.h = timData.ph; demo_left.tpage = GetTPage(1,0,832,256); demo_left.u = 0; demo_left.v = 0; demo_left.r = 128; demo_left.g = 128; demo_left.b = 128; demo_left.mx = 0; demo_left.my = 0; demo_left.scalex = ONE; demo_left.scaley = ONE; demo_left.rotate = 0; demo_left.cx = timData.cx; demo_left.cy = timData.cy; // other half of the demo sprite demo_right.attribute = (1<<24); demo_right.x = 160; demo_right.y = 0; demo_right.w = timData.pw; demo_right.h = timData.ph; demo_right.tpage = GetTPage(1,0,912,256); demo_right.u = 32; demo_right.v = 0; demo_right.r = 128; demo_right.g = 128; demo_right.b = 128; demo_right.mx = 0; demo_right.my = 0; demo_right.scalex = ONE; demo_right.scaley = ONE; demo_right.rotate = 0; demo_right.cx = timData.cx; demo_right.cy = timData.cy; DrawSync(0); } void InitPlayer1(PLAYER *player, short x, short y) { RECT rect; GsIMAGE timData; // Setup Player player->x = (x<<12); player->y = (y<<12); player->dir_move=PDnull; player->prev_face=PDnull; player->dir_face=PDdown; player->frame=0; player->timer=0; player->bullet_gap=0; player->sniper_timer=0; player->death_timer=0; player->x_speed=0; player->y_speed=0; player->bullets = NUM_BULLETS; player->sniper_shots = NUM_SNIPER_SHOTS; player->grenades = NUM_GRENADES; player->mines = NUM_MINES; player->energy_left = MAX_ENERGY; player->gasmask = 0; player->drop_mine=0; player->death=CDnull; GsGetTimInfo((u_long*)(DATA_SOLDIER1_TIM+4),&timData); rect.x=timData.px; rect.y=timData.py; rect.w=timData.pw; rect.h=timData.ph; LoadImage(&rect, timData.pixel); rect.x=timData.cx; rect.y=timData.cy; rect.w=timData.cw; rect.h=timData.ch; LoadImage(&rect, timData.clut); player->sprite.attribute = (1<<24); player->sprite.x = (player->x>>12); player->sprite.y = (player->y>>12); player->sprite.w = (16); player->sprite.h = (24); player->sprite.tpage = GetTPage(1,0,timData.px,timData.py); player->sprite.u = 64; player->sprite.v = 0; player->sprite.cx = timData.cx; player->sprite.cy = timData.cy; player->sprite.r = 128; player->sprite.g = 128; player->sprite.b = 128; player->sprite.mx = player->sprite.w/2; player->sprite.my = player->sprite.h/2; player->sprite.scalex = ONE; player->sprite.scaley = ONE; player->sprite.rotate = 0; DrawSync(0); } void InitPlayer2(PLAYER *player, short x, short y) { RECT rect; GsIMAGE timData; // Setup Player player->x = (x<<12); player->y = (y<<12); player->dir_move=PDnull; player->prev_face=PDnull; player->dir_face=PDdown; player->frame=0; player->timer=0; player->bullet_gap=0; player->sniper_timer=0; player->death_timer=0; player->x_speed=0; player->y_speed=0; player->bullets = NUM_BULLETS; player->sniper_shots = NUM_SNIPER_SHOTS; player->grenades = NUM_GRENADES; player->mines = NUM_MINES; player->energy_left = MAX_ENERGY; player->gasmask = 0; player->drop_mine=0; player->death=CDnull; GsGetTimInfo((u_long*)(DATA_SOLDIER2_TIM+4),&timData); rect.x=timData.px; rect.y=timData.py; rect.w=timData.pw; rect.h=timData.ph; LoadImage(&rect, timData.pixel); rect.x=timData.cx; rect.y=timData.cy; rect.w=timData.cw; rect.h=timData.ch; LoadImage(&rect, timData.clut); player->sprite.attribute = (1<<24); player->sprite.x = (player->x>>12); player->sprite.y = (player->y>>12); player->sprite.w = (16); player->sprite.h = (24); player->sprite.tpage = GetTPage(1,0,timData.px,timData.py); player->sprite.u = 64; player->sprite.v = 0; player->sprite.cx = timData.cx; player->sprite.cy = timData.cy; player->sprite.r = 128; player->sprite.g = 128; player->sprite.b = 128; player->sprite.mx = player->sprite.w/2; player->sprite.my = player->sprite.h/2; player->sprite.scalex = ONE; player->sprite.scaley = ONE; player->sprite.rotate = 0; DrawSync(0); } void InitBG() { //Setup Background (need to setup 2 sprites) RECT rect; GsIMAGE timData; GsGetTimInfo((u_long *)(DATA_TRENCH_TIM+4),&timData); rect.x = 320; //hard code the TIM position rect.y = 0; //ditto rect.w = timData.pw; rect.h = timData.ph; LoadImage(&rect, timData.pixel); rect.x=timData.cx; rect.y=timData.cy; rect.w=timData.cw; rect.h=timData.ch; LoadImage(&rect, timData.clut); // Initialise Sprite Structure! // First half of the BG sprite (sprites can only be 256x256) BG_left.attribute = (1<<24); // middling 8-bitter BG_left.x = 0; BG_left.y = 25; BG_left.w = timData.pw; BG_left.h = timData.ph; BG_left.tpage = GetTPage(1,0,320,0); BG_left.u = 0; BG_left.v = 0; BG_left.r = 128; BG_left.g = 128; BG_left.b = 128; BG_left.mx = 0; BG_left.my = 0; BG_left.scalex = ONE; BG_left.scaley = ONE; BG_left.rotate = 0; BG_left.cx = timData.cx; BG_left.cy = timData.cy; // other half of the BG sprite BG_right.attribute = (1<<24); BG_right.x = 160; BG_right.y = 25; BG_right.w = timData.pw; BG_right.h = timData.ph; BG_right.tpage = GetTPage(1,0,400,0); BG_right.u = 32; BG_right.v = 0; BG_right.r = 128; BG_right.g = 128; BG_right.b = 128; BG_right.mx = 0; BG_right.my = 0; BG_right.scalex = ONE; BG_right.scaley = ONE; BG_right.rotate = 0; BG_right.cx = timData.cx; BG_right.cy = timData.cy; DrawSync(0); } void InitBullets(BULLET *bullet) { RECT rect; GsIMAGE timData; int i; //for looping // Setup each bullet! GsGetTimInfo((u_long*)(DATA_BULLET_TIM+4),&timData); rect.x=timData.px; rect.y=timData.py; rect.w=timData.pw; rect.h=timData.ph; LoadImage(&rect, timData.pixel); rect.x=timData.cx; rect.y=timData.cy; rect.w=timData.cw; rect.h=timData.ch; LoadImage(&rect, timData.clut); for(i=0;ix = (0<<12); bullet->y = (0<<12); bullet->launched=0; bullet->speed=0; bullet->direction=0; bullet->sprite.attribute = (1<<24); bullet->sprite.x = (bullet->x>>12); bullet->sprite.y = (bullet->y>>12); bullet->sprite.w = (3); bullet->sprite.h = (3); bullet->sprite.tpage = GetTPage(1,0,timData.px,timData.py); bullet->sprite.u = 0; bullet->sprite.v = 0; bullet->sprite.cx = timData.cx; bullet->sprite.cy = timData.cy; bullet->sprite.r = 128; bullet->sprite.g = 128; bullet->sprite.b = 128; bullet->sprite.mx = bullet->sprite.w/2; bullet->sprite.my = bullet->sprite.h/2; bullet->sprite.scalex = ONE; bullet->sprite.scaley = ONE; bullet->sprite.rotate = 0; } DrawSync(0); } void InitBulletHits(BULLET_HIT *bullet_hit) { RECT rect; GsIMAGE timData; int i; //for looping // Setup each bullet hit sprite/struct GsGetTimInfo((u_long*)(DATA_SIGHTSHOT_TIM+4),&timData); rect.x=timData.px; rect.y=timData.py; rect.w=timData.pw; rect.h=timData.ph; LoadImage(&rect, timData.pixel); rect.x=timData.cx; rect.y=timData.cy; rect.w=timData.cw; rect.h=timData.ch; LoadImage(&rect, timData.clut); for(i=0; itimer=0; bullet_hit->x_diff=0; bullet_hit->y_diff=0; bullet_hit->sprite.attribute = (1<<24); bullet_hit->sprite.x = (0); bullet_hit->sprite.y = (0); bullet_hit->sprite.w = (11); bullet_hit->sprite.h = (11); bullet_hit->sprite.tpage = GetTPage(1,0,timData.px,timData.py); bullet_hit->sprite.u = 0; bullet_hit->sprite.v = 22; bullet_hit->sprite.cx = timData.cx; bullet_hit->sprite.cy = timData.cy; bullet_hit->sprite.r = 128; bullet_hit->sprite.g = 128; bullet_hit->sprite.b = 128; bullet_hit->sprite.mx = bullet_hit->sprite.w/2; bullet_hit->sprite.my = bullet_hit->sprite.h/2; bullet_hit->sprite.scalex = ONE; bullet_hit->sprite.scaley = ONE; bullet_hit->sprite.rotate = 0; } DrawSync(0); } void InitSight1(SIGHT *sight) { RECT rect; GsIMAGE timData; // Setup sight GsGetTimInfo((u_long*)(DATA_SIGHT_TIM+4),&timData); rect.x=timData.px; rect.y=timData.py; rect.w=timData.pw; rect.h=timData.ph; LoadImage(&rect, timData.pixel); rect.x=timData.cx; rect.y=timData.cy; rect.w=timData.cw; rect.h=timData.ch; LoadImage(&rect, timData.clut); sight->x = (10<<12); sight->y = (10<<12); sight->x_speed=0; sight->y_speed=0; sight->timer=0; sight->x_diff=0; sight->y_diff=0; sight->sprite.attribute = (1<<24); sight->sprite.x = (sight->x>>12); sight->sprite.y = (sight->y>>12); sight->sprite.w = (11); sight->sprite.h = (11); sight->sprite.tpage = GetTPage(1,0,timData.px,timData.py); sight->sprite.u = 0; sight->sprite.v = 0; sight->sprite.cx = timData.cx; sight->sprite.cy = timData.cy; sight->sprite.r = 128; sight->sprite.g = 128; sight->sprite.b = 128; sight->sprite.mx = sight->sprite.w/2; sight->sprite.my = sight->sprite.h/2; sight->sprite.scalex = ONE; sight->sprite.scaley = ONE; sight->sprite.rotate = 0; DrawSync(0); } void InitSight2(SIGHT *sight) { RECT rect; GsIMAGE timData; // Setup sight GsGetTimInfo((u_long*)(DATA_SIGHT_TIM+4),&timData); rect.x=timData.px; rect.y=timData.py; rect.w=timData.pw; rect.h=timData.ph; LoadImage(&rect, timData.pixel); rect.x=timData.cx; rect.y=timData.cy; rect.w=timData.cw; rect.h=timData.ch; LoadImage(&rect, timData.clut); sight->x = (10<<12); sight->y = (10<<12); sight->x_speed=0; sight->y_speed=0; sight->timer=0; sight->x_diff=0; sight->y_diff=0; sight->sprite.attribute = (1<<24); sight->sprite.x = (sight->x>>12); sight->sprite.y = (sight->y>>12); sight->sprite.w = (11); sight->sprite.h = (11); sight->sprite.tpage = GetTPage(1,0,timData.px,timData.py); sight->sprite.u = 11; sight->sprite.v = 0; sight->sprite.cx = timData.cx; sight->sprite.cy = timData.cy; sight->sprite.r = 128; sight->sprite.g = 128; sight->sprite.b = 128; sight->sprite.mx = sight->sprite.w/2; sight->sprite.my = sight->sprite.h/2; sight->sprite.scalex = ONE; sight->sprite.scaley = ONE; sight->sprite.rotate = 0; DrawSync(0); } void InitPowerup(POWERUP *powerup) { RECT rect; GsIMAGE timData; powerup->timer = POWERUP_LENGTH; // Setup Powerups sprite GsGetTimInfo((u_long*)(DATA_POWERUPS_TIM+4),&timData); rect.x=timData.px; rect.y=timData.py; rect.w=timData.pw; rect.h=timData.ph; LoadImage(&rect, timData.pixel); rect.x=timData.cx; rect.y=timData.cy; rect.w=timData.cw; rect.h=timData.ch; LoadImage(&rect, timData.clut); powerup->sprite.attribute = (1<<24); powerup->sprite.w = (16); powerup->sprite.h = (16); powerup->sprite.tpage = GetTPage(1,0,timData.px,timData.py); powerup->sprite.u = 0; powerup->sprite.cx = timData.cx; powerup->sprite.cy = timData.cy; powerup->sprite.r = 128; powerup->sprite.g = 128; powerup->sprite.b = 128; powerup->sprite.mx = powerup->sprite.w/2; powerup->sprite.my = powerup->sprite.h/2; powerup->sprite.scalex = ONE; powerup->sprite.scaley = ONE; powerup->sprite.rotate = 0; switch(powerup->contents) { case PUbullets: powerup->sprite.v = 0; break; case PUsniper: powerup->sprite.v = 16; break; case PUgasmask: powerup->sprite.v = 32; break; case PUmines: powerup->sprite.v = 48; break; case PUhealth: powerup->sprite.v = 64; break; default: break; } DrawSync(0); } void InitMines(MINE *mines) { RECT rect; GsIMAGE timData; int i; //for looping // Setup each mine! GsGetTimInfo((u_long*)(DATA_MINE_TIM+4),&timData); rect.x=timData.px; rect.y=timData.py; rect.w=timData.pw; rect.h=timData.ph; LoadImage(&rect, timData.pixel); rect.x=timData.cx; rect.y=timData.cy; rect.w=timData.cw; rect.h=timData.ch; LoadImage(&rect, timData.clut); for(i=0;idisplay=0; mine->timer=0; mine->primed=0; mine->explode=0; mine->sprite.attribute = (1<<24); mine->sprite.x = (0); mine->sprite.y = (0); mine->sprite.w = timData.pw*2; mine->sprite.h = timData.ph; mine->sprite.tpage = GetTPage(1,0,timData.px,timData.py); mine->sprite.u = 0; mine->sprite.v = 0; mine->sprite.cx = timData.cx; mine->sprite.cy = timData.cy; mine->sprite.r = 128; mine->sprite.g = 128; mine->sprite.b = 128; mine->sprite.mx = mine->sprite.w/2; mine->sprite.my = mine->sprite.h/2; mine->sprite.scalex = ONE; mine->sprite.scaley = ONE; mine->sprite.rotate = 0; } DrawSync(0); } void InitExplosions(EXPLOSION *explode) { RECT rect; GsIMAGE timData; int i; //for looping // Setup each explosion sprite GsGetTimInfo((u_long*)(DATA_EXPLOSION_TIM+4),&timData); rect.x=timData.px; rect.y=timData.py; rect.w=timData.pw; rect.h=timData.ph; LoadImage(&rect, timData.pixel); rect.x=timData.cx; rect.y=timData.cy; rect.w=timData.cw; rect.h=timData.ch; LoadImage(&rect, timData.clut); for(i=0;itimer=0; explode->type=EXPinactive; explode->sprite.attribute = (1<<24); //+(1<<30) explode->sprite.x = (0); explode->sprite.y = (0); explode->sprite.w = (60); explode->sprite.h = (60); explode->sprite.tpage = GetTPage(1,0,timData.px,timData.py); explode->sprite.u = 0; explode->sprite.v = 0; explode->sprite.cx = timData.cx; explode->sprite.cy = timData.cy; explode->sprite.r = 128; explode->sprite.g = 128; explode->sprite.b = 128; explode->sprite.mx = explode->sprite.w/2; explode->sprite.my = explode->sprite.h/2; explode->sprite.scalex = ONE; explode->sprite.scaley = ONE; explode->sprite.rotate = 0; } DrawSync(0); } void InitSightShot(SIGHTSHOT *sightshot) { RECT rect; GsIMAGE timData; int i; //for looping // Setup each sightshot sprite/struct GsGetTimInfo((u_long*)(DATA_SIGHTSHOT_TIM+4),&timData); rect.x=timData.px; rect.y=timData.py; rect.w=timData.pw; rect.h=timData.ph; LoadImage(&rect, timData.pixel); rect.x=timData.cx; rect.y=timData.cy; rect.w=timData.cw; rect.h=timData.ch; LoadImage(&rect, timData.clut); for(i=0; i<3 ;i++, sightshot++) { sightshot->timer=0; sightshot->x_diff=0; sightshot->y_diff=0; sightshot->type=STmiss; sightshot->sprite.attribute = (1<<24); sightshot->sprite.x = (0); sightshot->sprite.y = (0); sightshot->sprite.w = (11); sightshot->sprite.h = (11); sightshot->sprite.tpage = GetTPage(1,0,timData.px,timData.py); sightshot->sprite.u = 0; sightshot->sprite.v = 0; sightshot->sprite.cx = timData.cx; sightshot->sprite.cy = timData.cy; sightshot->sprite.r = 128; sightshot->sprite.g = 128; sightshot->sprite.b = 128; sightshot->sprite.mx = sightshot->sprite.w/2; sightshot->sprite.my = sightshot->sprite.h/2; sightshot->sprite.scalex = ONE; sightshot->sprite.scaley = ONE; sightshot->sprite.rotate = 0; } DrawSync(0); } void InitStatus1(STATUS *status) { RECT rect; GsIMAGE timData; int i; //for looping // Setup status bar sprite! // Load the BG of the status bar and place in memory... GsGetTimInfo((u_long*)(DATA_STATUS_TIM+4),&timData); rect.x=timData.px; rect.y=timData.py; rect.w=timData.pw; rect.h=timData.ph; LoadImage(&rect, timData.pixel); rect.x=timData.cx; rect.y=timData.cy; rect.w=timData.cw; rect.h=timData.ch; LoadImage(&rect, timData.clut); status->menubar.attribute = (1<<24); status->menubar.x = (10); status->menubar.y = (0); status->menubar.w = (120); status->menubar.h = (26); status->menubar.tpage = GetTPage(1,0,timData.px,timData.py); status->menubar.u = 0; status->menubar.v = 0; status->menubar.cx = timData.cx; status->menubar.cy = timData.cy; status->menubar.r = 128; status->menubar.g = 128; status->menubar.b = 128; status->menubar.mx = status->menubar.w/2; status->menubar.my = status->menubar.h/2; status->menubar.scalex = ONE; status->menubar.scaley = ONE; status->menubar.rotate = 0; DrawSync(0); // Load all the number sprites for the status bar... GsGetTimInfo((u_long*)(DATA_NUMBERS_TIM+4),&timData); rect.x=timData.px; rect.y=timData.py; rect.w=timData.pw; rect.h=timData.ph; LoadImage(&rect, timData.pixel); rect.x=timData.cx; rect.y=timData.cy; rect.w=timData.cw; rect.h=timData.ch; LoadImage(&rect, timData.clut); status->lives.attribute = (1<<24); status->lives.x = (23); status->lives.y = (2); status->lives.w = (10); status->lives.h = (10); status->lives.tpage = GetTPage(1,0,timData.px,timData.py); status->lives.u = 0; status->lives.v = 0; status->lives.cx = timData.cx; status->lives.cy = timData.cy; status->lives.r = 128; status->lives.g = 128; status->lives.b = 128; status->lives.mx = status->lives.w/2; status->lives.my = status->lives.h/2; status->lives.scalex = ONE; status->lives.scaley = ONE; status->lives.rotate = 0; DrawSync(0); status->ammo1.attribute = (1<<24); status->ammo1.x = (30); status->ammo1.y = (14); status->ammo1.w = (10); status->ammo1.h = (10); status->ammo1.tpage = GetTPage(1,0,timData.px,timData.py); status->ammo1.u = 0; status->ammo1.v = 0; status->ammo1.cx = timData.cx; status->ammo1.cy = timData.cy; status->ammo1.r = 128; status->ammo1.g = 128; status->ammo1.b = 128; status->ammo1.mx = status->ammo1.w/2; status->ammo1.my = status->ammo1.h/2; status->ammo1.scalex = ONE; status->ammo1.scaley = ONE; status->ammo1.rotate = 0; DrawSync(0); status->ammo2.attribute = (1<<24); status->ammo2.x = (40); status->ammo2.y = (14); status->ammo2.w = (10); status->ammo2.h = (10); status->ammo2.tpage = GetTPage(1,0,timData.px,timData.py); status->ammo2.u = 0; status->ammo2.v = 0; status->ammo2.cx = timData.cx; status->ammo2.cy = timData.cy; status->ammo2.r = 128; status->ammo2.g = 128; status->ammo2.b = 128; status->ammo2.mx = status->ammo1.w/2; status->ammo2.my = status->ammo1.h/2; status->ammo2.scalex = ONE; status->ammo2.scaley = ONE; status->ammo2.rotate = 0; DrawSync(0); status->sniper1.attribute = (1<<24); status->sniper1.x = (66); status->sniper1.y = (14); status->sniper1.w = (10); status->sniper1.h = (10); status->sniper1.tpage = GetTPage(1,0,timData.px,timData.py); status->sniper1.u = 0; status->sniper1.v = 0; status->sniper1.cx = timData.cx; status->sniper1.cy = timData.cy; status->sniper1.r = 128; status->sniper1.g = 128; status->sniper1.b = 128; status->sniper1.mx = status->sniper1.w/2; status->sniper1.my = status->sniper1.h/2; status->sniper1.scalex = ONE; status->sniper1.scaley = ONE; status->sniper1.rotate = 0; DrawSync(0); status->sniper2.attribute = (1<<24); status->sniper2.x = (76); status->sniper2.y = (14); status->sniper2.w = (10); status->sniper2.h = (10); status->sniper2.tpage = GetTPage(1,0,timData.px,timData.py); status->sniper2.u = 0; status->sniper2.v = 0; status->sniper2.cx = timData.cx; status->sniper2.cy = timData.cy; status->sniper2.r = 128; status->sniper2.g = 128; status->sniper2.b = 128; status->sniper2.mx = status->sniper1.w/2; status->sniper2.my = status->sniper1.h/2; status->sniper2.scalex = ONE; status->sniper2.scaley = ONE; status->sniper2.rotate = 0; DrawSync(0); status->mines1.attribute = (1<<24); status->mines1.x = (102); status->mines1.y = (14); status->mines1.w = (10); status->mines1.h = (10); status->mines1.tpage = GetTPage(1,0,timData.px,timData.py); status->mines1.u = 0; status->mines1.v = 0; status->mines1.cx = timData.cx; status->mines1.cy = timData.cy; status->mines1.r = 128; status->mines1.g = 128; status->mines1.b = 128; status->mines1.mx = status->mines1.w/2; status->mines1.my = status->mines1.h/2; status->mines1.scalex = ONE; status->mines1.scaley = ONE; status->mines1.rotate = 0; DrawSync(0); status->mines2.attribute = (1<<24); status->mines2.x = (112); status->mines2.y = (14); status->mines2.w = (10); status->mines2.h = (10); status->mines2.tpage = GetTPage(1,0,timData.px,timData.py); status->mines2.u = 0; status->mines2.v = 0; status->mines2.cx = timData.cx; status->mines2.cy = timData.cy; status->mines2.r = 128; status->mines2.g = 128; status->mines2.b = 128; status->mines2.mx = status->mines1.w/2; status->mines2.my = status->mines1.h/2; status->mines2.scalex = ONE; status->mines2.scaley = ONE; status->mines2.rotate = 0; DrawSync(0); status->energy.attribute = 0; status->energy.x = 37; status->energy.y = 1; status->energy.w = (MAX_ENERGY>>12); status->energy.h = 12; status->energy.r = 255; status->energy.g = 255; status->energy.b = 255; DrawSync(0); } void InitStatus2(STATUS *status) { RECT rect; GsIMAGE timData; int i; //for looping // Setup status bar sprite! // Load the BG of the status bar and place in memory... GsGetTimInfo((u_long*)(DATA_STATUS_TIM+4),&timData); rect.x=timData.px; rect.y=timData.py; rect.w=timData.pw; rect.h=timData.ph; LoadImage(&rect, timData.pixel); rect.x=timData.cx; rect.y=timData.cy; rect.w=timData.cw; rect.h=timData.ch; LoadImage(&rect, timData.clut); status->menubar.attribute = (1<<24); status->menubar.x = (190); status->menubar.y = (0); status->menubar.w = (120); status->menubar.h = (26); status->menubar.tpage = GetTPage(1,0,timData.px,timData.py); status->menubar.u = 0; status->menubar.v = 26; status->menubar.cx = timData.cx; status->menubar.cy = timData.cy; status->menubar.r = 128; status->menubar.g = 128; status->menubar.b = 128; status->menubar.mx = status->menubar.w/2; status->menubar.my = status->menubar.h/2; status->menubar.scalex = ONE; status->menubar.scaley = ONE; status->menubar.rotate = 0; DrawSync(0); // Load all the number sprites for the status bar... GsGetTimInfo((u_long*)(DATA_NUMBERS_TIM+4),&timData); rect.x=timData.px; rect.y=timData.py; rect.w=timData.pw; rect.h=timData.ph; LoadImage(&rect, timData.pixel); rect.x=timData.cx; rect.y=timData.cy; rect.w=timData.cw; rect.h=timData.ch; LoadImage(&rect, timData.clut); status->lives.attribute = (1<<24); status->lives.x = (203); status->lives.y = (2); status->lives.w = (10); status->lives.h = (10); status->lives.tpage = GetTPage(1,0,timData.px,timData.py); status->lives.u = 0; status->lives.v = 0; status->lives.cx = timData.cx; status->lives.cy = timData.cy; status->lives.r = 128; status->lives.g = 128; status->lives.b = 128; status->lives.mx = status->lives.w/2; status->lives.my = status->lives.h/2; status->lives.scalex = ONE; status->lives.scaley = ONE; status->lives.rotate = 0; DrawSync(0); status->ammo1.attribute = (1<<24); status->ammo1.x = (210); status->ammo1.y = (14); status->ammo1.w = (10); status->ammo1.h = (10); status->ammo1.tpage = GetTPage(1,0,timData.px,timData.py); status->ammo1.u = 0; status->ammo1.v = 0; status->ammo1.cx = timData.cx; status->ammo1.cy = timData.cy; status->ammo1.r = 128; status->ammo1.g = 128; status->ammo1.b = 128; status->ammo1.mx = status->ammo1.w/2; status->ammo1.my = status->ammo1.h/2; status->ammo1.scalex = ONE; status->ammo1.scaley = ONE; status->ammo1.rotate = 0; DrawSync(0); status->ammo2.attribute = (1<<24); status->ammo2.x = (220); status->ammo2.y = (14); status->ammo2.w = (10); status->ammo2.h = (10); status->ammo2.tpage = GetTPage(1,0,timData.px,timData.py); status->ammo2.u = 0; status->ammo2.v = 0; status->ammo2.cx = timData.cx; status->ammo2.cy = timData.cy; status->ammo2.r = 128; status->ammo2.g = 128; status->ammo2.b = 128; status->ammo2.mx = status->ammo1.w/2; status->ammo2.my = status->ammo1.h/2; status->ammo2.scalex = ONE; status->ammo2.scaley = ONE; status->ammo2.rotate = 0; DrawSync(0); status->sniper1.attribute = (1<<24); status->sniper1.x = (246); status->sniper1.y = (14); status->sniper1.w = (10); status->sniper1.h = (10); status->sniper1.tpage = GetTPage(1,0,timData.px,timData.py); status->sniper1.u = 0; status->sniper1.v = 0; status->sniper1.cx = timData.cx; status->sniper1.cy = timData.cy; status->sniper1.r = 128; status->sniper1.g = 128; status->sniper1.b = 128; status->sniper1.mx = status->sniper1.w/2; status->sniper1.my = status->sniper1.h/2; status->sniper1.scalex = ONE; status->sniper1.scaley = ONE; status->sniper1.rotate = 0; DrawSync(0); status->sniper2.attribute = (1<<24); status->sniper2.x = (256); status->sniper2.y = (14); status->sniper2.w = (10); status->sniper2.h = (10); status->sniper2.tpage = GetTPage(1,0,timData.px,timData.py); status->sniper2.u = 0; status->sniper2.v = 0; status->sniper2.cx = timData.cx; status->sniper2.cy = timData.cy; status->sniper2.r = 128; status->sniper2.g = 128; status->sniper2.b = 128; status->sniper2.mx = status->sniper1.w/2; status->sniper2.my = status->sniper1.h/2; status->sniper2.scalex = ONE; status->sniper2.scaley = ONE; status->sniper2.rotate = 0; DrawSync(0); status->mines1.attribute = (1<<24); status->mines1.x = (282); status->mines1.y = (14); status->mines1.w = (10); status->mines1.h = (10); status->mines1.tpage = GetTPage(1,0,timData.px,timData.py); status->mines1.u = 0; status->mines1.v = 0; status->mines1.cx = timData.cx; status->mines1.cy = timData.cy; status->mines1.r = 128; status->mines1.g = 128; status->mines1.b = 128; status->mines1.mx = status->mines1.w/2; status->mines1.my = status->mines1.h/2; status->mines1.scalex = ONE; status->mines1.scaley = ONE; status->mines1.rotate = 0; DrawSync(0); status->mines2.attribute = (1<<24); status->mines2.x = (292); status->mines2.y = (14); status->mines2.w = (10); status->mines2.h = (10); status->mines2.tpage = GetTPage(1,0,timData.px,timData.py); status->mines2.u = 0; status->mines2.v = 0; status->mines2.cx = timData.cx; status->mines2.cy = timData.cy; status->mines2.r = 128; status->mines2.g = 128; status->mines2.b = 128; status->mines2.mx = status->mines1.w/2; status->mines2.my = status->mines1.h/2; status->mines2.scalex = ONE; status->mines2.scaley = ONE; status->mines2.rotate = 0; DrawSync(0); status->energy.attribute = 0; status->energy.x = 217; status->energy.y = 1; status->energy.w = (MAX_ENERGY>>12); status->energy.h = 12; status->energy.r = 255; status->energy.g = 255; status->energy.b = 255; DrawSync(0); }