Import of version 1.1 minus music, sound and graphics.
This commit is contained in:
commit
09b007411c
|
@ -0,0 +1,148 @@
|
||||||
|
/*
|
||||||
|
Project: Starfighter
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
All Rights Reserved
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "version.h"
|
||||||
|
#include "Starfighter.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
defineGlobals(); // Must do this first!
|
||||||
|
|
||||||
|
signed char cheatAttempt = 0;
|
||||||
|
|
||||||
|
if (argc > 1)
|
||||||
|
{
|
||||||
|
if (strcmp("--help", argv[1]) == 0)
|
||||||
|
{
|
||||||
|
printf("\nProject: Starfighter %s\n", VERSION);
|
||||||
|
printf("Copyright Parallel Realities 2003\n\n");
|
||||||
|
printf("Additional Commands\n");
|
||||||
|
printf("\t-noaudio Disables sound and music\n");
|
||||||
|
printf("\t-mono Mono sound output (best for headphones)\n\n");
|
||||||
|
printf("www.parallelrealities.co.uk\n");
|
||||||
|
printf("\n");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 1 ; i < argc ; i++)
|
||||||
|
{
|
||||||
|
#if USEPACK
|
||||||
|
#else
|
||||||
|
if (strcmp(argv[i], "-nomove") == 0)
|
||||||
|
{printf("Enemy movement disabled\n"); dev.moveAliens = 0;}
|
||||||
|
if (strcmp(argv[i], "-nofire") == 0)
|
||||||
|
{printf("Enemy firing disabled\n"); dev.fireAliens = 0;}
|
||||||
|
#endif
|
||||||
|
if (strcmp(argv[i], "-cheat") == 0)
|
||||||
|
cheatAttempt = 1;
|
||||||
|
if (strcmp(argv[i], "-noaudio") == 0)
|
||||||
|
{printf("No Audio\n"); engine.useAudio = 0;}
|
||||||
|
if (strcmp(argv[i], "-mono") == 0)
|
||||||
|
{printf("Mono sound output\n"); engine.useAudio = 1;}
|
||||||
|
}
|
||||||
|
|
||||||
|
atexit(cleanUp);
|
||||||
|
|
||||||
|
initSystem(); // Opens video mode and sound
|
||||||
|
loadFont();
|
||||||
|
|
||||||
|
if (cheatAttempt)
|
||||||
|
{
|
||||||
|
graphics.clearScreen(graphics.black);
|
||||||
|
graphics.drawString("That doesn't work anymore", -1, 285, FONT_WHITE);
|
||||||
|
graphics.drawString("Try harder...", -1, 315, FONT_WHITE);
|
||||||
|
graphics.updateScreen();
|
||||||
|
SDL_Delay(2000);
|
||||||
|
graphics.clearScreen(graphics.black);
|
||||||
|
graphics.updateScreen();
|
||||||
|
SDL_Delay(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.freeGraphics();
|
||||||
|
loadSound();
|
||||||
|
|
||||||
|
initWeapons();
|
||||||
|
|
||||||
|
initVars();
|
||||||
|
defineAliens();
|
||||||
|
|
||||||
|
graphics.setColorIndexes();
|
||||||
|
|
||||||
|
setAllyMessages();
|
||||||
|
|
||||||
|
showStory();
|
||||||
|
|
||||||
|
// Determine which part of the game we will go to...
|
||||||
|
int section = 0;
|
||||||
|
|
||||||
|
newGame();
|
||||||
|
|
||||||
|
/*
|
||||||
|
currentGame.system = 3;
|
||||||
|
currentGame.area = 24;
|
||||||
|
currentGame.shieldUnits = 4;
|
||||||
|
currentGame.hasWingMate1 = 1;
|
||||||
|
currentGame.hasWingMate2 = 1;
|
||||||
|
|
||||||
|
player.shield = (currentGame.shieldUnits * 25);
|
||||||
|
|
||||||
|
player.weaponType[1] = W_LASER;
|
||||||
|
|
||||||
|
player.ammo[0] = 1;
|
||||||
|
weapon[1].ammo[0] = 3;
|
||||||
|
weapon[1].damage = 5;
|
||||||
|
weapon[1].reload[0] = 7;
|
||||||
|
|
||||||
|
engine.cheatAmmo = 1;
|
||||||
|
engine.cheatShield = 1;
|
||||||
|
engine.cheatCash = 1;
|
||||||
|
updateSystemStatus();
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
switch(section)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
section = doTitle();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
section = galaxyMap();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if (currentGame.stationedPlanet == -1) {doCutscene(0);}
|
||||||
|
section = mainGameLoop();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//doTitle();
|
||||||
|
//galaxyMap();
|
||||||
|
//mainGameLoop();
|
||||||
|
//doCutscene(2);
|
||||||
|
//doCredits();
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern void initSystem();
|
||||||
|
extern void loadGameGraphics();
|
||||||
|
extern void loadSound();
|
||||||
|
extern void initWeapons();
|
||||||
|
extern void initMissions();
|
||||||
|
extern void initVars();
|
||||||
|
extern void showStory();
|
||||||
|
extern int doTitle();
|
||||||
|
extern void defineAliens();
|
||||||
|
extern void loadFont();
|
||||||
|
extern int galaxyMap();
|
||||||
|
extern void defineGlobals();
|
||||||
|
extern void cleanUp();
|
||||||
|
extern int mainGameLoop();
|
||||||
|
extern void setAllyMessages();
|
||||||
|
extern void newGame();
|
||||||
|
extern void doCredits();
|
||||||
|
extern void getPlayerInput();
|
||||||
|
extern void initPlanetMissions(signed char system);
|
||||||
|
extern void updateSystemStatus();
|
||||||
|
extern void doCutscene(int scene);
|
||||||
|
|
||||||
|
globalEngineVariables engine;
|
||||||
|
devVariables dev;
|
||||||
|
Game currentGame;
|
||||||
|
object player;
|
||||||
|
mission currentMission;
|
||||||
|
Graphics graphics;
|
||||||
|
|
||||||
|
object enemy[MAX_ALIENS];
|
||||||
|
Star star[200];
|
||||||
|
Planet systemPlanet[10];
|
||||||
|
mission missions[MAX_MISSIONS];
|
||||||
|
ShopItem shopItems[MAX_SHOPITEMS];
|
||||||
|
Mix_Chunk *sound[MAX_SOUNDS];
|
||||||
|
object weapon[MAX_WEAPONS];
|
||||||
|
object cargo[MAX_CARGO];
|
||||||
|
event gameEvent[10];
|
||||||
|
cutMsg cutMessage[10];
|
|
@ -0,0 +1,200 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ai.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Some very simple artificial intelligence routines for the aliens.
|
||||||
|
Shouldn't really be called AI since they just do things at random.
|
||||||
|
Aliens are assigned various AI types and this routine makes use of them.
|
||||||
|
Levels of aggression, defence and evasion are all here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void setEnemyAI(object *theEnemy)
|
||||||
|
{
|
||||||
|
// Make friendly craft generally concentrate on smaller fighters
|
||||||
|
if ((theEnemy->flags & FL_FRIEND) && (theEnemy->target == &enemy[WC_BOSS]))
|
||||||
|
{
|
||||||
|
if ((rand() % 5) == 0)
|
||||||
|
{
|
||||||
|
theEnemy->target = theEnemy;
|
||||||
|
theEnemy->thinktime = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int i = rand() % 10;
|
||||||
|
float tx = theEnemy->target->x;
|
||||||
|
float ty = theEnemy->target->y;
|
||||||
|
|
||||||
|
int chase = 0; // Chance in 10 of chasing player
|
||||||
|
int area = 0; // Chance in 10 of moving to an area around the player
|
||||||
|
int stop = 0; // Chance in 10 of hanging back
|
||||||
|
int point = 0; // Size of area alien will move into
|
||||||
|
|
||||||
|
switch (theEnemy->AIType)
|
||||||
|
{
|
||||||
|
case AI_NORMAL:
|
||||||
|
chase = 3;
|
||||||
|
point = 6;
|
||||||
|
stop = 9;
|
||||||
|
area = 250;
|
||||||
|
break;
|
||||||
|
case AI_OFFENSIVE:
|
||||||
|
chase = 7;
|
||||||
|
point = 8;
|
||||||
|
stop = 9;
|
||||||
|
area = 50;
|
||||||
|
break;
|
||||||
|
case AI_DEFENSIVE:
|
||||||
|
chase = 2;
|
||||||
|
point = 6;
|
||||||
|
stop = 8;
|
||||||
|
area = 300;
|
||||||
|
break;
|
||||||
|
case AI_EVASIVE:
|
||||||
|
chase = 1;
|
||||||
|
point = 8;
|
||||||
|
stop = 9;
|
||||||
|
area = 600;
|
||||||
|
break;
|
||||||
|
case AI_WANDER:
|
||||||
|
chase = -1;
|
||||||
|
point = 0;
|
||||||
|
stop = 10;
|
||||||
|
area = 1200;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i <= chase)
|
||||||
|
{
|
||||||
|
// Chase the target
|
||||||
|
theEnemy->dx = ((theEnemy->x - tx) / ((300 / theEnemy->speed) + rand() % 100));
|
||||||
|
theEnemy->dy = ((theEnemy->y - ty) / ((300 / theEnemy->speed) + rand() % 100));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if ((i >= point) && (i <= stop))
|
||||||
|
{
|
||||||
|
// Fly to a random point around the target
|
||||||
|
tx += (rand() % area - (rand() % area * 2));
|
||||||
|
ty += (rand() % area - (rand() % area * 2));
|
||||||
|
theEnemy->dx = ((theEnemy->x - tx) / ((300 / theEnemy->speed) + rand() % 100));
|
||||||
|
theEnemy->dy = ((theEnemy->y - ty) / ((300 / theEnemy->speed) + rand() % 100));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Hang back
|
||||||
|
theEnemy->dx = 0;
|
||||||
|
theEnemy->dy = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setKlineAttackMethod(object *theEnemy)
|
||||||
|
{
|
||||||
|
theEnemy->maxShield -= 500;
|
||||||
|
if (theEnemy->maxShield == 0)
|
||||||
|
theEnemy->flags -= FL_CANNOTDIE;
|
||||||
|
|
||||||
|
if (theEnemy->maxShield == 1000)
|
||||||
|
{
|
||||||
|
setRadioMessage(FACE_KLINE, "Very good, Bainfield. Now let's get a little more serious...", 1);
|
||||||
|
theEnemy->weaponType[0] = W_SPREADSHOT;
|
||||||
|
theEnemy->chance[1] = 40;
|
||||||
|
}
|
||||||
|
else if (theEnemy->maxShield == 500)
|
||||||
|
{
|
||||||
|
setRadioMessage(FACE_KLINE, "Your ability to stay alive irritates me!! Try dodging some of these!!", 1);
|
||||||
|
theEnemy->weaponType[0] = W_DIRSHOCKMISSILE;
|
||||||
|
theEnemy->weaponType[1] = W_DIRSHOCKMISSILE;
|
||||||
|
theEnemy->chance[0] = 2;
|
||||||
|
theEnemy->chance[1] = 2;
|
||||||
|
theEnemy->flags += FL_AIMS;
|
||||||
|
}
|
||||||
|
else if (theEnemy->maxShield == 0)
|
||||||
|
{
|
||||||
|
setRadioMessage(FACE_KLINE, "ENOUGH!! THIS ENDS NOW!!!", 1);
|
||||||
|
theEnemy->weaponType[0] = W_AIMED_SHOT;
|
||||||
|
theEnemy->weaponType[1] = W_MICRO_HOMING_MISSILES;
|
||||||
|
theEnemy->flags += FL_CANCLOAK;
|
||||||
|
theEnemy->chance[0] = 100;
|
||||||
|
theEnemy->chance[1] = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
theEnemy->shield = 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This AI is exclusively for Kline.
|
||||||
|
*/
|
||||||
|
void setKlineAI(object *theEnemy)
|
||||||
|
{
|
||||||
|
// Weapon type change
|
||||||
|
if ((rand() % 3) == 0)
|
||||||
|
{
|
||||||
|
if (currentGame.area != 26)
|
||||||
|
{
|
||||||
|
if (theEnemy->flags & FL_AIMS)
|
||||||
|
theEnemy->flags -= FL_AIMS;
|
||||||
|
|
||||||
|
switch(rand() % 2)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
theEnemy->weaponType[0] = W_TRIPLE_SHOT;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
theEnemy->weaponType[0] = W_AIMED_SHOT;
|
||||||
|
theEnemy->flags += FL_AIMS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theEnemy->flags & FL_CIRCLES)
|
||||||
|
theEnemy->flags -= FL_CIRCLES;
|
||||||
|
if (theEnemy->flags & FL_CONTINUOUS_FIRE)
|
||||||
|
theEnemy->flags -= FL_CONTINUOUS_FIRE;
|
||||||
|
if (theEnemy->flags & FL_DROPMINES)
|
||||||
|
theEnemy->flags -= FL_DROPMINES;
|
||||||
|
|
||||||
|
switch(rand() % 10)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if ((theEnemy->weaponType[0] != W_DIRSHOCKMISSILE) && (theEnemy->weaponType[1] != W_MICRO_HOMING_MISSILES))
|
||||||
|
theEnemy->flags += FL_CONTINUOUS_FIRE;
|
||||||
|
theEnemy->dx = ((theEnemy->x - theEnemy->target->x) / ((300 / theEnemy->speed) + rand() % 100));
|
||||||
|
theEnemy->dy = ((theEnemy->y - theEnemy->target->y) / ((300 / theEnemy->speed) + rand() % 100));
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
// Kline only attacks then he is ready!
|
||||||
|
if ((!(theEnemy->flags & FL_NOFIRE)) && (currentGame.area == 11))
|
||||||
|
theEnemy->flags += FL_DROPMINES;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
theEnemy->flags += FL_CIRCLES;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
setEnemyAI(theEnemy);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern void setRadioMessage(signed char face, char *in, int priority);
|
||||||
|
|
||||||
|
extern object enemy[MAX_ALIENS];
|
||||||
|
extern object player;
|
||||||
|
extern Game currentGame;
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern void setEnemyAI(object *theEnemy);
|
||||||
|
extern void setKlineAI(object *theEnemy);
|
||||||
|
extern void fireBullet(object *attacker, int weaponType);
|
||||||
|
extern void addExplosion(float x, float y, int type);
|
||||||
|
extern void addEngine(object *craft);
|
||||||
|
extern void fireRay(object *attacker);
|
||||||
|
extern void addDebris(int x, int y, int amount);
|
||||||
|
extern void playSound(int sid);
|
||||||
|
extern int locateDataInPak(char *file, signed char required);
|
||||||
|
extern object *addCargo(object *owner, int cargoType);
|
||||||
|
extern void addCollectable(float x, float y, int type, int value, int life);
|
||||||
|
extern void updateMissionRequirements(int type, int id, int value);
|
||||||
|
extern void setInfoLine(char *in, int color);
|
||||||
|
extern void addBullet(object *theWeapon, object *attacker, int y, int dy);
|
||||||
|
extern void showErrorAndExit(int errorId, char *name);
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern devVariables dev;
|
||||||
|
extern Game currentGame;
|
||||||
|
extern object player;
|
||||||
|
extern object enemy[MAX_ALIENS];
|
||||||
|
extern Graphics graphics;
|
||||||
|
extern mission currentMission;
|
||||||
|
extern object weapon[MAX_WEAPONS];
|
||||||
|
|
||||||
|
object defEnemy[MAX_DEFALIENS]; // A predefined enemy
|
|
@ -0,0 +1,136 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "audio.h"
|
||||||
|
|
||||||
|
void playSound(int sid)
|
||||||
|
{
|
||||||
|
if ((!currentGame.useSound) || (!engine.useAudio))
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch(sid)
|
||||||
|
{
|
||||||
|
case SFX_DEATH:
|
||||||
|
case SFX_CLOCK:
|
||||||
|
case SFX_FLY:
|
||||||
|
case SFX_SHIELDUP:
|
||||||
|
case SFX_PICKUP:
|
||||||
|
case SFX_CLOAK:
|
||||||
|
case SFX_PLASMA2:
|
||||||
|
case SFX_PLASMA3:
|
||||||
|
Mix_PlayChannel(-1, sound[sid], 0);
|
||||||
|
break;
|
||||||
|
case SFX_PLASMA:
|
||||||
|
case SFX_LASER:
|
||||||
|
Mix_PlayChannel(0, sound[sid], 0);
|
||||||
|
break;
|
||||||
|
case SFX_ENERGYRAY:
|
||||||
|
case SFX_MISSILE:
|
||||||
|
Mix_PlayChannel(1, sound[sid], 0);
|
||||||
|
break;
|
||||||
|
case SFX_HIT:
|
||||||
|
Mix_PlayChannel(4, sound[sid], 0);
|
||||||
|
break;
|
||||||
|
case SFX_EXPLOSION:
|
||||||
|
case SFX_DEBRIS:
|
||||||
|
case SFX_DEBRIS2:
|
||||||
|
Mix_PlayChannel(3, sound[sid], 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Mix_Chunk *loadSound(char *filename)
|
||||||
|
{
|
||||||
|
Mix_Chunk *chunk;
|
||||||
|
|
||||||
|
#if USEPACK
|
||||||
|
unpack(filename, PAK_WAV);
|
||||||
|
chunk = Mix_LoadWAV_RW(engine.sdlrw, 1);
|
||||||
|
#else
|
||||||
|
chunk = Mix_LoadWAV(filename);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadMusic(char *filename)
|
||||||
|
{
|
||||||
|
if (Mix_PlayingMusic())
|
||||||
|
Mix_HaltMusic();
|
||||||
|
|
||||||
|
if (engine.music != NULL)
|
||||||
|
Mix_FreeMusic(engine.music);
|
||||||
|
|
||||||
|
#if USEPACK
|
||||||
|
unpack(filename, PAK_MOD);
|
||||||
|
|
||||||
|
char musicFilename[PATH_MAX];
|
||||||
|
strcpy(musicFilename, "");
|
||||||
|
sprintf(musicFilename, "%smusic.mod", engine.userHomeDirectory);
|
||||||
|
|
||||||
|
engine.music = Mix_LoadMUS(musicFilename);
|
||||||
|
#else
|
||||||
|
engine.music = Mix_LoadMUS(filename);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void playRandomTrack()
|
||||||
|
{
|
||||||
|
if ((!currentGame.useMusic) || (!engine.useAudio))
|
||||||
|
return;
|
||||||
|
|
||||||
|
int tracks = 0;
|
||||||
|
|
||||||
|
char track[][30] = {
|
||||||
|
"music/Frantic.mod", "music/Artificial.mod", "music/Lunatic.mod", "music/ToxicFriend.mod",
|
||||||
|
"music/DigitalInferno.mod", "music/TempoTrance.mod", "music/IntoTheMachine.mod"
|
||||||
|
};
|
||||||
|
|
||||||
|
switch(currentGame.system)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
tracks = 3;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
tracks = 5;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
tracks = 7;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(currentGame.area)
|
||||||
|
{
|
||||||
|
case 5:
|
||||||
|
case 11:
|
||||||
|
case 18:
|
||||||
|
case 25:
|
||||||
|
loadMusic("music/HardTranceDub.mod");
|
||||||
|
break;
|
||||||
|
case 26:
|
||||||
|
loadMusic("music/LoopsAndTings.mod");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
loadMusic(track[rand() % tracks]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Mix_PlayMusic(engine.music, -1);
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
|
||||||
|
extern void unpack(char *file, signed char fileType);
|
||||||
|
extern void freePackBuffer();
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern Game currentGame;
|
||||||
|
extern Mix_Chunk *sound[MAX_SOUNDS];
|
|
@ -0,0 +1,797 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "bullets.h"
|
||||||
|
|
||||||
|
void addBullet(object *theWeapon, object *attacker, int y, int dy)
|
||||||
|
{
|
||||||
|
object *bullet;
|
||||||
|
signed char imageIndex;
|
||||||
|
int tempX, tempY, steps;
|
||||||
|
|
||||||
|
bullet = new object;
|
||||||
|
|
||||||
|
if (attacker == &player)
|
||||||
|
currentGame.shots++;
|
||||||
|
|
||||||
|
bullet->next = NULL;
|
||||||
|
bullet->active = 1;
|
||||||
|
bullet->x = attacker->x - ((attacker->image[0]->w / 2) * attacker->face);
|
||||||
|
bullet->y = attacker->y + y;
|
||||||
|
bullet->flags = theWeapon->flags;
|
||||||
|
bullet->shield = 300; // bullets live for (approximately) 5 seconds
|
||||||
|
|
||||||
|
// Timed explosions live between 1 and 3 seconds
|
||||||
|
if (bullet->flags & WF_TIMEDEXPLOSION)
|
||||||
|
bullet->shield = 60 + ((rand() % 3) * 60);
|
||||||
|
|
||||||
|
if (attacker->face == 0)
|
||||||
|
{
|
||||||
|
bullet->dx = theWeapon->speed;
|
||||||
|
if ((currentGame.area == 18) || (currentGame.area == 24))
|
||||||
|
bullet->dx += fabs(engine.ssx);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bullet->dx = (0 - theWeapon->speed);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bullet->flags & WF_VARIABLE_SPEED)
|
||||||
|
{
|
||||||
|
bullet->dx = Math::rrand(100, 200);
|
||||||
|
bullet->dx /= 10;
|
||||||
|
if (attacker->face == 1)
|
||||||
|
bullet->dx = 0 - bullet->dx;
|
||||||
|
}
|
||||||
|
|
||||||
|
bullet->dy = dy;
|
||||||
|
|
||||||
|
if (bullet->flags & WF_SCATTER)
|
||||||
|
{
|
||||||
|
bullet->dy = Math::rrand(-200, 200);
|
||||||
|
if (bullet->dy != 0)
|
||||||
|
bullet->dy /= 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attacker->flags & FL_WEAPCO)
|
||||||
|
bullet->flags += WF_WEAPCO;
|
||||||
|
else
|
||||||
|
bullet->flags += WF_FRIEND;
|
||||||
|
|
||||||
|
bullet->owner = attacker->owner;
|
||||||
|
|
||||||
|
bullet->id = theWeapon->id;
|
||||||
|
|
||||||
|
bullet->damage = theWeapon->damage;
|
||||||
|
|
||||||
|
if (bullet->id == WT_CHARGER)
|
||||||
|
{
|
||||||
|
bullet->damage = attacker->ammo[1];
|
||||||
|
if (bullet->damage < 50)
|
||||||
|
{
|
||||||
|
bullet->damage = 1;
|
||||||
|
bullet->id = WT_PLASMA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bullet->target = NULL;
|
||||||
|
|
||||||
|
if (attacker->flags & FL_FRIEND)
|
||||||
|
imageIndex = 0;
|
||||||
|
else
|
||||||
|
imageIndex = 1;
|
||||||
|
|
||||||
|
// Use the enemy's images if applicable
|
||||||
|
if (bullet->id != WT_ROCKET)
|
||||||
|
bullet->image[0] = theWeapon->image[imageIndex];
|
||||||
|
else
|
||||||
|
bullet->image[0] = theWeapon->image[attacker->face];
|
||||||
|
|
||||||
|
if (bullet->flags & WF_AIMED)
|
||||||
|
{
|
||||||
|
tempX = (int)fabs(attacker->target->x - attacker->x);
|
||||||
|
tempY = (int)fabs(attacker->target->y - attacker->y);
|
||||||
|
steps = max(tempX, tempY);
|
||||||
|
|
||||||
|
if (steps == 0)
|
||||||
|
steps = 12;
|
||||||
|
|
||||||
|
if (!(bullet->flags & WF_TIMEDEXPLOSION))
|
||||||
|
steps /= 8;
|
||||||
|
else
|
||||||
|
steps /= 6 + (rand() % 6);
|
||||||
|
|
||||||
|
tempX = (int)(attacker->target->x - attacker->x);
|
||||||
|
tempY = (int)(attacker->target->y - attacker->y);
|
||||||
|
|
||||||
|
bullet->dx = tempX / steps;
|
||||||
|
bullet->dy = tempY / steps;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attacker->classDef == CD_ASTEROID)
|
||||||
|
{
|
||||||
|
bullet->dx = Math::rrand(-20, 20);
|
||||||
|
bullet->dy = Math::rrand(-20, 20);
|
||||||
|
bullet->image[0] = graphics.shape[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
engine.bulletTail->next = bullet;
|
||||||
|
engine.bulletTail = bullet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fill in later...
|
||||||
|
*/
|
||||||
|
void fireBullet(object *attacker, int weaponType)
|
||||||
|
{
|
||||||
|
if (attacker->reload[weaponType] > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int y = (attacker->image[0]->h) / 5;
|
||||||
|
|
||||||
|
// Remove some ammo from the player
|
||||||
|
if ((attacker == &player) && (weaponType == 1) && (!engine.cheatAmmo))
|
||||||
|
player.ammo[1]--;
|
||||||
|
|
||||||
|
object *theWeapon = &weapon[attacker->weaponType[weaponType]];
|
||||||
|
|
||||||
|
switch(theWeapon->id)
|
||||||
|
{
|
||||||
|
case WT_PLASMA:
|
||||||
|
case WT_SPREAD:
|
||||||
|
case WT_DIRECTIONAL:
|
||||||
|
playSound(SFX_PLASMA);
|
||||||
|
break;
|
||||||
|
case WT_ROCKET:
|
||||||
|
playSound(SFX_MISSILE);
|
||||||
|
break;
|
||||||
|
case WT_LASER:
|
||||||
|
playSound(SFX_LASER);
|
||||||
|
break;
|
||||||
|
case WT_CHARGER:
|
||||||
|
playSound(SFX_PLASMA3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theWeapon->flags & WF_STRAIGHT)
|
||||||
|
{
|
||||||
|
switch (theWeapon->ammo[0])
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
addBullet(theWeapon, attacker, y * 3, 0);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
addBullet(theWeapon, attacker, y * 2, 0);
|
||||||
|
addBullet(theWeapon, attacker, y * 4, 0);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
addBullet(theWeapon, attacker, y * 2, 0);
|
||||||
|
addBullet(theWeapon, attacker, y * 3, 0);
|
||||||
|
addBullet(theWeapon, attacker, y * 4, 0);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
addBullet(theWeapon, attacker, y, 0);
|
||||||
|
addBullet(theWeapon, attacker, y * 2, 0);
|
||||||
|
addBullet(theWeapon, attacker, y * 4, 0);
|
||||||
|
addBullet(theWeapon, attacker, y * 5, 0);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
for (int i = 1 ; i < 6; i++)
|
||||||
|
addBullet(theWeapon, attacker, y * i, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (theWeapon->flags & WF_THIN_SPREAD)
|
||||||
|
{
|
||||||
|
addBullet(theWeapon, attacker, y * 2, -1);
|
||||||
|
if (theWeapon->ammo[0] == 3)
|
||||||
|
{
|
||||||
|
addBullet(theWeapon, attacker, y * 3, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
addBullet(theWeapon, attacker, y * 2, 0);
|
||||||
|
addBullet(theWeapon, attacker, y * 4, 0);
|
||||||
|
}
|
||||||
|
addBullet(theWeapon, attacker, y * 4, 1);
|
||||||
|
}
|
||||||
|
else if (theWeapon->flags & WF_WIDE_SPREAD)
|
||||||
|
{
|
||||||
|
addBullet(theWeapon, attacker, y * 1, -2);
|
||||||
|
addBullet(theWeapon, attacker, y * 2, -1);
|
||||||
|
addBullet(theWeapon, attacker, y * 3, 0);
|
||||||
|
addBullet(theWeapon, attacker, y * 4, 1);
|
||||||
|
addBullet(theWeapon, attacker, y * 5, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset the weapon reload time. Double it if it is not friendly or a boss or Kline
|
||||||
|
attacker->reload[weaponType] = theWeapon->reload[0];
|
||||||
|
if ((attacker->flags & FL_WEAPCO) && (attacker != &enemy[WC_BOSS]) && (attacker != &enemy[WC_KLINE]) && (theWeapon->id != W_LASER))
|
||||||
|
attacker->reload[weaponType] *= 2;
|
||||||
|
|
||||||
|
if ((engine.cheatAmmo) || (theWeapon->id == WT_LASER))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((attacker == &player) && (weaponType == 0))
|
||||||
|
{
|
||||||
|
if (player.ammo[0] > 0)
|
||||||
|
{
|
||||||
|
player.ammo[0]--;
|
||||||
|
if (player.ammo[0] == 0)
|
||||||
|
{
|
||||||
|
player.weaponType[0] = W_PLAYER_WEAPON;
|
||||||
|
weapon[W_PLAYER_WEAPON2] = weapon[W_PLAYER_WEAPON]; // reset to weapon 1 defaults
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Used for homing missiles. When a missile is active and it is told to home in
|
||||||
|
on an enemy, it will attempt to randomly grab one every frame if it does not
|
||||||
|
already have a target. If the target it is currently chasing is killed, it will
|
||||||
|
begin to look for a new one (done in doBullets()). The homing missile will make
|
||||||
|
one attempt per call (one call per frame) to find a suitable target. If the target
|
||||||
|
it picks is dead or outside the screen range, then it returns NULL. A suitable
|
||||||
|
target will be returned as the object address.
|
||||||
|
*/
|
||||||
|
object *getRandomEnemy(object *bullet)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (bullet->owner->flags & FL_WEAPCO)
|
||||||
|
{
|
||||||
|
i = (rand() % 10);
|
||||||
|
|
||||||
|
if (i < 1)
|
||||||
|
return &player;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = rand() % MAX_ALIENS;
|
||||||
|
|
||||||
|
if ((enemy[i].shield < 1) || (!enemy[i].active))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if ((bullet->owner->flags & FL_WEAPCO) && (enemy[i].flags & FL_WEAPCO))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if ((bullet->owner->flags & FL_FRIEND) && (enemy[i].flags & FL_FRIEND))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (abs((int)bullet->x - (int)enemy[i].target->x) > 800)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (abs((int)bullet->y - (int)enemy[i].target->y) > 200)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return &enemy[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fill in later...
|
||||||
|
*/
|
||||||
|
void destroyAlien(object *bullet, object *theEnemy)
|
||||||
|
{
|
||||||
|
playSound(SFX_EXPLOSION);
|
||||||
|
|
||||||
|
// Chain reaction destruction if needed
|
||||||
|
if (theEnemy->flags & FL_DAMAGEOWNER)
|
||||||
|
{
|
||||||
|
theEnemy->owner->shield -= theEnemy->maxShield;
|
||||||
|
if (theEnemy->owner->shield < 1)
|
||||||
|
destroyAlien(bullet, theEnemy->owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theEnemy->flags & FL_FRIEND)
|
||||||
|
{
|
||||||
|
if (theEnemy->classDef == CD_PHOEBE)
|
||||||
|
currentGame.wingMate1Ejects++;
|
||||||
|
else if (theEnemy->classDef == CD_URSULA)
|
||||||
|
currentGame.wingMate2Ejects++;
|
||||||
|
|
||||||
|
// Phoebe cannot eject on the rescue mission
|
||||||
|
if (currentGame.area != 7)
|
||||||
|
{
|
||||||
|
if ((theEnemy->classDef == CD_PHOEBE) || (theEnemy->classDef == CD_URSULA))
|
||||||
|
setInfoLine(">> Ally has ejected! <<\n", FONT_RED);
|
||||||
|
else
|
||||||
|
setInfoLine(">> Friendly craft has been destroy!! <<\n", FONT_RED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bullet->owner == &player)
|
||||||
|
{
|
||||||
|
// Once again, stop point leeching
|
||||||
|
if (currentGame.area != MAX_MISSIONS - 1)
|
||||||
|
currentGame.cash += theEnemy->score;
|
||||||
|
currentGame.cashEarned += theEnemy->score;
|
||||||
|
currentGame.totalKills++;
|
||||||
|
}
|
||||||
|
else if (bullet->owner->classDef == CD_PHOEBE)
|
||||||
|
{
|
||||||
|
currentGame.wingMate1Kills++;
|
||||||
|
}
|
||||||
|
else if (bullet->owner->classDef == CD_URSULA)
|
||||||
|
{
|
||||||
|
currentGame.wingMate2Kills++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentGame.totalOtherKills++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((bullet->owner->classDef == CD_PHOEBE) || (bullet->owner->classDef == CD_URSULA))
|
||||||
|
{
|
||||||
|
if ((rand() % 8) == 0)
|
||||||
|
{
|
||||||
|
getKillMessage(bullet->owner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMissionRequirements(M_DESTROY_TARGET_TYPE, theEnemy->classDef, 1);
|
||||||
|
updateMissionRequirements(M_PROTECT_TARGET, theEnemy->classDef, 1);
|
||||||
|
|
||||||
|
if (rand() % 100 <= theEnemy->collectChance)
|
||||||
|
{
|
||||||
|
unsigned char value;
|
||||||
|
|
||||||
|
if ((rand() % 10) == 0)
|
||||||
|
theEnemy->collectValue *= 2;
|
||||||
|
|
||||||
|
while (theEnemy->collectValue > 0)
|
||||||
|
{
|
||||||
|
value = (10 + (rand() % theEnemy->collectValue));
|
||||||
|
if (value > theEnemy->collectValue)
|
||||||
|
value =theEnemy->collectValue;
|
||||||
|
addCollectable(theEnemy->x, theEnemy->y, theEnemy->collectType, value, 600);
|
||||||
|
theEnemy->collectValue -= value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make it explode immediately
|
||||||
|
if (theEnemy->classDef == CD_ASTEROID)
|
||||||
|
{
|
||||||
|
theEnemy->shield = -999;
|
||||||
|
if ((currentGame.area == 10) && (theEnemy != &enemy[0]) && (currentMission.completed1[0] == 0) && (currentMission.targetValue1[1] == 1))
|
||||||
|
engine.targetArrowTimer = 120;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((theEnemy->classDef == CD_KRASS) && (bullet->owner == &player))
|
||||||
|
setRadioMessage(FACE_CHRIS, "My NAME is CHRIS!!!!!!!!", 1);
|
||||||
|
|
||||||
|
if (theEnemy->classDef == CD_KLINE)
|
||||||
|
{
|
||||||
|
setRadioMessage(FACE_KLINE, "It was an honor... to have fought you...", 1);
|
||||||
|
theEnemy->dx = theEnemy->dy = 0;
|
||||||
|
theEnemy->maxShield = 1500;
|
||||||
|
theEnemy->shield = -200;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char checkPlayerShockDamage(float x, float y, int radius)
|
||||||
|
{
|
||||||
|
// Don't let the player be hurt by an explosion after they have completed
|
||||||
|
// all the mission objectives. That would be *really* annoying!
|
||||||
|
if ((engine.cheatShield) || (engine.missionCompleteTimer != 0))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
float distX = fabs(x - player.x);
|
||||||
|
float distY = fabs(y - player.y);
|
||||||
|
|
||||||
|
if ((distX <= 50) && (distY <= 50))
|
||||||
|
{
|
||||||
|
if (distX >= 1)
|
||||||
|
distX /= 5;
|
||||||
|
|
||||||
|
if (distY >= 1)
|
||||||
|
distY /= 5;
|
||||||
|
|
||||||
|
player.shield -= (int)(10 - distX);
|
||||||
|
player.shield -= (int)(10 - distY);
|
||||||
|
Math::limitInt(&player.shield, 0, player.maxShield);
|
||||||
|
player.hit = 10;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fill in later...
|
||||||
|
*/
|
||||||
|
void fireRay(object *attacker)
|
||||||
|
{
|
||||||
|
SDL_Rect ray;
|
||||||
|
|
||||||
|
if (attacker->face == 0)
|
||||||
|
{
|
||||||
|
ray.x = (int)(attacker->x + attacker->image[0]->w);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ray.x = (int)(attacker->x - 800);
|
||||||
|
}
|
||||||
|
ray.y = (int)(attacker->y + attacker->engineY - 1);
|
||||||
|
ray.h = 3;
|
||||||
|
ray.w = 800;
|
||||||
|
|
||||||
|
int red = SDL_MapRGB(graphics.screen->format, rand() % 256, 0x00, 0x00);
|
||||||
|
SDL_FillRect(graphics.screen, &ray, red);
|
||||||
|
graphics.addBuffer(ray.x, ray.y, ray.w, ray.h);
|
||||||
|
|
||||||
|
if (attacker != &player)
|
||||||
|
{
|
||||||
|
if (player.shield > 0)
|
||||||
|
{
|
||||||
|
if (Collision::collision(player.x, player.y, player.image[0]->w, player.image[0]->h, ray.x, ray.y, ray.w, ray.h) && (!engine.cheatShield))
|
||||||
|
{
|
||||||
|
if (player.shield > engine.lowShield)
|
||||||
|
{
|
||||||
|
if (player.shield - 1 <= engine.lowShield)
|
||||||
|
{
|
||||||
|
setInfoLine("!!! WARNING: SHIELD LOW !!!", FONT_RED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
player.shield--;
|
||||||
|
|
||||||
|
addExplosion(player.x, player.y, E_SMALL_EXPLOSION);
|
||||||
|
playSound(SFX_HIT);
|
||||||
|
if (player.shield < 1)
|
||||||
|
{
|
||||||
|
playSound(SFX_DEATH);
|
||||||
|
playSound(SFX_EXPLOSION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object *anEnemy = enemy;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < MAX_ALIENS ; i++)
|
||||||
|
{
|
||||||
|
if (anEnemy->flags & FL_IMMORTAL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((anEnemy->shield > 0) && (attacker != anEnemy) && (attacker->classDef != anEnemy->classDef))
|
||||||
|
{
|
||||||
|
if (Collision::collision(anEnemy->x, anEnemy->y, anEnemy->image[0]->w, anEnemy->image[0]->h, ray.x, ray.y, ray.w, ray.h))
|
||||||
|
{
|
||||||
|
anEnemy->shield--;
|
||||||
|
addExplosion(anEnemy->x, anEnemy->y, E_SMALL_EXPLOSION);
|
||||||
|
playSound(SFX_HIT);
|
||||||
|
if (anEnemy->shield < 1)
|
||||||
|
{
|
||||||
|
destroyAlien(attacker, anEnemy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*anEnemy++;
|
||||||
|
}
|
||||||
|
|
||||||
|
attacker->ammo[0]--;
|
||||||
|
if (attacker->ammo[0] < 1)
|
||||||
|
attacker->flags -= FL_FIRERAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This handles active bullets in a linked list. The current bullet and
|
||||||
|
previous bullet pointers are first assigned to the main header bullet
|
||||||
|
and each successive bullet is pulled out. Bullets are moved in their
|
||||||
|
delta coordinates, with rockets having fire trails added to them. Seperate
|
||||||
|
collision checks are done for a bullet that belongs to the enemy and one
|
||||||
|
that belongs to a player. However rockets can hit anyone. Upon an enemy
|
||||||
|
being killed, mission requirements are checked and collectables are randomly
|
||||||
|
spawned.
|
||||||
|
*/
|
||||||
|
void doBullets()
|
||||||
|
{
|
||||||
|
object *bullet = engine.bulletHead;
|
||||||
|
object *prevBullet = engine.bulletHead;
|
||||||
|
engine.bulletTail = engine.bulletHead;
|
||||||
|
|
||||||
|
object *theEnemy, *theCargo;
|
||||||
|
|
||||||
|
signed char okayToHit = 0;
|
||||||
|
float homingMissileSpeed = 0;
|
||||||
|
|
||||||
|
while (bullet->next != NULL)
|
||||||
|
{
|
||||||
|
bullet = bullet->next;
|
||||||
|
|
||||||
|
if (bullet->active == 1)
|
||||||
|
{
|
||||||
|
if (bullet->flags & WF_HOMING)
|
||||||
|
{
|
||||||
|
if (bullet->target == NULL)
|
||||||
|
bullet->target = getRandomEnemy(bullet);
|
||||||
|
|
||||||
|
if (bullet->owner->flags & FL_FRIEND)
|
||||||
|
homingMissileSpeed = 0.25;
|
||||||
|
else
|
||||||
|
homingMissileSpeed = 0.05;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bullet->id == WT_ROCKET)
|
||||||
|
{
|
||||||
|
addExplosion(bullet->x, bullet->y, E_SMALL_EXPLOSION);
|
||||||
|
}
|
||||||
|
else if (bullet->id == WT_MICROROCKET)
|
||||||
|
{
|
||||||
|
addExplosion(bullet->x, bullet->y, E_TINY_EXPLOSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((bullet->flags & WF_AIMED) || (bullet->flags & WF_THIN_SPREAD))
|
||||||
|
{
|
||||||
|
graphics.blit(bullet->image[0], (int)(bullet->x - bullet->dx), (int)(bullet->y - bullet->dy));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bullet->id == WT_CHARGER)
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < bullet->damage ; i++)
|
||||||
|
graphics.blit(bullet->image[0], (int)(bullet->x - Math::rrand(-(bullet->damage / 3), 0)), (int)(bullet->y + Math::rrand(-3, 3)));
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.blit(bullet->image[0], (int)bullet->x, (int)bullet->y);
|
||||||
|
bullet->x += bullet->dx;
|
||||||
|
bullet->y += bullet->dy;
|
||||||
|
|
||||||
|
if (bullet->target != NULL)
|
||||||
|
{
|
||||||
|
if (bullet->x < bullet->target->x)
|
||||||
|
Math::limitFloat(&(bullet->dx += homingMissileSpeed), -15, 15);
|
||||||
|
if (bullet->x > bullet->target->x)
|
||||||
|
Math::limitFloat(&(bullet->dx -= homingMissileSpeed), -15, 15);
|
||||||
|
|
||||||
|
//Rocket is (more or less) inline with target. Fly straight
|
||||||
|
if ((bullet->x > bullet->target->x - 1) && (bullet->x < bullet->target->x + 5))
|
||||||
|
bullet->dx = 0;
|
||||||
|
|
||||||
|
if (bullet->y < bullet->target->y)
|
||||||
|
Math::limitFloat(&(bullet->dy += homingMissileSpeed), -15, 15);
|
||||||
|
if (bullet->y > bullet->target->y)
|
||||||
|
Math::limitFloat(&(bullet->dy -= homingMissileSpeed), -15, 15);
|
||||||
|
|
||||||
|
//Rocket is (more or less) inline with target. Fly straight
|
||||||
|
if ((bullet->y > bullet->target->y - 1) && (bullet->y < bullet->target->y + 5))
|
||||||
|
bullet->dy = 0;
|
||||||
|
|
||||||
|
if ((bullet->target->shield < 1) || (bullet->target->flags & FL_ISCLOAKED))
|
||||||
|
bullet->target = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bullet->x += engine.ssx;
|
||||||
|
bullet->y += engine.ssy;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < MAX_ALIENS ; i++)
|
||||||
|
{
|
||||||
|
theEnemy = &enemy[i];
|
||||||
|
|
||||||
|
if ((theEnemy->shield < 1) || (!theEnemy->active))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
okayToHit = 0;
|
||||||
|
|
||||||
|
if ((bullet->flags & WF_FRIEND) && (theEnemy->flags & FL_WEAPCO))
|
||||||
|
okayToHit = 1;
|
||||||
|
if ((bullet->flags & WF_WEAPCO) && (theEnemy->flags & FL_FRIEND))
|
||||||
|
okayToHit = 1;
|
||||||
|
if ((bullet->id == WT_ROCKET) || (bullet->id == WT_LASER) || (bullet->id == WT_CHARGER))
|
||||||
|
okayToHit = 1;
|
||||||
|
|
||||||
|
if (bullet->owner == theEnemy->owner)
|
||||||
|
okayToHit = 0;
|
||||||
|
|
||||||
|
if (okayToHit)
|
||||||
|
{
|
||||||
|
if ((bullet->active == 1) && (Collision::collision(bullet, theEnemy)))
|
||||||
|
{
|
||||||
|
if (bullet->owner == &player)
|
||||||
|
{
|
||||||
|
currentGame.hits++;
|
||||||
|
if ((theEnemy->classDef == CD_PHOEBE) || (theEnemy->classDef == CD_URSULA))
|
||||||
|
getMissFireMessage(theEnemy);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(theEnemy->flags & FL_IMMORTAL))
|
||||||
|
{
|
||||||
|
if (!(bullet->flags & WF_DISABLE))
|
||||||
|
theEnemy->shield -= bullet->damage;
|
||||||
|
else
|
||||||
|
theEnemy->systemPower -= bullet->damage;
|
||||||
|
|
||||||
|
theEnemy->hit = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theEnemy->flags & FL_CANNOTDIE)
|
||||||
|
{
|
||||||
|
Math::limitInt(&theEnemy->shield, 1, theEnemy->maxShield);
|
||||||
|
if (theEnemy->shield == 1)
|
||||||
|
{
|
||||||
|
if (currentGame.area != 26)
|
||||||
|
{
|
||||||
|
if (!(theEnemy->flags & FL_LEAVESECTOR))
|
||||||
|
{
|
||||||
|
theEnemy->flags += FL_LEAVESECTOR;
|
||||||
|
if (theEnemy->flags & FL_CIRCLES)
|
||||||
|
theEnemy->flags -= FL_CIRCLES;
|
||||||
|
if (currentGame.area == 11)
|
||||||
|
setRadioMessage(FACE_KLINE, "Seems I underestimated you, Bainfield! We'll meet again!", 1);
|
||||||
|
else if (currentGame.area == 25)
|
||||||
|
setRadioMessage(FACE_SID, "Chris, Kethlan is getting away!", 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setKlineAttackMethod(theEnemy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((theEnemy->flags & FL_RUNSAWAY) && ((rand() % 50) == 0))
|
||||||
|
{
|
||||||
|
if (!(theEnemy->flags & FL_LEAVESECTOR))
|
||||||
|
theEnemy->flags += FL_LEAVESECTOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bullet->id != WT_CHARGER)
|
||||||
|
{
|
||||||
|
bullet->active = 0;
|
||||||
|
bullet->shield = 0;
|
||||||
|
}
|
||||||
|
else if (bullet->id == WT_CHARGER)
|
||||||
|
{
|
||||||
|
bullet->shield -= theEnemy->shield;
|
||||||
|
if (bullet->shield < 0)
|
||||||
|
bullet->active = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
playSound(SFX_HIT);
|
||||||
|
if (theEnemy->AIType == AI_EVASIVE)
|
||||||
|
theEnemy->thinktime = 0;
|
||||||
|
|
||||||
|
if (theEnemy->shield < 1)
|
||||||
|
destroyAlien(bullet, theEnemy);
|
||||||
|
|
||||||
|
if (theEnemy->systemPower < 1)
|
||||||
|
{
|
||||||
|
if (!(theEnemy->flags & FL_DISABLED))
|
||||||
|
{
|
||||||
|
theEnemy->flags += FL_DISABLED;
|
||||||
|
updateMissionRequirements(M_DISABLE_TARGET, theEnemy->classDef, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
theEnemy->systemPower = 0;
|
||||||
|
if (theEnemy->classDef == CD_KLINE)
|
||||||
|
theEnemy->systemPower = theEnemy->maxShield;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bullet->id == WT_ROCKET)
|
||||||
|
addExplosion(bullet->x, bullet->y, E_BIG_EXPLOSION);
|
||||||
|
else
|
||||||
|
addExplosion(bullet->x, bullet->y, E_SMALL_EXPLOSION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for bullets hitting player
|
||||||
|
if ((bullet->flags & WF_WEAPCO) || (bullet->id == WT_ROCKET) || (bullet->id == WT_LASER) || (bullet->id == WT_CHARGER))
|
||||||
|
{
|
||||||
|
if ((bullet->active == 1) && (player.shield > 0) && (Collision::collision(bullet, &player)) && (bullet->owner != &player))
|
||||||
|
{
|
||||||
|
if ((!engine.cheatShield) || (engine.missionCompleteTimer != 0))
|
||||||
|
{
|
||||||
|
if (player.shield > engine.lowShield)
|
||||||
|
{
|
||||||
|
if (player.shield - bullet->damage <= engine.lowShield)
|
||||||
|
{
|
||||||
|
setInfoLine("!!! WARNING: SHIELD LOW !!!", FONT_RED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
player.shield -= bullet->damage;
|
||||||
|
Math::limitInt(&player.shield, 0, player.maxShield);
|
||||||
|
player.hit = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((bullet->owner->classDef == CD_PHOEBE) || (bullet->owner->classDef == CD_URSULA))
|
||||||
|
getPlayerHitMessage(bullet->owner);
|
||||||
|
|
||||||
|
if (bullet->id != WT_CHARGER)
|
||||||
|
{
|
||||||
|
bullet->active = 0;
|
||||||
|
bullet->shield = 0;
|
||||||
|
}
|
||||||
|
else if (bullet->id == WT_CHARGER)
|
||||||
|
{
|
||||||
|
bullet->shield -= theEnemy->shield;
|
||||||
|
if (bullet->shield < 0)
|
||||||
|
bullet->active = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
playSound(SFX_HIT);
|
||||||
|
|
||||||
|
if (bullet->id == WT_ROCKET)
|
||||||
|
addExplosion(bullet->x, bullet->y, E_BIG_EXPLOSION);
|
||||||
|
else
|
||||||
|
addExplosion(bullet->x, bullet->y, E_SMALL_EXPLOSION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((bullet->owner == &player)) || (bullet->id == WT_ROCKET))
|
||||||
|
{
|
||||||
|
for (int j = 0 ; j < 20 ; j++)
|
||||||
|
{
|
||||||
|
theCargo = &cargo[j];
|
||||||
|
if (theCargo->active)
|
||||||
|
{
|
||||||
|
if (Collision::collision(bullet, theCargo))
|
||||||
|
{
|
||||||
|
bullet->active = 0;
|
||||||
|
addExplosion(bullet->x, bullet->y, E_SMALL_EXPLOSION);
|
||||||
|
playSound(SFX_HIT);
|
||||||
|
if (theCargo->collectType != P_PHOEBE)
|
||||||
|
{
|
||||||
|
theCargo->active = 0;
|
||||||
|
playSound(SFX_EXPLOSION);
|
||||||
|
for (int i = 0 ; i < 10 ; i++)
|
||||||
|
addExplosion(theCargo->x + Math::rrand(-15, 15), theCargo->y + Math::rrand(-15, 15), E_BIG_EXPLOSION);
|
||||||
|
updateMissionRequirements(M_PROTECT_PICKUP, P_CARGO, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check to see if a bullet (on any side) hits a mine
|
||||||
|
checkMineBulletCollisions(bullet);
|
||||||
|
|
||||||
|
bullet->shield--;
|
||||||
|
|
||||||
|
if (bullet->shield < 1)
|
||||||
|
{
|
||||||
|
if ((bullet->flags & WF_TIMEDEXPLOSION) || (bullet->id == WT_CHARGER))
|
||||||
|
{
|
||||||
|
playSound(SFX_EXPLOSION);
|
||||||
|
for (int i = 0 ; i < 10 ; i++)
|
||||||
|
addExplosion(bullet->x + Math::rrand(-35, 35), bullet->y + Math::rrand(-35, 35), E_BIG_EXPLOSION);
|
||||||
|
|
||||||
|
if (bullet->flags & WF_TIMEDEXPLOSION)
|
||||||
|
if (checkPlayerShockDamage(bullet->x, bullet->y, 75))
|
||||||
|
setInfoLine("Warning: Missile Shockwave Damage!!", FONT_RED);
|
||||||
|
}
|
||||||
|
bullet->active = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bullet->active == 1)
|
||||||
|
{
|
||||||
|
prevBullet = bullet;
|
||||||
|
engine.bulletTail = bullet;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prevBullet->next = bullet->next;
|
||||||
|
delete bullet;
|
||||||
|
bullet = prevBullet;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern void playSound(int sid);
|
||||||
|
extern void updateMissionRequirements(int type, int id, int value);
|
||||||
|
extern void addCollectable(float x, float y, int type, int value, int life);
|
||||||
|
extern void addExplosion(float x, float y, int type);
|
||||||
|
extern void generateShockWave(object *bullet);
|
||||||
|
extern void setInfoLine(char *in, int color);
|
||||||
|
extern void getKillMessage(object *ally);
|
||||||
|
extern void getMissFireMessage(object *ally);
|
||||||
|
extern void getPlayerHitMessage(object *ally);
|
||||||
|
extern void checkMineBulletCollisions(object *bullet);
|
||||||
|
extern void setKlineAttackMethod(object *theEnemy);
|
||||||
|
extern void setRadioMessage(signed char face, char *in, int priority);
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern devVariables dev;
|
||||||
|
extern object weapon[MAX_WEAPONS];
|
||||||
|
extern object player;
|
||||||
|
extern mission currentMission;
|
||||||
|
extern object enemy[MAX_ALIENS];
|
||||||
|
extern object cargo[20];
|
||||||
|
extern Game currentGame;
|
||||||
|
extern Graphics graphics;
|
|
@ -0,0 +1,120 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cargo.h"
|
||||||
|
|
||||||
|
void initCargo()
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < MAX_CARGO ; i++)
|
||||||
|
{
|
||||||
|
cargo[i].active = 0;
|
||||||
|
cargo[i].owner = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* I think you all know what this does by now! ;)
|
||||||
|
*/
|
||||||
|
int getCargo()
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < MAX_CARGO ; i++)
|
||||||
|
{
|
||||||
|
if (cargo[i].active == 0)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
object *addCargo(object *owner, int cargoType)
|
||||||
|
{
|
||||||
|
int index = getCargo();
|
||||||
|
|
||||||
|
if (index == -1)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cargo[index].active = 1;
|
||||||
|
cargo[index].owner = owner;
|
||||||
|
cargo[index].x = owner->x;
|
||||||
|
cargo[index].y = owner->y;
|
||||||
|
cargo[index].dx = 0;
|
||||||
|
cargo[index].dy = 0;
|
||||||
|
cargo[index].collectType = cargoType;
|
||||||
|
cargo[index].image[0] = graphics.shape[32];
|
||||||
|
if (cargoType == P_PHOEBE)
|
||||||
|
cargo[index].image[0] = graphics.shipShape[20];
|
||||||
|
|
||||||
|
return &cargo[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
void becomeCollectable(int i)
|
||||||
|
{
|
||||||
|
if (cargo[i].collectType != P_PHOEBE)
|
||||||
|
{
|
||||||
|
addCollectable(cargo[i].x, cargo[i].y, cargo[i].collectType, 1, 600);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
enemy[FR_PHOEBE].active = 1;
|
||||||
|
enemy[FR_PHOEBE].x = cargo[i].x;
|
||||||
|
enemy[FR_PHOEBE].y = cargo[i].y;
|
||||||
|
setRadioMessage(FACE_PHOEBE, "Thanks!! Watch out, WEAPCO! Phoebe's loose and she's ANGRY!!!", 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
cargo[i].active = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doCargo()
|
||||||
|
{
|
||||||
|
float dx, dy, chainX, chainY;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < MAX_CARGO ; i++)
|
||||||
|
{
|
||||||
|
if (cargo[i].active)
|
||||||
|
{
|
||||||
|
if (!cargo[i].owner->active)
|
||||||
|
{
|
||||||
|
becomeCollectable(i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.blit(cargo[i].image[0], (int)cargo[i].x, (int)cargo[i].y);
|
||||||
|
|
||||||
|
cargo[i].x += engine.ssx;
|
||||||
|
cargo[i].y += engine.ssy;
|
||||||
|
|
||||||
|
Math::limitFloat(&cargo[i].x, cargo[i].owner->x - 50, cargo[i].owner->x + 50);
|
||||||
|
Math::limitFloat(&cargo[i].y, cargo[i].owner->y - 50, cargo[i].owner->y + 50);
|
||||||
|
|
||||||
|
dx = (cargo[i].x - cargo[i].owner->x) / 10;
|
||||||
|
dy = (cargo[i].y - cargo[i].owner->y) / 10;
|
||||||
|
chainX = cargo[i].x - cargo[i].dx;
|
||||||
|
chainY = cargo[i].y - cargo[i].dy;
|
||||||
|
|
||||||
|
// draw the chain link line
|
||||||
|
for (int j = 0 ; j < 10 ; j++)
|
||||||
|
{
|
||||||
|
graphics.blit(graphics.shape[30], (int)chainX, (int)chainY);
|
||||||
|
chainX -= dx;
|
||||||
|
chainY -= dy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern void addCollectable(float x, float y, int type, int value, int life);
|
||||||
|
extern void setRadioMessage(signed char face, char *in, int priority);
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern Game currentGame;
|
||||||
|
extern Graphics graphics;
|
||||||
|
extern object enemy[MAX_ALIENS];
|
||||||
|
extern object player;
|
||||||
|
extern object cargo[MAX_CARGO];
|
|
@ -0,0 +1,710 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void showErrorAndExit(int errorId, char *name);
|
||||||
|
|
||||||
|
class Collision {
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Collision(){}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
static signed char collision(float x0, float y0, int w0, int h0, float x2, float y2, int w1, int h1)
|
||||||
|
{
|
||||||
|
float x1 = x0 + w0;
|
||||||
|
float y1 = y0 + h0;
|
||||||
|
|
||||||
|
float x3 = x2 + w1;
|
||||||
|
float y3 = y2 + h1;
|
||||||
|
|
||||||
|
return !(x1<x2 || x3<x0 || y1<y2 || y3<y0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static signed char collision(object *object1, object *object2)
|
||||||
|
{
|
||||||
|
float x0 = object1->x;
|
||||||
|
float y0 = object1->y;
|
||||||
|
float w0 = object1->image[0]->w;
|
||||||
|
float h0 = object1->image[0]->h;
|
||||||
|
|
||||||
|
float x2 = object2->x;
|
||||||
|
float y2 = object2->y;
|
||||||
|
float w1 = object2->image[0]->w;
|
||||||
|
float h1 = object2->image[0]->h;
|
||||||
|
|
||||||
|
float x1 = x0 + w0;
|
||||||
|
float y1 = y0 + h0;
|
||||||
|
|
||||||
|
float x3 = x2 + w1;
|
||||||
|
float y3 = y2 + h1;
|
||||||
|
|
||||||
|
return !(x1<x2 || x3<x0 || y1<y2 || y3<y0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static signed char collision(collectables *object1, object *object2)
|
||||||
|
{
|
||||||
|
float x0 = object1->x;
|
||||||
|
float y0 = object1->y;
|
||||||
|
float w0 = object1->image->w;
|
||||||
|
float h0 = object1->image->h;
|
||||||
|
|
||||||
|
float x2 = object2->x;
|
||||||
|
float y2 = object2->y;
|
||||||
|
float w1 = object2->image[0]->w;
|
||||||
|
float h1 = object2->image[0]->h;
|
||||||
|
|
||||||
|
float x1 = x0 + w0;
|
||||||
|
float y1 = y0 + h0;
|
||||||
|
|
||||||
|
float x3 = x2 + w1;
|
||||||
|
float y3 = y2 + h1;
|
||||||
|
|
||||||
|
return !(x1<x2 || x3<x0 || y1<y2 || y3<y0);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class Math {
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
Math(){}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
static void limitChar(signed char *in, int low, int high)
|
||||||
|
{
|
||||||
|
if (*in < low)
|
||||||
|
*in = low;
|
||||||
|
if (*in > high)
|
||||||
|
*in = high;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void limitChar(unsigned char *in, int low, int high)
|
||||||
|
{
|
||||||
|
if (*in < low)
|
||||||
|
*in = low;
|
||||||
|
if (*in > high)
|
||||||
|
*in = high;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void limitInt(int *in, int low, int high)
|
||||||
|
{
|
||||||
|
if (*in < low)
|
||||||
|
*in = low;
|
||||||
|
if (*in > high)
|
||||||
|
*in = high;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void limitFloat(float *in, float low, float high)
|
||||||
|
{
|
||||||
|
if (*in < low)
|
||||||
|
*in = low;
|
||||||
|
if (*in > high)
|
||||||
|
*in = high;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wrapChar(signed char *in, signed char low, signed char high)
|
||||||
|
{
|
||||||
|
if (*in < low)
|
||||||
|
*in = high;
|
||||||
|
if (*in > high)
|
||||||
|
*in = low;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wrapInt(int *in, int low, int high)
|
||||||
|
{
|
||||||
|
if (*in < low)
|
||||||
|
*in = high;
|
||||||
|
if (*in > high)
|
||||||
|
*in = low;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void wrapFloat(float *in, float low, float high)
|
||||||
|
{
|
||||||
|
if (*in < low)
|
||||||
|
*in = high;
|
||||||
|
if (*in > high)
|
||||||
|
*in = low;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rrand(int min, int max)
|
||||||
|
{
|
||||||
|
int r = min;
|
||||||
|
|
||||||
|
max++;
|
||||||
|
|
||||||
|
if ((max - min) == 0)
|
||||||
|
return min;
|
||||||
|
|
||||||
|
r += rand() % (max - min);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Graphics {
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Uint32 red;
|
||||||
|
Uint32 darkRed;
|
||||||
|
Uint32 yellow;
|
||||||
|
Uint32 darkYellow;
|
||||||
|
Uint32 green;
|
||||||
|
Uint32 darkGreen;
|
||||||
|
Uint32 blue;
|
||||||
|
Uint32 darkBlue;
|
||||||
|
Uint32 darkerBlue;
|
||||||
|
Uint32 black;
|
||||||
|
Uint32 white;
|
||||||
|
Uint32 lightGrey;
|
||||||
|
Uint32 darkGrey;
|
||||||
|
SDL_Surface *screen, *background;
|
||||||
|
SDL_Surface *shape[MAX_SHAPES];
|
||||||
|
SDL_Surface *shipShape[MAX_SHIPSHAPES];
|
||||||
|
SDL_Surface *fontShape[MAX_FONTSHAPES];
|
||||||
|
SDL_Surface *shopSurface[MAX_SHOPSHAPES];
|
||||||
|
bRect *bufferHead;
|
||||||
|
bRect *bufferTail;
|
||||||
|
textObject textShape[MAX_TEXTSHAPES];
|
||||||
|
SDL_Rect blitRect;
|
||||||
|
SDL_Surface *messageBox;
|
||||||
|
|
||||||
|
Graphics()
|
||||||
|
{
|
||||||
|
bufferHead = new bRect;
|
||||||
|
bufferHead->next = NULL;
|
||||||
|
bufferTail = bufferHead;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < MAX_SHAPES ; i++)
|
||||||
|
shape[i] = NULL;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < MAX_SHIPSHAPES ; i++)
|
||||||
|
shipShape[i] = NULL;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < MAX_TEXTSHAPES ; i++)
|
||||||
|
textShape[i].image = NULL;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < MAX_SHOPSHAPES ; i++)
|
||||||
|
shopSurface[i] = NULL;
|
||||||
|
|
||||||
|
background = NULL;
|
||||||
|
messageBox = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface *setTransparent(SDL_Surface *sprite)
|
||||||
|
{
|
||||||
|
SDL_SetColorKey(sprite, (SDL_SRCCOLORKEY|SDL_RLEACCEL), SDL_MapRGB(sprite->format, 0, 0, 0));
|
||||||
|
return sprite;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addBuffer(int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
bRect *rect = new bRect;
|
||||||
|
|
||||||
|
rect->next = NULL;
|
||||||
|
rect->x = x;
|
||||||
|
rect->y = y;
|
||||||
|
rect->w = w;
|
||||||
|
rect->h = h;
|
||||||
|
|
||||||
|
bufferTail->next = rect;
|
||||||
|
bufferTail = rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
void blit(SDL_Surface *image, int x, int y, SDL_Surface *dest)
|
||||||
|
{
|
||||||
|
// Set up a rectangle to draw to
|
||||||
|
blitRect.x = x;
|
||||||
|
blitRect.y = y;
|
||||||
|
blitRect.w = image->w;
|
||||||
|
blitRect.h = image->h;
|
||||||
|
|
||||||
|
/* Blit onto the screen surface */
|
||||||
|
if(SDL_BlitSurface(image, NULL, dest, &blitRect) < 0)
|
||||||
|
{
|
||||||
|
printf("BlitSurface error: %s\n", SDL_GetError());
|
||||||
|
showErrorAndExit(2, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
addBuffer(blitRect.x, blitRect.y, blitRect.w, blitRect.h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void blit(SDL_Surface *image, int x, int y)
|
||||||
|
{
|
||||||
|
blit(image, x, y, screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void blitText(int i)
|
||||||
|
{
|
||||||
|
blit(textShape[i].image, (int)textShape[i].x, (int)textShape[i].y, screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void flushBuffer()
|
||||||
|
{
|
||||||
|
bRect *prevRect = bufferHead;
|
||||||
|
bRect *rect = bufferHead;
|
||||||
|
bufferTail = bufferHead;
|
||||||
|
|
||||||
|
while (rect->next != NULL)
|
||||||
|
{
|
||||||
|
rect = rect->next;
|
||||||
|
|
||||||
|
prevRect->next = rect->next;
|
||||||
|
delete rect;
|
||||||
|
rect = prevRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufferHead->next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void unBuffer()
|
||||||
|
{
|
||||||
|
bRect *prevRect = bufferHead;
|
||||||
|
bRect *rect = bufferHead;
|
||||||
|
bufferTail = bufferHead;
|
||||||
|
|
||||||
|
while (rect->next != NULL)
|
||||||
|
{
|
||||||
|
rect = rect->next;
|
||||||
|
|
||||||
|
blitRect.x = rect->x;
|
||||||
|
blitRect.y = rect->y;
|
||||||
|
blitRect.w = rect->w;
|
||||||
|
blitRect.h = rect->h;
|
||||||
|
|
||||||
|
if (SDL_BlitSurface(background, &blitRect, screen, &blitRect) < 0)
|
||||||
|
{
|
||||||
|
printf("BlitSurface error: %s\n", SDL_GetError());
|
||||||
|
showErrorAndExit(2, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
prevRect->next = rect->next;
|
||||||
|
delete rect;
|
||||||
|
rect = prevRect;
|
||||||
|
}
|
||||||
|
|
||||||
|
bufferHead->next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
In 16 bit mode this is slow. VERY slow. Don't write directly to a surface
|
||||||
|
that constantly needs updating (eg - the main game screen)
|
||||||
|
*/
|
||||||
|
int renderString(char *in, int x, int y, int fontColor, signed char wrap, SDL_Surface *dest)
|
||||||
|
{
|
||||||
|
SDL_Rect area;
|
||||||
|
area.x = x;
|
||||||
|
area.y = y;
|
||||||
|
area.w = 8;
|
||||||
|
area.h = 14;
|
||||||
|
|
||||||
|
SDL_Rect letter;
|
||||||
|
letter.y = 0;
|
||||||
|
letter.w = 8;
|
||||||
|
letter.h = 14;
|
||||||
|
|
||||||
|
while (*in != '\0')
|
||||||
|
{
|
||||||
|
if (*in != 32)
|
||||||
|
{
|
||||||
|
letter.x = (*in - 33);
|
||||||
|
letter.x *= 8;
|
||||||
|
letter.x--; // Temp fix
|
||||||
|
|
||||||
|
/* Blit onto the screen surface */
|
||||||
|
if(SDL_BlitSurface(fontShape[fontColor], &letter, dest, &area) < 0)
|
||||||
|
{
|
||||||
|
printf("BlitSurface error: %s\n", SDL_GetError());
|
||||||
|
showErrorAndExit(2, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
area.x += 9;
|
||||||
|
|
||||||
|
if (wrap)
|
||||||
|
{
|
||||||
|
if ((area.x > (dest->w - 70)) && (*in == 32))
|
||||||
|
{
|
||||||
|
area.y += 16;
|
||||||
|
area.x = x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*in++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return area.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int drawString(char *in, int x, int y, int fontColor, signed char wrap, SDL_Surface *dest)
|
||||||
|
{
|
||||||
|
renderString(in, x, y - 1, FONT_OUTLINE, wrap, dest);
|
||||||
|
renderString(in, x, y + 1, FONT_OUTLINE, wrap, dest);
|
||||||
|
renderString(in, x, y + 2, FONT_OUTLINE, wrap, dest);
|
||||||
|
renderString(in, x - 1, y, FONT_OUTLINE, wrap, dest);
|
||||||
|
renderString(in, x - 2, y, FONT_OUTLINE, wrap, dest);
|
||||||
|
renderString(in, x + 1, y, FONT_OUTLINE, wrap, dest);
|
||||||
|
return renderString(in, x, y, fontColor, wrap, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
int drawString(char *in, int x, int y, int fontColor, SDL_Surface *dest)
|
||||||
|
{
|
||||||
|
if (x == -1)
|
||||||
|
x = (dest->w - (strlen(in) * 9)) / 2;
|
||||||
|
return drawString(in, x, y, fontColor, 0, dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
int drawString(char *in, int x, int y, int fontColor)
|
||||||
|
{
|
||||||
|
if (x == -1)
|
||||||
|
x = (800 - (strlen(in) * 9)) / 2;
|
||||||
|
return drawString(in, x, y, fontColor, 0, screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Finds the location of the requested color within the palette and returns
|
||||||
|
it's number. This colors are used for drawing rectangles, circle, etc in
|
||||||
|
the correct colors.
|
||||||
|
*/
|
||||||
|
void setColorIndexes()
|
||||||
|
{
|
||||||
|
red = SDL_MapRGB(screen->format, 0xff, 0x00, 0x00);
|
||||||
|
darkRed = SDL_MapRGB(screen->format, 0x66, 0x00, 0x00);
|
||||||
|
|
||||||
|
yellow = SDL_MapRGB(screen->format, 0xff, 0xff, 0x00);
|
||||||
|
darkYellow = SDL_MapRGB(screen->format, 0x66, 0x66, 0x00);
|
||||||
|
|
||||||
|
green = SDL_MapRGB(screen->format, 0x00, 0xff, 0x00);
|
||||||
|
darkGreen = SDL_MapRGB(screen->format, 0x00, 0x66, 0x00);
|
||||||
|
|
||||||
|
blue = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
|
||||||
|
darkBlue = SDL_MapRGB(screen->format, 0x00, 0x00, 0x99);
|
||||||
|
darkerBlue = SDL_MapRGB(screen->format, 0x00, 0x00, 0x44);
|
||||||
|
|
||||||
|
black = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
|
||||||
|
white = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
|
||||||
|
lightGrey = SDL_MapRGB(screen->format, 0xcc, 0xcc, 0xcc);
|
||||||
|
darkGrey = SDL_MapRGB(screen->format, 0x99, 0x99, 0x99);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Draws the background surface that has been loaded
|
||||||
|
*/
|
||||||
|
void drawBackGround()
|
||||||
|
{
|
||||||
|
blit(background, 0, 0, screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearScreen(Uint32 color)
|
||||||
|
{
|
||||||
|
SDL_FillRect(screen, NULL, color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateScreen()
|
||||||
|
{
|
||||||
|
SDL_Flip(screen);
|
||||||
|
// Give the audio (and possibly the X server) time to work...
|
||||||
|
SDL_Delay(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the pixel at (x, y) to the given value
|
||||||
|
* NOTE: The surface must be locked before calling this!
|
||||||
|
*/
|
||||||
|
void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
|
||||||
|
{
|
||||||
|
int bpp = surface->format->BytesPerPixel;
|
||||||
|
/* Here p is the address to the pixel we want to set */
|
||||||
|
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
|
||||||
|
|
||||||
|
switch(bpp) {
|
||||||
|
case 1:
|
||||||
|
*p = pixel;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
*(Uint16 *)p = pixel;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
|
||||||
|
p[0] = (pixel >> 16) & 0xff;
|
||||||
|
p[1] = (pixel >> 8) & 0xff;
|
||||||
|
p[2] = pixel & 0xff;
|
||||||
|
} else {
|
||||||
|
p[0] = pixel & 0xff;
|
||||||
|
p[1] = (pixel >> 8) & 0xff;
|
||||||
|
p[2] = (pixel >> 16) & 0xff;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
*(Uint32 *)p = pixel;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawLine(SDL_Surface *dest, int x1, int y1, int x2, int y2, int col)
|
||||||
|
{
|
||||||
|
int counter = 0;
|
||||||
|
|
||||||
|
if ( SDL_MUSTLOCK(dest) ) {
|
||||||
|
if ( SDL_LockSurface(dest) < 0 ) {
|
||||||
|
printf("Can't lock screen: %s\n", SDL_GetError());
|
||||||
|
showErrorAndExit(2, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
putpixel(dest, x1, y1, col);
|
||||||
|
|
||||||
|
if (x1 > x2) x1--;
|
||||||
|
if (x1 < x2) x1++;
|
||||||
|
if (y1 > y2) y1--;
|
||||||
|
if (y1 < y2) y1++;
|
||||||
|
|
||||||
|
if ((x1 == x2) && (y1 == y2))
|
||||||
|
{break;}
|
||||||
|
if (counter == 1000)
|
||||||
|
{printf("Loop Error!\n"); break;}
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( SDL_MUSTLOCK(dest) ) {
|
||||||
|
SDL_UnlockSurface(dest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawLine(int x1, int y1, int x2, int y2, int col)
|
||||||
|
{
|
||||||
|
drawLine(screen, x1, y1, x2, y2, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
A quick(?) circle draw function. This code was posted to the SDL
|
||||||
|
mailing list... I didn't write it myself.
|
||||||
|
*/
|
||||||
|
void circle(int xc, int yc, int R, SDL_Surface *PIX, int col)
|
||||||
|
{
|
||||||
|
int x = 0, xx = 0;
|
||||||
|
int y = R, yy = R+R;
|
||||||
|
int p = 1-R;
|
||||||
|
|
||||||
|
putpixel(PIX, xc, yc - y, col);
|
||||||
|
putpixel(PIX, xc, yc + y, col);
|
||||||
|
putpixel(PIX, xc - y, yc, col);
|
||||||
|
putpixel(PIX, xc + y, yc, col);
|
||||||
|
|
||||||
|
while(x < y)
|
||||||
|
{
|
||||||
|
xx += 2;
|
||||||
|
++x;
|
||||||
|
if (p >= 0)
|
||||||
|
{
|
||||||
|
yy -= 2;
|
||||||
|
--y;
|
||||||
|
p -= yy;
|
||||||
|
}
|
||||||
|
p += xx + 1;
|
||||||
|
|
||||||
|
putpixel(PIX, xc - x, yc - y, col);
|
||||||
|
putpixel(PIX, xc + x, yc - y, col);
|
||||||
|
putpixel(PIX, xc - x, yc + y, col);
|
||||||
|
putpixel(PIX, xc + x, yc + y, col);
|
||||||
|
putpixel(PIX, xc - y, yc - x, col);
|
||||||
|
putpixel(PIX, xc + y, yc - x, col);
|
||||||
|
putpixel(PIX, xc - y, yc + x, col);
|
||||||
|
putpixel(PIX, xc + y, yc + x, col);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((x = y))
|
||||||
|
{
|
||||||
|
putpixel(PIX, xc - x, yc - y, col);
|
||||||
|
putpixel(PIX, xc + x, yc - y, col);
|
||||||
|
putpixel(PIX, xc - x, yc + y, col);
|
||||||
|
putpixel(PIX, xc + x, yc + y, col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void blevelRect(SDL_Surface *dest, int x, int y, int w, int h, Uint8 red, Uint8 green, Uint8 blue)
|
||||||
|
{
|
||||||
|
SDL_Rect r = {x, y, w, h};
|
||||||
|
SDL_FillRect(dest, &r, SDL_MapRGB(screen->format, red, green, blue));
|
||||||
|
|
||||||
|
drawLine(dest, x, y, x + w, y, SDL_MapRGB(screen->format, 255, 255, 255));
|
||||||
|
drawLine(dest, x, y, x, y + h, SDL_MapRGB(screen->format, 255, 255, 255));
|
||||||
|
drawLine(dest, x, y + h, x + w, y + h, SDL_MapRGB(screen->format, 128, 128, 128));
|
||||||
|
drawLine(dest, x + w, y + 1, x + w, y + h, SDL_MapRGB(screen->format, 128, 128, 128));
|
||||||
|
}
|
||||||
|
|
||||||
|
void blevelRect(int x, int y, int w, int h, Uint8 red, Uint8 green, Uint8 blue)
|
||||||
|
{
|
||||||
|
blevelRect(screen, x, y, w, h, red, green, blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface *createSurface(int width, int height)
|
||||||
|
{
|
||||||
|
SDL_Surface *surface, *newImage;
|
||||||
|
Uint32 rmask, gmask, bmask, amask;
|
||||||
|
|
||||||
|
/* SDL interprets each pixel as a 32-bit number, so our masks must depend
|
||||||
|
on the endianness (byte order) of the machine */
|
||||||
|
#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
|
||||||
|
rmask = 0xff000000;
|
||||||
|
gmask = 0x00ff0000;
|
||||||
|
bmask = 0x0000ff00;
|
||||||
|
amask = 0x000000ff;
|
||||||
|
#else
|
||||||
|
rmask = 0x000000ff;
|
||||||
|
gmask = 0x0000ff00;
|
||||||
|
bmask = 0x00ff0000;
|
||||||
|
amask = 0xff000000;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, rmask, gmask, bmask, amask);
|
||||||
|
|
||||||
|
if (surface == NULL) {
|
||||||
|
printf("CreateRGBSurface failed: %s\n", SDL_GetError());
|
||||||
|
showErrorAndExit(2, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
newImage = SDL_DisplayFormat(surface);
|
||||||
|
|
||||||
|
SDL_FreeSurface(surface);
|
||||||
|
|
||||||
|
return newImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface *textSurface(char *inString, int color)
|
||||||
|
{
|
||||||
|
SDL_Surface *surface = createSurface(strlen(inString) * 9, 16);
|
||||||
|
|
||||||
|
drawString(inString, 1, 1, color, surface);
|
||||||
|
|
||||||
|
return setTransparent(surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
void textSurface(int index, char *inString, int x, int y, int fontColor)
|
||||||
|
{
|
||||||
|
strcpy(textShape[index].text, inString);
|
||||||
|
textShape[index].x = x;
|
||||||
|
textShape[index].y = y;
|
||||||
|
textShape[index].fontColor = fontColor;
|
||||||
|
if (textShape[index].image != NULL)
|
||||||
|
{
|
||||||
|
SDL_FreeSurface(textShape[index].image);
|
||||||
|
}
|
||||||
|
textShape[index].image = textSurface(inString, fontColor);
|
||||||
|
if (x == -1)
|
||||||
|
textShape[index].x = (800 - textShape[index].image->w) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface *alphaRect(int width, int height, Uint8 red, Uint8 green, Uint8 blue)
|
||||||
|
{
|
||||||
|
SDL_Surface *surface = createSurface(width, height);
|
||||||
|
|
||||||
|
SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, red, green, blue));
|
||||||
|
|
||||||
|
SDL_SetAlpha(surface, SDL_SRCALPHA|SDL_RLEACCEL, 128);
|
||||||
|
|
||||||
|
return surface;
|
||||||
|
}
|
||||||
|
|
||||||
|
void createMessageBox(SDL_Surface *face, char *message, signed char transparent)
|
||||||
|
{
|
||||||
|
if (messageBox != NULL)
|
||||||
|
{
|
||||||
|
SDL_FreeSurface(messageBox);
|
||||||
|
messageBox = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transparent)
|
||||||
|
messageBox = alphaRect(550, 60, 0x00, 0x00, 0x00);
|
||||||
|
else
|
||||||
|
messageBox = createSurface(550, 60);
|
||||||
|
|
||||||
|
signed char x = 60;
|
||||||
|
|
||||||
|
if (face != NULL)
|
||||||
|
{
|
||||||
|
blevelRect(messageBox, 0, 0, messageBox->w - 1, messageBox->h - 1, 0x00, 0x00, 0xaa);
|
||||||
|
blit(face, 5, 5, messageBox);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
blevelRect(messageBox, 0, 0, messageBox->w - 1, messageBox->h - 1, 0x00, 0x00, 0x00);
|
||||||
|
x = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
drawString(message, x, 5, FONT_WHITE, 1, messageBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeGraphics()
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < MAX_SHAPES ; i++)
|
||||||
|
{
|
||||||
|
if (shape[i] != NULL)
|
||||||
|
{
|
||||||
|
SDL_FreeSurface(shape[i]);
|
||||||
|
shape[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < MAX_SHIPSHAPES ; i++)
|
||||||
|
{
|
||||||
|
if (shipShape[i] != NULL)
|
||||||
|
{
|
||||||
|
SDL_FreeSurface(shipShape[i]);
|
||||||
|
shipShape[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < MAX_TEXTSHAPES ; i++)
|
||||||
|
{
|
||||||
|
if (textShape[i].image != NULL)
|
||||||
|
{
|
||||||
|
SDL_FreeSurface(textShape[i].image);
|
||||||
|
textShape[i].image = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < MAX_SHOPSHAPES ; i++)
|
||||||
|
{
|
||||||
|
if (shopSurface[i] != NULL)
|
||||||
|
{
|
||||||
|
SDL_FreeSurface(shopSurface[i]);
|
||||||
|
shopSurface[i] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (messageBox != NULL)
|
||||||
|
{
|
||||||
|
SDL_FreeSurface(messageBox);
|
||||||
|
messageBox = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,430 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "collectable.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create a new collectable item based on supplied arguments.
|
||||||
|
*/
|
||||||
|
void addCollectable(float x, float y, int type, int value, int life)
|
||||||
|
{
|
||||||
|
if (type == P_ANYTHING)
|
||||||
|
{
|
||||||
|
type = P_CASH;
|
||||||
|
|
||||||
|
int r = rand() % 9;
|
||||||
|
|
||||||
|
switch (r)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
type = P_PLASMA_AMMO;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
type = P_SHIELD;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
type = P_ROCKET;
|
||||||
|
value /= 10;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == P_WEAPONS)
|
||||||
|
{
|
||||||
|
type = P_PLASMA_RATE;
|
||||||
|
|
||||||
|
int r = rand() % 61;
|
||||||
|
|
||||||
|
if (r <= 19)
|
||||||
|
type = P_PLASMA_DAMAGE;
|
||||||
|
else if (r <= 39)
|
||||||
|
type = P_PLASMA_SHOT;
|
||||||
|
else if (r <= 59)
|
||||||
|
type = P_PLASMA_RATE;
|
||||||
|
else
|
||||||
|
type = P_SUPER;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == P_SUPER)
|
||||||
|
value = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Cash is rare on interceptions. Stops people from point leeching(!)
|
||||||
|
*/
|
||||||
|
if ((currentGame.area == MAX_MISSIONS - 1) && (type == P_CASH))
|
||||||
|
{
|
||||||
|
if (rand() % 10 > 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value == 0)
|
||||||
|
return; // don't bother!
|
||||||
|
|
||||||
|
// If the player has a charge cannon or a laser cannon, don't give them
|
||||||
|
// rockets. Causes problems otherwise :)
|
||||||
|
if (type == P_ROCKET)
|
||||||
|
{
|
||||||
|
if ((player.weaponType[1] == W_CHARGER) || (player.weaponType[1] == W_LASER))
|
||||||
|
{
|
||||||
|
type = P_CASH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
collectables *collectable = new collectables;
|
||||||
|
|
||||||
|
collectable->next = NULL;
|
||||||
|
collectable->active = 1;
|
||||||
|
collectable->x = x;
|
||||||
|
collectable->y = y;
|
||||||
|
|
||||||
|
collectable->dx = Math::rrand(-100, 100);
|
||||||
|
if (collectable->dx != 0)
|
||||||
|
collectable->dx /= 100;
|
||||||
|
|
||||||
|
collectable->dy = Math::rrand(-100, 100);
|
||||||
|
if (collectable->dy != 0)
|
||||||
|
collectable->dy /= 100;
|
||||||
|
|
||||||
|
collectable->type = type;
|
||||||
|
collectable->value = value;
|
||||||
|
collectable->life = life;
|
||||||
|
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case P_CASH:
|
||||||
|
collectable->image = graphics.shape[24];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_ROCKET:
|
||||||
|
collectable->image = graphics.shape[49];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_PLASMA_AMMO:
|
||||||
|
collectable->image = graphics.shape[25];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_SHIELD:
|
||||||
|
collectable->image = graphics.shape[26];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_PLASMA_SHOT:
|
||||||
|
collectable->image = graphics.shape[27];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_PLASMA_RATE:
|
||||||
|
collectable->image = graphics.shape[28];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_PLASMA_DAMAGE:
|
||||||
|
collectable->image = graphics.shape[29];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_CARGO:
|
||||||
|
collectable->image = graphics.shape[32];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_SUPER:
|
||||||
|
collectable->image = graphics.shape[50];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_MINE:
|
||||||
|
collectable->image = graphics.shape[31];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_SLAVES:
|
||||||
|
case P_ESCAPEPOD:
|
||||||
|
collectable->image = graphics.shape[45];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_ORE:
|
||||||
|
collectable->image = graphics.shape[46 + rand() % 3];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
engine.collectableTail->next = collectable;
|
||||||
|
engine.collectableTail = collectable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void explodeMine(collectables *collectable)
|
||||||
|
{
|
||||||
|
if ((collectable->x >= 0) && (collectable->x <= 800) && (collectable->y >= 0) && (collectable->y <= 600))
|
||||||
|
playSound(SFX_EXPLOSION);
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 10 ; i++)
|
||||||
|
addExplosion(collectable->x + rand() % 25 - rand() % 25, collectable->y + rand() % 25 - rand() % 25, E_BIG_EXPLOSION);
|
||||||
|
|
||||||
|
if (checkPlayerShockDamage(collectable->x, collectable->y, 50))
|
||||||
|
setInfoLine("Warning: Mine damage to shield!!", FONT_RED);
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkMineBulletCollisions(object *bullet)
|
||||||
|
{
|
||||||
|
collectables *collectable = engine.collectableHead;
|
||||||
|
collectables *prevCollectable = engine.collectableHead;
|
||||||
|
engine.collectableTail = engine.collectableHead;
|
||||||
|
|
||||||
|
while (collectable->next != NULL)
|
||||||
|
{
|
||||||
|
collectable = collectable->next;
|
||||||
|
|
||||||
|
if (collectable->type == P_MINE)
|
||||||
|
{
|
||||||
|
if (Collision::collision(collectable, bullet))
|
||||||
|
{
|
||||||
|
collectable->active = 0;
|
||||||
|
|
||||||
|
if (bullet->id != WT_CHARGER)
|
||||||
|
{
|
||||||
|
bullet->active = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bullet->shield--;
|
||||||
|
if (bullet->shield < 0)
|
||||||
|
bullet->active = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bullet->owner == &player)
|
||||||
|
{
|
||||||
|
currentGame.minesKilled++;
|
||||||
|
currentGame.hits++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (collectable->active == 1)
|
||||||
|
{
|
||||||
|
prevCollectable = collectable;
|
||||||
|
engine.collectableTail = collectable;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
explodeMine(collectable);
|
||||||
|
prevCollectable->next = collectable->next;
|
||||||
|
delete collectable;
|
||||||
|
collectable = prevCollectable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Loops through the currently active collectables (in a linked list). The collectable
|
||||||
|
will travel in the direction that was defined when it was made. Its life will decreased
|
||||||
|
whilst it remains active. It will be removed if the player touches it or if its life
|
||||||
|
reaches 0. When it is picked up, depending on the type of collectable it is, mission requirements
|
||||||
|
will be updated. Information will be displayed and appropriate player variables altered.
|
||||||
|
*/
|
||||||
|
void doCollectables()
|
||||||
|
{
|
||||||
|
collectables *collectable = engine.collectableHead;
|
||||||
|
collectables *prevCollectable = engine.collectableHead;
|
||||||
|
engine.collectableTail = engine.collectableHead;
|
||||||
|
|
||||||
|
while (collectable->next != NULL)
|
||||||
|
{
|
||||||
|
collectable = collectable->next;
|
||||||
|
|
||||||
|
if (collectable->active == 1)
|
||||||
|
{
|
||||||
|
if ((collectable->x + collectable->image->w > 0) && (collectable->x < 800) && (collectable->y + collectable->image->h > 0) && (collectable->y < 600))
|
||||||
|
graphics.blit(collectable->image, (int)collectable->x, (int)collectable->y);
|
||||||
|
|
||||||
|
collectable->x += engine.ssx;
|
||||||
|
collectable->y += engine.ssy;
|
||||||
|
collectable->x += collectable->dx;
|
||||||
|
collectable->y += collectable->dy;
|
||||||
|
|
||||||
|
collectable->life--;
|
||||||
|
|
||||||
|
if ((player.shield > 0) && (Collision::collision(collectable, &player)))
|
||||||
|
{
|
||||||
|
char temp[40];
|
||||||
|
switch(collectable->type)
|
||||||
|
{
|
||||||
|
case P_CASH:
|
||||||
|
currentGame.cash += collectable->value;
|
||||||
|
currentGame.cashEarned += collectable->value;
|
||||||
|
sprintf(temp, "Got $%d ", collectable->value);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_ROCKET:
|
||||||
|
Math::limitChar(&(player.ammo[1] += collectable->value), 0, currentGame.maxRocketAmmo);
|
||||||
|
if (player.ammo[1] == currentGame.maxRocketAmmo)
|
||||||
|
sprintf(temp, "Rocket Ammo at Maximum");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (collectable->value > 1)
|
||||||
|
sprintf(temp, "Got %d rockets", collectable->value);
|
||||||
|
else
|
||||||
|
sprintf(temp, "Got a rocket");
|
||||||
|
}
|
||||||
|
currentGame.rocketPickups += collectable->value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_SHIELD:
|
||||||
|
Math::limitInt(&(player.shield += 10), 0, player.maxShield);
|
||||||
|
currentGame.shieldPickups ++;
|
||||||
|
sprintf(temp, "Restored 10 shield points");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_PLASMA_RATE:
|
||||||
|
Math::limitChar(&(weapon[1].reload[0] -= 2), currentGame.maxPlasmaRate, 15);
|
||||||
|
player.weaponType[0] = 1;
|
||||||
|
if (player.ammo[0] < 50)
|
||||||
|
player.ammo[0] = 50;
|
||||||
|
Math::limitChar(&(player.ammo[0]), 0, currentGame.maxPlasmaAmmo);
|
||||||
|
if (weapon[1].reload[0] == currentGame.maxPlasmaRate)
|
||||||
|
sprintf(temp, "Firing Rate at Maximum");
|
||||||
|
else
|
||||||
|
sprintf(temp, "Firing rate increased");
|
||||||
|
currentGame.powerups++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_PLASMA_SHOT:
|
||||||
|
Math::limitChar(&(weapon[1].ammo[0] += 1), 1, currentGame.maxPlasmaOutput);
|
||||||
|
if (player.ammo[0] < 50)
|
||||||
|
player.ammo[0] = 50;
|
||||||
|
Math::limitChar(&(player.ammo[0]), 0, currentGame.maxPlasmaAmmo);
|
||||||
|
if (weapon[1].ammo[0] == currentGame.maxPlasmaOutput)
|
||||||
|
sprintf(temp, "Plasma output at Maximum");
|
||||||
|
else
|
||||||
|
sprintf(temp, "Plasma output increased");
|
||||||
|
player.weaponType[0] = 1;
|
||||||
|
currentGame.powerups++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_PLASMA_DAMAGE:
|
||||||
|
Math::limitChar(&(weapon[1].damage += 1), 1, currentGame.maxPlasmaDamage);
|
||||||
|
if (player.ammo[0] < 50)
|
||||||
|
player.ammo[0] = 50;
|
||||||
|
Math::limitChar(&(player.ammo[0]), 0, currentGame.maxPlasmaAmmo);
|
||||||
|
if (weapon[1].damage == currentGame.maxPlasmaDamage)
|
||||||
|
sprintf(temp, "Plasma damage at Maximum");
|
||||||
|
else
|
||||||
|
sprintf(temp, "Plasma damage increased");
|
||||||
|
player.weaponType[0] = 1;
|
||||||
|
currentGame.powerups++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_SUPER:
|
||||||
|
weapon[1].ammo[0] = 5;
|
||||||
|
weapon[1].damage = 5;
|
||||||
|
weapon[1].reload[0] = 7;
|
||||||
|
|
||||||
|
if (weapon[1].flags & WF_STRAIGHT)
|
||||||
|
weapon[1].flags -= WF_STRAIGHT;
|
||||||
|
|
||||||
|
if (weapon[1].flags & WF_THIN_SPREAD)
|
||||||
|
weapon[1].flags -= WF_THIN_SPREAD;
|
||||||
|
|
||||||
|
if (!(weapon[1].flags & WF_WIDE_SPREAD))
|
||||||
|
weapon[1].flags += WF_WIDE_SPREAD;
|
||||||
|
|
||||||
|
sprintf(temp, "Picked up a Super Charge!!");
|
||||||
|
|
||||||
|
if (player.ammo[0] < 50)
|
||||||
|
player.ammo[0] = 50;
|
||||||
|
player.weaponType[0] = 1;
|
||||||
|
currentGame.powerups++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_PLASMA_AMMO:
|
||||||
|
Math::limitChar(&(player.ammo[0] += collectable->value), 0, currentGame.maxPlasmaAmmo);
|
||||||
|
if (player.ammo[0] == currentGame.maxPlasmaAmmo)
|
||||||
|
sprintf(temp, "Plasma cells at Maximum");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (collectable->value > 1)
|
||||||
|
{
|
||||||
|
sprintf(temp, "Got %d plasma cells", collectable->value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(temp, "Got a plasma cell");
|
||||||
|
if ((rand() % 25) == 0)
|
||||||
|
sprintf(temp, "Got one whole plasma cell (wahoo!)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
player.weaponType[0] = 1;
|
||||||
|
currentGame.cellPickups += collectable->value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_CARGO:
|
||||||
|
strcpy(temp, "Picked up some Cargo");
|
||||||
|
currentGame.cargoPickups++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_SLAVES:
|
||||||
|
sprintf(temp, "Rescued %d slaves", collectable->value);
|
||||||
|
currentGame.slavesRescued += collectable->value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_ESCAPEPOD:
|
||||||
|
sprintf(temp, "Picked up an Escape Pod");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case P_ORE:
|
||||||
|
sprintf(temp, "Picked up some Ore");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateMissionRequirements(M_COLLECT, collectable->type, collectable->value);
|
||||||
|
|
||||||
|
collectable->active = 0;
|
||||||
|
if (collectable->type != P_MINE)
|
||||||
|
{
|
||||||
|
setInfoLine(temp, FONT_WHITE);
|
||||||
|
if (collectable->type == P_SHIELD)
|
||||||
|
playSound(SFX_SHIELDUP);
|
||||||
|
else
|
||||||
|
playSound(SFX_PICKUP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// stop people from exploiting a weapon check condition
|
||||||
|
if (player.ammo[0] == 0)
|
||||||
|
{
|
||||||
|
player.weaponType[0] = 0;
|
||||||
|
weapon[1] = weapon[0]; // reset to weapon 1 defaults
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (collectable->life < 1)
|
||||||
|
{
|
||||||
|
collectable->active = 0;
|
||||||
|
if ((collectable->type == P_CARGO) || (collectable->type == P_ESCAPEPOD) || (collectable->type == P_SLAVES))
|
||||||
|
updateMissionRequirements(M_PROTECT_PICKUP, collectable->type, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (collectable->active == 1)
|
||||||
|
{
|
||||||
|
prevCollectable = collectable;
|
||||||
|
engine.collectableTail = collectable;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (collectable->type == P_MINE)
|
||||||
|
explodeMine(collectable);
|
||||||
|
prevCollectable->next = collectable->next;
|
||||||
|
delete collectable;
|
||||||
|
collectable = prevCollectable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern void updateMissionRequirements(int type, int id, int value);
|
||||||
|
extern void setInfoLine(char *in, int color);
|
||||||
|
extern object *addCargo(object *owner, int cargoType);
|
||||||
|
extern void addExplosion(float x, float y, int type);
|
||||||
|
extern void playSound(int sid);
|
||||||
|
extern char checkPlayerShockDamage(float x, float y, int radius);
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern object player;
|
||||||
|
extern Game currentGame;
|
||||||
|
extern object weapon[MAX_WEAPONS];
|
||||||
|
extern Graphics graphics;
|
|
@ -0,0 +1,156 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "comms.h"
|
||||||
|
|
||||||
|
void updateCommsSurface(SDL_Surface *comms)
|
||||||
|
{
|
||||||
|
if (engine.commsSection == 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
char string[255];
|
||||||
|
|
||||||
|
graphics.blevelRect(comms, 0, 10, comms->w - 1, 55, 0x00, 0x22, 0x00);
|
||||||
|
graphics.blit(graphics.shape[FACE_CHRIS], 20, 15, comms);
|
||||||
|
graphics.drawString("Chris Bainfield", 80, 15, FONT_WHITE, comms);
|
||||||
|
sprintf(string, "Current Location: %s", systemPlanet[currentGame.stationedPlanet].name);
|
||||||
|
graphics.drawString(string, 80, 35, FONT_WHITE, comms);
|
||||||
|
}
|
||||||
|
|
||||||
|
void createCommsSurface(SDL_Surface *comms)
|
||||||
|
{
|
||||||
|
engine.commsSection = 0;
|
||||||
|
|
||||||
|
graphics.blevelRect(comms, 0, 0, comms->w - 1, comms->h - 1, 0x00, 0x00, 0x25);
|
||||||
|
|
||||||
|
graphics.drawString("+++ RECIEVED MESSAGES +++", 115, 80, FONT_GREEN, comms);
|
||||||
|
|
||||||
|
int yOffset;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 10 ; i++)
|
||||||
|
{
|
||||||
|
if ((systemPlanet[i].messageSlot != -1) && (systemPlanet[i].missionCompleted == 0))
|
||||||
|
{
|
||||||
|
yOffset = systemPlanet[i].messageSlot * 60;
|
||||||
|
graphics.blevelRect(comms, 0, 105 + yOffset, comms->w - 1, 55, 0x00, 0x00, 0x77);
|
||||||
|
graphics.blit(graphics.shape[systemPlanet[i].faceImage], 20, 110 + yOffset, comms);
|
||||||
|
graphics.drawString(systemPlanet[i].from, 80, 110 + yOffset, FONT_WHITE, comms);
|
||||||
|
graphics.drawString(systemPlanet[i].subject, 80, 130 + yOffset, FONT_CYAN, comms);
|
||||||
|
graphics.drawString("INCOMPLETE", 350, 110 + yOffset, FONT_RED, comms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCommsSurface(comms);
|
||||||
|
}
|
||||||
|
|
||||||
|
void createMissionDetailSurface(SDL_Surface *comms, int missionSlot)
|
||||||
|
{
|
||||||
|
char name[50];
|
||||||
|
char string[2000];
|
||||||
|
int lines = 0;
|
||||||
|
int y = 50;
|
||||||
|
int newY = y;
|
||||||
|
int col = FONT_WHITE;
|
||||||
|
int mission = -1;
|
||||||
|
int faceNumber = -1;
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 10 ; i++)
|
||||||
|
{
|
||||||
|
if ((systemPlanet[i].messageSlot == missionSlot) && (systemPlanet[i].missionCompleted == 0))
|
||||||
|
{
|
||||||
|
//printf("Slot %d - Mission %d - Completed %d\n", missionSlot, systemPlanet[i].messageMission, systemPlanet[i].missionCompleted);
|
||||||
|
mission = systemPlanet[i].messageMission;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mission == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
graphics.blevelRect(comms, 0, 0, comms->w - 1, comms->h - 1, 0x00, 0x00, 0x25);
|
||||||
|
|
||||||
|
strcpy(string, "");
|
||||||
|
sprintf(string, "data/brief%d.txt", mission);
|
||||||
|
|
||||||
|
#if USEPACK
|
||||||
|
int dataLocation = locateDataInPak(string, 1);
|
||||||
|
fp = fopen(PACKLOCATION, "rb");
|
||||||
|
fseek(fp, dataLocation, SEEK_SET);
|
||||||
|
#else
|
||||||
|
fp = fopen(string, "rb");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fscanf(fp, "%[^\n]%*c", name);
|
||||||
|
sprintf(string, "+++ Communication with %s +++", name);
|
||||||
|
graphics.drawString(string, -1, 20, FONT_GREEN, comms);
|
||||||
|
|
||||||
|
fscanf(fp, "%d%*c", &lines);
|
||||||
|
|
||||||
|
for (int i = 0 ; i < lines ; i++)
|
||||||
|
{
|
||||||
|
fscanf(fp, "%[^\n]%*c", string);
|
||||||
|
faceNumber = getFace(string);
|
||||||
|
if (faceNumber > -1)
|
||||||
|
{
|
||||||
|
graphics.blit(graphics.shape[faceNumber], 10, y, comms);
|
||||||
|
col = FONT_WHITE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newY = graphics.drawString(string, 80, y, col, 1, comms) + 25;
|
||||||
|
if (newY < y + 60)
|
||||||
|
newY += (60 - (newY - y));
|
||||||
|
y = newY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
graphics.blevelRect(comms, 5, comms->h - 28, 180, 20, 0x25, 0x00, 0x00);
|
||||||
|
graphics.drawString("RETURN TO MESSAGES", 15, comms->h - 25, FONT_WHITE, 1, comms);
|
||||||
|
|
||||||
|
engine.commsSection = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doComms(SDL_Surface *comms)
|
||||||
|
{
|
||||||
|
if ((engine.keyState[SDLK_LCTRL]) || (engine.keyState[SDLK_RCTRL]))
|
||||||
|
{
|
||||||
|
if (engine.commsSection == 0)
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < 4 ; i++)
|
||||||
|
{
|
||||||
|
if (Collision::collision(engine.cursor_x + 13, engine.cursor_y + 13, 6, 6, 170, 180 + (i * 60), 430, 50))
|
||||||
|
{
|
||||||
|
createMissionDetailSurface(comms, i);
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Collision::collision(engine.cursor_x + 13, engine.cursor_y + 13, 6, 6, 170, 440, 160, 20))
|
||||||
|
{
|
||||||
|
createCommsSurface(comms);
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern int locateDataInPak(char *file, signed char required);
|
||||||
|
extern int getFace(char *face);
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern Game currentGame;
|
||||||
|
extern Graphics graphics;
|
||||||
|
extern Planet systemPlanet[10];
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "debris.h"
|
||||||
|
|
||||||
|
void addDebris(int x, int y, int amount)
|
||||||
|
{
|
||||||
|
if ((rand() % 2) == 0)
|
||||||
|
playSound(SFX_DEBRIS);
|
||||||
|
else
|
||||||
|
playSound(SFX_DEBRIS2);
|
||||||
|
|
||||||
|
object *debris;
|
||||||
|
|
||||||
|
amount = Math::rrand(3, rand() % amount);
|
||||||
|
Math::limitInt(&amount, 3, 8);
|
||||||
|
|
||||||
|
for (int i = 0 ; i < amount ; i++)
|
||||||
|
{
|
||||||
|
debris = new object;
|
||||||
|
|
||||||
|
debris->next = NULL;
|
||||||
|
debris->x = x;
|
||||||
|
debris->y = y;
|
||||||
|
|
||||||
|
debris->thinktime = Math::rrand(60, 180);
|
||||||
|
|
||||||
|
debris->dx = Math::rrand(-500, 500);
|
||||||
|
debris->dy = Math::rrand(-500, 500);
|
||||||
|
|
||||||
|
if (debris->dx != 0)
|
||||||
|
debris->dx /= 100;
|
||||||
|
|
||||||
|
if (debris->dy != 0)
|
||||||
|
debris->dy /= 100;
|
||||||
|
|
||||||
|
engine.debrisTail->next = debris;
|
||||||
|
engine.debrisTail = debris;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void doDebris()
|
||||||
|
{
|
||||||
|
object *prevDebris = engine.debrisHead;
|
||||||
|
object *debris = engine.debrisHead;
|
||||||
|
engine.debrisTail = engine.debrisHead;
|
||||||
|
|
||||||
|
while (debris->next != NULL)
|
||||||
|
{
|
||||||
|
debris = debris->next;
|
||||||
|
|
||||||
|
if (debris->thinktime > 0)
|
||||||
|
{
|
||||||
|
debris->thinktime--;
|
||||||
|
|
||||||
|
debris->x += engine.ssx;
|
||||||
|
debris->y += engine.ssy;
|
||||||
|
debris->x += debris->dx;
|
||||||
|
debris->y += debris->dy;
|
||||||
|
|
||||||
|
addExplosion(debris->x + Math::rrand(-10, 10), debris->y + Math::rrand(-10, 10), E_BIG_EXPLOSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debris->thinktime < 1)
|
||||||
|
{
|
||||||
|
prevDebris->next = debris->next;
|
||||||
|
delete debris;
|
||||||
|
debris = prevDebris;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prevDebris = debris;
|
||||||
|
engine.debrisTail = debris;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern void addExplosion(float x, float y, int type);
|
||||||
|
extern void playSound(int sid);
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern Graphics graphics;
|
|
@ -0,0 +1,315 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define min(a, b) ((a) < (b) ? (a) : (b))
|
||||||
|
#define max(a, b) ((a) > (b) ? (a) : (b))
|
||||||
|
|
||||||
|
// ALL
|
||||||
|
#define NONE 0
|
||||||
|
|
||||||
|
//AI Types
|
||||||
|
enum {
|
||||||
|
|
||||||
|
AI_NORMAL = 1,
|
||||||
|
AI_DEFENSIVE,
|
||||||
|
AI_OFFENSIVE,
|
||||||
|
AI_EVASIVE,
|
||||||
|
AI_WANDER
|
||||||
|
};
|
||||||
|
|
||||||
|
// Object Flags
|
||||||
|
#define FL_WEAPCO 1
|
||||||
|
#define FL_FRIEND 2
|
||||||
|
#define FL_IMMORTAL 4
|
||||||
|
#define FL_NOMOVE 8
|
||||||
|
#define FL_NOFIRE 16
|
||||||
|
#define FL_FIRERAY 32
|
||||||
|
#define FL_DAMAGEOWNER 64
|
||||||
|
#define FL_LEAVESECTOR 128
|
||||||
|
#define FL_ESCAPED 256
|
||||||
|
#define FL_DROPMINES 512
|
||||||
|
#define FL_AIMS 1024
|
||||||
|
#define FL_DISABLED 2048
|
||||||
|
#define FL_CANNOTDIE 4096 // This will only apply to Kline before the final mission
|
||||||
|
#define FL_RUNSAWAY 8192
|
||||||
|
#define FL_ALWAYSFACE 16384 // Kline doesn't turn his back on you! ;)
|
||||||
|
#define FL_CIRCLES 32768 // Kline can circle around
|
||||||
|
#define FL_CONTINUOUS_FIRE 65536 // Go absolutely nutts(!)
|
||||||
|
#define FL_DEPLOYDRONES 131072 // Deploys small drone - Used by Boss 2
|
||||||
|
#define FL_CANCLOAK 262144
|
||||||
|
#define FL_ISCLOAKED 524288
|
||||||
|
#define FL_ACTIVATE 1048576
|
||||||
|
#define FL_HASMINIMUMSPEED 2097152
|
||||||
|
#define FL_FIRELASER 4194304
|
||||||
|
|
||||||
|
// These are for Alien *indexes* NOT classdefs!!
|
||||||
|
enum {
|
||||||
|
|
||||||
|
WC_BOSS = 14,
|
||||||
|
WC_KLINE,
|
||||||
|
FR_PHOEBE,
|
||||||
|
FR_URSULA,
|
||||||
|
FR_SID
|
||||||
|
};
|
||||||
|
|
||||||
|
// Droppables
|
||||||
|
enum {
|
||||||
|
|
||||||
|
P_ANYTHING = 1,
|
||||||
|
P_WEAPONS,
|
||||||
|
P_CASH,
|
||||||
|
P_ROCKET,
|
||||||
|
P_SHIELD,
|
||||||
|
P_CARGO,
|
||||||
|
P_PLASMA_AMMO,
|
||||||
|
P_PLASMA_RATE,
|
||||||
|
P_PLASMA_SHOT,
|
||||||
|
P_PLASMA_DAMAGE,
|
||||||
|
P_MINE, // mines detonate when you "pick them up!"
|
||||||
|
P_PHOEBE, // only used as an attachment(!)
|
||||||
|
P_SLAVES,
|
||||||
|
P_ESCAPEPOD,
|
||||||
|
P_ORE,
|
||||||
|
P_SUPER
|
||||||
|
};
|
||||||
|
|
||||||
|
// Jobs
|
||||||
|
enum {
|
||||||
|
|
||||||
|
WT_PLASMA = 1,
|
||||||
|
WT_ROCKET,
|
||||||
|
WT_ENERGYRAY,
|
||||||
|
WT_LASER,
|
||||||
|
WT_MICROROCKET,
|
||||||
|
WT_CHARGER,
|
||||||
|
WT_DIRECTIONAL,
|
||||||
|
WT_SPREAD
|
||||||
|
};
|
||||||
|
|
||||||
|
// Explosions
|
||||||
|
#define E_SMALL_EXPLOSION 4
|
||||||
|
#define E_BIG_EXPLOSION 8
|
||||||
|
#define E_SMOKE 12
|
||||||
|
#define E_TINY_EXPLOSION 16
|
||||||
|
#define E_ELECTRICAL 20
|
||||||
|
|
||||||
|
// Weapons
|
||||||
|
enum {
|
||||||
|
|
||||||
|
W_NONE = -1,
|
||||||
|
W_PLAYER_WEAPON,
|
||||||
|
W_PLAYER_WEAPON2,
|
||||||
|
W_SINGLE_SHOT,
|
||||||
|
W_DOUBLE_SHOT,
|
||||||
|
W_TRIPLE_SHOT,
|
||||||
|
W_ROCKETS,
|
||||||
|
W_DOUBLE_ROCKETS,
|
||||||
|
W_MICRO_ROCKETS,
|
||||||
|
W_ENERGYRAY,
|
||||||
|
W_LASER,
|
||||||
|
W_CHARGER,
|
||||||
|
W_HOMING_MISSILE,
|
||||||
|
W_DOUBLE_HOMING_MISSILES,
|
||||||
|
W_MICRO_HOMING_MISSILES,
|
||||||
|
W_AIMED_SHOT,
|
||||||
|
W_SPREADSHOT,
|
||||||
|
W_IONCANNON,
|
||||||
|
W_DIRSHOCKMISSILE
|
||||||
|
};
|
||||||
|
|
||||||
|
// Weapon flags
|
||||||
|
#define WF_STRAIGHT 1
|
||||||
|
#define WF_THIN_SPREAD 2
|
||||||
|
#define WF_WIDE_SPREAD 4
|
||||||
|
#define WF_SCATTER 8
|
||||||
|
#define WF_VARIABLE_SPEED 16
|
||||||
|
#define WF_HOMING 32
|
||||||
|
#define WF_SHOCKWAVE 64
|
||||||
|
#define WF_WEAPCO 128
|
||||||
|
#define WF_FRIEND 256
|
||||||
|
#define WF_AIMED 512
|
||||||
|
#define WF_DISABLE 1024
|
||||||
|
#define WF_TIMEDEXPLOSION 2048
|
||||||
|
|
||||||
|
// Missions
|
||||||
|
enum {
|
||||||
|
|
||||||
|
M_DESTROY_ALL_TARGETS = 1,
|
||||||
|
M_DESTROY_TARGET_TYPE,
|
||||||
|
M_COLLECT,
|
||||||
|
M_PROTECT_PICKUP,
|
||||||
|
M_PROTECT_TARGET,
|
||||||
|
M_DISABLE_TARGET,
|
||||||
|
M_ESCAPE_TARGET
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
|
||||||
|
OB_JUST_FAILED = -2,
|
||||||
|
OB_FAILED,
|
||||||
|
OB_INCOMPLETE,
|
||||||
|
OB_COMPLETED,
|
||||||
|
OB_JUST_COMPLETED,
|
||||||
|
OB_CONDITION,
|
||||||
|
OB_HIDDEN
|
||||||
|
};
|
||||||
|
|
||||||
|
// Class Defs - Some of these are just place holders
|
||||||
|
enum {
|
||||||
|
|
||||||
|
CD_DUALFIGHTER, // 0
|
||||||
|
CD_MISSILEBOAT,
|
||||||
|
CD_PROTOFIGHTER,
|
||||||
|
CD_FRIEND,
|
||||||
|
CD_FRIGATE,
|
||||||
|
CD_FRIGATE_WING1,
|
||||||
|
CD_FRIGATE_WING2,
|
||||||
|
CD_TRANSPORTSHIP,
|
||||||
|
CD_CARGOSHIP,
|
||||||
|
CD_MINER,
|
||||||
|
CD_KLINE, // 10
|
||||||
|
CD_AIMFIGHTER,
|
||||||
|
CD_SLAVETRANSPORT,
|
||||||
|
CD_GOODTRANSPORT,
|
||||||
|
CD_SID,
|
||||||
|
CD_MINEBOSS,
|
||||||
|
CD_BOSS2_WING1,
|
||||||
|
CD_BOSS2_WING2,
|
||||||
|
CD_BOSS2_WING3,
|
||||||
|
CD_BOSS2_WING4,
|
||||||
|
CD_DRONE, // 20
|
||||||
|
CD_CLOAKFIGHTER,
|
||||||
|
CD_EVILURSULA,
|
||||||
|
CD_KRASS,
|
||||||
|
CD_EXEC,
|
||||||
|
CD_ASTEROID,
|
||||||
|
CD_ASTEROID2,
|
||||||
|
CD_ESCORT,
|
||||||
|
CD_MOBILE_RAY,
|
||||||
|
CD_REBELCARRIER,
|
||||||
|
CD_PLUTOBOSS, // 30
|
||||||
|
CD_BARRIER,
|
||||||
|
CD_NEPTUNEBOSS,
|
||||||
|
CD_MOBILESHIELD,
|
||||||
|
CD_PIRATE,
|
||||||
|
CD_FIREFLY,
|
||||||
|
CD_URANUSBOSS,
|
||||||
|
CD_URANUSBOSSWING1,
|
||||||
|
CD_URANUSBOSSWING2,
|
||||||
|
|
||||||
|
// Some special ones
|
||||||
|
CD_ANY = 100,
|
||||||
|
CD_BOSS,
|
||||||
|
CD_PHOEBE,
|
||||||
|
CD_URSULA
|
||||||
|
};
|
||||||
|
|
||||||
|
// Font Colors
|
||||||
|
enum {
|
||||||
|
|
||||||
|
FONT_WHITE,
|
||||||
|
FONT_RED,
|
||||||
|
FONT_YELLOW,
|
||||||
|
FONT_GREEN,
|
||||||
|
FONT_CYAN,
|
||||||
|
FONT_OUTLINE // a dark blue color
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sounds
|
||||||
|
enum {
|
||||||
|
|
||||||
|
SFX_EXPLOSION,
|
||||||
|
SFX_HIT,
|
||||||
|
SFX_DEATH,
|
||||||
|
SFX_MISSILE,
|
||||||
|
SFX_PLASMA,
|
||||||
|
SFX_CLOCK,
|
||||||
|
SFX_FLY,
|
||||||
|
SFX_ENERGYRAY,
|
||||||
|
SFX_PICKUP,
|
||||||
|
SFX_SHIELDUP,
|
||||||
|
SFX_CLOAK,
|
||||||
|
SFX_DEBRIS,
|
||||||
|
SFX_DEBRIS2,
|
||||||
|
SFX_LASER,
|
||||||
|
SFX_PLASMA2,
|
||||||
|
SFX_PLASMA3
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
|
||||||
|
SECTION_TITLE,
|
||||||
|
SECTION_INTERMISSION,
|
||||||
|
SECTION_GAME
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
|
||||||
|
FACE_CHRIS = 90,
|
||||||
|
FACE_SID,
|
||||||
|
FACE_KRASS,
|
||||||
|
FACE_KLINE,
|
||||||
|
FACE_PHOEBE,
|
||||||
|
FACE_URSULA,
|
||||||
|
FACE_CREW
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_WEAPONS 20
|
||||||
|
#define MAX_SHAPES 100
|
||||||
|
#define MAX_SHIPSHAPES 120
|
||||||
|
#define MAX_SOUNDS 17
|
||||||
|
#define MAX_ALIENS 25
|
||||||
|
#define MAX_TEXTSHAPES 70
|
||||||
|
#define MAX_FONTSHAPES 6
|
||||||
|
#define MAX_SHOPSHAPES 6
|
||||||
|
#define MAX_DEFALIENS 40
|
||||||
|
#define MAX_MISSIONS 28
|
||||||
|
#define MAX_CARGO 20
|
||||||
|
#define MAX_SHOPITEMS 17
|
||||||
|
|
||||||
|
#define SHIP_HIT_INDEX 60
|
||||||
|
|
||||||
|
#define USEPACK 1
|
||||||
|
#ifndef PACKLOCATION
|
||||||
|
#define PACKLOCATION "starfighter.pak"
|
||||||
|
#endif
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#define PATH_MAX 4096
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum {
|
||||||
|
|
||||||
|
PAK_IMG,
|
||||||
|
PAK_WAV,
|
||||||
|
PAK_MOD,
|
||||||
|
PAK_FONT,
|
||||||
|
PAK_S3M
|
||||||
|
};
|
||||||
|
|
||||||
|
const char systemNames[][15] = {"Spirit", "Eyananth", "Mordor", "Sol"};
|
||||||
|
|
||||||
|
const char faces[][12] = {
|
||||||
|
"FACE_CHRIS", "FACE_SID", "FACE_KRASS",
|
||||||
|
"FACE_KLINE", "FACE_PHOEBE", "FACE_URSULA",
|
||||||
|
"FACE_CREW"};
|
||||||
|
|
||||||
|
const char systemBackground[][20] = {
|
||||||
|
"gfx/spirit.jpg", "gfx/eyananth.jpg",
|
||||||
|
"gfx/mordor.jpg", "gfx/sol.jpg"};
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "events.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Checked during the main game loop. When the game is paused
|
||||||
|
it goes into a constant loop checking this routine. If escape is
|
||||||
|
pressed, the game automatically ends and goes back to the title screen
|
||||||
|
*/
|
||||||
|
signed char checkPauseRequest()
|
||||||
|
{
|
||||||
|
getPlayerInput();
|
||||||
|
|
||||||
|
if (engine.keyState[SDLK_ESCAPE])
|
||||||
|
{
|
||||||
|
engine.paused = 0;
|
||||||
|
engine.done = 1;
|
||||||
|
player.shield = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (engine.keyState[SDLK_p])
|
||||||
|
{
|
||||||
|
engine.paused = 0;
|
||||||
|
engine.keyState[SDLK_p] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void compareLastKeyInputs()
|
||||||
|
{
|
||||||
|
if (strstr(lastKeyEvents, "humansdoitbetter") != NULL)
|
||||||
|
{engine.cheat = 1; memset(lastKeyEvents, ' ', 25);}
|
||||||
|
|
||||||
|
if (strstr(lastKeyEvents, "credits") != NULL)
|
||||||
|
{engine.cheatCredits = 1; memset(lastKeyEvents, ' ', 25);}
|
||||||
|
}
|
||||||
|
|
||||||
|
void addKeyEvent(char *keyName)
|
||||||
|
{
|
||||||
|
if (strlen(keyName) > 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int index = -1;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 25 ; i++)
|
||||||
|
{
|
||||||
|
if (lastKeyEvents[i] == ' ')
|
||||||
|
{
|
||||||
|
index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index == -1)
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < 25 ; i++)
|
||||||
|
{
|
||||||
|
lastKeyEvents[i] = lastKeyEvents[i + 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
index = 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
lastKeyEvents[index] = keyName[0];
|
||||||
|
|
||||||
|
compareLastKeyInputs();
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "structs.h"
|
||||||
|
|
||||||
|
extern void getPlayerInput();
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern object player;
|
||||||
|
extern Game currentGame;
|
||||||
|
extern devVariables dev;
|
||||||
|
|
||||||
|
char lastKeyEvents[] = " ";
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "explosions.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create a new explosion based on supplied parameters.
|
||||||
|
The "type" will actually be used as an explosion frame check.
|
||||||
|
All explosion types have 4 images. The "thinktime" will be used
|
||||||
|
to change frames on a 21, 14, 7 basis.
|
||||||
|
*/
|
||||||
|
void addExplosion(float x, float y, int type)
|
||||||
|
{
|
||||||
|
object *explosion = new object;
|
||||||
|
|
||||||
|
explosion->next = NULL;
|
||||||
|
explosion->active = 1;
|
||||||
|
explosion->x = x;
|
||||||
|
explosion->y = y;
|
||||||
|
explosion->thinktime = 28;
|
||||||
|
explosion->face = type;
|
||||||
|
explosion->image[0] = graphics.shape[type];
|
||||||
|
|
||||||
|
engine.explosionTail->next = explosion;
|
||||||
|
engine.explosionTail = explosion;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This very simply just adds a tiny explosion at the coordinate specified.
|
||||||
|
* It creates a small engine like effect.
|
||||||
|
*/
|
||||||
|
void addEngine(object *craft)
|
||||||
|
{
|
||||||
|
if (rand() % 2 == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
float x = craft->x + (craft->engineX * craft->face);
|
||||||
|
float y = craft->y + craft->engineY;
|
||||||
|
|
||||||
|
y += Math::rrand(-3, 3);
|
||||||
|
addExplosion(x, y, E_TINY_EXPLOSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Loops through active explosions and decrements their think time.
|
||||||
|
If their thinktime is divisable by 5, then the frame is changed to
|
||||||
|
the next one up (for example 0->1->2-3). When their think time is 0,
|
||||||
|
the explosion is killed off.
|
||||||
|
*/
|
||||||
|
void doExplosions()
|
||||||
|
{
|
||||||
|
object *prevExplosion = engine.explosionHead;
|
||||||
|
object *explosion = engine.explosionHead;
|
||||||
|
engine.explosionTail = engine.explosionHead;
|
||||||
|
|
||||||
|
while (explosion->next != NULL)
|
||||||
|
{
|
||||||
|
explosion = explosion->next;
|
||||||
|
|
||||||
|
if (explosion->active == 1)
|
||||||
|
{
|
||||||
|
explosion->thinktime--;
|
||||||
|
|
||||||
|
explosion->x += engine.ssx;
|
||||||
|
explosion->y += engine.ssy;
|
||||||
|
|
||||||
|
if (isOnScreen((int)explosion->x, (int)explosion->y, explosion->image[0]->w, explosion->image[0]->h))
|
||||||
|
graphics.blit(explosion->image[0], (int)explosion->x, (int)explosion->y);
|
||||||
|
|
||||||
|
if (explosion->thinktime < 1)
|
||||||
|
{
|
||||||
|
explosion->active = 0;
|
||||||
|
}
|
||||||
|
else if (explosion->thinktime % 7 == 0)
|
||||||
|
{
|
||||||
|
explosion->face++;
|
||||||
|
explosion->image[0] = graphics.shape[explosion->face];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (explosion->active == 1)
|
||||||
|
{
|
||||||
|
prevExplosion = explosion;
|
||||||
|
engine.explosionTail = explosion;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prevExplosion->next = explosion->next;
|
||||||
|
delete explosion;
|
||||||
|
explosion = prevExplosion;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern int isOnScreen(int x, int y, int w, int h);
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern devVariables dev;
|
||||||
|
extern object enemy[MAX_ALIENS];
|
||||||
|
extern Graphics graphics;
|
|
@ -0,0 +1,344 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "game.h"
|
||||||
|
|
||||||
|
void newGame()
|
||||||
|
{
|
||||||
|
currentGame.system = 0;
|
||||||
|
currentGame.area = 0;
|
||||||
|
currentGame.sfxVolume = 0;
|
||||||
|
currentGame.musicVolume = 0;
|
||||||
|
|
||||||
|
if (!engine.useAudio)
|
||||||
|
{
|
||||||
|
currentGame.useSound = 0;
|
||||||
|
currentGame.useMusic = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentGame.autoSaveSlot = -1;
|
||||||
|
|
||||||
|
currentGame.cash = 0;
|
||||||
|
currentGame.cashEarned = 0;
|
||||||
|
currentGame.shots = 0;
|
||||||
|
currentGame.hits = 0;
|
||||||
|
currentGame.accuracy = 0;
|
||||||
|
currentGame.totalKills = currentGame.wingMate1Kills = currentGame.wingMate2Kills = 0;
|
||||||
|
currentGame.totalOtherKills = 0;
|
||||||
|
currentGame.hasWingMate1 = currentGame.hasWingMate2 = 0;
|
||||||
|
currentGame.wingMate1Ejects = currentGame.wingMate2Ejects = 0;
|
||||||
|
currentGame.secondaryMissions = currentGame.secondaryMissionsCompleted = 0;
|
||||||
|
currentGame.shieldPickups = currentGame.rocketPickups = currentGame.cellPickups = 0;
|
||||||
|
currentGame.powerups = currentGame.minesKilled = currentGame.cargoPickups = 0;
|
||||||
|
|
||||||
|
currentGame.slavesRescued = 0;
|
||||||
|
currentGame.experimentalShield = 1000;
|
||||||
|
|
||||||
|
currentGame.timeTaken = 0;
|
||||||
|
|
||||||
|
currentGame.stationedPlanet = -1;
|
||||||
|
currentGame.destinationPlanet = -1;
|
||||||
|
for (int i = 0 ; i < 10 ; i++)
|
||||||
|
currentGame.missionCompleted[i] = 0;
|
||||||
|
currentGame.distanceCovered = 0;
|
||||||
|
|
||||||
|
currentGame.maxPlasmaRate = 13;
|
||||||
|
currentGame.maxPlasmaOutput = 2;
|
||||||
|
currentGame.maxPlasmaDamage = 2;
|
||||||
|
currentGame.maxPlasmaAmmo = 100;
|
||||||
|
currentGame.maxRocketAmmo = 10;
|
||||||
|
|
||||||
|
currentGame.shieldUnits = 1;
|
||||||
|
|
||||||
|
player.maxShield = 25;
|
||||||
|
player.shield = 25;
|
||||||
|
player.ammo[0] = 0;
|
||||||
|
player.ammo[1] = 5;
|
||||||
|
player.weaponType[0] = W_PLAYER_WEAPON;
|
||||||
|
player.weaponType[1] = W_ROCKETS;
|
||||||
|
|
||||||
|
initWeapons();
|
||||||
|
initMissions();
|
||||||
|
initPlanetMissions(currentGame.system);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mainGameLoop()
|
||||||
|
{
|
||||||
|
Uint32 then, now, frames;
|
||||||
|
|
||||||
|
resetLists();
|
||||||
|
|
||||||
|
setMission(currentGame.area);
|
||||||
|
missionBriefScreen();
|
||||||
|
|
||||||
|
initCargo();
|
||||||
|
initPlayer();
|
||||||
|
initAliens();
|
||||||
|
clearInfoLines();
|
||||||
|
|
||||||
|
loadScriptEvents();
|
||||||
|
|
||||||
|
engine.ssx = 0;
|
||||||
|
engine.ssy = 0;
|
||||||
|
|
||||||
|
engine.done = 0;
|
||||||
|
frames = 0;
|
||||||
|
|
||||||
|
engine.counter = (SDL_GetTicks() + 1000);
|
||||||
|
engine.counter2 = (SDL_GetTicks() + 1000);
|
||||||
|
|
||||||
|
engine.missionCompleteTimer = 0;
|
||||||
|
engine.musicVolume = 100;
|
||||||
|
|
||||||
|
int rtn = 0;
|
||||||
|
unsigned long frameLimit = SDL_GetTicks();
|
||||||
|
|
||||||
|
int allowableAliens = 999999999;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 3 ; i++)
|
||||||
|
{
|
||||||
|
if ((currentMission.primaryType[i] == M_DESTROY_TARGET_TYPE) && (currentMission.target1[i] == CD_ANY))
|
||||||
|
allowableAliens = currentMission.targetValue1[i];
|
||||||
|
|
||||||
|
if (currentMission.primaryType[i] == M_DESTROY_ALL_TARGETS)
|
||||||
|
allowableAliens = 999999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < MAX_ALIENS ; i++)
|
||||||
|
{
|
||||||
|
if ((enemy[i].active) && (enemy[i].flags & FL_WEAPCO))
|
||||||
|
{
|
||||||
|
allowableAliens--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
then = SDL_GetTicks();
|
||||||
|
|
||||||
|
graphics.drawBackGround();
|
||||||
|
graphics.flushBuffer();
|
||||||
|
|
||||||
|
// Default to no aliens dead...
|
||||||
|
engine.allAliensDead = 0;
|
||||||
|
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = engine.keyState[SDLK_SPACE] = 0;
|
||||||
|
flushInput();
|
||||||
|
|
||||||
|
while (engine.done != 1)
|
||||||
|
{
|
||||||
|
++frames;
|
||||||
|
|
||||||
|
graphics.updateScreen();
|
||||||
|
|
||||||
|
if ((allMissionsCompleted()) && (engine.missionCompleteTimer == 0))
|
||||||
|
{
|
||||||
|
engine.missionCompleteTimer = SDL_GetTicks() + 4000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((missionFailed()) && (engine.missionCompleteTimer == 0))
|
||||||
|
{
|
||||||
|
if (currentGame.area != 5)
|
||||||
|
engine.missionCompleteTimer = SDL_GetTicks() + 4000;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (engine.missionCompleteTimer != 0)
|
||||||
|
{
|
||||||
|
engine.gameSection = SECTION_INTERMISSION;
|
||||||
|
if (player.shield > 0)
|
||||||
|
{
|
||||||
|
if (SDL_GetTicks() >= engine.missionCompleteTimer)
|
||||||
|
{
|
||||||
|
if ((!missionFailed()) && (currentGame.area != 26))
|
||||||
|
{
|
||||||
|
leaveSector();
|
||||||
|
if ((engine.done == 2) && (currentGame.area != 10) && (currentGame.area != 15))
|
||||||
|
{
|
||||||
|
if ((enemy[FR_PHOEBE].shield > 0) && (currentGame.area != 25))
|
||||||
|
{
|
||||||
|
enemy[FR_PHOEBE].x = player.x - 40;
|
||||||
|
enemy[FR_PHOEBE].y = player.y - 35;
|
||||||
|
enemy[FR_PHOEBE].face = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((enemy[FR_URSULA].shield > 0) && (currentGame.area != 25))
|
||||||
|
{
|
||||||
|
enemy[FR_URSULA].x = player.x - 40;
|
||||||
|
enemy[FR_URSULA].y = player.y + 45;
|
||||||
|
enemy[FR_URSULA].face = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((currentGame.area == 9) || (currentGame.area == 17))
|
||||||
|
{
|
||||||
|
enemy[FR_SID].x = player.x - 100;
|
||||||
|
enemy[FR_SID].y = player.y;
|
||||||
|
enemy[FR_SID].face = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((currentGame.area == 26) && (engine.musicVolume > 0))
|
||||||
|
{
|
||||||
|
Math::limitFloat(&(engine.musicVolume -= 0.2), 0, 100);
|
||||||
|
Mix_VolumeMusic((int)engine.musicVolume);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
engine.done = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
getPlayerInput();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Math::limitFloat(&(engine.musicVolume -= 0.2), 0, 100);
|
||||||
|
Mix_VolumeMusic((int)engine.musicVolume);
|
||||||
|
if (SDL_GetTicks() >= engine.missionCompleteTimer)
|
||||||
|
{
|
||||||
|
engine.done = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
getPlayerInput();
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.unBuffer();
|
||||||
|
doStarfield();
|
||||||
|
doCollectables();
|
||||||
|
doBullets();
|
||||||
|
doAliens();
|
||||||
|
doPlayer();
|
||||||
|
doCargo();
|
||||||
|
doDebris();
|
||||||
|
doExplosions();
|
||||||
|
doInfo();
|
||||||
|
|
||||||
|
Math::wrapChar(&(--engine.eventTimer), 0, 60);
|
||||||
|
|
||||||
|
while (engine.paused)
|
||||||
|
{
|
||||||
|
engine.done = checkPauseRequest();
|
||||||
|
then = SDL_GetTicks();
|
||||||
|
frames = 0;
|
||||||
|
graphics.updateScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((currentGame.area == 24) && (engine.addAliens > -1))
|
||||||
|
{
|
||||||
|
if ((rand() % 10) == 0)
|
||||||
|
addCollectable(Math::rrand(800, 100), player.y, P_MINE, 25, 180 + rand() % 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (engine.addAliens > -1)
|
||||||
|
{
|
||||||
|
Math::wrapInt(&(--engine.addAliens), 0, currentMission.addAliens);
|
||||||
|
if ((engine.addAliens == 0) && (allowableAliens > 0))
|
||||||
|
{
|
||||||
|
allowableAliens -= addAlien();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((player.shield <= 0) && (engine.missionCompleteTimer == 0))
|
||||||
|
engine.missionCompleteTimer = SDL_GetTicks() + 7000;
|
||||||
|
|
||||||
|
// specific to Boss 1
|
||||||
|
if ((currentGame.area == 5) && (enemy[WC_BOSS].flags & FL_ESCAPED))
|
||||||
|
{
|
||||||
|
playSound(SFX_DEATH);
|
||||||
|
graphics.clearScreen(graphics.white);
|
||||||
|
graphics.updateScreen();
|
||||||
|
for (int i = 0 ; i < 300 ; i++)
|
||||||
|
{
|
||||||
|
SDL_Delay(10);
|
||||||
|
if ((rand() % 25) == 0)
|
||||||
|
playSound(SFX_EXPLOSION);
|
||||||
|
}
|
||||||
|
SDL_Delay(1000);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// (Attempt to) Limit us to 60 frame a second
|
||||||
|
while (SDL_GetTicks() < (frameLimit + 16))
|
||||||
|
{
|
||||||
|
// Do nothing. If we were to insert an SDL_Delay(1) in here
|
||||||
|
// then we would actually lose around 10 frames per second!!
|
||||||
|
}
|
||||||
|
frameLimit = SDL_GetTicks();
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.flushBuffer();
|
||||||
|
|
||||||
|
now = SDL_GetTicks();
|
||||||
|
if ( now > then )
|
||||||
|
{
|
||||||
|
//printf("Mission %d: %2.2f frames per second\n", currentGame.area, ((double)frames*1000)/(now-then));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((player.shield > 0) && (!missionFailed()))
|
||||||
|
{
|
||||||
|
if (currentGame.area < 26)
|
||||||
|
missionFinishedScreen();
|
||||||
|
|
||||||
|
switch (currentGame.area)
|
||||||
|
{
|
||||||
|
case 5:
|
||||||
|
doCutscene(1);
|
||||||
|
doCutscene(2);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
doCutscene(3);
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
doCutscene(4);
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
doCutscene(5);
|
||||||
|
break;
|
||||||
|
case 18:
|
||||||
|
doCutscene(6);
|
||||||
|
break;
|
||||||
|
case 26:
|
||||||
|
doCredits();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentGame.area < 26)
|
||||||
|
{
|
||||||
|
updateSystemStatus();
|
||||||
|
|
||||||
|
if (currentGame.autoSaveSlot > -1)
|
||||||
|
saveGame(currentGame.autoSaveSlot + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
rtn = 1;
|
||||||
|
|
||||||
|
if (currentGame.area == 26)
|
||||||
|
rtn = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gameover();
|
||||||
|
rtn = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtn;
|
||||||
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern void resetLists();
|
||||||
|
extern void setMission(int mission);
|
||||||
|
extern void missionBriefScreen();
|
||||||
|
extern void initPlayer();
|
||||||
|
extern void initAliens();
|
||||||
|
extern signed char allMissionsCompleted();
|
||||||
|
extern void getPlayerInput();
|
||||||
|
extern void leaveSector();
|
||||||
|
extern void doStarfield();
|
||||||
|
extern void doCollectables();
|
||||||
|
extern void doCargo();
|
||||||
|
extern void doBullets();
|
||||||
|
extern void doAliens();
|
||||||
|
extern void doPlayer();
|
||||||
|
extern void doExplosions();
|
||||||
|
extern void doDebris();
|
||||||
|
extern void doInfo();
|
||||||
|
extern signed char allMissionsCompleted();
|
||||||
|
extern signed char checkPauseRequest();
|
||||||
|
extern signed char addAlien();
|
||||||
|
extern void missionFinishedScreen();
|
||||||
|
extern void gameover();
|
||||||
|
extern void clearInfoLines();
|
||||||
|
extern signed char missionFailed();
|
||||||
|
extern void playSound(int sid);
|
||||||
|
extern void loadScriptEvents();
|
||||||
|
extern void doCutscene(int scene);
|
||||||
|
extern void addCollectable(float x, float y, int type, int value, int life);
|
||||||
|
extern void doCredits();
|
||||||
|
extern void updateSystemStatus();
|
||||||
|
extern void saveGame(int slot);
|
||||||
|
extern void flushInput();
|
||||||
|
|
||||||
|
extern void initWeapons();
|
||||||
|
extern void initMissions();
|
||||||
|
extern void initCargo();
|
||||||
|
extern void initPlanetMissions(signed char system);
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern object player;
|
||||||
|
extern object enemy[MAX_ALIENS];
|
||||||
|
extern mission currentMission;
|
||||||
|
extern Game currentGame;
|
||||||
|
extern Graphics graphics;
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "globals.h"
|
||||||
|
|
||||||
|
void defineGlobals()
|
||||||
|
{
|
||||||
|
engine.musicVolume = 100;
|
||||||
|
engine.useAudio = 2;
|
||||||
|
|
||||||
|
engine.maxAliens = 9;
|
||||||
|
|
||||||
|
engine.ssx = 0;
|
||||||
|
engine.ssy = 0;
|
||||||
|
|
||||||
|
engine.bulletHead = new object;
|
||||||
|
engine.bulletHead->next = NULL;
|
||||||
|
engine.bulletTail = engine.bulletHead;
|
||||||
|
|
||||||
|
engine.explosionHead = new object;
|
||||||
|
engine.explosionHead->next = NULL;
|
||||||
|
engine.explosionTail = engine.explosionHead;
|
||||||
|
|
||||||
|
engine.collectableHead = new collectables;
|
||||||
|
engine.collectableHead->next = NULL;
|
||||||
|
engine.collectableTail = engine.collectableHead;
|
||||||
|
|
||||||
|
engine.debrisHead = new object;
|
||||||
|
engine.debrisHead->next = NULL;
|
||||||
|
engine.debrisTail = engine.debrisHead;
|
||||||
|
|
||||||
|
engine.commsSection = 0;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 350 ; i++)
|
||||||
|
engine.keyState[i] = 0;
|
||||||
|
|
||||||
|
engine.eventTimer = 0;
|
||||||
|
engine.counter2 = 0;
|
||||||
|
engine.timeTaken = 0;
|
||||||
|
engine.timeMission = 0;
|
||||||
|
engine.counter = 0;
|
||||||
|
engine.seconds = 0;
|
||||||
|
engine.minutes = 0;
|
||||||
|
engine.paused = 0;
|
||||||
|
engine.gameSection = SECTION_TITLE;
|
||||||
|
|
||||||
|
engine.targetArrow = -1;
|
||||||
|
engine.targetArrowTimer = 0;
|
||||||
|
|
||||||
|
engine.cheat = 0;
|
||||||
|
engine.cheatShield = 0;
|
||||||
|
engine.cheatAmmo = 0;
|
||||||
|
engine.cheatCash = 0;
|
||||||
|
|
||||||
|
// All Development Stuff...
|
||||||
|
dev.moveAliens = 1;
|
||||||
|
dev.fireAliens = 1;
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern devVariables dev;
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "graphics.h"
|
||||||
|
|
||||||
|
SDL_Surface *loadImage(char *filename)
|
||||||
|
{
|
||||||
|
SDL_Surface *image, *newImage;
|
||||||
|
|
||||||
|
#if USEPACK
|
||||||
|
unpack(filename, PAK_IMG);
|
||||||
|
image = IMG_Load_RW(engine.sdlrw, 1);
|
||||||
|
#else
|
||||||
|
image = IMG_Load(filename);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (image == NULL) {
|
||||||
|
printf("Couldn't load %s: %s\n", filename, SDL_GetError());
|
||||||
|
showErrorAndExit(0, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
newImage = SDL_DisplayFormat(image);
|
||||||
|
if ( newImage ) {
|
||||||
|
SDL_FreeSurface(image);
|
||||||
|
} else {
|
||||||
|
// This happens when we are loading the window icon image
|
||||||
|
newImage = image;
|
||||||
|
}
|
||||||
|
|
||||||
|
return graphics.setTransparent(newImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Simply draws the stars in their positions on screen and moves
|
||||||
|
them around. They are wrapped around using the wrapFloat()
|
||||||
|
function, as defined above, and putpixel as defined in graphics.cpp
|
||||||
|
*/
|
||||||
|
void doStarfield()
|
||||||
|
{
|
||||||
|
/* Lock the screen for direct access to the pixels */
|
||||||
|
if (SDL_MUSTLOCK(graphics.screen))
|
||||||
|
{
|
||||||
|
if (SDL_LockSurface(graphics.screen) < 0 )
|
||||||
|
{
|
||||||
|
showErrorAndExit(2, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int color = 0;
|
||||||
|
|
||||||
|
SDL_Rect r;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 200 ; i++)
|
||||||
|
{
|
||||||
|
if (star[i].speed == 3)
|
||||||
|
color = graphics.white;
|
||||||
|
else if (star[i].speed == 2)
|
||||||
|
color = graphics.lightGrey;
|
||||||
|
else if (star[i].speed == 1)
|
||||||
|
color = graphics.darkGrey;
|
||||||
|
|
||||||
|
Math::wrapFloat(&(star[i].x += (engine.ssx * star[i].speed)), 0, 799);
|
||||||
|
Math::wrapFloat(&(star[i].y += (engine.ssy * star[i].speed)), 0, 599);
|
||||||
|
|
||||||
|
graphics.putpixel(graphics.screen, (int)star[i].x, (int)star[i].y, color);
|
||||||
|
r.x = (int)star[i].x;
|
||||||
|
r.y = (int)star[i].y;
|
||||||
|
r.w = 1;
|
||||||
|
r.h = 1;
|
||||||
|
|
||||||
|
graphics.addBuffer(r.x, r.y, r.w, r.h);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SDL_MUSTLOCK(graphics.screen))
|
||||||
|
{
|
||||||
|
SDL_UnlockSurface(graphics.screen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int isOnScreen(int x, int y, int w, int h)
|
||||||
|
{
|
||||||
|
if ((x + w > 0) && (x < 800) && (y + h > 0) && (y < 600))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern void unpack(char *file, signed char fileType);
|
||||||
|
extern void showErrorAndExit(int errorId, char *name);
|
||||||
|
|
||||||
|
extern Star star[200];
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern Graphics graphics;
|
|
@ -0,0 +1,271 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "init.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Initalises a whole load of variables
|
||||||
|
*/
|
||||||
|
void initVars()
|
||||||
|
{
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 200 ; i++)
|
||||||
|
{
|
||||||
|
star[i].x = rand() % 800;
|
||||||
|
star[i].y = rand() % 600;
|
||||||
|
star[i].speed = 1 + (rand() % 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// These are good values for sound and music
|
||||||
|
|
||||||
|
if (engine.useAudio)
|
||||||
|
{
|
||||||
|
Mix_Volume(-1, 25);
|
||||||
|
Mix_VolumeMusic((int)engine.musicVolume);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Something went wrong. This stops the game, present the error message and
|
||||||
|
prompts the user to press space or ctrl to exit the game. This is unlikely to
|
||||||
|
be seen by people unless something really stoopid happens!
|
||||||
|
*/
|
||||||
|
void showErrorAndExit(int errorId, char *name)
|
||||||
|
{
|
||||||
|
graphics.clearScreen(graphics.black);
|
||||||
|
|
||||||
|
if (errorId != 2)
|
||||||
|
{
|
||||||
|
graphics.drawString("A file error has occurred", -1, 200, FONT_RED);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Couldn't create or write to directory '%s'\n", name);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char string[255];
|
||||||
|
|
||||||
|
switch(errorId)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
strcpy(string, "");
|
||||||
|
sprintf(string, "%s was not found in the Starfighter data package", name);
|
||||||
|
graphics.drawString(string, -1, 250, FONT_WHITE);
|
||||||
|
graphics.drawString("Please try again. If this error persists, contact Parallel Realities", -1, 275, FONT_WHITE);
|
||||||
|
graphics.drawString("or reinstall the game", -1, 300, FONT_WHITE);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
graphics.drawString("Project: Starfighter encountered an error whilst", -1, 250, FONT_WHITE);
|
||||||
|
graphics.drawString("attempting to load game data. Please try running", -1, 275, FONT_WHITE);
|
||||||
|
graphics.drawString("the game again. If the errors persist, reinstall the game", -1, 300, FONT_WHITE);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
graphics.drawString("Project: Starfighter encountered a critical error", -1, 250, FONT_WHITE);
|
||||||
|
graphics.drawString("while attempting to perform a required program function.", -1, 275, FONT_WHITE);
|
||||||
|
graphics.drawString("Please contact Parallel Realities with details", -1, 300, FONT_WHITE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.drawString("Project: Starfighter will now exit", -1, 450, FONT_WHITE);
|
||||||
|
graphics.drawString("Press Space to continue", -1, 475, FONT_WHITE);
|
||||||
|
|
||||||
|
engine.keyState[SDLK_SPACE] = 0;
|
||||||
|
|
||||||
|
while (!engine.keyState[SDLK_SPACE])
|
||||||
|
{
|
||||||
|
getPlayerInput();
|
||||||
|
graphics.updateScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This bit is just for Linux users. It attempts to get the user's
|
||||||
|
home directory, then creates the .parallelrealities and .parallelrealities/starfighter
|
||||||
|
directories so that saves and temporary data files can be written there. Good, eh? :)
|
||||||
|
*/
|
||||||
|
#if LINUX
|
||||||
|
void setupUserHomeDirectory()
|
||||||
|
{
|
||||||
|
char *userHome;
|
||||||
|
|
||||||
|
char *name = getlogin();
|
||||||
|
|
||||||
|
passwd *pass;
|
||||||
|
|
||||||
|
if (name != NULL)
|
||||||
|
pass = getpwnam(name);
|
||||||
|
else
|
||||||
|
pass = getpwuid(geteuid());
|
||||||
|
|
||||||
|
if (pass == NULL)
|
||||||
|
{
|
||||||
|
printf("Couldn't determine the user home directory. Exitting.\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
userHome = pass->pw_dir;
|
||||||
|
|
||||||
|
char dir[PATH_MAX];
|
||||||
|
strcpy(dir, "");
|
||||||
|
|
||||||
|
sprintf(dir, "%s/.parallelrealities", userHome);
|
||||||
|
if ((mkdir(dir, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH) != 0) && (errno != EEXIST))
|
||||||
|
showErrorAndExit(2, dir);
|
||||||
|
|
||||||
|
sprintf(dir, "%s/.parallelrealities/starfighter", userHome);
|
||||||
|
if ((mkdir(dir, S_IRWXU|S_IRWXG|S_IROTH|S_IXOTH) != 0) && (errno != EEXIST))
|
||||||
|
showErrorAndExit(2, dir);
|
||||||
|
|
||||||
|
sprintf(engine.userHomeDirectory, "%s/.parallelrealities/starfighter/", userHome);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
Chugg chugg chugg.... brrr... chugg chugg chugg...brrrrrr... chugg ch..
|
||||||
|
BRRRRRRRRRRRRRRRRRMMMMMMMMMMMMMMMMMMM!! Well, hopefully anyway! ;)
|
||||||
|
*/
|
||||||
|
void initSystem()
|
||||||
|
{
|
||||||
|
strcpy(engine.userHomeDirectory, "");
|
||||||
|
|
||||||
|
#if LINUX
|
||||||
|
setupUserHomeDirectory();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Initialize the SDL library */
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0) {
|
||||||
|
printf("Couldn't initialize SDL: %s\n", SDL_GetError());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentGame.useSound = 1;
|
||||||
|
currentGame.useMusic = 1;
|
||||||
|
currentGame.fullScreen = 0;
|
||||||
|
|
||||||
|
char filename[PATH_MAX];
|
||||||
|
int fullScreen = 0, useSound = 1, useMusic = 1;
|
||||||
|
|
||||||
|
FILE *fp;
|
||||||
|
sprintf(filename, "%sconf", engine.userHomeDirectory);
|
||||||
|
fp = fopen(filename, "rb");
|
||||||
|
|
||||||
|
if (fp != NULL)
|
||||||
|
{
|
||||||
|
fscanf(fp, "%d %d %d", &fullScreen, &useSound, &useMusic);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
currentGame.fullScreen = fullScreen;
|
||||||
|
currentGame.useSound = useSound;
|
||||||
|
currentGame.useMusic = useMusic;
|
||||||
|
|
||||||
|
SDL_WM_SetCaption("Project: Starfighter", "starfighter");
|
||||||
|
SDL_WM_SetIcon(loadImage("gfx/alienDevice.png"), NULL);
|
||||||
|
|
||||||
|
if (currentGame.fullScreen)
|
||||||
|
graphics.screen = SDL_SetVideoMode(800, 600, 16, SDL_HWPALETTE|SDL_FULLSCREEN);
|
||||||
|
else
|
||||||
|
graphics.screen = SDL_SetVideoMode(800, 600, 0, SDL_HWPALETTE);
|
||||||
|
|
||||||
|
if (graphics.screen == NULL) {
|
||||||
|
printf("Couldn't set 800x600x16 video mode: %s\n", SDL_GetError());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (engine.useAudio)
|
||||||
|
{
|
||||||
|
if (Mix_OpenAudio(22050, AUDIO_S16, engine.useAudio, 1024) < 0)
|
||||||
|
{
|
||||||
|
printf("Warning: Couldn't set 22050 Hz 16-bit audio - Reason: %s\n", Mix_GetError());
|
||||||
|
printf("Sound and Music will be disabled\n");
|
||||||
|
engine.useAudio = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_ShowCursor(SDL_DISABLE);
|
||||||
|
SDL_EventState(SDL_MOUSEMOTION, SDL_DISABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Removes [hopefully] all the resources that has been
|
||||||
|
loaded and created during the game. This is called by
|
||||||
|
atexit();
|
||||||
|
*/
|
||||||
|
void cleanUp()
|
||||||
|
{
|
||||||
|
printf("Cleaning Up...\n");
|
||||||
|
printf("Freeing Graphics\n");
|
||||||
|
graphics.freeGraphics();
|
||||||
|
printf("Freeing Background\n");
|
||||||
|
SDL_FreeSurface(graphics.background);
|
||||||
|
printf("Freeing Sounds\n");
|
||||||
|
freeSound();
|
||||||
|
printf("Resetting Lists\n");
|
||||||
|
resetLists();
|
||||||
|
delete(engine.bulletHead);
|
||||||
|
delete(engine.explosionHead);
|
||||||
|
delete(engine.collectableHead);
|
||||||
|
delete(graphics.bufferHead);
|
||||||
|
|
||||||
|
printf("Freeing Font\n");
|
||||||
|
for (int i = 0 ; i < MAX_FONTSHAPES ; i++)
|
||||||
|
{
|
||||||
|
if (graphics.fontShape[i] != NULL)
|
||||||
|
SDL_FreeSurface(graphics.fontShape[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Removing Mod\n");
|
||||||
|
char filename[PATH_MAX];
|
||||||
|
strcpy(filename, "");
|
||||||
|
|
||||||
|
sprintf(filename, "%smusic.mod", engine.userHomeDirectory);
|
||||||
|
remove(filename);
|
||||||
|
|
||||||
|
sprintf(filename, "%smusic.s3m", engine.userHomeDirectory);
|
||||||
|
remove(filename);
|
||||||
|
|
||||||
|
if (engine.useAudio)
|
||||||
|
{
|
||||||
|
printf("Closing Audio\n");
|
||||||
|
Mix_CloseAudio();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the config using current settings
|
||||||
|
FILE *fp;
|
||||||
|
sprintf(filename, "%sconf", engine.userHomeDirectory);
|
||||||
|
fp = fopen(filename, "wb");
|
||||||
|
if (fp != NULL)
|
||||||
|
{
|
||||||
|
fprintf(fp, "%d %d %d\n", currentGame.fullScreen, currentGame.useSound, currentGame.useMusic);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Error saving config\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Quit();
|
||||||
|
printf("Done Cleaning Up...\nThank You for playing Starfighter\n");
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#if LINUX
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern void freeSound();
|
||||||
|
extern void resetLists();
|
||||||
|
extern void getPlayerInput();
|
||||||
|
extern void drawString(char *in, int x, int y, int fontColor);
|
||||||
|
extern SDL_Surface *loadImage(char *filename);
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern Game currentGame;
|
||||||
|
extern Graphics graphics;
|
||||||
|
extern Star star[200];
|
|
@ -0,0 +1,869 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "intermission.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Drives the cursor. Is used by some other screens too
|
||||||
|
*/
|
||||||
|
void doCursor()
|
||||||
|
{
|
||||||
|
getPlayerInput();
|
||||||
|
|
||||||
|
Math::limitInt(&engine.cursor_x, 10, 790);
|
||||||
|
Math::limitInt(&engine.cursor_y, 10, 590);
|
||||||
|
graphics.blit(graphics.shape[0], engine.cursor_x, engine.cursor_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Sets the player's current status information lines. These are the lines
|
||||||
|
that are scrolled up the screen when the player clicks on Current Status
|
||||||
|
These are set only once.
|
||||||
|
*/
|
||||||
|
void setStatusLines()
|
||||||
|
{
|
||||||
|
char string[50];
|
||||||
|
|
||||||
|
sprintf(string, "System : %s", systemNames[currentGame.system]);
|
||||||
|
|
||||||
|
graphics.textSurface(0, string, 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
signed char total = 0;
|
||||||
|
signed char completed = 0;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 10 ; i++)
|
||||||
|
{
|
||||||
|
if (systemPlanet[i].missionNumber > -1)
|
||||||
|
{
|
||||||
|
switch(systemPlanet[i].missionCompleted)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
total++;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
total++;
|
||||||
|
completed++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 30 ; i++)
|
||||||
|
graphics.textSurface(i, "", 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "Missions Completed : %d/%d", completed, total);
|
||||||
|
graphics.textSurface(1, string, 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "Shots Fired : %d", currentGame.shots);
|
||||||
|
graphics.textSurface(2, string, 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "Hits Scored : %d", currentGame.hits);
|
||||||
|
graphics.textSurface(3, string, 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "Accuracy : %d%%", currentGame.accuracy);
|
||||||
|
graphics.textSurface(4, string, 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "Enemies Killed by Others : %d", currentGame.totalOtherKills);
|
||||||
|
graphics.textSurface(5, string, 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "Total Cash Earned : %d", currentGame.cashEarned);
|
||||||
|
graphics.textSurface(6, string, 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
graphics.textSurface(7, "*** Chris ***", 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "Enemies Killed : %d", currentGame.totalKills);
|
||||||
|
graphics.textSurface(8, string, 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "Shield Restores Picked Up : %d", currentGame.shieldPickups);
|
||||||
|
graphics.textSurface(9, string, 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "Plasma Cells Picked Up : %d", currentGame.cellPickups);
|
||||||
|
graphics.textSurface(10, string, 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "Rockets Picked Up : %d", currentGame.rocketPickups);
|
||||||
|
graphics.textSurface(11, string, 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "Powerups Picked Up : %d", currentGame.rocketPickups);
|
||||||
|
graphics.textSurface(12, string, 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "Mines Destroyed : %d", currentGame.minesKilled);
|
||||||
|
graphics.textSurface(13, string, 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "Slaves Rescued : %d", currentGame.slavesRescued);
|
||||||
|
graphics.textSurface(14, string, 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "Cargo Picked Up : %d", currentGame.cargoPickups);
|
||||||
|
graphics.textSurface(15, string, 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
if (currentGame.hasWingMate1)
|
||||||
|
{
|
||||||
|
graphics.textSurface(16, "*** Phoebe ***", 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "Enemies Killed : %d", currentGame.wingMate1Kills);
|
||||||
|
graphics.textSurface(17, string, 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "Ejections : %d", currentGame.wingMate1Ejects);
|
||||||
|
graphics.textSurface(18, string, 0, 0, FONT_WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentGame.hasWingMate2)
|
||||||
|
{
|
||||||
|
graphics.textSurface(19, "*** Ursula ***", 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "Enemies Killed : %d", currentGame.wingMate2Kills);
|
||||||
|
graphics.textSurface(20, string, 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "Ejections : %d", currentGame.wingMate2Ejects);
|
||||||
|
graphics.textSurface(21, string, 0, 0, FONT_WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
signed char percentage = 0;
|
||||||
|
if ((currentGame.secondaryMissions > 0) && (currentGame.secondaryMissionsCompleted > 0))
|
||||||
|
percentage = (currentGame.secondaryMissionsCompleted / currentGame.secondaryMissions) * 100;
|
||||||
|
sprintf(string, "Seconday Missions Completed : %d / %d (%d%%)", currentGame.secondaryMissionsCompleted, currentGame.secondaryMissions, percentage);
|
||||||
|
graphics.textSurface(24, string, 0, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
int timeTaken = currentGame.timeTaken;
|
||||||
|
|
||||||
|
signed char clock = 0;
|
||||||
|
while (timeTaken > 3599)
|
||||||
|
{
|
||||||
|
clock++;
|
||||||
|
timeTaken -= 3600;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(string, "Total Time : %.2d", clock);
|
||||||
|
|
||||||
|
clock = 0;
|
||||||
|
while (timeTaken > 59)
|
||||||
|
{
|
||||||
|
clock++;
|
||||||
|
timeTaken -= 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(string, "%s:%.2d:%.2d", string, clock, timeTaken);
|
||||||
|
graphics.textSurface(26, string, -1, 0, FONT_WHITE);
|
||||||
|
graphics.textSurface(27, "Current Status", -1, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
graphics.textShape[0].y = 400;
|
||||||
|
graphics.textShape[0].x = 150;
|
||||||
|
|
||||||
|
for (int i = 1 ; i < 25 ; i++)
|
||||||
|
{
|
||||||
|
graphics.textShape[i].y = graphics.textShape[i - 1].y + 20;
|
||||||
|
if ((i == 7) || (i == 16) || (i == 19))
|
||||||
|
graphics.textShape[i].y += 25;
|
||||||
|
|
||||||
|
graphics.textShape[i].x = 150;
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.textShape[26].y = 404;
|
||||||
|
graphics.textShape[27].y = 83;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Sets the names and stats of the planets within the current system.
|
||||||
|
This will later be placed into a data file.
|
||||||
|
*/
|
||||||
|
void setSystemPlanets()
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
char string[100];
|
||||||
|
strcpy(string, "");
|
||||||
|
|
||||||
|
switch (currentGame.system)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
strcpy(string, "data/planets_spirit.dat");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
strcpy(string, "data/planets_eyananth.dat");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
strcpy(string, "data/planets_mordor.dat");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
strcpy(string, "data/planets_sol.dat");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if USEPACK
|
||||||
|
int dataLocation = locateDataInPak(string, 1);
|
||||||
|
fp = fopen(PACKLOCATION, "rb");
|
||||||
|
fseek(fp, dataLocation, SEEK_SET);
|
||||||
|
#else
|
||||||
|
fp = fopen(string, "rb");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int distance;
|
||||||
|
char name[50];
|
||||||
|
int image;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 10 ; i++)
|
||||||
|
{
|
||||||
|
fscanf(fp, "%d %s %d", &distance, name, &image);
|
||||||
|
|
||||||
|
systemPlanet[i].y = distance;
|
||||||
|
strcpy(systemPlanet[i].name, name);
|
||||||
|
systemPlanet[i].image = graphics.shape[image];
|
||||||
|
}
|
||||||
|
|
||||||
|
int messageMission;
|
||||||
|
int messageSlot;
|
||||||
|
char face[50];
|
||||||
|
char from[100];
|
||||||
|
char subject[100];
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 10 ; i++)
|
||||||
|
{
|
||||||
|
fscanf(fp, "%d %d %s%*c", &messageMission, &messageSlot, face);
|
||||||
|
fscanf(fp, "%[^\n]%*c", from);
|
||||||
|
fscanf(fp, "%[^\n]%*c", subject);
|
||||||
|
|
||||||
|
systemPlanet[i].messageMission = messageMission;
|
||||||
|
systemPlanet[i].messageSlot = messageSlot;
|
||||||
|
systemPlanet[i].faceImage = getFace(face);
|
||||||
|
|
||||||
|
strcpy(systemPlanet[i].from, from);
|
||||||
|
strcpy(systemPlanet[i].subject, subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Spins the planets around the sun, spaced according to their Y value
|
||||||
|
as defined in setSystemPlanets(). Moving the cursor over the planet
|
||||||
|
will show their name and their current status
|
||||||
|
*/
|
||||||
|
signed char showSystem(float x, float y)
|
||||||
|
{
|
||||||
|
SDL_Rect r;
|
||||||
|
signed char planet = 0;
|
||||||
|
int planetSpace = systemPlanet[planet].y;
|
||||||
|
signed char rtn = 0;
|
||||||
|
|
||||||
|
// Blit the sun
|
||||||
|
graphics.blit(graphics.shape[30], 370, 220);
|
||||||
|
|
||||||
|
for (int i = 50 ; i < 300 ; i+= planetSpace)
|
||||||
|
{
|
||||||
|
x *= 0.75;
|
||||||
|
y *= 0.75;
|
||||||
|
|
||||||
|
graphics.circle(400, 250, i, graphics.screen, graphics.darkGrey);
|
||||||
|
|
||||||
|
r.x = int(400 + (sin(x) * i));
|
||||||
|
r.y = int(250 + (cos(y) * i));
|
||||||
|
r.w = 10;
|
||||||
|
r.h = 10;
|
||||||
|
|
||||||
|
r.x -= (systemPlanet[planet].image->w / 2);
|
||||||
|
r.y -= (systemPlanet[planet].image->h / 2);
|
||||||
|
graphics.blit(systemPlanet[planet].image, r.x, r.y);
|
||||||
|
|
||||||
|
if (Collision::collision(engine.cursor_x + 13, engine.cursor_y + 13, 6, 6, r.x, r.y, systemPlanet[planet].image->w, systemPlanet[planet].image->h))
|
||||||
|
{
|
||||||
|
graphics.drawString(systemPlanet[planet].name, -1, 545, FONT_WHITE);
|
||||||
|
if ((engine.keyState[SDLK_LCTRL]) || (engine.keyState[SDLK_RCTRL]))
|
||||||
|
{
|
||||||
|
if (currentGame.system == 0)
|
||||||
|
{
|
||||||
|
currentGame.stationedPlanet = planet;
|
||||||
|
currentGame.destinationPlanet = planet;
|
||||||
|
currentGame.area = systemPlanet[currentGame.stationedPlanet].missionNumber;
|
||||||
|
strcpy(currentGame.stationedName, systemPlanet[currentGame.stationedPlanet].name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
currentGame.destinationPlanet = planet;
|
||||||
|
strcpy(currentGame.destinationName, systemPlanet[currentGame.destinationPlanet].name);
|
||||||
|
}
|
||||||
|
|
||||||
|
rtn = 1;
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
planet++;
|
||||||
|
if (systemPlanet[planet].y == -1)
|
||||||
|
break;
|
||||||
|
planetSpace = systemPlanet[planet].y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Scrolls the player's current information up the screen. When
|
||||||
|
the specified status line reaches a certain Y value, the entire
|
||||||
|
list is reset and the information lines begin again from the bottom
|
||||||
|
(in other words, they loop around).
|
||||||
|
*/
|
||||||
|
void showStatus(SDL_Surface *infoSurface)
|
||||||
|
{
|
||||||
|
graphics.blit(infoSurface, 100, 80);
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 22 ; i++)
|
||||||
|
{
|
||||||
|
graphics.textShape[i].y -= 0.25;
|
||||||
|
if ((graphics.textShape[i].y > 80) && (graphics.textShape[i].y < 400))
|
||||||
|
graphics.blitText(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (graphics.textShape[21].y < 65)
|
||||||
|
{
|
||||||
|
graphics.textShape[0].y = 400;
|
||||||
|
|
||||||
|
for (int i = 1 ; i < 25 ; i++)
|
||||||
|
{
|
||||||
|
graphics.textShape[i].y = graphics.textShape[i - 1].y + 20;
|
||||||
|
if ((i == 7) || (i == 16) || (i == 19))
|
||||||
|
graphics.textShape[i].y += 25;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.blevelRect(100, 80, 600, 20, 0x00, 0x00, 0x99);
|
||||||
|
|
||||||
|
graphics.blevelRect(100, 400, 600, 20, 0x00, 0x00, 0x99);
|
||||||
|
|
||||||
|
graphics.blitText(26);
|
||||||
|
graphics.blitText(27);
|
||||||
|
}
|
||||||
|
|
||||||
|
void createOptions(SDL_Surface *optionsSurface)
|
||||||
|
{
|
||||||
|
SDL_FillRect(optionsSurface, NULL, graphics.black);
|
||||||
|
|
||||||
|
graphics.blevelRect(optionsSurface, 0, 0, optionsSurface->w - 2, optionsSurface->h - 2, 0x00, 0x00, 0x44);
|
||||||
|
|
||||||
|
graphics.drawString("++ OPTIONS ++", 105, 8, FONT_WHITE, optionsSurface);
|
||||||
|
|
||||||
|
graphics.blevelRect(optionsSurface, 190, 45, 50, 22, 0x00, 0x00, 0x00);
|
||||||
|
graphics.blevelRect(optionsSurface, 250, 45, 50, 22, 0x00, 0x00, 0x00);
|
||||||
|
graphics.blevelRect(optionsSurface, 20, 45, 150, 22, 0x00, 0x00, 0x00);
|
||||||
|
if (currentGame.useSound)
|
||||||
|
graphics.blevelRect(optionsSurface, 190, 45, 50, 22, 0xff, 0x00, 0x00);
|
||||||
|
else
|
||||||
|
graphics.blevelRect(optionsSurface, 250, 45, 50, 22, 0xff, 0x00, 0x00);
|
||||||
|
graphics.drawString("ON", 207, 50, FONT_WHITE, optionsSurface);
|
||||||
|
graphics.drawString("OFF", 263, 50, FONT_WHITE, optionsSurface);
|
||||||
|
graphics.drawString("SOUND", 30, 50, FONT_WHITE, optionsSurface);
|
||||||
|
|
||||||
|
graphics.blevelRect(optionsSurface, 190, 95, 50, 22, 0x00, 0x00, 0x00);
|
||||||
|
graphics.blevelRect(optionsSurface, 250, 95, 50, 22, 0x00, 0x00, 0x00);
|
||||||
|
graphics.blevelRect(optionsSurface, 20, 95, 150, 22, 0x00, 0x00, 0x00);
|
||||||
|
if (currentGame.useMusic)
|
||||||
|
graphics.blevelRect(optionsSurface, 190, 95, 50, 22, 0xff, 0x00, 0x00);
|
||||||
|
else
|
||||||
|
graphics.blevelRect(optionsSurface, 250, 95, 50, 22, 0xff, 0x00, 0x00);
|
||||||
|
graphics.drawString("ON", 207, 100, FONT_WHITE, optionsSurface);
|
||||||
|
graphics.drawString("OFF", 263, 100, FONT_WHITE, optionsSurface);
|
||||||
|
graphics.drawString("MUSIC", 30, 100, FONT_WHITE, optionsSurface);
|
||||||
|
|
||||||
|
graphics.blevelRect(optionsSurface, 190, 145, 50, 22, 0x00, 0x00, 0x00);
|
||||||
|
graphics.blevelRect(optionsSurface, 250, 145, 50, 22, 0x00, 0x00, 0x00);
|
||||||
|
graphics.blevelRect(optionsSurface, 20, 145, 150, 22, 0x00, 0x00, 0x00);
|
||||||
|
if (currentGame.fullScreen)
|
||||||
|
graphics.blevelRect(optionsSurface, 190, 145, 50, 22, 0xff, 0x00, 0x00);
|
||||||
|
else
|
||||||
|
graphics.blevelRect(optionsSurface, 250, 145, 50, 22, 0xff, 0x00, 0x00);
|
||||||
|
graphics.drawString("ON", 207, 150, FONT_WHITE, optionsSurface);
|
||||||
|
graphics.drawString("OFF", 263, 150, FONT_WHITE, optionsSurface);
|
||||||
|
graphics.drawString("FULLSCREEN", 30, 150, FONT_WHITE, optionsSurface);
|
||||||
|
|
||||||
|
graphics.blevelRect(optionsSurface, 20, 195, 150, 22, 0x00, 0x00, 0x00);
|
||||||
|
graphics.blevelRect(optionsSurface, 190, 195, 110, 22, 0x00, 0x00, 0x00);
|
||||||
|
if (currentGame.autoSaveSlot == -1)
|
||||||
|
{
|
||||||
|
graphics.drawString("NONE", 225, 200, FONT_WHITE, optionsSurface);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char string[] = "Slot %d";
|
||||||
|
sprintf(string, "Slot %d", currentGame.autoSaveSlot + 1);
|
||||||
|
graphics.blevelRect(optionsSurface, 190, 195, 110, 22, 0xff, 0x00, 0x00);
|
||||||
|
graphics.drawString(string, 225, 200, FONT_WHITE, optionsSurface);
|
||||||
|
}
|
||||||
|
graphics.drawString("AUTOSAVE SLOT", 30, 200, FONT_WHITE, optionsSurface);
|
||||||
|
}
|
||||||
|
|
||||||
|
void showOptions(SDL_Surface *optionsSurface)
|
||||||
|
{
|
||||||
|
if ((engine.keyState[SDLK_LCTRL]) || (engine.keyState[SDLK_RCTRL]))
|
||||||
|
{
|
||||||
|
if (Collision::collision(engine.cursor_x + 13, engine.cursor_y + 13, 6, 6, 417, 172, 45, 22))
|
||||||
|
currentGame.useSound = 1;
|
||||||
|
|
||||||
|
if (Collision::collision(engine.cursor_x + 13, engine.cursor_y + 13, 6, 6, 478, 172, 45, 22))
|
||||||
|
currentGame.useSound = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if (Collision::collision(engine.cursor_x + 13, engine.cursor_y + 13, 6, 6, 417, 222, 45, 22))
|
||||||
|
{
|
||||||
|
currentGame.useMusic = 1;
|
||||||
|
if (engine.useAudio)
|
||||||
|
{
|
||||||
|
if (Mix_PausedMusic() == 1)
|
||||||
|
Mix_ResumeMusic();
|
||||||
|
else
|
||||||
|
Mix_PlayMusic(engine.music, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Collision::collision(engine.cursor_x + 13, engine.cursor_y + 13, 6, 6, 478, 222, 45, 22))
|
||||||
|
{
|
||||||
|
currentGame.useMusic = 0;
|
||||||
|
if (engine.useAudio)
|
||||||
|
Mix_PauseMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Collision::collision(engine.cursor_x + 13, engine.cursor_y + 13, 6, 6, 417, 272, 45, 22))
|
||||||
|
{
|
||||||
|
if (!currentGame.fullScreen)
|
||||||
|
{
|
||||||
|
#if LINUX
|
||||||
|
SDL_WM_ToggleFullScreen(graphics.screen);
|
||||||
|
#else
|
||||||
|
graphics.screen = SDL_SetVideoMode(800, 600, 16, SDL_HWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN);
|
||||||
|
graphics.drawBackground();
|
||||||
|
flushBuffer();
|
||||||
|
#endif
|
||||||
|
currentGame.fullScreen = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Collision::collision(engine.cursor_x + 13, engine.cursor_y + 13, 6, 6, 478, 272, 45, 22))
|
||||||
|
{
|
||||||
|
if (currentGame.fullScreen)
|
||||||
|
{
|
||||||
|
#if LINUX
|
||||||
|
SDL_WM_ToggleFullScreen(graphics.screen);
|
||||||
|
#else
|
||||||
|
graphics.screen = SDL_SetVideoMode(800, 600, 0, SDL_HWSURFACE|SDL_HWPALETTE);
|
||||||
|
graphics.drawBackground();
|
||||||
|
flushBuffer();
|
||||||
|
#endif
|
||||||
|
currentGame.fullScreen = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Collision::collision(engine.cursor_x + 13, engine.cursor_y + 13, 6, 6, 417, 322, 100, 22))
|
||||||
|
{
|
||||||
|
Math::wrapChar(&(++currentGame.autoSaveSlot), -1, 4);
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
createOptions(optionsSurface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Oddly named function that controls the entire intermission
|
||||||
|
screen. This simply draws a background, stars, gridlines and the icons
|
||||||
|
at the bottom of the screen. Will call (and continue to call) the specified
|
||||||
|
functions when the player has selected an icon.
|
||||||
|
*/
|
||||||
|
int galaxyMap()
|
||||||
|
{
|
||||||
|
graphics.freeGraphics();
|
||||||
|
|
||||||
|
checkForBossMission(); // double check just to make sure!
|
||||||
|
|
||||||
|
// Tell the game we are not in a mission so
|
||||||
|
// do not perform certain keyboard actions
|
||||||
|
engine.gameSection = SECTION_INTERMISSION;
|
||||||
|
|
||||||
|
graphics.clearScreen(graphics.black);
|
||||||
|
graphics.updateScreen();
|
||||||
|
graphics.clearScreen(graphics.black);
|
||||||
|
|
||||||
|
initSaveSlots();
|
||||||
|
|
||||||
|
SDL_Delay(1000);
|
||||||
|
|
||||||
|
loadMusic("music/3DParadise.mod");
|
||||||
|
|
||||||
|
loadBackground((char *)systemBackground[currentGame.system]);
|
||||||
|
|
||||||
|
char string[25];
|
||||||
|
|
||||||
|
engine.cursor_x = engine.cursor_y = 500;
|
||||||
|
graphics.shape[0] = loadImage("gfx/cursor.bmp");
|
||||||
|
|
||||||
|
// Icons 1 - 29
|
||||||
|
for (int i = 0 ; i < 26 ; i++)
|
||||||
|
{
|
||||||
|
sprintf(string, "gfx/icon%d.bmp", (i + 1));
|
||||||
|
graphics.shape[i + 1] = loadImage(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.shape[27] = loadImage("gfx/buyIcon.bmp");
|
||||||
|
graphics.shape[28] = loadImage("gfx/sellIcon.bmp");
|
||||||
|
graphics.shape[29] = loadImage("gfx/firefly1.png");
|
||||||
|
|
||||||
|
// Planets 30 - 39
|
||||||
|
graphics.shape[30] = loadImage("gfx/planet_sun.gif");
|
||||||
|
graphics.shape[31] = loadImage("gfx/planet_green.gif");
|
||||||
|
graphics.shape[32] = loadImage("gfx/planet_blue.gif");
|
||||||
|
graphics.shape[33] = loadImage("gfx/planet_red.gif");
|
||||||
|
graphics.shape[34] = loadImage("gfx/planet_orange.gif");
|
||||||
|
|
||||||
|
// Faces (as defines)
|
||||||
|
graphics.shape[FACE_CHRIS] = loadImage("gfx/face_chris.png");
|
||||||
|
graphics.shape[FACE_SID] = loadImage("gfx/face_sid.png");
|
||||||
|
graphics.shape[FACE_KRASS] = loadImage("gfx/face_krass.png");
|
||||||
|
graphics.shape[FACE_PHOEBE] = loadImage("gfx/face_phoebe.png");
|
||||||
|
graphics.shape[FACE_URSULA] = loadImage("gfx/face_ursula.png");
|
||||||
|
graphics.shape[FACE_KLINE] = loadImage("gfx/face_kline.png");
|
||||||
|
|
||||||
|
engine.done = 0;
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = 0;
|
||||||
|
engine.ssx = engine.ssy = 0;
|
||||||
|
|
||||||
|
SDL_Rect r;
|
||||||
|
SDL_Rect destRect;
|
||||||
|
int distance = 0;
|
||||||
|
int interceptionChance = 0;
|
||||||
|
|
||||||
|
setStatusLines();
|
||||||
|
initShop();
|
||||||
|
setSystemPlanets();
|
||||||
|
|
||||||
|
SDL_Surface *statsSurface = graphics.alphaRect(600, 330, 0x00, 0x00, 0x99);
|
||||||
|
SDL_Surface *savesSurface = graphics.createSurface(350, 300);
|
||||||
|
SDL_Surface *optionsSurface = graphics.createSurface(320, 240);
|
||||||
|
SDL_Surface *commsSurface = graphics.createSurface(450, 400);
|
||||||
|
|
||||||
|
createSavesSurface(savesSurface, -1);
|
||||||
|
createOptions(optionsSurface);
|
||||||
|
createCommsSurface(commsSurface);
|
||||||
|
|
||||||
|
signed char section = 1;
|
||||||
|
|
||||||
|
float sinX = 300;
|
||||||
|
float cosY = 300;
|
||||||
|
signed char movePlanets = 1;
|
||||||
|
signed char saveSlot = -1;
|
||||||
|
|
||||||
|
if (currentGame.system > 0)
|
||||||
|
interceptionChance = (300 / currentGame.system);
|
||||||
|
|
||||||
|
// There is no chance of being interceptted after the final attack on Earth
|
||||||
|
if ((currentGame.system == 3) && (systemPlanet[2].missionCompleted))
|
||||||
|
interceptionChance = 0;
|
||||||
|
|
||||||
|
int rtn = 0;
|
||||||
|
|
||||||
|
if ((engine.useAudio) && (currentGame.useMusic))
|
||||||
|
Mix_PlayMusic(engine.music, -1);
|
||||||
|
|
||||||
|
textObject iconInfo[12];
|
||||||
|
|
||||||
|
iconInfo[0].image = graphics.textSurface("Start Next Mission", FONT_WHITE);
|
||||||
|
iconInfo[1].image = graphics.textSurface("View System Map", FONT_WHITE);
|
||||||
|
iconInfo[2].image = graphics.textSurface("Current Status", FONT_WHITE);
|
||||||
|
iconInfo[3].image = graphics.textSurface("Save Game", FONT_WHITE);
|
||||||
|
iconInfo[4].image = graphics.textSurface("Upgrade FIREFLY", FONT_WHITE);
|
||||||
|
iconInfo[5].image = graphics.textSurface("Comms", FONT_WHITE);
|
||||||
|
iconInfo[6].image = graphics.textSurface("Options", FONT_WHITE);
|
||||||
|
iconInfo[7].image = graphics.textSurface("Exit to Title Screen", FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "System : %s", systemNames[currentGame.system]);
|
||||||
|
iconInfo[8].image = graphics.textSurface(string, FONT_WHITE);
|
||||||
|
|
||||||
|
sprintf(string, "Stationed At: %s", systemPlanet[currentGame.stationedPlanet].name);
|
||||||
|
iconInfo[9].image = graphics.textSurface(string, FONT_WHITE);
|
||||||
|
|
||||||
|
strcpy(string, "Destination: None");
|
||||||
|
if (currentGame.destinationPlanet > -1)
|
||||||
|
sprintf(string, "Destination: %s", systemPlanet[currentGame.destinationPlanet].name);
|
||||||
|
iconInfo[10].image = graphics.textSurface(string, FONT_WHITE);
|
||||||
|
for (int i = 0 ; i < 9 ; i++)
|
||||||
|
iconInfo[i].x = (800 - iconInfo[i].image->w) / 2;
|
||||||
|
|
||||||
|
iconInfo[11].image = graphics.textSurface("Go to Destination Planet", FONT_WHITE);
|
||||||
|
|
||||||
|
signed char redrawBackGround = 1;
|
||||||
|
|
||||||
|
player.maxShield = (25 * currentGame.shieldUnits);
|
||||||
|
|
||||||
|
if (currentGame.distanceCovered > 0)
|
||||||
|
section = 0;
|
||||||
|
else
|
||||||
|
player.shield = player.maxShield;
|
||||||
|
|
||||||
|
unsigned long frameLimit = SDL_GetTicks();
|
||||||
|
|
||||||
|
flushInput();
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = engine.keyState[SDLK_SPACE] = 0;
|
||||||
|
engine.done = 0;
|
||||||
|
|
||||||
|
while (!engine.done)
|
||||||
|
{
|
||||||
|
graphics.updateScreen();
|
||||||
|
|
||||||
|
if (redrawBackGround)
|
||||||
|
{
|
||||||
|
graphics.drawBackGround();
|
||||||
|
redrawBackGround = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
graphics.unBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
doStarfield();
|
||||||
|
|
||||||
|
r.x = 0;
|
||||||
|
r.y = 0;
|
||||||
|
r.h = 600;
|
||||||
|
r.w = 1;
|
||||||
|
for (int i = 40 ; i < 800 ; i+= 40)
|
||||||
|
{
|
||||||
|
r.x = i;
|
||||||
|
SDL_FillRect(graphics.screen, &r, graphics.darkerBlue);
|
||||||
|
}
|
||||||
|
|
||||||
|
r.x = 0;
|
||||||
|
r.y = 0;
|
||||||
|
r.h = 1;
|
||||||
|
r.w = 800;
|
||||||
|
for (int i = 40 ; i < 600 ; i+= 40)
|
||||||
|
{
|
||||||
|
r.y = i;
|
||||||
|
SDL_FillRect(graphics.screen, &r, graphics.darkerBlue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (rand() % 1000 < 2)
|
||||||
|
{
|
||||||
|
engine.ssx = Math::rrand(100, 100);
|
||||||
|
engine.ssy = Math::rrand(100, 100);
|
||||||
|
engine.ssx /= 100;
|
||||||
|
engine.ssy /= 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.blit(iconInfo[8].image, (int)iconInfo[8].x, 15);
|
||||||
|
|
||||||
|
switch(section)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if (currentGame.stationedPlanet == currentGame.destinationPlanet)
|
||||||
|
{
|
||||||
|
currentGame.area = systemPlanet[currentGame.stationedPlanet].missionNumber;
|
||||||
|
rtn = 2;
|
||||||
|
engine.done = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
distance = abs(currentGame.stationedPlanet - currentGame.destinationPlanet);
|
||||||
|
distance = (5 / distance);
|
||||||
|
if (distance < 1)
|
||||||
|
distance = 1;
|
||||||
|
|
||||||
|
SDL_FreeSurface(iconInfo[9].image);
|
||||||
|
iconInfo[9].image = graphics.textSurface(systemPlanet[currentGame.stationedPlanet].name, FONT_WHITE);
|
||||||
|
|
||||||
|
SDL_FreeSurface(iconInfo[10].image);
|
||||||
|
iconInfo[10].image = graphics.textSurface(systemPlanet[currentGame.destinationPlanet].name, FONT_WHITE);
|
||||||
|
|
||||||
|
section = 8;
|
||||||
|
|
||||||
|
destRect.x = 180;
|
||||||
|
destRect.y = 450;
|
||||||
|
destRect.w = 1;
|
||||||
|
if (currentGame.distanceCovered > 0)
|
||||||
|
destRect.w = currentGame.distanceCovered;
|
||||||
|
destRect.h = 20;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
if (engine.keyState[SDLK_SPACE])
|
||||||
|
{
|
||||||
|
movePlanets = !movePlanets;
|
||||||
|
engine.keyState[SDLK_SPACE] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (movePlanets)
|
||||||
|
{
|
||||||
|
sinX += 0.01;
|
||||||
|
cosY += 0.01;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showSystem(sinX, cosY))
|
||||||
|
{
|
||||||
|
if (currentGame.system == 0)
|
||||||
|
{
|
||||||
|
sprintf(string, "Stationed At: %s", systemPlanet[currentGame.stationedPlanet].name);
|
||||||
|
SDL_FreeSurface(iconInfo[9].image);
|
||||||
|
iconInfo[9].image = graphics.textSurface(string, FONT_WHITE);
|
||||||
|
updateCommsSurface(commsSurface);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(string, "Destination: %s", systemPlanet[currentGame.destinationPlanet].name);
|
||||||
|
SDL_FreeSurface(iconInfo[10].image);
|
||||||
|
iconInfo[10].image = graphics.textSurface(string, FONT_WHITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.blit(iconInfo[9].image, 90, 450);
|
||||||
|
if ((currentGame.system > 0) && (currentGame.stationedPlanet != currentGame.destinationPlanet))
|
||||||
|
graphics.blit(iconInfo[10].image, 550, 450);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
showStatus(statsSurface);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
graphics.blit(savesSurface, 200, 100);
|
||||||
|
saveSlot = showSaveSlots(savesSurface, saveSlot);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
showShop();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
graphics.blit(commsSurface, 170, 70);
|
||||||
|
doComms(commsSurface);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
graphics.blit(optionsSurface, 230, 130);
|
||||||
|
showOptions(optionsSurface);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
rtn = 0;
|
||||||
|
engine.done = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
showSystem(sinX, cosY);
|
||||||
|
|
||||||
|
graphics.blit(systemPlanet[currentGame.stationedPlanet].image, 150, 450);
|
||||||
|
graphics.blit(iconInfo[9].image, 135, 480);
|
||||||
|
graphics.blit(systemPlanet[currentGame.destinationPlanet].image, 650, 450);
|
||||||
|
graphics.blit(iconInfo[10].image, 635, 480);
|
||||||
|
|
||||||
|
destRect.w += distance;
|
||||||
|
SDL_FillRect(graphics.screen, &destRect, graphics.red);
|
||||||
|
|
||||||
|
if (destRect.w >= 450)
|
||||||
|
{
|
||||||
|
currentGame.stationedPlanet = currentGame.destinationPlanet;
|
||||||
|
currentGame.distanceCovered = 0;
|
||||||
|
player.shield = player.maxShield;
|
||||||
|
sprintf(string, "Stationed At: %s", systemPlanet[currentGame.stationedPlanet].name);
|
||||||
|
strcpy(currentGame.stationedName, systemPlanet[currentGame.stationedPlanet].name);
|
||||||
|
SDL_FreeSurface(iconInfo[9].image);
|
||||||
|
iconInfo[9].image = graphics.textSurface(string, FONT_WHITE);
|
||||||
|
updateCommsSurface(commsSurface);
|
||||||
|
section = 1;
|
||||||
|
redrawBackGround = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interceptionChance > 0)
|
||||||
|
{
|
||||||
|
if ((rand() % interceptionChance) == 0)
|
||||||
|
{
|
||||||
|
currentGame.area = MAX_MISSIONS - 1;
|
||||||
|
rtn = 2;
|
||||||
|
engine.done = 1;
|
||||||
|
currentGame.distanceCovered = destRect.w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.addBuffer(300, 545, 200, 15);
|
||||||
|
|
||||||
|
if (section != 8)
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < 8 ; i++)
|
||||||
|
{
|
||||||
|
// if the mission has been completed, there is no "Start Next Mission" icon
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
if ((currentGame.stationedPlanet == currentGame.destinationPlanet) && (systemPlanet[currentGame.stationedPlanet].missionCompleted != 0))
|
||||||
|
continue;
|
||||||
|
else if (currentGame.stationedPlanet == currentGame.destinationPlanet)
|
||||||
|
graphics.blit(graphics.shape[1], 80 + (i * 90), 500);
|
||||||
|
else if (currentGame.stationedPlanet != currentGame.destinationPlanet)
|
||||||
|
graphics.blit(graphics.shape[26], 80 + (i * 90), 500);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
graphics.blit(graphics.shape[i + 1], 80 + (i * 90), 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Collision::collision(engine.cursor_x + 13, engine.cursor_y + 13, 6, 6, 80 + (i * 90), 500, 32, 32))
|
||||||
|
{
|
||||||
|
if (i != 0)
|
||||||
|
{
|
||||||
|
graphics.blit(iconInfo[i].image, (int)iconInfo[i].x, 545);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (currentGame.stationedPlanet == currentGame.destinationPlanet)
|
||||||
|
graphics.blit(iconInfo[0].image, (int)iconInfo[i].x, 545);
|
||||||
|
else
|
||||||
|
graphics.blit(iconInfo[11].image, (int)iconInfo[i].x, 545);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((engine.keyState[SDLK_LCTRL]) || (engine.keyState[SDLK_RCTRL]))
|
||||||
|
{
|
||||||
|
redrawBackGround = 1;
|
||||||
|
section = i;
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = engine.keyState[SDLK_SPACE] = 0;
|
||||||
|
doCursor();
|
||||||
|
|
||||||
|
// Limit us to 60 frame a second
|
||||||
|
while (SDL_GetTicks() < (frameLimit + 16)){}
|
||||||
|
frameLimit = SDL_GetTicks();
|
||||||
|
}
|
||||||
|
|
||||||
|
Mix_HaltMusic();
|
||||||
|
SDL_FreeSurface(statsSurface);
|
||||||
|
SDL_FreeSurface(savesSurface);
|
||||||
|
SDL_FreeSurface(optionsSurface);
|
||||||
|
SDL_FreeSurface(commsSurface);
|
||||||
|
for (int i = 0 ; i < 12 ; i++)
|
||||||
|
SDL_FreeSurface(iconInfo[i].image);
|
||||||
|
|
||||||
|
player.maxShield = (25 * currentGame.shieldUnits);
|
||||||
|
if (currentGame.distanceCovered == 0)
|
||||||
|
player.shield = player.maxShield;
|
||||||
|
|
||||||
|
return rtn;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern SDL_Surface *loadImage(char *filename);
|
||||||
|
extern void doStarfield();
|
||||||
|
extern void getPlayerInput();
|
||||||
|
extern void showShop();
|
||||||
|
extern void initShop();
|
||||||
|
extern int initSaveSlots();
|
||||||
|
extern int showSaveSlots(SDL_Surface *savesSurface, signed char saveSlot);
|
||||||
|
extern void saveGame(int slot);
|
||||||
|
extern void loadMusic(char *filename);
|
||||||
|
extern void loadBackground(char *filename);
|
||||||
|
extern void createCommsSurface(SDL_Surface *comms);
|
||||||
|
extern void updateCommsSurface(SDL_Surface *comms);
|
||||||
|
extern void createSavesSurface(SDL_Surface *savesSurface, signed char clickedSlot);
|
||||||
|
extern void checkForBossMission();
|
||||||
|
extern void doComms(SDL_Surface *comms);
|
||||||
|
extern int locateDataInPak(char *file, signed char required);
|
||||||
|
extern int getFace(char *face);
|
||||||
|
extern void flushInput();
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern object player;
|
||||||
|
extern Game currentGame;
|
||||||
|
extern Graphics graphics;
|
||||||
|
extern Planet systemPlanet[10];
|
|
@ -0,0 +1,253 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "loadSave.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Reads in each save game that it finds and gives it an appropriate
|
||||||
|
description using the area variable contained in the game binary
|
||||||
|
data. It returns the slot number (1 - 10) of the most recently
|
||||||
|
used file. On the title screen, this is used to determine whether
|
||||||
|
a player can "Continue Current Game" and "Load Saved Game".
|
||||||
|
*/
|
||||||
|
int initSaveSlots()
|
||||||
|
{
|
||||||
|
char fileName[PATH_MAX];
|
||||||
|
int imagePos = 350;
|
||||||
|
Game tempGame;
|
||||||
|
struct stat fileInfo;
|
||||||
|
int modTime = 0;
|
||||||
|
int continueSaveIndex = 0;
|
||||||
|
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
//READ SAVE GAME DATA
|
||||||
|
for (int i = 0 ; i < 5 ; i++)
|
||||||
|
{
|
||||||
|
sprintf(fileName, "%ssave%.2d.dat", engine.userHomeDirectory, (i + 1));
|
||||||
|
fp = fopen(fileName, "rb");
|
||||||
|
if (fp == NULL)
|
||||||
|
{
|
||||||
|
sprintf(saveSlot[i], "%.2d - Empty", (i + 1));
|
||||||
|
if (engine.gameSection == SECTION_TITLE)
|
||||||
|
graphics.textSurface(13 + i, saveSlot[i], -1, imagePos, FONT_WHITE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (fread(&tempGame, sizeof(Game), 1, fp) != 1)
|
||||||
|
{
|
||||||
|
sprintf(saveSlot[i], "%.2d - Corrupt Game Data", (i + 1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(saveSlot[i], "%.2d - %s, %s", (i + 1), systemNames[tempGame.system], tempGame.stationedName);
|
||||||
|
if (engine.gameSection == SECTION_TITLE)
|
||||||
|
graphics.textSurface(13 + i, saveSlot[i], -1, imagePos, FONT_WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stat(fileName, &fileInfo) != -1)
|
||||||
|
{
|
||||||
|
if (fileInfo.st_mtime > modTime)
|
||||||
|
{modTime = fileInfo.st_mtime; continueSaveIndex = (i + 1);}
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
imagePos += 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
return continueSaveIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fill in later...
|
||||||
|
*/
|
||||||
|
signed char loadGame(int slot)
|
||||||
|
{
|
||||||
|
char filename[PATH_MAX];
|
||||||
|
FILE *fp;
|
||||||
|
sprintf(filename, "%ssave%.2d.dat", engine.userHomeDirectory, slot);
|
||||||
|
|
||||||
|
fp = fopen(filename, "rb");
|
||||||
|
|
||||||
|
if (fp == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (fread(¤tGame, sizeof(Game), 1, fp) != 1)
|
||||||
|
{
|
||||||
|
printf("Save game error. The file was not of the expected format.\n");
|
||||||
|
fclose(fp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
weapon[0] = currentGame.playerWeapon;
|
||||||
|
weapon[1] = currentGame.playerWeapon2;
|
||||||
|
player = currentGame.thePlayer;
|
||||||
|
|
||||||
|
// Re-init all the planets in this system...
|
||||||
|
initPlanetMissions(currentGame.system);
|
||||||
|
|
||||||
|
// ... and then override with completition status
|
||||||
|
for (int i = 0 ; i < 10 ; i++)
|
||||||
|
systemPlanet[i].missionCompleted = currentGame.missionCompleted[i];
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveGame(int slot)
|
||||||
|
{
|
||||||
|
if ((slot < 1) || (slot > 5))
|
||||||
|
{
|
||||||
|
printf("Error - Saves may only be 1 to 5\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fp;
|
||||||
|
char fileName[PATH_MAX];
|
||||||
|
sprintf(fileName, "%ssave%.2d.dat", engine.userHomeDirectory, slot);
|
||||||
|
fp = fopen(fileName, "wb");
|
||||||
|
|
||||||
|
currentGame.playerWeapon = weapon[0];
|
||||||
|
currentGame.playerWeapon2 = weapon[1];
|
||||||
|
currentGame.thePlayer = player;
|
||||||
|
for (int i = 0 ; i < 10 ; i++)
|
||||||
|
currentGame.missionCompleted[i] = systemPlanet[i].missionCompleted;
|
||||||
|
|
||||||
|
if (fp != NULL)
|
||||||
|
{
|
||||||
|
if (fwrite(¤tGame, sizeof(Game), 1, fp) != 1)
|
||||||
|
{
|
||||||
|
printf("Error Saving Game to Slot %d\n", slot);
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("Error Saving Game to Slot %d\n", slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recall to update the save slots... (lazy, yes)
|
||||||
|
initSaveSlots();
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void createSavesSurface(SDL_Surface *savesSurface, signed char clickedSlot)
|
||||||
|
{
|
||||||
|
graphics.blevelRect(savesSurface, 0, 0, 348, 298, 0x00, 0x00, 0x00);
|
||||||
|
|
||||||
|
int y = 10;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 5 ; i++)
|
||||||
|
{
|
||||||
|
if (clickedSlot == i)
|
||||||
|
graphics.blevelRect(savesSurface, 5, y, 338, 25, 0x99, 0x00, 0x00);
|
||||||
|
else
|
||||||
|
graphics.blevelRect(savesSurface, 5, y, 338, 25, 0x00, 0x00, 0x99);
|
||||||
|
graphics.drawString(saveSlot[i], 70, y + 5, FONT_WHITE, savesSurface);
|
||||||
|
y += 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.drawString("*** HELP ***", 120, 170, FONT_WHITE, savesSurface);
|
||||||
|
|
||||||
|
switch(clickedSlot)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
graphics.blevelRect(savesSurface, 5, 265, 100, 25, 0x00, 0x99, 0x00);
|
||||||
|
graphics.blevelRect(savesSurface, 125, 265, 100, 25, 0x99, 0x99, 0x00);
|
||||||
|
graphics.blevelRect(savesSurface, 243, 265, 100, 25, 0x99, 0x00, 0x00);
|
||||||
|
graphics.drawString("SAVE", 40, 270, FONT_WHITE, savesSurface);
|
||||||
|
graphics.drawString("CANCEL", 150, 270, FONT_WHITE, savesSurface);
|
||||||
|
graphics.drawString("DELETE", 270, 270, FONT_WHITE, savesSurface);
|
||||||
|
|
||||||
|
graphics.drawString("SAVE will save the game", 17, 200, FONT_WHITE, savesSurface);
|
||||||
|
graphics.drawString("CANCEL will unselect that slot", 17, 220, FONT_WHITE, savesSurface);
|
||||||
|
graphics.drawString("DELETE will remove the save", 17, 240, FONT_WHITE, savesSurface);
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
graphics.drawString("First click a Save game slot to use", 17, 200, FONT_WHITE, savesSurface);
|
||||||
|
break;
|
||||||
|
case -10:
|
||||||
|
graphics.drawString("Game Saved", 130, 200, FONT_WHITE, savesSurface);
|
||||||
|
break;
|
||||||
|
case -11:
|
||||||
|
graphics.drawString("Save Deleted", 130, 200, FONT_WHITE, savesSurface);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Displays the save slot available. For use with an interface that
|
||||||
|
has the cursor enabled. It returns the index number of the slot clicked
|
||||||
|
so that the function invoking it can perform a load or save on that slot.
|
||||||
|
*/
|
||||||
|
int showSaveSlots(SDL_Surface *savesSurface, signed char saveSlot)
|
||||||
|
{
|
||||||
|
SDL_Rect r;
|
||||||
|
r.x = 201;
|
||||||
|
r.y = 115;
|
||||||
|
r.w = 348;
|
||||||
|
r.h = 25;
|
||||||
|
|
||||||
|
int clickedSlot = -1;
|
||||||
|
|
||||||
|
if ((engine.keyState[SDLK_LCTRL]) || (engine.keyState[SDLK_RCTRL]))
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < 5 ; i++)
|
||||||
|
{
|
||||||
|
if (Collision::collision(engine.cursor_x + 13, engine.cursor_y + 13, 6, 6, r.x, r.y, r.w, r.h))
|
||||||
|
{
|
||||||
|
clickedSlot = i;
|
||||||
|
createSavesSurface(savesSurface, i);
|
||||||
|
}
|
||||||
|
r.y += 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Collision::collision(engine.cursor_x + 13, engine.cursor_y + 13, 6, 6, 215, 365, 100, 25))
|
||||||
|
{
|
||||||
|
saveGame(saveSlot + 1);
|
||||||
|
createSavesSurface(savesSurface, -10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Collision::collision(engine.cursor_x + 13, engine.cursor_y + 13, 6, 6, 335, 365, 100, 25))
|
||||||
|
createSavesSurface(savesSurface, -1);
|
||||||
|
|
||||||
|
if (Collision::collision(engine.cursor_x + 13, engine.cursor_y + 13, 6, 6, 453, 365, 100, 25))
|
||||||
|
{
|
||||||
|
char filename[PATH_MAX];
|
||||||
|
sprintf(filename, "%ssave%.2d.dat", engine.userHomeDirectory, (saveSlot + 1));
|
||||||
|
remove(filename);
|
||||||
|
initSaveSlots();
|
||||||
|
createSavesSurface(savesSurface, -11);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clickedSlot > -1)
|
||||||
|
saveSlot = clickedSlot;
|
||||||
|
|
||||||
|
return saveSlot;
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
char saveSlot[10][25];
|
||||||
|
|
||||||
|
extern void getPlayerInput();
|
||||||
|
extern void initPlanetMissions(signed char system);
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern object player;
|
||||||
|
extern object weapon[MAX_WEAPONS];
|
||||||
|
extern Game currentGame;
|
||||||
|
extern Graphics graphics;
|
||||||
|
extern Planet systemPlanet[10];
|
|
@ -0,0 +1,232 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "messages.h"
|
||||||
|
|
||||||
|
void setKillMessages()
|
||||||
|
{
|
||||||
|
strcpy(killMessage[0], "Chalk another one up for me!");
|
||||||
|
strcpy(killMessage[1], "That'll teach you!");
|
||||||
|
strcpy(killMessage[2], "One more for me!");
|
||||||
|
strcpy(killMessage[3], "Target destroyed!");
|
||||||
|
strcpy(killMessage[4], "You aint so tough!");
|
||||||
|
strcpy(killMessage[5], "Kicked your ass!");
|
||||||
|
|
||||||
|
strcpy(killMessage[6], "That takes me up to %d");
|
||||||
|
|
||||||
|
strcpy(killMessage[7], "Hey %s, you asleep over there?!");
|
||||||
|
strcpy(killMessage[8], "I'm catching up with you, %s!");
|
||||||
|
|
||||||
|
strcpy(killMessage[9], "Number One, Baby!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPlayerDeadMessages()
|
||||||
|
{
|
||||||
|
strcpy(deathMessage[0], "Oh my God... No!");
|
||||||
|
strcpy(deathMessage[1], "NOOOOOOOOOOOOOOOOOOOOOOOOOOO!!!!");
|
||||||
|
strcpy(deathMessage[2], "Please tell me that didn't just happen...");
|
||||||
|
strcpy(deathMessage[3], "Chris, Answer Me!!");
|
||||||
|
strcpy(deathMessage[4], "What the hell happened?!");
|
||||||
|
strcpy(deathMessage[5], "Chriiiiiiiiiiiiiiiiiiiiiiiiiiis!!!!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void setMissFireMessages()
|
||||||
|
{
|
||||||
|
strcpy(missFireMessage[0], "I am NOT your enemy!");
|
||||||
|
strcpy(missFireMessage[1], "Hey! Watch it!");
|
||||||
|
strcpy(missFireMessage[2], "What are you doing?! Shoot THEM!");
|
||||||
|
strcpy(missFireMessage[3], "OW!!! I hope that was an accident!");
|
||||||
|
strcpy(missFireMessage[4], "Open your eyes!!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void setHitPlayerMessages()
|
||||||
|
{
|
||||||
|
strcpy(playerHitMessage[0], "Oops! Sorry!");
|
||||||
|
strcpy(playerHitMessage[1], "Get out of the way!");
|
||||||
|
strcpy(playerHitMessage[2], "Don't fly into my missiles!");
|
||||||
|
}
|
||||||
|
|
||||||
|
void setAllyMessages()
|
||||||
|
{
|
||||||
|
setKillMessages();
|
||||||
|
setPlayerDeadMessages();
|
||||||
|
setMissFireMessages();
|
||||||
|
setHitPlayerMessages();
|
||||||
|
}
|
||||||
|
|
||||||
|
void getKillMessage(object *ally)
|
||||||
|
{
|
||||||
|
char in[50], name[30], otherName[30];
|
||||||
|
int kills, difference;
|
||||||
|
signed char firstPlace = 0;
|
||||||
|
int faceToUse = FACE_PHOEBE;
|
||||||
|
|
||||||
|
if (ally == &enemy[FR_PHOEBE])
|
||||||
|
{
|
||||||
|
strcpy(name, "Phoebe");
|
||||||
|
strcpy(otherName, "Ursula");
|
||||||
|
kills = currentGame.wingMate1Kills;
|
||||||
|
difference = currentGame.wingMate1Kills - currentGame.wingMate2Kills;
|
||||||
|
if ((currentGame.wingMate1Kills > currentGame.wingMate2Kills) && (currentGame.wingMate1Kills > currentGame.totalKills))
|
||||||
|
firstPlace = 1;
|
||||||
|
faceToUse = FACE_PHOEBE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy(name, "Ursula");
|
||||||
|
strcpy(otherName, "Phoebe");
|
||||||
|
kills = currentGame.wingMate2Kills;
|
||||||
|
difference = currentGame.wingMate2Kills - currentGame.wingMate1Kills;
|
||||||
|
if ((currentGame.wingMate2Kills > currentGame.wingMate1Kills) && (currentGame.wingMate2Kills > currentGame.totalKills))
|
||||||
|
firstPlace = 1;
|
||||||
|
faceToUse = FACE_URSULA;
|
||||||
|
}
|
||||||
|
|
||||||
|
int r = rand() % 10;
|
||||||
|
|
||||||
|
if (currentGame.hasWingMate2 == 0)
|
||||||
|
r = rand() % 7;
|
||||||
|
|
||||||
|
switch(r)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
sprintf(in, killMessage[rand() % 6]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
case 7:
|
||||||
|
sprintf(in, killMessage[6], kills);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
if (difference > 0)
|
||||||
|
{
|
||||||
|
sprintf(in, killMessage[7], otherName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(in, killMessage[8], otherName);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 9:
|
||||||
|
if (firstPlace == 1)
|
||||||
|
{
|
||||||
|
sprintf(in, killMessage[9]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(in, killMessage[rand() % 6]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
setRadioMessage(faceToUse, in, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *getKlineInsult()
|
||||||
|
{
|
||||||
|
static char insult[][40] = {
|
||||||
|
"Pathetic", "How very disappointing...", "Heroic. And stupid", "Fool", "And now you're nothing but a DEAD hero"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (currentGame.area != 26)
|
||||||
|
return (insult[rand() % 3]);
|
||||||
|
else
|
||||||
|
return (insult[3 + (rand() % 2)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void getPlayerDeathMessage()
|
||||||
|
{
|
||||||
|
if (enemy[WC_KLINE].active)
|
||||||
|
{
|
||||||
|
setRadioMessage(FACE_KLINE, getKlineInsult(), 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((enemy[WC_BOSS].active) && (enemy[WC_BOSS].classDef == CD_KRASS))
|
||||||
|
{
|
||||||
|
setRadioMessage(FACE_KRASS, "That was the easiest $90,000,000 I've ever earned! Bwwah!! Ha!! Ha!! Ha!!", 1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char name[30], in[50];
|
||||||
|
int faceToUse = FACE_PHOEBE;
|
||||||
|
|
||||||
|
strcpy(name, "Phoebe");
|
||||||
|
faceToUse = FACE_PHOEBE;
|
||||||
|
|
||||||
|
if (currentGame.hasWingMate2)
|
||||||
|
{
|
||||||
|
if ((rand() % 2) == 0)
|
||||||
|
{
|
||||||
|
strcpy(name, "Ursula");
|
||||||
|
faceToUse = FACE_URSULA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(in, deathMessage[rand() % 6]);
|
||||||
|
setRadioMessage(faceToUse, in, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void getMissFireMessage(object *ally)
|
||||||
|
{
|
||||||
|
char name[30], in[50];
|
||||||
|
int faceToUse = FACE_PHOEBE;
|
||||||
|
|
||||||
|
if (ally == &enemy[FR_PHOEBE])
|
||||||
|
{
|
||||||
|
strcpy(name, "Phoebe");
|
||||||
|
faceToUse = FACE_PHOEBE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy(name, "Ursula");
|
||||||
|
faceToUse = FACE_URSULA;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(in, missFireMessage[rand() % 5]);
|
||||||
|
setRadioMessage(faceToUse, in, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void getPlayerHitMessage(object *ally)
|
||||||
|
{
|
||||||
|
char name[30], in[50];
|
||||||
|
int faceToUse = FACE_PHOEBE;
|
||||||
|
|
||||||
|
if (ally == &enemy[FR_PHOEBE])
|
||||||
|
{
|
||||||
|
strcpy(name, "Phoebe");
|
||||||
|
faceToUse = FACE_PHOEBE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy(name, "Ursula");
|
||||||
|
faceToUse = FACE_URSULA;
|
||||||
|
}
|
||||||
|
|
||||||
|
sprintf(in, playerHitMessage[rand() % 3]);
|
||||||
|
setRadioMessage(faceToUse, in, 0);
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
|
||||||
|
extern void setRadioMessage(signed char face, char *in, int priority);
|
||||||
|
|
||||||
|
char killMessage[10][50];
|
||||||
|
char deathMessage[6][50];
|
||||||
|
char missFireMessage[5][50];
|
||||||
|
char playerHitMessage[3][50];
|
||||||
|
|
||||||
|
extern object enemy[MAX_ALIENS];
|
||||||
|
extern Game currentGame;
|
||||||
|
|
|
@ -0,0 +1,473 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
void clearInfoLines()
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < 4 ; i++)
|
||||||
|
{
|
||||||
|
graphics.textShape[i].life = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// from a to b
|
||||||
|
void copyInfoLine(int a, int b)
|
||||||
|
{
|
||||||
|
graphics.textSurface(b, graphics.textShape[a].text, -1, 0, graphics.textShape[a].fontColor);
|
||||||
|
graphics.textShape[b].life = graphics.textShape[a].life;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Sets one of the three information lines on the screen. The accepts the
|
||||||
|
string and colors. It will set the information to the first free infoline
|
||||||
|
it finds (top to bottom). If it doesn't find any free ones, it will push
|
||||||
|
all the other info lines down one and add itself to the top.
|
||||||
|
*/
|
||||||
|
void setInfoLine(char *in, int color)
|
||||||
|
{
|
||||||
|
int index = -1;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 3 ; i++)
|
||||||
|
{
|
||||||
|
if ((graphics.textShape[i].life == 0) && (index == -1))
|
||||||
|
{
|
||||||
|
index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bump down
|
||||||
|
if (index == -1)
|
||||||
|
{
|
||||||
|
index = 2;
|
||||||
|
copyInfoLine(1, 0);
|
||||||
|
copyInfoLine(2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.textSurface(index, in, -1, 0, color);
|
||||||
|
graphics.textShape[index].life = 240;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Sets a radio message that appears at the top of the screen. Used for
|
||||||
|
script events, etc. We send a message priority too, since we don't want
|
||||||
|
Phoebe or Ursula's banter to interrupt an important message
|
||||||
|
*/
|
||||||
|
void setRadioMessage(signed char face, char *in, int priority)
|
||||||
|
{
|
||||||
|
if ((graphics.textShape[3].life > 0) && (priority == 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
graphics.textSurface(3, in, -1, 50, FONT_WHITE);
|
||||||
|
graphics.textShape[3].life = 240;
|
||||||
|
|
||||||
|
SDL_Surface *faceShape = NULL;
|
||||||
|
if (face > -1)
|
||||||
|
faceShape = graphics.shape[face];
|
||||||
|
|
||||||
|
graphics.createMessageBox(faceShape, in, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void doTargetArrow()
|
||||||
|
{
|
||||||
|
if ((engine.targetArrowTimer == 0) || (enemy[engine.targetIndex].shield < 1))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (enemy[engine.targetIndex].flags & FL_ISCLOAKED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (graphics.textShape[3].life > 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
engine.targetArrow = -1;
|
||||||
|
|
||||||
|
if (engine.targetArrowTimer > 0)
|
||||||
|
engine.targetArrowTimer--;
|
||||||
|
|
||||||
|
int distX = (int)(enemy[engine.targetIndex].x - player.x);
|
||||||
|
int distY = (int)(enemy[engine.targetIndex].y - player.y);
|
||||||
|
|
||||||
|
if (distY < -300)
|
||||||
|
engine.targetArrow = 36;
|
||||||
|
|
||||||
|
if (distY > 300)
|
||||||
|
engine.targetArrow = 40;
|
||||||
|
|
||||||
|
if (distX < -400)
|
||||||
|
engine.targetArrow = 42;
|
||||||
|
|
||||||
|
if (distX > 400)
|
||||||
|
engine.targetArrow = 38;
|
||||||
|
|
||||||
|
if ((distY < -300) && (distX > 400))
|
||||||
|
engine.targetArrow = 37;
|
||||||
|
|
||||||
|
if ((distY > 300) && (distX > 400))
|
||||||
|
engine.targetArrow = 39;
|
||||||
|
|
||||||
|
if ((distY > 300) && (distX < -400))
|
||||||
|
engine.targetArrow = 41;
|
||||||
|
|
||||||
|
if ((distY < -300) && (distX < -400))
|
||||||
|
engine.targetArrow = 43;
|
||||||
|
|
||||||
|
if (engine.targetArrow != -1)
|
||||||
|
{
|
||||||
|
graphics.blit(graphics.shape[engine.targetArrow], 380, 50);
|
||||||
|
graphics.blit(graphics.shape[44], 365, 70);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Fill in later...
|
||||||
|
*/
|
||||||
|
void doInfo()
|
||||||
|
{
|
||||||
|
int shieldColor = 0;
|
||||||
|
SDL_Rect bar;
|
||||||
|
signed char fontColor;
|
||||||
|
char text[25];
|
||||||
|
|
||||||
|
graphics.addBuffer(0, 20, 800, 25);
|
||||||
|
graphics.addBuffer(0, 545, 800, 25);
|
||||||
|
|
||||||
|
if (engine.minutes > -1)
|
||||||
|
{
|
||||||
|
if ((engine.minutes == 0) && (engine.seconds <= 29))
|
||||||
|
fontColor = FONT_RED;
|
||||||
|
else if ((engine.minutes == 0) && (engine.seconds > 29))
|
||||||
|
fontColor = FONT_YELLOW;
|
||||||
|
else
|
||||||
|
fontColor = FONT_WHITE;
|
||||||
|
graphics.blitText(10); // time remaining
|
||||||
|
sprintf(text, "%.2d:%.2d", engine.minutes, engine.seconds);
|
||||||
|
graphics.drawString(text, 410, 21, fontColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentGame.area != MAX_MISSIONS - 1)
|
||||||
|
{
|
||||||
|
graphics.blitText(9); // mission objectives
|
||||||
|
sprintf(text, "%d", (currentMission.remainingObjectives1 + currentMission.remainingObjectives2));
|
||||||
|
graphics.drawString(text, 745, 21, FONT_WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.blitText(8); // cash
|
||||||
|
sprintf(text, "%.6d", currentGame.cash);
|
||||||
|
graphics.drawString(text, 90, 21, FONT_WHITE);
|
||||||
|
|
||||||
|
doTargetArrow();
|
||||||
|
|
||||||
|
fontColor = FONT_WHITE;
|
||||||
|
if (player.ammo[0] > 0)
|
||||||
|
{
|
||||||
|
if (player.ammo[0] <= 25) fontColor = FONT_YELLOW;
|
||||||
|
if (player.ammo[0] <= 10) fontColor = FONT_RED;
|
||||||
|
}
|
||||||
|
graphics.blitText(5); // plasma ammo
|
||||||
|
sprintf(text, "%.3d", player.ammo[0]);
|
||||||
|
graphics.drawString(text, 320, 551, fontColor);
|
||||||
|
|
||||||
|
graphics.blitText(6);
|
||||||
|
|
||||||
|
if ((player.weaponType[1] != W_CHARGER) && (player.weaponType[1] != W_LASER))
|
||||||
|
{
|
||||||
|
if (player.ammo[1] == 1)
|
||||||
|
fontColor = FONT_RED;
|
||||||
|
else
|
||||||
|
fontColor = FONT_WHITE;
|
||||||
|
sprintf(text, "%.3d", player.ammo[1]); // rocket ammo
|
||||||
|
graphics.drawString(text, 465, 551, fontColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((player.weaponType[1] == W_CHARGER) || (player.weaponType[1] == W_LASER)) && (player.ammo[1] > 0))
|
||||||
|
{
|
||||||
|
int c = graphics.white;
|
||||||
|
if (player.ammo[1] > 100)
|
||||||
|
c = graphics.red;
|
||||||
|
|
||||||
|
bar.x = 450;
|
||||||
|
bar.y = 550;
|
||||||
|
bar.h = 12;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < (player.ammo[1] / 5) ; i++)
|
||||||
|
{
|
||||||
|
bar.w = 1;
|
||||||
|
SDL_FillRect(graphics.screen, &bar, c);
|
||||||
|
bar.x += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((!allMissionsCompleted()) && (SDL_GetTicks() >= engine.counter2))
|
||||||
|
{
|
||||||
|
engine.timeTaken++;
|
||||||
|
engine.counter2 = SDL_GetTicks() + 1000;
|
||||||
|
if (engine.missionCompleteTimer == 0)
|
||||||
|
checkScriptEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((engine.timeMission) && (!engine.cheatTime) && (player.shield > 0))
|
||||||
|
{
|
||||||
|
if (SDL_GetTicks() >= engine.counter)
|
||||||
|
{
|
||||||
|
if ((engine.seconds > 1) && (engine.seconds <= 11) && (engine.minutes == 0))
|
||||||
|
{
|
||||||
|
playSound(SFX_CLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (engine.seconds > 0)
|
||||||
|
{
|
||||||
|
engine.seconds--;
|
||||||
|
engine.counter = (SDL_GetTicks() + 1000);
|
||||||
|
}
|
||||||
|
else if ((engine.seconds == 0) && (engine.minutes > 0))
|
||||||
|
{
|
||||||
|
engine.minutes--;
|
||||||
|
engine.seconds = 59;
|
||||||
|
engine.counter = (SDL_GetTicks() + 1000);
|
||||||
|
for (int i = 0 ; i < 3 ; i++)
|
||||||
|
{
|
||||||
|
if (currentMission.timeLimit1[i] > -1)
|
||||||
|
currentMission.timeLimit1[i]--;
|
||||||
|
if (currentMission.timeLimit2[i] > -1)
|
||||||
|
currentMission.timeLimit2[i]--;
|
||||||
|
}
|
||||||
|
checkTimer();
|
||||||
|
checkScriptEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((engine.seconds == 0) && (engine.minutes == 0))
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < 3 ; i++)
|
||||||
|
{
|
||||||
|
if (currentMission.timeLimit1[i] > -1)
|
||||||
|
currentMission.timeLimit1[i]--;
|
||||||
|
if (currentMission.timeLimit2[i] > -1)
|
||||||
|
currentMission.timeLimit2[i]--;
|
||||||
|
}
|
||||||
|
checkTimer();
|
||||||
|
checkScriptEvents();
|
||||||
|
//engine.counter = 0;
|
||||||
|
engine.counter = (SDL_GetTicks() + 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 3 ; i++)
|
||||||
|
{
|
||||||
|
if (graphics.textShape[i].life > 0)
|
||||||
|
{
|
||||||
|
graphics.textShape[i].y = (525 - (i * 20));
|
||||||
|
graphics.blitText(i);
|
||||||
|
graphics.textShape[i].life--;
|
||||||
|
|
||||||
|
if (graphics.textShape[i].life == 0)
|
||||||
|
{
|
||||||
|
copyInfoLine(i + 1, i);
|
||||||
|
copyInfoLine(i + 2, i + 1);
|
||||||
|
graphics.textShape[2].life = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show the radio message if there is one
|
||||||
|
if (graphics.textShape[3].life > 0)
|
||||||
|
{
|
||||||
|
graphics.blit(graphics.messageBox, (800 - graphics.messageBox->w) / 2, 50);
|
||||||
|
graphics.textShape[3].life--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do the target's remaining shield (if required)
|
||||||
|
if (currentGame.area != 10)
|
||||||
|
{
|
||||||
|
if ((engine.targetIndex > -1) && (enemy[engine.targetIndex].shield > 0) && (engine.targetIndex > 9))
|
||||||
|
{
|
||||||
|
graphics.blitText(7);
|
||||||
|
bar.w = 1;
|
||||||
|
bar.h = 12;
|
||||||
|
bar.x = 620;
|
||||||
|
bar.y = 550;
|
||||||
|
|
||||||
|
for (float i = 0 ; i < (engine.targetShield * enemy[engine.targetIndex].shield) ; i++)
|
||||||
|
{
|
||||||
|
if (i > 50)
|
||||||
|
shieldColor = graphics.green;
|
||||||
|
else if ((i >= 25) && (i <= 50))
|
||||||
|
shieldColor = graphics.yellow;
|
||||||
|
else
|
||||||
|
shieldColor = graphics.red;
|
||||||
|
SDL_FillRect(graphics.screen, &bar, shieldColor);
|
||||||
|
bar.x += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.blitText(11);
|
||||||
|
|
||||||
|
bar.w = 25;
|
||||||
|
bar.h = 12;
|
||||||
|
bar.x = 80;
|
||||||
|
bar.y = 571;
|
||||||
|
SDL_FillRect(graphics.screen, &bar, graphics.green);
|
||||||
|
|
||||||
|
for (int i = 1 ; i < currentGame.maxPlasmaDamage ; i++)
|
||||||
|
{
|
||||||
|
bar.x += 30;
|
||||||
|
if (weapon[1].damage >= (i + 1))
|
||||||
|
SDL_FillRect(graphics.screen, &bar, graphics.green);
|
||||||
|
else
|
||||||
|
SDL_FillRect(graphics.screen, &bar, graphics.darkGreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.blitText(12);
|
||||||
|
|
||||||
|
bar.w = 25;
|
||||||
|
bar.h = 12;
|
||||||
|
bar.x = 315;
|
||||||
|
bar.y = 571;
|
||||||
|
SDL_FillRect(graphics.screen, &bar, graphics.yellow);
|
||||||
|
|
||||||
|
for (int i = 1 ; i < currentGame.maxPlasmaDamage ; i++)
|
||||||
|
{
|
||||||
|
bar.x += 30;
|
||||||
|
if (weapon[1].ammo[0] >= (i + 1))
|
||||||
|
SDL_FillRect(graphics.screen, &bar, graphics.yellow);
|
||||||
|
else
|
||||||
|
SDL_FillRect(graphics.screen, &bar, graphics.darkYellow);
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.blitText(13);
|
||||||
|
|
||||||
|
bar.w = 25;
|
||||||
|
bar.h = 12;
|
||||||
|
bar.x = 550;
|
||||||
|
bar.y = 571;
|
||||||
|
|
||||||
|
for (int i = 15 ; i > (currentGame.maxPlasmaRate - 1) ; i -= 2)
|
||||||
|
{
|
||||||
|
if (weapon[1].reload[0] <= i)
|
||||||
|
SDL_FillRect(graphics.screen, &bar, graphics.blue);
|
||||||
|
else
|
||||||
|
SDL_FillRect(graphics.screen, &bar, graphics.darkerBlue);
|
||||||
|
bar.x += 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.blitText(4);
|
||||||
|
if (player.shield < 1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((!engine.keyState[SDLK_SPACE]) && (player.weaponType[1] == W_LASER) && (engine.eventTimer % 8 == 1))
|
||||||
|
Math::limitChar(&(--player.ammo[1]), 1, 255);
|
||||||
|
|
||||||
|
if ((engine.eventTimer < 30) && (player.shield <= engine.lowShield))
|
||||||
|
return;
|
||||||
|
|
||||||
|
signed char blockSize = 1;
|
||||||
|
|
||||||
|
bar.w = blockSize;
|
||||||
|
bar.h = 12;
|
||||||
|
bar.x = 95;
|
||||||
|
bar.y = 550;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < player.shield ; i += blockSize)
|
||||||
|
{
|
||||||
|
if (i >= engine.averageShield)
|
||||||
|
shieldColor = graphics.green;
|
||||||
|
else if ((i >= engine.lowShield) && (i < engine.averageShield))
|
||||||
|
shieldColor = graphics.yellow;
|
||||||
|
else
|
||||||
|
shieldColor = graphics.red;
|
||||||
|
SDL_FillRect(graphics.screen, &bar, shieldColor);
|
||||||
|
bar.x += blockSize;
|
||||||
|
if (player.maxShield < 75)
|
||||||
|
bar.x++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int getFace(char *face)
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < 7 ; i++)
|
||||||
|
{
|
||||||
|
if (strcmp(faces[i], face) == 0)
|
||||||
|
return 90 + i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void resetLists()
|
||||||
|
{
|
||||||
|
object *ob, *ob2;
|
||||||
|
collectables *c1, *c2;
|
||||||
|
bRect *r1, *r2;
|
||||||
|
|
||||||
|
ob = engine.bulletHead->next;
|
||||||
|
while(ob != NULL)
|
||||||
|
{
|
||||||
|
ob2 = ob;
|
||||||
|
ob = ob->next;
|
||||||
|
delete ob2;
|
||||||
|
}
|
||||||
|
engine.bulletHead->next = NULL;
|
||||||
|
engine.bulletTail = engine.bulletHead;
|
||||||
|
|
||||||
|
ob = engine.explosionHead->next;
|
||||||
|
while(ob != NULL)
|
||||||
|
{
|
||||||
|
ob2 = ob;
|
||||||
|
ob = ob->next;
|
||||||
|
delete ob2;
|
||||||
|
}
|
||||||
|
engine.explosionHead->next = NULL;
|
||||||
|
engine.explosionTail = engine.explosionHead;
|
||||||
|
|
||||||
|
c1 = engine.collectableHead->next;
|
||||||
|
while (c1 != NULL)
|
||||||
|
{
|
||||||
|
c2 = c1;
|
||||||
|
c1 = c1->next;
|
||||||
|
delete c2;
|
||||||
|
}
|
||||||
|
|
||||||
|
engine.collectableHead->next = NULL;
|
||||||
|
engine.collectableTail = engine.collectableHead;
|
||||||
|
|
||||||
|
r1 = graphics.bufferHead->next;
|
||||||
|
while (r1 != NULL)
|
||||||
|
{
|
||||||
|
r2 = r1;
|
||||||
|
r1 = r1->next;
|
||||||
|
delete r2;
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.bufferHead->next = NULL;
|
||||||
|
graphics.bufferTail = graphics.bufferHead;
|
||||||
|
|
||||||
|
ob = engine.debrisHead->next;
|
||||||
|
while(ob != NULL)
|
||||||
|
{
|
||||||
|
ob2 = ob;
|
||||||
|
ob = ob->next;
|
||||||
|
delete ob2;
|
||||||
|
}
|
||||||
|
engine.debrisHead->next = NULL;
|
||||||
|
engine.debrisTail = engine.debrisHead;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern signed char allMissionsCompleted();
|
||||||
|
extern void playSound(int sid);
|
||||||
|
extern void checkTimer();
|
||||||
|
extern void checkScriptEvents();
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern devVariables dev;
|
||||||
|
extern object player;
|
||||||
|
extern object enemy[MAX_ALIENS];
|
||||||
|
extern object weapon[MAX_WEAPONS];
|
||||||
|
extern mission currentMission;
|
||||||
|
extern Game currentGame;
|
||||||
|
extern Graphics graphics;
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern SDL_Surface *loadImage(char *file_name);
|
||||||
|
extern void playRandomTrack();
|
||||||
|
extern void getPlayerInput();
|
||||||
|
extern void setInfoLine(char *in, int color);
|
||||||
|
extern void loadGameGraphics();
|
||||||
|
extern void killAllAliens();
|
||||||
|
extern int locateDataInPak(char *file, signed char required);
|
||||||
|
extern void setRadioMessage(signed char face, char *in, int priority);
|
||||||
|
extern void syncScriptEvents();
|
||||||
|
extern void loadMusic(char *filename);
|
||||||
|
extern void setTarget(int index);
|
||||||
|
extern void flushInput();
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern object player;
|
||||||
|
extern object enemy[MAX_ALIENS];
|
||||||
|
extern mission currentMission;
|
||||||
|
extern Game currentGame;
|
||||||
|
extern Graphics graphics;
|
||||||
|
extern Planet systemPlanet[10];
|
||||||
|
extern mission missions[MAX_MISSIONS];
|
|
@ -0,0 +1,429 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "player.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Initialises the player for a new game.
|
||||||
|
*/
|
||||||
|
void initPlayer()
|
||||||
|
{
|
||||||
|
player.active = 1;
|
||||||
|
player.x = 200;
|
||||||
|
player.y = 200;
|
||||||
|
player.speed = 2;
|
||||||
|
player.maxShield = (25 * currentGame.shieldUnits);
|
||||||
|
player.systemPower = player.maxShield;
|
||||||
|
player.face = 0;
|
||||||
|
|
||||||
|
player.image[0] = graphics.shipShape[0];
|
||||||
|
player.image[1] = graphics.shipShape[1];
|
||||||
|
|
||||||
|
player.engineX = player.image[0]->w;
|
||||||
|
player.engineY = (player.image[0]->h / 2);
|
||||||
|
|
||||||
|
player.owner = &player;
|
||||||
|
player.flags = FL_FRIEND;
|
||||||
|
|
||||||
|
player.weaponType[0] = W_PLAYER_WEAPON;
|
||||||
|
|
||||||
|
if (player.ammo[0] > 0)
|
||||||
|
{
|
||||||
|
player.weaponType[0] = W_PLAYER_WEAPON2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player.weaponType[0] = W_PLAYER_WEAPON;
|
||||||
|
weapon[1] = weapon[0]; // reset to weapon 1 defaults
|
||||||
|
}
|
||||||
|
|
||||||
|
player.hit = 0;
|
||||||
|
|
||||||
|
engine.lowShield = (player.maxShield / 3);
|
||||||
|
engine.averageShield = engine.lowShield + engine.lowShield;
|
||||||
|
|
||||||
|
if (player.weaponType[1] == W_CHARGER)
|
||||||
|
player.ammo[1] = 0;
|
||||||
|
|
||||||
|
if (player.weaponType[1] == W_LASER)
|
||||||
|
player.ammo[1] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doPlayer()
|
||||||
|
{
|
||||||
|
// This causes the motion to slow
|
||||||
|
engine.ssx *= 0.99;
|
||||||
|
engine.ssy *= 0.99;
|
||||||
|
|
||||||
|
int shapeToUse;
|
||||||
|
|
||||||
|
if (player.shield > -100)
|
||||||
|
{
|
||||||
|
if (player.shield > 0)
|
||||||
|
{
|
||||||
|
if ((engine.keyState[SDLK_LCTRL]) || (engine.keyState[SDLK_RCTRL]))
|
||||||
|
fireBullet(&player, 0);
|
||||||
|
|
||||||
|
if ((engine.keyState[SDLK_SPACE]) && (player.weaponType[1] != W_NONE))
|
||||||
|
{
|
||||||
|
if ((player.weaponType[1] != W_CHARGER) && (player.weaponType[1] != W_LASER) && (player.ammo[1] > 0))
|
||||||
|
{
|
||||||
|
fireBullet(&player, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.weaponType[1] == W_LASER)
|
||||||
|
{
|
||||||
|
if (player.ammo[1] < 100)
|
||||||
|
{
|
||||||
|
fireBullet(&player, 1);
|
||||||
|
player.ammo[1] += 2;
|
||||||
|
if (player.ammo[1] >= 100)
|
||||||
|
{
|
||||||
|
player.ammo[1] = 200;
|
||||||
|
setInfoLine("Laser Overheat!!", FONT_WHITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.weaponType[1] == W_CHARGER)
|
||||||
|
{
|
||||||
|
if (engine.keyState[SDLK_SPACE])
|
||||||
|
{
|
||||||
|
Math::limitChar(&(++player.ammo[1]), 0, 200);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (player.ammo[1] > 0)
|
||||||
|
fireBullet(&player, 1);
|
||||||
|
player.ammo[1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((engine.keyState[SDLK_LSHIFT]) || (engine.keyState[SDLK_RSHIFT]))
|
||||||
|
{
|
||||||
|
if (player.ammo[0] < 1)
|
||||||
|
{
|
||||||
|
if (weapon[0].ammo[0] == 3)
|
||||||
|
{
|
||||||
|
if (weapon[0].flags & WF_THIN_SPREAD)
|
||||||
|
{
|
||||||
|
weapon[0].flags -= WF_THIN_SPREAD;
|
||||||
|
weapon[0].flags += WF_STRAIGHT;
|
||||||
|
setInfoLine("Weapon set to Concentrate", FONT_WHITE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
weapon[0].flags -= WF_STRAIGHT;
|
||||||
|
weapon[0].flags += WF_THIN_SPREAD;
|
||||||
|
setInfoLine("Weapon set to Spread", FONT_WHITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (weapon[1].ammo[0] == 3)
|
||||||
|
{
|
||||||
|
if (weapon[1].flags & WF_THIN_SPREAD)
|
||||||
|
{
|
||||||
|
weapon[1].flags -= WF_THIN_SPREAD;
|
||||||
|
weapon[1].flags += WF_STRAIGHT;
|
||||||
|
setInfoLine("Weapon set to Concentrate", FONT_WHITE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
weapon[1].flags -= WF_STRAIGHT;
|
||||||
|
weapon[1].flags += WF_THIN_SPREAD;
|
||||||
|
setInfoLine("Weapon set to Spread", FONT_WHITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (weapon[1].ammo[0] == 4)
|
||||||
|
{
|
||||||
|
if (weapon[1].flags & WF_THIN_SPREAD)
|
||||||
|
{
|
||||||
|
weapon[1].flags -= WF_THIN_SPREAD;
|
||||||
|
weapon[1].flags += WF_STRAIGHT;
|
||||||
|
setInfoLine("Weapon set to Concentrate", FONT_WHITE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
weapon[1].flags -= WF_STRAIGHT;
|
||||||
|
weapon[1].flags += WF_THIN_SPREAD;
|
||||||
|
setInfoLine("Weapon set to Spread", FONT_WHITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (weapon[1].ammo[0] == 5)
|
||||||
|
{
|
||||||
|
if (weapon[1].flags & WF_WIDE_SPREAD)
|
||||||
|
{
|
||||||
|
if (weapon[1].flags & WF_THIN_SPREAD)
|
||||||
|
weapon[1].flags -= WF_THIN_SPREAD;
|
||||||
|
weapon[1].flags -= WF_WIDE_SPREAD;
|
||||||
|
weapon[1].flags += WF_STRAIGHT;
|
||||||
|
setInfoLine("Weapon set to Concentrate", FONT_WHITE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (weapon[1].flags & WF_THIN_SPREAD)
|
||||||
|
weapon[1].flags -= WF_THIN_SPREAD;
|
||||||
|
weapon[1].flags -= WF_STRAIGHT;
|
||||||
|
weapon[1].flags += WF_WIDE_SPREAD;
|
||||||
|
setInfoLine("Weapon set to Spread", FONT_WHITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
engine.keyState[SDLK_LSHIFT] = engine.keyState[SDLK_RSHIFT] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Math::limitChar(&--player.reload[0], 0, 999);
|
||||||
|
Math::limitChar(&--player.reload[1], 0, 999);
|
||||||
|
|
||||||
|
if (engine.keyState[SDLK_UP])
|
||||||
|
{
|
||||||
|
player.y -= player.speed;
|
||||||
|
engine.ssy += 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (engine.keyState[SDLK_DOWN])
|
||||||
|
{
|
||||||
|
player.y += player.speed;
|
||||||
|
engine.ssy -= 0.1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (engine.keyState[SDLK_LEFT])
|
||||||
|
{
|
||||||
|
player.x -= player.speed;
|
||||||
|
engine.ssx += 0.1;
|
||||||
|
player.face = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (engine.keyState[SDLK_RIGHT])
|
||||||
|
{
|
||||||
|
player.x += player.speed;
|
||||||
|
engine.ssx -= 0.1;
|
||||||
|
player.face = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (engine.keyState[SDLK_ESCAPE])
|
||||||
|
{
|
||||||
|
if ((engine.done == 0) && (engine.gameSection == SECTION_GAME) && (currentMission.remainingObjectives1 == 0))
|
||||||
|
{
|
||||||
|
playSound(SFX_FLY);
|
||||||
|
engine.done = 2;
|
||||||
|
engine.missionCompleteTimer = (SDL_GetTicks() - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (engine.keyState[SDLK_p])
|
||||||
|
{
|
||||||
|
engine.paused = 1;
|
||||||
|
engine.keyState[SDLK_p] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((engine.keyState[SDLK_t]) && (currentGame.area != 10))
|
||||||
|
{
|
||||||
|
if (engine.targetArrowTimer == -1)
|
||||||
|
engine.targetArrowTimer = 0;
|
||||||
|
else
|
||||||
|
engine.targetArrowTimer = -1;
|
||||||
|
|
||||||
|
engine.keyState[SDLK_t] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((engine.missionCompleteTimer == 0) && (engine.targetArrowTimer == -1))
|
||||||
|
{
|
||||||
|
if ((enemy[engine.targetIndex].shield < 1) && (currentGame.area != 10))
|
||||||
|
{
|
||||||
|
engine.targetIndex = rand() % MAX_ALIENS;
|
||||||
|
|
||||||
|
if (enemy[engine.targetIndex].flags & FL_FRIEND)
|
||||||
|
engine.targetIndex = 0;
|
||||||
|
else
|
||||||
|
setTarget(engine.targetIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((currentGame.area == 18) && (enemy[WC_BOSS].shield > 0)) || (currentGame.area == 24))
|
||||||
|
player.face = 0;
|
||||||
|
|
||||||
|
if (engine.done == 0)
|
||||||
|
{
|
||||||
|
Math::limitFloat(&player.x, 100, 700);
|
||||||
|
Math::limitFloat(&player.y, 100, 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.shield > engine.lowShield)
|
||||||
|
addEngine(&player);
|
||||||
|
|
||||||
|
shapeToUse = player.face;
|
||||||
|
|
||||||
|
if (player.hit)
|
||||||
|
shapeToUse += SHIP_HIT_INDEX;
|
||||||
|
|
||||||
|
Math::limitChar(&--player.hit, 0, 100);
|
||||||
|
|
||||||
|
graphics.blit(graphics.shipShape[shapeToUse], (int)player.x, (int)player.y);
|
||||||
|
if ((player.shield <= engine.lowShield) && (rand() % 5 < 1))
|
||||||
|
addExplosion(player.x + Math::rrand(-10, 10), player.y + Math::rrand(-10, 20), E_SMOKE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
player.active = 0;
|
||||||
|
player.shield--;
|
||||||
|
if (player.shield == -1)
|
||||||
|
{
|
||||||
|
if ((currentGame.hasWingMate1) || (enemy[WC_KLINE].active))
|
||||||
|
getPlayerDeathMessage();
|
||||||
|
|
||||||
|
// Make it look like the ships are all still moving...
|
||||||
|
if (currentGame.area == 18)
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < MAX_ALIENS ; i++)
|
||||||
|
enemy[i].flags += FL_LEAVESECTOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
playSound(SFX_DEATH);
|
||||||
|
playSound(SFX_EXPLOSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
engine.keyState[SDLK_UP] = engine.keyState[SDLK_DOWN] = engine.keyState[SDLK_LEFT] = engine.keyState[SDLK_RIGHT] = 0;
|
||||||
|
if ((rand() % 3) == 0)
|
||||||
|
addExplosion(player.x + Math::rrand(-10, 10), player.y + Math::rrand(-10, 10), E_BIG_EXPLOSION);
|
||||||
|
if (player.shield == -99)
|
||||||
|
addDebris((int)player.x, (int)player.y, player.maxShield);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Math::limitFloat(&engine.ssx, -3, 3);
|
||||||
|
Math::limitFloat(&engine.ssy, -3, 3);
|
||||||
|
|
||||||
|
// Specific for the mission were you have to chase the Executive Transport
|
||||||
|
if ((currentGame.area == 18) && (enemy[WC_BOSS].shield > 0) && (player.shield > 0))
|
||||||
|
{
|
||||||
|
engine.ssx = -6;
|
||||||
|
engine.ssy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentGame.area == 24)
|
||||||
|
{
|
||||||
|
engine.ssx = -6;
|
||||||
|
engine.ssy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
player.dx = engine.ssx;
|
||||||
|
player.dy = engine.ssy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void flushInput()
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < 350 ; i++)
|
||||||
|
engine.keyState[i] = 0;
|
||||||
|
|
||||||
|
while (SDL_PollEvent(&engine.event)){}
|
||||||
|
}
|
||||||
|
|
||||||
|
void getPlayerInput()
|
||||||
|
{
|
||||||
|
if (engine.gameSection == SECTION_INTERMISSION)
|
||||||
|
{
|
||||||
|
// Get the current mouse position
|
||||||
|
int x, y;
|
||||||
|
SDL_GetMouseState(&x, &y);
|
||||||
|
engine.cursor_x = x;
|
||||||
|
engine.cursor_y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SDL_PollEvent(&engine.event))
|
||||||
|
{
|
||||||
|
switch (engine.event.type)
|
||||||
|
{
|
||||||
|
case SDL_QUIT:
|
||||||
|
exit(0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
|
if (engine.gameSection == SECTION_INTERMISSION)
|
||||||
|
{
|
||||||
|
if (engine.event.button.button == SDL_BUTTON_LEFT) engine.keyState[SDLK_LCTRL] = 1;
|
||||||
|
if (engine.event.button.button == SDL_BUTTON_RIGHT) engine.keyState[SDLK_SPACE] = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_KEYDOWN:
|
||||||
|
if (engine.gameSection == SECTION_TITLE)
|
||||||
|
addKeyEvent(SDL_GetKeyName(engine.event.key.keysym.sym));
|
||||||
|
|
||||||
|
engine.keyState[engine.event.key.keysym.sym] = 1;
|
||||||
|
|
||||||
|
if (engine.gameSection != SECTION_GAME)
|
||||||
|
engine.paused = 0;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SDL_KEYUP:
|
||||||
|
if (engine.event.key.keysym.sym != SDLK_p)
|
||||||
|
engine.keyState[engine.event.key.keysym.sym] = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void leaveSector()
|
||||||
|
{
|
||||||
|
engine.keyState[SDLK_UP] = engine.keyState[SDLK_DOWN] = engine.keyState[SDLK_LEFT] = engine.keyState[SDLK_RIGHT] = 0;
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = engine.keyState[SDLK_SPACE] = 0;
|
||||||
|
|
||||||
|
if (engine.done == 0)
|
||||||
|
engine.done = 3;
|
||||||
|
|
||||||
|
if (engine.done == 3)
|
||||||
|
{
|
||||||
|
player.face = 0;
|
||||||
|
if (player.x > -100)
|
||||||
|
{
|
||||||
|
player.x += engine.ssx;
|
||||||
|
engine.ssx -= 1;
|
||||||
|
if (player.y > 300)
|
||||||
|
player.y--;
|
||||||
|
if (player.y < 300)
|
||||||
|
player.y++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player.x <= -100)
|
||||||
|
{
|
||||||
|
engine.done = 2;
|
||||||
|
playSound(SFX_FLY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (engine.done == 2)
|
||||||
|
{
|
||||||
|
player.face = 0;
|
||||||
|
player.x += 12;
|
||||||
|
engine.ssx -= 0.2;
|
||||||
|
if (player.x > 1600)
|
||||||
|
engine.done = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern void fireBullet(object *attacker, int weaponType);
|
||||||
|
extern void addExplosion(float x, float y, int type);
|
||||||
|
extern void playSound(int sid);
|
||||||
|
extern void addEngine(object *craft);
|
||||||
|
extern void addKeyEvent(char *keyName);
|
||||||
|
extern void addDebris(int x, int y, int amount);
|
||||||
|
extern void setRadioMessage(signed char face, char *in, int priority);
|
||||||
|
extern void setInfoLine(char *in, int color);
|
||||||
|
extern void getPlayerDeathMessage();
|
||||||
|
extern void playSound(int sid);
|
||||||
|
extern void setTarget(int index);
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern object player;
|
||||||
|
extern mission currentMission;
|
||||||
|
extern Game currentGame;
|
||||||
|
extern object weapon[MAX_WEAPONS];
|
||||||
|
extern object enemy[MAX_ALIENS];
|
||||||
|
extern Graphics graphics;
|
|
@ -0,0 +1,221 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "resources.h"
|
||||||
|
|
||||||
|
void loadBackground(char *filename)
|
||||||
|
{
|
||||||
|
if (graphics.background != NULL)
|
||||||
|
{
|
||||||
|
SDL_FreeSurface(graphics.background);
|
||||||
|
graphics.background = NULL;
|
||||||
|
}
|
||||||
|
graphics.background = loadImage(filename);
|
||||||
|
SDL_SetColorKey(graphics.background, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadGameGraphics()
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
char string[75];
|
||||||
|
|
||||||
|
graphics.freeGraphics();
|
||||||
|
|
||||||
|
graphics.shipShape[0] = loadImage("gfx/firefly1.png");
|
||||||
|
graphics.shipShape[1] = loadImage("gfx/firefly2.png");
|
||||||
|
|
||||||
|
strcpy(string, "");
|
||||||
|
switch(currentGame.system)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
strcpy(string, "data/resources_spirit.dat");
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
strcpy(string, "data/resources_eyananth.dat");
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
strcpy(string, "data/resources_mordor.dat");
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
strcpy(string, "data/resources_sol.dat");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
#if USEPACK
|
||||||
|
int dataLocation = locateDataInPak(string, 1);
|
||||||
|
fp = fopen(PACKLOCATION, "rb");
|
||||||
|
fseek(fp, dataLocation, SEEK_SET);
|
||||||
|
#else
|
||||||
|
fp = fopen(string, "rb");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (fp == NULL)
|
||||||
|
exit(1);
|
||||||
|
|
||||||
|
fscanf(fp, "%d %s", &index, string);
|
||||||
|
while (index != -1)
|
||||||
|
{
|
||||||
|
graphics.shipShape[index] = loadImage(string);
|
||||||
|
fscanf(fp, "%d %s", &index, string);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Overlay a red alpha surface onto
|
||||||
|
*/
|
||||||
|
SDL_Surface *hitRect;
|
||||||
|
for (int i = SHIP_HIT_INDEX ; i < MAX_SHIPSHAPES ; i++)
|
||||||
|
{
|
||||||
|
if (graphics.shipShape[i - SHIP_HIT_INDEX] == NULL)
|
||||||
|
continue;
|
||||||
|
graphics.shipShape[i] = graphics.createSurface(graphics.shipShape[i - SHIP_HIT_INDEX]->w, graphics.shipShape[i- SHIP_HIT_INDEX]->h);
|
||||||
|
graphics.blit(graphics.shipShape[i - SHIP_HIT_INDEX], 0, 0, graphics.shipShape[i]);
|
||||||
|
hitRect = graphics.alphaRect(graphics.shipShape[i]->w, graphics.shipShape[i]->h, 255, 0, 0);
|
||||||
|
graphics.blit(hitRect, 0, 0, graphics.shipShape[i]);
|
||||||
|
SDL_SetColorKey(graphics.shipShape[i], (SDL_SRCCOLORKEY|SDL_RLEACCEL), SDL_MapRGB(graphics.shipShape[i]->format, 127, 0, 0));
|
||||||
|
SDL_FreeSurface(hitRect);
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(string, "data/resources_all.dat");
|
||||||
|
|
||||||
|
#if USEPACK
|
||||||
|
dataLocation = locateDataInPak(string, 1);
|
||||||
|
fp = fopen(PACKLOCATION, "rb");
|
||||||
|
fseek(fp, dataLocation, SEEK_SET);
|
||||||
|
#else
|
||||||
|
fp = fopen(string, "rb");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fscanf(fp, "%d %s", &index, string);
|
||||||
|
while (index != -1)
|
||||||
|
{
|
||||||
|
graphics.shape[index] = loadImage(string);
|
||||||
|
fscanf(fp, "%d %s", &index, string);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
loadBackground((char *)systemBackground[currentGame.system]);
|
||||||
|
|
||||||
|
setAlienShapes();
|
||||||
|
|
||||||
|
setWeaponShapes();
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadSound()
|
||||||
|
{
|
||||||
|
sound[SFX_EXPLOSION] = loadSound("sound/explode.wav");
|
||||||
|
sound[SFX_HIT] = loadSound("sound/explode2.wav");
|
||||||
|
sound[SFX_DEATH] = loadSound("sound/maledeath.wav");
|
||||||
|
sound[SFX_MISSILE] = loadSound("sound/missile.wav");
|
||||||
|
sound[SFX_PLASMA] = loadSound("sound/plasma.wav");
|
||||||
|
sound[SFX_CLOCK] = loadSound("sound/clock.wav");
|
||||||
|
sound[SFX_FLY] = loadSound("sound/flyby.wav");
|
||||||
|
sound[SFX_ENERGYRAY] = loadSound("sound/beamLaser.wav");
|
||||||
|
sound[SFX_PICKUP] = loadSound("sound/item.wav");
|
||||||
|
sound[SFX_SHIELDUP] = loadSound("sound/shield.wav");
|
||||||
|
sound[SFX_CLOAK] = loadSound("sound/cloak.wav");
|
||||||
|
sound[SFX_DEBRIS] = loadSound("sound/explode3.wav");
|
||||||
|
sound[SFX_DEBRIS2] = loadSound("sound/explode4.wav");
|
||||||
|
sound[SFX_LASER] = loadSound("sound/laser.wav");
|
||||||
|
sound[SFX_PLASMA2] = loadSound("sound/plasma2.wav");
|
||||||
|
sound[SFX_PLASMA3] = loadSound("sound/plasma3.wav");
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeSound()
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < MAX_SOUNDS ; i++)
|
||||||
|
{
|
||||||
|
if (sound[i] != NULL)
|
||||||
|
Mix_FreeChunk(sound[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (engine.music != NULL)
|
||||||
|
Mix_FreeMusic(engine.music);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void setFontColor(SDL_Surface *image, int red, int green, int blue)
|
||||||
|
{
|
||||||
|
SDL_Color colors[256];
|
||||||
|
colors[0].r = 0;
|
||||||
|
colors[0].g = 0;
|
||||||
|
colors[0].b = 0;
|
||||||
|
for (int i = 1 ; i < 256 ; i++)
|
||||||
|
{
|
||||||
|
colors[i].r = red;
|
||||||
|
colors[i].g = green;
|
||||||
|
colors[i].b = blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_SetPalette(image, SDL_LOGPAL|SDL_PHYSPAL, colors, 0, 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Custom loading to alter the font color before doing
|
||||||
|
all other things
|
||||||
|
*/
|
||||||
|
void loadFont()
|
||||||
|
{
|
||||||
|
SDL_Surface *image, *newImage;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < MAX_FONTSHAPES ; i++)
|
||||||
|
{
|
||||||
|
#if USEPACK
|
||||||
|
unpack("gfx/smallFont.bmp", PAK_FONT);
|
||||||
|
image = IMG_Load_RW(engine.sdlrw, 1);
|
||||||
|
#else
|
||||||
|
image = IMG_Load("gfx/smallFont.bmp");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (image == NULL) {
|
||||||
|
printf("Couldn't load game font! (%s) Exitting.\n", SDL_GetError());
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
setFontColor(image, 255, 0, 0);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
setFontColor(image, 255, 255, 0);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
setFontColor(image, 0, 255, 0);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
setFontColor(image, 0, 255, 255);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
setFontColor(image, 0, 0, 10);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
newImage = SDL_DisplayFormat(image);
|
||||||
|
|
||||||
|
graphics.fontShape[i] = graphics.setTransparent(newImage);
|
||||||
|
|
||||||
|
SDL_FreeSurface(image);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern void unpack(char *file, signed char fileType);
|
||||||
|
extern SDL_Surface *loadImage(char *filename);
|
||||||
|
extern Mix_Chunk *loadSound(char *filename);
|
||||||
|
extern int locateDataInPak(char *file, signed char required);
|
||||||
|
extern void setAlienShapes();
|
||||||
|
extern void setWeaponShapes();
|
||||||
|
extern void loadGameGraphics();
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern object weapon[MAX_WEAPONS];
|
||||||
|
extern Mix_Chunk *sound[MAX_SOUNDS];
|
||||||
|
extern object enemy[MAX_ALIENS];
|
||||||
|
extern Graphics graphics;
|
||||||
|
extern Game currentGame;
|
|
@ -0,0 +1,312 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "script.h"
|
||||||
|
|
||||||
|
void setKlineGreeting()
|
||||||
|
{
|
||||||
|
char greet[][50] = {
|
||||||
|
"How nice to see you again, Bainfield!",
|
||||||
|
"It all ends here, rebel!",
|
||||||
|
"I hope you won't disappoint me this time...",
|
||||||
|
"Do you really think you can defeat us?!"
|
||||||
|
};
|
||||||
|
|
||||||
|
gameEvent[0].time = 2;
|
||||||
|
gameEvent[0].face = FACE_KLINE;
|
||||||
|
strcpy(gameEvent[0].message, greet[rand() % 4]);
|
||||||
|
gameEvent[0].entity = -1;
|
||||||
|
gameEvent[0].flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadScriptEvents()
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < 10 ; i++)
|
||||||
|
{
|
||||||
|
gameEvent[i].time = 0;
|
||||||
|
strcpy(gameEvent[i].message, "");
|
||||||
|
gameEvent[i].entity = -1;
|
||||||
|
gameEvent[i].flag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((currentGame.area == 27) && (enemy[WC_KLINE].classDef == CD_KLINE))
|
||||||
|
setKlineGreeting();
|
||||||
|
|
||||||
|
char filename[255];
|
||||||
|
strcpy(filename, "");
|
||||||
|
sprintf(filename, "data/script%d.txt", currentGame.area);
|
||||||
|
|
||||||
|
FILE *fp;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
int time, entity, flags;
|
||||||
|
char face[255], message[255];
|
||||||
|
|
||||||
|
#if USEPACK
|
||||||
|
int dataLocation = locateDataInPak(filename, 0);
|
||||||
|
if (dataLocation == -1)
|
||||||
|
return;
|
||||||
|
fp = fopen(PACKLOCATION, "rb");
|
||||||
|
fseek(fp, dataLocation, SEEK_SET);
|
||||||
|
#else
|
||||||
|
fp = fopen(filename, "rb");
|
||||||
|
if (fp == NULL)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fscanf(fp, "%d ", &time);
|
||||||
|
|
||||||
|
while (time != 0)
|
||||||
|
{
|
||||||
|
fscanf(fp, "%s %d %d ", face, &entity, &flags);
|
||||||
|
fscanf(fp, "%[^\n]%*c", message);
|
||||||
|
|
||||||
|
gameEvent[i].time = time;
|
||||||
|
gameEvent[i].face = getFace(face);
|
||||||
|
gameEvent[i].entity = entity;
|
||||||
|
gameEvent[i].flag = flags;
|
||||||
|
strcpy(gameEvent[i].message, message);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
fscanf(fp, "%d ", &time);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkScriptEvents()
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < 10 ; i++)
|
||||||
|
{
|
||||||
|
if (engine.timeTaken == gameEvent[i].time)
|
||||||
|
{
|
||||||
|
if (strcmp(gameEvent[i].message, "@none@") != 0)
|
||||||
|
{
|
||||||
|
setRadioMessage(gameEvent[i].face, gameEvent[i].message, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gameEvent[i].entity > -1)
|
||||||
|
{
|
||||||
|
if (gameEvent[i].flag != -FL_ACTIVATE)
|
||||||
|
{
|
||||||
|
enemy[gameEvent[i].entity].flags += gameEvent[i].flag;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
enemy[gameEvent[i].entity].active = 1;
|
||||||
|
enemy[gameEvent[i].entity].x = Math::rrand((int)player.x + 400, (int)player.x + 800);
|
||||||
|
enemy[gameEvent[i].entity].y = Math::rrand((int)player.y - 400, (int)player.y + 800);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gameEvent[i].time = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void syncScriptEvents()
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < 10 ; i++)
|
||||||
|
{
|
||||||
|
if (gameEvent[i].time < 0)
|
||||||
|
{
|
||||||
|
gameEvent[i].time = engine.timeTaken + abs(gameEvent[i].time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setScene(int scene)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char string[255], face[255];
|
||||||
|
float sx, sy, x, y, speed;
|
||||||
|
int index, shape;
|
||||||
|
|
||||||
|
strcpy(string, "");
|
||||||
|
sprintf(string, "data/cutscene%d.dat", scene);
|
||||||
|
|
||||||
|
#if USEPACK
|
||||||
|
int dataLocation = locateDataInPak(string, 1);
|
||||||
|
fp = fopen(PACKLOCATION, "rb");
|
||||||
|
fseek(fp, dataLocation, SEEK_SET);
|
||||||
|
#else
|
||||||
|
fp = fopen(string, "rb");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Load in the specified background
|
||||||
|
fscanf(fp, "%s", string);
|
||||||
|
loadBackground(string);
|
||||||
|
|
||||||
|
// Set the star speed
|
||||||
|
fscanf(fp, "%f %f", &sx, &sy);
|
||||||
|
engine.ssx = sx;
|
||||||
|
engine.ssy = sy;
|
||||||
|
|
||||||
|
// Read in the specs for each ship
|
||||||
|
for (int i = 0 ; i < 15 ; i++)
|
||||||
|
{
|
||||||
|
fscanf(fp, "%d %d %f %f %f", &index, &shape, &x, &y, &speed);
|
||||||
|
|
||||||
|
if (x < 0) x = (rand() % abs((int)x));
|
||||||
|
if (y < 0) y = (rand() % abs((int)y));
|
||||||
|
if (speed <= -1) speed = 1 + (rand() % abs((int)speed));
|
||||||
|
|
||||||
|
if (shape > -1)
|
||||||
|
{
|
||||||
|
enemy[index].image[0] = graphics.shipShape[shape];
|
||||||
|
enemy[index].x = x;
|
||||||
|
enemy[index].y = y;
|
||||||
|
enemy[index].dx = speed;
|
||||||
|
enemy[index].active = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// And finally read in the messages
|
||||||
|
for (int i = 0 ; i < 10 ; i++)
|
||||||
|
{
|
||||||
|
fscanf(fp, "%s%*c", face);
|
||||||
|
fscanf(fp, "%[^\n]", string);
|
||||||
|
|
||||||
|
if (strcmp(string, "@none@") == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
cutMessage[i].face = getFace(face);
|
||||||
|
strcpy(cutMessage[i].message, string);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void doCutscene(int scene)
|
||||||
|
{
|
||||||
|
graphics.clearScreen(graphics.black);
|
||||||
|
graphics.updateScreen();
|
||||||
|
graphics.clearScreen(graphics.black);
|
||||||
|
SDL_Delay(1000);
|
||||||
|
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = engine.keyState[SDLK_SPACE] = 0;
|
||||||
|
|
||||||
|
engine.ssx = -0.5;
|
||||||
|
engine.ssy = 0;
|
||||||
|
|
||||||
|
graphics.flushBuffer();
|
||||||
|
graphics.freeGraphics();
|
||||||
|
resetLists();
|
||||||
|
loadGameGraphics();
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 15 ; i++)
|
||||||
|
{
|
||||||
|
enemy[i] = defEnemy[0];
|
||||||
|
enemy[i].face = 0;
|
||||||
|
enemy[i].active = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 10 ; i++)
|
||||||
|
{
|
||||||
|
strcpy(cutMessage[i].message, "");
|
||||||
|
cutMessage[i].face = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
setScene(scene);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Because we can fiddle with the images, we need to set the engines to
|
||||||
|
the correct places on the craft. Otherwise it will look wrong
|
||||||
|
*/
|
||||||
|
for (int i = 0 ; i < 15 ; i++)
|
||||||
|
{
|
||||||
|
enemy[i].engineX = enemy[i].image[0]->w;
|
||||||
|
enemy[i].engineY = (enemy[i].image[0]->h / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long frameLimit = SDL_GetTicks();
|
||||||
|
signed char showMessage = 0;
|
||||||
|
signed char currentMessage = -1;
|
||||||
|
int timer = 60 * 4;
|
||||||
|
|
||||||
|
graphics.drawBackGround();
|
||||||
|
|
||||||
|
SDL_Surface *face;
|
||||||
|
|
||||||
|
flushInput();
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
graphics.updateScreen();
|
||||||
|
graphics.unBuffer();
|
||||||
|
getPlayerInput();
|
||||||
|
doStarfield();
|
||||||
|
doExplosions();
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 15 ; i++)
|
||||||
|
{
|
||||||
|
if (enemy[i].active)
|
||||||
|
{
|
||||||
|
addEngine(&enemy[i]);
|
||||||
|
enemy[i].x += enemy[i].dx;
|
||||||
|
enemy[i].x += engine.ssx;
|
||||||
|
graphics.blit(enemy[i].image[0], (int)enemy[i].x, (int)enemy[i].y);
|
||||||
|
if (enemy[i].x > 850)
|
||||||
|
{
|
||||||
|
enemy[i].x = -50;
|
||||||
|
enemy[i].y = rand() % 560;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
timer--;
|
||||||
|
if (timer == 0)
|
||||||
|
{
|
||||||
|
showMessage = 1 - showMessage;
|
||||||
|
timer = 120;
|
||||||
|
if (showMessage)
|
||||||
|
{
|
||||||
|
timer = 60 * 7;
|
||||||
|
currentMessage++;
|
||||||
|
|
||||||
|
if (currentMessage == 10)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (strcmp(cutMessage[currentMessage].message, "") == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
face = NULL;
|
||||||
|
if (cutMessage[currentMessage].face != -1)
|
||||||
|
face = graphics.shape[cutMessage[currentMessage].face];
|
||||||
|
graphics.createMessageBox(face, cutMessage[currentMessage].message, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((showMessage) && (graphics.messageBox != NULL))
|
||||||
|
graphics.blit(graphics.messageBox, (800 - graphics.messageBox->w) / 2, 500);
|
||||||
|
|
||||||
|
while (SDL_GetTicks() < (frameLimit + 16)){}
|
||||||
|
frameLimit = SDL_GetTicks();
|
||||||
|
|
||||||
|
if (engine.keyState[SDLK_ESCAPE])
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.flushBuffer();
|
||||||
|
graphics.freeGraphics();
|
||||||
|
graphics.clearScreen(graphics.black);
|
||||||
|
graphics.updateScreen();
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern void doStarfield();
|
||||||
|
extern void getPlayerInput();
|
||||||
|
extern void loadGameGraphics();
|
||||||
|
extern void loadBackground(char *filename);
|
||||||
|
extern void setRadioMessage(signed char face, char *in, int priority);
|
||||||
|
extern void doExplosions();
|
||||||
|
extern void addEngine(object *craft);
|
||||||
|
extern void doExplosions();
|
||||||
|
extern void resetLists();
|
||||||
|
extern int getFace(char *face);
|
||||||
|
extern int locateDataInPak(char *file, signed char required);
|
||||||
|
extern void flushInput();
|
||||||
|
|
||||||
|
extern Game currentGame;
|
||||||
|
extern object enemy[MAX_ALIENS];
|
||||||
|
extern object player;
|
||||||
|
extern object defEnemy[MAX_DEFALIENS];
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern Graphics graphics;
|
||||||
|
extern event gameEvent[10];
|
||||||
|
extern cutMsg cutMessage[10];
|
|
@ -0,0 +1,772 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "shop.h"
|
||||||
|
|
||||||
|
void drawSecondaryWeaponSurface()
|
||||||
|
{
|
||||||
|
char description[50];
|
||||||
|
strcpy(description, "");
|
||||||
|
|
||||||
|
graphics.drawString("Secondary Weapon", 10, 3, FONT_WHITE, graphics.shopSurface[2]);
|
||||||
|
|
||||||
|
switch (player.weaponType[1])
|
||||||
|
{
|
||||||
|
case W_NONE:
|
||||||
|
strcpy(description, "Type : None");
|
||||||
|
break;
|
||||||
|
case W_ROCKETS:
|
||||||
|
strcpy(description, "Type : Rockets");
|
||||||
|
break;
|
||||||
|
case W_DOUBLE_ROCKETS:
|
||||||
|
strcpy(description, "Type : Dbl Rockets");
|
||||||
|
break;
|
||||||
|
case W_MICRO_ROCKETS:
|
||||||
|
strcpy(description, "Type : Micro Rockets");
|
||||||
|
break;
|
||||||
|
case W_LASER:
|
||||||
|
strcpy(description, "Type : Laser");
|
||||||
|
break;
|
||||||
|
case W_CHARGER:
|
||||||
|
strcpy(description, "Type : Charger");
|
||||||
|
break;
|
||||||
|
case W_HOMING_MISSILE:
|
||||||
|
strcpy(description, "Type : Homing Missile");
|
||||||
|
break;
|
||||||
|
case W_DOUBLE_HOMING_MISSILES:
|
||||||
|
strcpy(description, "Type : Dbl Homing Missiles");
|
||||||
|
break;
|
||||||
|
case W_MICRO_HOMING_MISSILES:
|
||||||
|
strcpy(description, "Type : Mcr Homing Missiles");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
graphics.drawString(description, 10, 22, FONT_WHITE, graphics.shopSurface[2]);
|
||||||
|
|
||||||
|
if ((player.weaponType[1] != W_LASER) && (player.weaponType[1] != W_CHARGER) && (player.weaponType[1] != W_NONE))
|
||||||
|
{
|
||||||
|
sprintf(description, "Capacity : %d", currentGame.maxRocketAmmo);
|
||||||
|
graphics.drawString(description, 10, 37, FONT_WHITE, graphics.shopSurface[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void adjustShopPrices()
|
||||||
|
{
|
||||||
|
shopItems[0].price = (500 * currentGame.maxPlasmaOutput);
|
||||||
|
shopItems[1].price = (500 * currentGame.maxPlasmaDamage);
|
||||||
|
shopItems[2].price = (500 * (16 - currentGame.maxPlasmaRate));
|
||||||
|
|
||||||
|
shopItems[5].price = (2000 * weapon[0].ammo[0]);
|
||||||
|
shopItems[6].price = (2000 * weapon[0].damage);
|
||||||
|
shopItems[7].price = (2000 * (16 - weapon[0].reload[0]));
|
||||||
|
|
||||||
|
shopItems[8].price = (5 * currentGame.maxPlasmaAmmo);
|
||||||
|
shopItems[9].price = (25 * currentGame.maxRocketAmmo);
|
||||||
|
|
||||||
|
if (currentGame.maxPlasmaOutput == 5)
|
||||||
|
shopItems[0].price = 0;
|
||||||
|
|
||||||
|
if (currentGame.maxPlasmaDamage == 5)
|
||||||
|
shopItems[1].price = 0;
|
||||||
|
|
||||||
|
if (currentGame.maxPlasmaRate == 7)
|
||||||
|
shopItems[2].price = 0;
|
||||||
|
|
||||||
|
if (weapon[0].ammo[0] == 3)
|
||||||
|
shopItems[5].price = 0;
|
||||||
|
|
||||||
|
if (weapon[0].damage == 3)
|
||||||
|
shopItems[6].price = 0;
|
||||||
|
|
||||||
|
if (weapon[0].reload[0] == 11)
|
||||||
|
shopItems[7].price = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void drawShop()
|
||||||
|
{
|
||||||
|
adjustShopPrices();
|
||||||
|
|
||||||
|
for (int i = 0 ; i < MAX_SHOPSHAPES ; i++)
|
||||||
|
{
|
||||||
|
if (graphics.shopSurface[i] != NULL)
|
||||||
|
{
|
||||||
|
SDL_FreeSurface(graphics.shopSurface[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 3 ; i++)
|
||||||
|
graphics.shopSurface[i] = graphics.createSurface(246, 91);
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 3 ; i++)
|
||||||
|
{
|
||||||
|
graphics.blevelRect(graphics.shopSurface[i], 0, 0, 245, 90, 0x00, 0x00, 0x55);
|
||||||
|
graphics.blevelRect(graphics.shopSurface[i], 0, 0, 245, 20, 0x00, 0x00, 0x99);
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.shopSurface[4] = graphics.alphaRect(601, 101, 0x00, 0x00, 0x00);
|
||||||
|
graphics.blevelRect(graphics.shopSurface[4], 0, 0, 600, 100, 0x00, 0x00, 0x33);
|
||||||
|
|
||||||
|
switch (shopSelectedItem)
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
case -2:
|
||||||
|
case -3:
|
||||||
|
case -4:
|
||||||
|
case -5:
|
||||||
|
case -6:
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 8:
|
||||||
|
graphics.blevelRect(graphics.shopSurface[1], 0, 0, 245, 90, 0x55, 0x00, 0x00);
|
||||||
|
graphics.blevelRect(graphics.shopSurface[1], 0, 0, 245, 20, 0x99, 0x00, 0x00);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
graphics.blevelRect(graphics.shopSurface[4], 0, 0, 600, 100, 0x33, 0x00, 0x00);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
case 6:
|
||||||
|
case 7:
|
||||||
|
graphics.blevelRect(graphics.shopSurface[0], 0, 0, 245, 90, 0x55, 0x00, 0x00);
|
||||||
|
graphics.blevelRect(graphics.shopSurface[0], 0, 0, 245, 20, 0x99, 0x00, 0x00);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
graphics.blevelRect(graphics.shopSurface[2], 0, 0, 245, 90, 0x55, 0x00, 0x00);
|
||||||
|
graphics.blevelRect(graphics.shopSurface[2], 0, 0, 245, 20, 0x99, 0x00, 0x00);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
char description[100];
|
||||||
|
strcpy(description, "");
|
||||||
|
|
||||||
|
graphics.drawString("Primary Weapon", 10, 3, FONT_WHITE, graphics.shopSurface[0]);
|
||||||
|
sprintf(description, "Plasma Cannons : %d", weapon[0].ammo[0]);
|
||||||
|
graphics.drawString(description, 10, 22, FONT_WHITE, graphics.shopSurface[0]);
|
||||||
|
sprintf(description, "Plasma Power : Stage %d", weapon[0].damage);
|
||||||
|
graphics.drawString(description, 10, 37, FONT_WHITE, graphics.shopSurface[0]);
|
||||||
|
sprintf(description, "Cooler : Stage %d", ((15 - weapon[0].reload[0]) / 2) + 1);
|
||||||
|
graphics.drawString(description, 10, 52, FONT_WHITE, graphics.shopSurface[0]);
|
||||||
|
|
||||||
|
graphics.drawString("Powerup Weapon", 10, 3, FONT_WHITE, graphics.shopSurface[1]);
|
||||||
|
sprintf(description, "Plasma Output : Stage %d", currentGame.maxPlasmaOutput);
|
||||||
|
graphics.drawString(description, 10, 22, FONT_WHITE, graphics.shopSurface[1]);
|
||||||
|
sprintf(description, "Plasma Condensor : Stage %d", currentGame.maxPlasmaDamage);
|
||||||
|
graphics.drawString(description, 10, 37, FONT_WHITE, graphics.shopSurface[1]);
|
||||||
|
sprintf(description, "Liquid Nitrogen : Stage %d", ((15 - currentGame.maxPlasmaRate) / 2) + 1);
|
||||||
|
graphics.drawString(description, 10, 52, FONT_WHITE, graphics.shopSurface[1]);
|
||||||
|
sprintf(description, "Plasma Capacity : %d", currentGame.maxPlasmaAmmo);
|
||||||
|
graphics.drawString(description, 10, 67, FONT_WHITE, graphics.shopSurface[1]);
|
||||||
|
|
||||||
|
drawSecondaryWeaponSurface();
|
||||||
|
|
||||||
|
graphics.shopSurface[3] = graphics.createSurface(601, 121);
|
||||||
|
|
||||||
|
graphics.blevelRect(graphics.shopSurface[3], 0, 0, 600, 120, 0x00, 0x00, 0x22);
|
||||||
|
|
||||||
|
graphics.drawString("Temporary Weapons", 10, 2, FONT_WHITE, graphics.shopSurface[3]);
|
||||||
|
graphics.drawString("Ammo and Storage", 260, 2, FONT_WHITE, graphics.shopSurface[3]);
|
||||||
|
|
||||||
|
graphics.drawString("Primary Weapons", 10, 62, FONT_WHITE, graphics.shopSurface[3]);
|
||||||
|
|
||||||
|
graphics.drawString("Secondary Weapons", 260, 62, FONT_WHITE, graphics.shopSurface[3]);
|
||||||
|
|
||||||
|
signed char icons = MAX_SHOPITEMS;
|
||||||
|
|
||||||
|
if (currentGame.system == 0)
|
||||||
|
icons = 11;
|
||||||
|
else if (currentGame.system == 1)
|
||||||
|
icons = 13;
|
||||||
|
else if (currentGame.system == 2)
|
||||||
|
icons = 15;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < icons ; i++)
|
||||||
|
graphics.blit(graphics.shape[shopItems[i].image], shopItems[i].x - 90, shopItems[i].y - 178, graphics.shopSurface[3]);
|
||||||
|
|
||||||
|
sprintf(description, "Shield Units : %d", currentGame.shieldUnits * 25);
|
||||||
|
graphics.drawString(description, 10, 4, FONT_WHITE, graphics.shopSurface[4]);
|
||||||
|
sprintf(description, "Cash : $%d", currentGame.cash);
|
||||||
|
graphics.drawString(description, 10, 80, FONT_WHITE, graphics.shopSurface[4]);
|
||||||
|
sprintf(description, "Plasma Cells : %.3d", player.ammo[0]);
|
||||||
|
graphics.drawString(description, 430, 4, FONT_WHITE, graphics.shopSurface[4]);
|
||||||
|
sprintf(description, "Rockets : %.3d", player.ammo[1]);
|
||||||
|
graphics.drawString(description, 475, 80, FONT_WHITE, graphics.shopSurface[4]);
|
||||||
|
|
||||||
|
graphics.shopSurface[5] = graphics.createSurface(601, 56);
|
||||||
|
graphics.blevelRect(graphics.shopSurface[5], 0, 0, 600, 35, 0x00, 0x99, 0x00);
|
||||||
|
graphics.blevelRect(graphics.shopSurface[5], 0, 20, 600, 35, 0x00, 0x33, 0x00);
|
||||||
|
graphics.drawString("Information", 5, 4, FONT_WHITE, graphics.shopSurface[5]);
|
||||||
|
|
||||||
|
switch (shopSelectedItem)
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
break;
|
||||||
|
case -2:
|
||||||
|
graphics.drawString("You don't have enough money", 20, 30, FONT_WHITE, graphics.shopSurface[5]);
|
||||||
|
break;
|
||||||
|
case -3:
|
||||||
|
graphics.drawString("Cannot upgrade ship", 5, 22, FONT_WHITE, graphics.shopSurface[5]);
|
||||||
|
graphics.drawString("Hardware capacity has been reached", 20, 38, FONT_CYAN, graphics.shopSurface[5]);
|
||||||
|
break;
|
||||||
|
case -4:
|
||||||
|
graphics.drawString("Ammunition limit reached", 20, 30, FONT_WHITE, graphics.shopSurface[5]);
|
||||||
|
break;
|
||||||
|
case -5:
|
||||||
|
graphics.drawString("You cannot sell that item", 20, 30, FONT_WHITE, graphics.shopSurface[5]);
|
||||||
|
break;
|
||||||
|
case -6:
|
||||||
|
graphics.drawString("Nothing to sell", 20, 30, FONT_WHITE, graphics.shopSurface[5]);
|
||||||
|
break;
|
||||||
|
case -7:
|
||||||
|
graphics.drawString("Rockets cannot be bought for Laser or Charger Cannon", 5, 30, FONT_WHITE, graphics.shopSurface[5]);
|
||||||
|
break;
|
||||||
|
case -8:
|
||||||
|
graphics.drawString("You already have that weapon", 20, 30, FONT_WHITE, graphics.shopSurface[5]);
|
||||||
|
break;
|
||||||
|
case -9:
|
||||||
|
graphics.drawString("This weapon's ammo limit has been reached", 20, 30, FONT_WHITE, graphics.shopSurface[5]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (shopItems[shopSelectedItem].price != 0)
|
||||||
|
{
|
||||||
|
sprintf(description, "%s ($%d)", shopItems[shopSelectedItem].description, shopItems[shopSelectedItem].price);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(description, "%s (N/A)", shopItems[shopSelectedItem].description);
|
||||||
|
}
|
||||||
|
graphics.drawString(shopItems[shopSelectedItem].name, 5, 22, FONT_WHITE, graphics.shopSurface[5]);
|
||||||
|
graphics.drawString(description, 20, 38, FONT_CYAN, graphics.shopSurface[5]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if USEPACK
|
||||||
|
|
||||||
|
void loadShop()
|
||||||
|
{
|
||||||
|
char name[255], description[255];
|
||||||
|
int price, image, x, y;
|
||||||
|
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
#if USEPACK
|
||||||
|
int dataLocation = locateDataInPak("data/shop.dat", 1);
|
||||||
|
fp = fopen(PACKLOCATION, "rb");
|
||||||
|
fseek(fp, dataLocation, SEEK_SET);
|
||||||
|
#else
|
||||||
|
fp = fopen("data/shop.dat", "rb");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (int i = 0 ; i < MAX_SHOPITEMS ; i++)
|
||||||
|
{
|
||||||
|
fscanf(fp, "%[^\n]%*c", name);
|
||||||
|
fscanf(fp, "%[^\n]%*c", description);
|
||||||
|
fscanf(fp, "%d", &price);
|
||||||
|
fscanf(fp, "%d", &image);
|
||||||
|
fscanf(fp, "%d", &x);
|
||||||
|
fscanf(fp, "%d%*c", &y);
|
||||||
|
|
||||||
|
strcpy(shopItems[i].name, name);
|
||||||
|
strcpy(shopItems[i].description, description);
|
||||||
|
shopItems[i].price = price;
|
||||||
|
shopItems[i].image = image;
|
||||||
|
shopItems[i].x = x;
|
||||||
|
shopItems[i].y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
shopSelectedItem = -1;
|
||||||
|
|
||||||
|
player.image[0] = graphics.shape[0];
|
||||||
|
player.x = 380;
|
||||||
|
player.y = 95;
|
||||||
|
|
||||||
|
drawShop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void initShop(){loadShop();}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void saveShop()
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
fp = fopen("data/shop.dat", "wb");
|
||||||
|
if (fp == NULL)
|
||||||
|
{
|
||||||
|
printf("Unable to write Shop Data File\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < MAX_SHOPITEMS ; i++)
|
||||||
|
{
|
||||||
|
fprintf(fp, "%s\n", shopItems[i].name);
|
||||||
|
fprintf(fp, "%s\n", shopItems[i].description);
|
||||||
|
fprintf(fp, "%d ", shopItems[i].price);
|
||||||
|
fprintf(fp, "%d ", shopItems[i].image);
|
||||||
|
fprintf(fp, "%d ", shopItems[i].x);
|
||||||
|
fprintf(fp, "%d\n", shopItems[i].y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put an extra line for the PAK file "just in case"
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Throw into a data file in final build
|
||||||
|
*/
|
||||||
|
void initShop()
|
||||||
|
{
|
||||||
|
/* ----------- Temporary Items ----------- */
|
||||||
|
|
||||||
|
shopItems[0].price = 1000;
|
||||||
|
strcpy(shopItems[0].name, "Plasma channel splitter");
|
||||||
|
strcpy(shopItems[0].description, "Improves poweredup plasma output");
|
||||||
|
shopItems[0].image = 9;
|
||||||
|
|
||||||
|
shopItems[1].price = 1000;
|
||||||
|
strcpy(shopItems[1].name, "Plasma capacity condensor");
|
||||||
|
strcpy(shopItems[1].description, "Increases poweredup plasma damage");
|
||||||
|
shopItems[1].image = 10;
|
||||||
|
|
||||||
|
shopItems[2].price = 1000;
|
||||||
|
strcpy(shopItems[2].name, "Liquid nitrogen capsules");
|
||||||
|
strcpy(shopItems[2].description, "Increases plasma firing rate");
|
||||||
|
shopItems[2].image = 11;
|
||||||
|
|
||||||
|
shopItems[3].price = 50;
|
||||||
|
strcpy(shopItems[3].name, "10 Plasma cells");
|
||||||
|
strcpy(shopItems[3].description, "Plasma ammunition");
|
||||||
|
shopItems[3].image = 12;
|
||||||
|
|
||||||
|
shopItems[4].price = 50;
|
||||||
|
strcpy(shopItems[4].name, "Rocket Ammo");
|
||||||
|
strcpy(shopItems[4].description, "High velocity dumb fire rocket");
|
||||||
|
shopItems[4].image = 13;
|
||||||
|
|
||||||
|
/* ----------- Permanent Items ----------- */
|
||||||
|
|
||||||
|
shopItems[5].price = 2000;
|
||||||
|
strcpy(shopItems[5].name, "Additional Plasma Cannon");
|
||||||
|
strcpy(shopItems[5].description, "Adds an extra plasma cannon to the Firefly");
|
||||||
|
shopItems[5].image = 14;
|
||||||
|
|
||||||
|
shopItems[6].price = 2000;
|
||||||
|
strcpy(shopItems[6].name, "Plasma Power Booster");
|
||||||
|
strcpy(shopItems[6].description, "Increases power of plasma shots");
|
||||||
|
shopItems[6].image = 15;
|
||||||
|
|
||||||
|
shopItems[7].price = 2000;
|
||||||
|
strcpy(shopItems[7].name, "Plasma Cooling Booster");
|
||||||
|
strcpy(shopItems[7].description, "Permanently increases firing rate");
|
||||||
|
shopItems[7].image = 16;
|
||||||
|
|
||||||
|
/* ----------- Ammo Items -------------- */
|
||||||
|
|
||||||
|
shopItems[8].price = 250;
|
||||||
|
strcpy(shopItems[8].name, "Plasma compressor");
|
||||||
|
strcpy(shopItems[8].description, "Increases plasma ammo capacity");
|
||||||
|
shopItems[8].image = 17;
|
||||||
|
|
||||||
|
shopItems[9].price = 250;
|
||||||
|
strcpy(shopItems[9].name, "Rocket Pod");
|
||||||
|
strcpy(shopItems[9].description, "Allows for an additional 5 rockets to be carried");
|
||||||
|
shopItems[9].image = 18;
|
||||||
|
|
||||||
|
/* ---------- Weaponary --------------- */
|
||||||
|
|
||||||
|
shopItems[10].price = 2000;
|
||||||
|
strcpy(shopItems[10].name, "Dual Rocket Launcher");
|
||||||
|
strcpy(shopItems[10].description, "Allows for two rockets to be fired at once");
|
||||||
|
shopItems[10].image = 19;
|
||||||
|
|
||||||
|
shopItems[11].price = 2500;
|
||||||
|
strcpy(shopItems[11].name, "Micro Rocket Launcher");
|
||||||
|
strcpy(shopItems[11].description, "Launches several less powerful rockets at once");
|
||||||
|
shopItems[11].image = 20;
|
||||||
|
|
||||||
|
shopItems[12].price = 5000;
|
||||||
|
strcpy(shopItems[12].name, "Laser Cannon");
|
||||||
|
strcpy(shopItems[12].description, "Laser Cannon");
|
||||||
|
shopItems[12].image = 21;
|
||||||
|
|
||||||
|
shopItems[13].price = 7500;
|
||||||
|
strcpy(shopItems[13].name, "Homing Missile Launcher");
|
||||||
|
strcpy(shopItems[13].description, "Fires homing missile");
|
||||||
|
shopItems[13].image = 22;
|
||||||
|
|
||||||
|
shopItems[14].price = 10000;
|
||||||
|
strcpy(shopItems[14].name, "Charge Cannon");
|
||||||
|
strcpy(shopItems[14].description, "A charge up cannon");
|
||||||
|
shopItems[14].image = 23;
|
||||||
|
|
||||||
|
shopItems[15].price = 20000;
|
||||||
|
strcpy(shopItems[15].name, "Dual Homing Missile Launcher");
|
||||||
|
strcpy(shopItems[15].description, "Fires two homing missiles");
|
||||||
|
shopItems[15].image = 24;
|
||||||
|
|
||||||
|
shopItems[16].price = 25000;
|
||||||
|
strcpy(shopItems[16].name, "Homing Micro Missile Launcher");
|
||||||
|
strcpy(shopItems[16].description, "Fires several small homing missiles");
|
||||||
|
shopItems[16].image = 25;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 3 ; i++)
|
||||||
|
{
|
||||||
|
shopItems[i].x = 100 + (i * 50);
|
||||||
|
shopItems[i].y = 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
shopItems[3].x = 350;
|
||||||
|
shopItems[3].y = 200;
|
||||||
|
|
||||||
|
shopItems[4].x = 400;
|
||||||
|
shopItems[4].y = 200;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 3 ; i++)
|
||||||
|
{
|
||||||
|
shopItems[i + 5].x = 100 + (i * 50);
|
||||||
|
shopItems[i + 5].y = 260;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 2 ; i++)
|
||||||
|
{
|
||||||
|
shopItems[i + 8].x = 450 + (i * 50);
|
||||||
|
shopItems[i + 8].y = 200;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 8 ; i++)
|
||||||
|
{
|
||||||
|
shopItems[i + 10].x = 350 + (i * 50);
|
||||||
|
shopItems[i + 10].y = 260;
|
||||||
|
}
|
||||||
|
|
||||||
|
shopSelectedItem = -1;
|
||||||
|
|
||||||
|
player.image[0] = graphics.shape[0];
|
||||||
|
player.x = 380;
|
||||||
|
player.y = 95;
|
||||||
|
|
||||||
|
saveShop();
|
||||||
|
|
||||||
|
drawShop();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void buy(int i)
|
||||||
|
{
|
||||||
|
if ((currentGame.cash < shopItems[i].price) && (!engine.cheatCash))
|
||||||
|
{
|
||||||
|
shopSelectedItem = -2;
|
||||||
|
drawShop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(i)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if (currentGame.maxPlasmaOutput == 5)
|
||||||
|
{shopSelectedItem = -3; return;}
|
||||||
|
currentGame.maxPlasmaOutput++;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (currentGame.maxPlasmaDamage == 5)
|
||||||
|
{shopSelectedItem = -3; return;}
|
||||||
|
currentGame.maxPlasmaDamage++;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (currentGame.maxPlasmaRate == 7)
|
||||||
|
{shopSelectedItem = -3; return;}
|
||||||
|
currentGame.maxPlasmaRate -= 2;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if (player.ammo[0] == currentGame.maxPlasmaAmmo)
|
||||||
|
{shopSelectedItem = -4; return;}
|
||||||
|
Math::limitChar(&(player.ammo[0] += 10), 0, currentGame.maxPlasmaAmmo);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if ((player.weaponType[1] == W_CHARGER) || (player.weaponType[1] == W_LASER))
|
||||||
|
{shopSelectedItem = -7; return;}
|
||||||
|
if (player.ammo[1] == currentGame.maxRocketAmmo)
|
||||||
|
{shopSelectedItem = -4; return;}
|
||||||
|
if ((player.weaponType[1] == W_HOMING_MISSILE) && (player.ammo[1] == 20))
|
||||||
|
{shopSelectedItem = -9; return;}
|
||||||
|
if ((player.weaponType[1] == W_DOUBLE_HOMING_MISSILES) && (player.ammo[1] == 10))
|
||||||
|
{shopSelectedItem = -9; return;}
|
||||||
|
if ((player.weaponType[1] == W_MICRO_HOMING_MISSILES) && (player.ammo[1] == 10))
|
||||||
|
{shopSelectedItem = -9; return;}
|
||||||
|
player.ammo[1]++;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
if (weapon[0].ammo[0] == 3)
|
||||||
|
{shopSelectedItem = -3; return;}
|
||||||
|
weapon[0].ammo[0]++;
|
||||||
|
if (currentGame.maxPlasmaOutput < weapon[0].ammo[0])
|
||||||
|
currentGame.maxPlasmaOutput = weapon[0].ammo[0];
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
if (weapon[0].damage == 3)
|
||||||
|
{shopSelectedItem = -3; return;}
|
||||||
|
weapon[0].damage++;
|
||||||
|
if (currentGame.maxPlasmaDamage < weapon[0].damage)
|
||||||
|
currentGame.maxPlasmaDamage = weapon[0].damage;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
if (weapon[0].reload[0] == 11)
|
||||||
|
{shopSelectedItem = -3; return;}
|
||||||
|
weapon[0].reload[0] -= 2;
|
||||||
|
if (currentGame.maxPlasmaRate > weapon[0].reload[0])
|
||||||
|
currentGame.maxPlasmaRate = weapon[0].reload[0];
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
if (currentGame.maxPlasmaAmmo == 250)
|
||||||
|
{shopSelectedItem = -3; return;}
|
||||||
|
Math::limitChar(&(currentGame.maxPlasmaAmmo += 10), 0, 250);
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
if ((player.weaponType[1] == W_CHARGER) || (player.weaponType[1] == W_LASER))
|
||||||
|
{shopSelectedItem = -7; return;}
|
||||||
|
if (currentGame.maxRocketAmmo == 50)
|
||||||
|
{shopSelectedItem = -3; return;}
|
||||||
|
currentGame.maxRocketAmmo += 5;
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
if (player.weaponType[1] == W_DOUBLE_ROCKETS)
|
||||||
|
{shopSelectedItem = -8; return;}
|
||||||
|
player.weaponType[1] = W_DOUBLE_ROCKETS;
|
||||||
|
shopSelectedItem = -1;
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
if (player.weaponType[1] == W_MICRO_ROCKETS)
|
||||||
|
{shopSelectedItem = -8; return;}
|
||||||
|
player.weaponType[1] = W_MICRO_ROCKETS;
|
||||||
|
shopSelectedItem = -1;
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
if (player.weaponType[1] == W_LASER)
|
||||||
|
{shopSelectedItem = -8; return;}
|
||||||
|
player.weaponType[1] = W_LASER;
|
||||||
|
player.ammo[1] = 0;
|
||||||
|
shopSelectedItem = -1;
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
if (player.weaponType[1] == W_HOMING_MISSILE)
|
||||||
|
{shopSelectedItem = -8; return;}
|
||||||
|
player.weaponType[1] = W_HOMING_MISSILE;
|
||||||
|
Math::limitChar(&player.ammo[1], 0, 20);
|
||||||
|
shopSelectedItem = -1;
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
if (player.weaponType[1] == W_CHARGER)
|
||||||
|
{shopSelectedItem = -8; return;}
|
||||||
|
player.weaponType[1] = W_CHARGER;
|
||||||
|
player.ammo[1] = 0;
|
||||||
|
shopSelectedItem = -1;
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
if (player.weaponType[1] == W_DOUBLE_HOMING_MISSILES)
|
||||||
|
{shopSelectedItem = -8; return;}
|
||||||
|
player.weaponType[1] = W_DOUBLE_HOMING_MISSILES;
|
||||||
|
Math::limitChar(&player.ammo[1], 0, 10);
|
||||||
|
shopSelectedItem = -1;
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
if (player.weaponType[1] == W_MICRO_HOMING_MISSILES)
|
||||||
|
{shopSelectedItem = -8; return;}
|
||||||
|
player.weaponType[1] = W_MICRO_HOMING_MISSILES;
|
||||||
|
Math::limitChar(&player.ammo[1], 0, 10);
|
||||||
|
shopSelectedItem = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!engine.cheatCash)
|
||||||
|
currentGame.cash -= shopItems[i].price;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sell(int i)
|
||||||
|
{
|
||||||
|
switch (i)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if (currentGame.maxPlasmaOutput == 2)
|
||||||
|
{shopSelectedItem = -5; return;}
|
||||||
|
currentGame.maxPlasmaOutput--;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (currentGame.maxPlasmaDamage == 2)
|
||||||
|
{shopSelectedItem = -5; return;}
|
||||||
|
currentGame.maxPlasmaDamage--;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (currentGame.maxPlasmaRate == 13)
|
||||||
|
{shopSelectedItem = -5; return;}
|
||||||
|
currentGame.maxPlasmaRate += 2;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if (player.ammo[0] == 0)
|
||||||
|
{shopSelectedItem = -6; return;}
|
||||||
|
if (player.ammo[0] > 9)
|
||||||
|
Math::limitChar(&(player.ammo[0] -= 10), 0, currentGame.maxPlasmaAmmo);
|
||||||
|
else
|
||||||
|
player.ammo[0] = 0;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
if (player.ammo[1] == 0)
|
||||||
|
{shopSelectedItem = -6; return;}
|
||||||
|
player.ammo[1]--;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
if (weapon[0].ammo[0] == 1)
|
||||||
|
{shopSelectedItem = -5; return;}
|
||||||
|
weapon[0].ammo[0]--;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
if (weapon[0].damage == 1)
|
||||||
|
{shopSelectedItem = -5; return;}
|
||||||
|
weapon[0].damage--;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
if (weapon[0].reload[0] == 15)
|
||||||
|
{shopSelectedItem = -5; return;}
|
||||||
|
weapon[0].reload[0] += 2;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
if (currentGame.maxPlasmaAmmo == 100)
|
||||||
|
{shopSelectedItem = -1; return;}
|
||||||
|
currentGame.maxPlasmaAmmo -= 10;
|
||||||
|
Math::limitChar(&player.ammo[0], 0, currentGame.maxPlasmaAmmo);
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
if (currentGame.maxRocketAmmo == 0)
|
||||||
|
{shopSelectedItem = -1; return;}
|
||||||
|
currentGame.maxRocketAmmo -= 5;
|
||||||
|
Math::limitChar(&player.ammo[1], 0, currentGame.maxRocketAmmo);
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
if (player.weaponType[1] != W_DOUBLE_ROCKETS)
|
||||||
|
{shopSelectedItem = -1; return;}
|
||||||
|
player.weaponType[1] = W_NONE;
|
||||||
|
shopSelectedItem = -1;
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
if (player.weaponType[1] != W_MICRO_ROCKETS)
|
||||||
|
{shopSelectedItem = -1; return;}
|
||||||
|
player.weaponType[1] = W_NONE;
|
||||||
|
shopSelectedItem = -1;
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
if (player.weaponType[1] != W_LASER)
|
||||||
|
{shopSelectedItem = -1; return;}
|
||||||
|
player.weaponType[1] = W_NONE;
|
||||||
|
player.ammo[1] = 0;
|
||||||
|
shopSelectedItem = -1;
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
if (player.weaponType[1] != W_HOMING_MISSILE)
|
||||||
|
{shopSelectedItem = -1; return;}
|
||||||
|
player.weaponType[1] = W_NONE;
|
||||||
|
shopSelectedItem = -1;
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
if (player.weaponType[1] != W_CHARGER)
|
||||||
|
{shopSelectedItem = -1; return;}
|
||||||
|
player.weaponType[1] = W_NONE;
|
||||||
|
player.ammo[1] = 0;
|
||||||
|
shopSelectedItem = -1;
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
if (player.weaponType[1] != W_DOUBLE_HOMING_MISSILES)
|
||||||
|
{shopSelectedItem = -1; return;}
|
||||||
|
player.weaponType[1] = W_NONE;
|
||||||
|
shopSelectedItem = -1;
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
if (player.weaponType[1] != W_MICRO_HOMING_MISSILES)
|
||||||
|
{shopSelectedItem = -1; return;}
|
||||||
|
player.weaponType[1] = W_NONE;
|
||||||
|
shopSelectedItem = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentGame.cash += (shopItems[i].price / 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void showShop()
|
||||||
|
{
|
||||||
|
graphics.blit(graphics.shopSurface[0], 20, 395);
|
||||||
|
graphics.blit(graphics.shopSurface[1], 275, 395);
|
||||||
|
graphics.blit(graphics.shopSurface[2], 530, 395);
|
||||||
|
graphics.blit(graphics.shopSurface[3], 100, 180);
|
||||||
|
graphics.blit(graphics.shopSurface[4], 100, 50);
|
||||||
|
graphics.blit(graphics.shopSurface[5], 100, 320);
|
||||||
|
|
||||||
|
if (shopSelectedItem > -1)
|
||||||
|
{
|
||||||
|
graphics.blit(graphics.shape[27], 60, 350);
|
||||||
|
graphics.blit(graphics.shape[28], 710, 350);
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics.blit(graphics.shape[29], (int)player.x, (int)player.y);
|
||||||
|
|
||||||
|
signed char icons = MAX_SHOPITEMS;
|
||||||
|
|
||||||
|
if (currentGame.system == 0)
|
||||||
|
icons = 11;
|
||||||
|
else if (currentGame.system == 1)
|
||||||
|
icons = 13;
|
||||||
|
else if (currentGame.system == 2)
|
||||||
|
icons = 15;
|
||||||
|
|
||||||
|
if ((engine.keyState[SDLK_LCTRL]) || (engine.keyState[SDLK_RCTRL]))
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < icons ; i++)
|
||||||
|
{
|
||||||
|
if (Collision::collision(engine.cursor_x + 13, engine.cursor_y + 13, 6, 6, shopItems[i].x, shopItems[i].y, 32, 25))
|
||||||
|
{
|
||||||
|
shopSelectedItem = i;
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = 0;
|
||||||
|
drawShop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shopSelectedItem > -1)
|
||||||
|
{
|
||||||
|
if (Collision::collision(engine.cursor_x + 13, engine.cursor_y + 13, 6, 6, 60, 350, 24, 16))
|
||||||
|
{
|
||||||
|
buy(shopSelectedItem);
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = 0;
|
||||||
|
drawShop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Collision::collision(engine.cursor_x + 13, engine.cursor_y + 13, 6, 6, 700, 350, 24, 16))
|
||||||
|
{
|
||||||
|
sell(shopSelectedItem);
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = 0;
|
||||||
|
drawShop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern int locateDataInPak(char *file, signed char required);
|
||||||
|
|
||||||
|
extern object player;
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern object weapon[MAX_WEAPONS];
|
||||||
|
extern Game currentGame;
|
||||||
|
extern Graphics graphics;
|
||||||
|
extern devVariables dev;
|
||||||
|
extern ShopItem shopItems[MAX_SHOPITEMS];
|
||||||
|
|
||||||
|
signed char shopSelectedItem;
|
||||||
|
|
|
@ -0,0 +1,306 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct object {
|
||||||
|
|
||||||
|
signed char active;
|
||||||
|
signed char classDef; // Used by aliens to determine what they are
|
||||||
|
signed char AIType; // Type of articifial intelligence
|
||||||
|
|
||||||
|
signed char id; // The "job" of the object
|
||||||
|
object *target; // index target in enemy array
|
||||||
|
|
||||||
|
signed char reload[2];
|
||||||
|
|
||||||
|
int systemPower; // computer systems for craft
|
||||||
|
int shield; // current shield
|
||||||
|
int maxShield; // max shield (for recharging)
|
||||||
|
int deathCounter; // how long to explode for
|
||||||
|
|
||||||
|
signed char speed;
|
||||||
|
unsigned char damage; // Contact damage for bullets
|
||||||
|
int score; // How much a kill of this is worth
|
||||||
|
unsigned char ammo[2]; // Ammo for 2nd weapon. Max of 100 (except laser)
|
||||||
|
|
||||||
|
signed char face; // Either 0 or 1
|
||||||
|
|
||||||
|
object *owner; // Who owns this object
|
||||||
|
|
||||||
|
int chance[2]; // Chance of using the weapons (out of 1000)
|
||||||
|
|
||||||
|
SDL_Surface *image[2]; // For facing left and right
|
||||||
|
unsigned char imageIndex[2]; // used for loading
|
||||||
|
signed char hit; // used to make a craft "flash" if it is struck by a shot
|
||||||
|
|
||||||
|
int engineX; // The place for the engine on the other side of the craft
|
||||||
|
int engineY; // The middle of the engine on the craft
|
||||||
|
|
||||||
|
int thinktime; // When the object will next react
|
||||||
|
signed char weaponType[2]; // Weapon types
|
||||||
|
|
||||||
|
signed char collectChance; // Chance of dropping the object
|
||||||
|
signed char collectType; // What the object is carrying
|
||||||
|
unsigned char collectValue; // What it is worth
|
||||||
|
|
||||||
|
int flags; // Various flags for an object
|
||||||
|
|
||||||
|
float x, y, dx, dy;
|
||||||
|
|
||||||
|
object *next;
|
||||||
|
|
||||||
|
} object;
|
||||||
|
|
||||||
|
typedef struct mission {
|
||||||
|
|
||||||
|
char primaryObjective[3][50]; // Description
|
||||||
|
signed char primaryType[3]; // The type of mission this is
|
||||||
|
signed char target1[3]; // index of target in enemy array
|
||||||
|
int targetValue1[3]; // Number of things to collect (slaves, cash, etc)
|
||||||
|
signed char timeLimit1[3]; // In minutes
|
||||||
|
int completed1[3];
|
||||||
|
|
||||||
|
char secondaryObjective[3][50]; // Description
|
||||||
|
signed char secondaryType[3]; // The type of mission this is
|
||||||
|
signed char target2[3]; // index of target in enemy array
|
||||||
|
int targetValue2[3]; // Number of things to collect (slaves, cash, etc)
|
||||||
|
signed char timeLimit2[3]; // In minutes
|
||||||
|
int completed2[3];
|
||||||
|
|
||||||
|
signed char remainingObjectives1;
|
||||||
|
signed char remainingObjectives2;
|
||||||
|
int addAliens; // How often to add new enemies
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Star {
|
||||||
|
|
||||||
|
float x, y, dx, dy;
|
||||||
|
signed char speed; // How fast the star moves
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct collectables {
|
||||||
|
|
||||||
|
signed char active;
|
||||||
|
float x, y, dx, dy;
|
||||||
|
SDL_Surface *image;
|
||||||
|
signed char type; // What kind of collectable is it?
|
||||||
|
unsigned char value; // How much is it worth?
|
||||||
|
int life; // How long it will stay around for
|
||||||
|
|
||||||
|
collectables *next;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct textObject {
|
||||||
|
|
||||||
|
SDL_Surface *image;
|
||||||
|
unsigned char life;
|
||||||
|
float x, y;
|
||||||
|
signed char fontColor;
|
||||||
|
char text[255];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct Game {
|
||||||
|
|
||||||
|
object thePlayer;
|
||||||
|
object playerWeapon;
|
||||||
|
object playerWeapon2;
|
||||||
|
|
||||||
|
unsigned char system;
|
||||||
|
unsigned char area;
|
||||||
|
unsigned char musicVolume;
|
||||||
|
unsigned char sfxVolume;
|
||||||
|
|
||||||
|
signed char fullScreen;
|
||||||
|
signed char useMusic;
|
||||||
|
signed char useSound;
|
||||||
|
signed char autoSaveSlot;
|
||||||
|
|
||||||
|
unsigned int cash;
|
||||||
|
unsigned int cashEarned;
|
||||||
|
unsigned int shots;
|
||||||
|
unsigned int hits;
|
||||||
|
unsigned char accuracy;
|
||||||
|
unsigned char hasWingMate1, hasWingMate2;
|
||||||
|
unsigned int totalKills, wingMate1Kills, wingMate2Kills;
|
||||||
|
unsigned char wingMate1Ejects, wingMate2Ejects;
|
||||||
|
unsigned int totalOtherKills;
|
||||||
|
unsigned char secondaryMissions, secondaryMissionsCompleted;
|
||||||
|
unsigned int shieldPickups, rocketPickups, cellPickups, powerups, minesKilled, cargoPickups;
|
||||||
|
|
||||||
|
// slaves for Eyananth
|
||||||
|
unsigned int slavesRescued;
|
||||||
|
|
||||||
|
// remaining shield for experimental fighter
|
||||||
|
unsigned int experimentalShield;
|
||||||
|
|
||||||
|
unsigned int timeTaken; // In seconds
|
||||||
|
unsigned char missionCompleted[10];
|
||||||
|
|
||||||
|
signed char stationedPlanet;
|
||||||
|
signed char destinationPlanet;
|
||||||
|
|
||||||
|
char stationedName[20];
|
||||||
|
char destinationName[20];
|
||||||
|
int distanceCovered;
|
||||||
|
|
||||||
|
unsigned char maxPlasmaRate;
|
||||||
|
unsigned char maxPlasmaDamage;
|
||||||
|
unsigned char maxPlasmaOutput;
|
||||||
|
unsigned char maxPlasmaAmmo;
|
||||||
|
unsigned char maxRocketAmmo;
|
||||||
|
unsigned char shieldUnits;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct ShopItem {
|
||||||
|
|
||||||
|
int x, y;
|
||||||
|
unsigned int price;
|
||||||
|
char name[50];
|
||||||
|
char description[255];
|
||||||
|
unsigned char image;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct bRect {
|
||||||
|
|
||||||
|
int x, y, w, h;
|
||||||
|
bRect *next;
|
||||||
|
|
||||||
|
} bRect;
|
||||||
|
|
||||||
|
typedef struct Planet {
|
||||||
|
|
||||||
|
int y;
|
||||||
|
char name[50];
|
||||||
|
SDL_Surface *image;
|
||||||
|
|
||||||
|
signed char missionNumber; // associated mission number
|
||||||
|
signed char missionCompleted; // whether it has been completed
|
||||||
|
|
||||||
|
signed char messageMission;
|
||||||
|
signed char messageSlot;
|
||||||
|
signed char faceImage;
|
||||||
|
char from[50];
|
||||||
|
char subject[100];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct globalEngineVariables {
|
||||||
|
|
||||||
|
SDL_Event event;
|
||||||
|
signed char done;
|
||||||
|
|
||||||
|
SDL_RWops *sdlrw;
|
||||||
|
|
||||||
|
float musicVolume;
|
||||||
|
|
||||||
|
signed char maxAliens;
|
||||||
|
|
||||||
|
float ssx;
|
||||||
|
float ssy;
|
||||||
|
|
||||||
|
Mix_Music *music;
|
||||||
|
|
||||||
|
object *bulletHead;
|
||||||
|
object *bulletTail;
|
||||||
|
object *explosionHead;
|
||||||
|
object *explosionTail;
|
||||||
|
collectables *collectableHead;
|
||||||
|
collectables *collectableTail;
|
||||||
|
object *debrisHead;
|
||||||
|
object *debrisTail;
|
||||||
|
|
||||||
|
int cursor_x, cursor_y;
|
||||||
|
|
||||||
|
signed char commsSection;
|
||||||
|
|
||||||
|
signed char eventTimer;
|
||||||
|
|
||||||
|
signed char lowShield;
|
||||||
|
signed char averageShield;
|
||||||
|
|
||||||
|
float targetShield;
|
||||||
|
signed char targetIndex;
|
||||||
|
signed char targetArrow;
|
||||||
|
int targetArrowTimer;
|
||||||
|
|
||||||
|
// Mission completion timer (allows for 4 seconds before leaving sector)
|
||||||
|
unsigned long missionCompleteTimer;
|
||||||
|
|
||||||
|
// Times the mission normally
|
||||||
|
unsigned int counter2;
|
||||||
|
int timeTaken; // In seconds
|
||||||
|
|
||||||
|
// For missions with a time limit
|
||||||
|
signed char timeMission;
|
||||||
|
unsigned int counter;
|
||||||
|
signed char seconds;
|
||||||
|
signed char minutes;
|
||||||
|
|
||||||
|
// Mission Related stuff
|
||||||
|
signed char allAliensDead;
|
||||||
|
int addAliens;
|
||||||
|
|
||||||
|
signed char paused;
|
||||||
|
signed char gameSection;
|
||||||
|
|
||||||
|
signed char useAudio;
|
||||||
|
|
||||||
|
// This really only applies to Linux users.
|
||||||
|
char userHomeDirectory[1024];
|
||||||
|
|
||||||
|
char keyState[350];
|
||||||
|
|
||||||
|
signed char cheat; // overall cheat
|
||||||
|
signed char cheatShield;
|
||||||
|
signed char cheatCash;
|
||||||
|
signed char cheatAmmo;
|
||||||
|
signed char cheatTime;
|
||||||
|
signed char cheatCredits;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct event {
|
||||||
|
|
||||||
|
int time;
|
||||||
|
char message[255];
|
||||||
|
signed char face;
|
||||||
|
signed char entity;
|
||||||
|
int flag;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct cutMsg {
|
||||||
|
|
||||||
|
int face;
|
||||||
|
char message[255];
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct devVariables {
|
||||||
|
|
||||||
|
signed char moveAliens;
|
||||||
|
signed char fireAliens;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,738 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "version.h"
|
||||||
|
#include "title.h"
|
||||||
|
|
||||||
|
signed char showGameMenu(signed char continueSaveSlot)
|
||||||
|
{
|
||||||
|
graphics.blitText(2);
|
||||||
|
if (continueSaveSlot != 0)
|
||||||
|
{
|
||||||
|
graphics.blitText(3);
|
||||||
|
graphics.blitText(4);
|
||||||
|
}
|
||||||
|
graphics.blitText(5);
|
||||||
|
if (engine.cheat)
|
||||||
|
{
|
||||||
|
graphics.textShape[7].y = 450;
|
||||||
|
graphics.blitText(6);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
graphics.textShape[7].y = 430;
|
||||||
|
}
|
||||||
|
graphics.blitText(7);
|
||||||
|
|
||||||
|
if (engine.cheat)
|
||||||
|
return 6;
|
||||||
|
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
signed char showLoadMenu()
|
||||||
|
{
|
||||||
|
signed char rtn = 1;
|
||||||
|
|
||||||
|
for (int i = 13 ; i < 18 ; i++)
|
||||||
|
{
|
||||||
|
if (graphics.textShape[i].image != NULL)
|
||||||
|
{
|
||||||
|
graphics.blitText(i);
|
||||||
|
rtn++;
|
||||||
|
graphics.textShape[12].y = graphics.textShape[i].y + 40;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
graphics.blitText(12);
|
||||||
|
|
||||||
|
return rtn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void createOptionsMenu()
|
||||||
|
{
|
||||||
|
if (currentGame.useSound)
|
||||||
|
graphics.textSurface(8, "SOUND - ON", -1, 350, FONT_WHITE);
|
||||||
|
else
|
||||||
|
graphics.textSurface(8, "SOUND - OFF", -1, 350, FONT_WHITE);
|
||||||
|
|
||||||
|
if (currentGame.useMusic)
|
||||||
|
graphics.textSurface(9, "MUSIC - ON", -1, 370, FONT_WHITE);
|
||||||
|
else
|
||||||
|
graphics.textSurface(9, "MUSIC - OFF", -1, 370, FONT_WHITE);
|
||||||
|
|
||||||
|
if (currentGame.fullScreen)
|
||||||
|
graphics.textSurface(10, "FULLSCREEN - ON", -1, 390, FONT_WHITE);
|
||||||
|
else
|
||||||
|
graphics.textSurface(10, "FULLSCREEN - OFF", -1, 390, FONT_WHITE);
|
||||||
|
|
||||||
|
char string[50];
|
||||||
|
strcpy(string, "AUTO SAVE SLOT - NONE");
|
||||||
|
if (currentGame.autoSaveSlot > -1)
|
||||||
|
sprintf(string, "AUTO SAVE SLOT - #%d", currentGame.autoSaveSlot + 1);
|
||||||
|
graphics.textSurface(11, string, -1, 410, FONT_WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
signed char showOptionsMenu()
|
||||||
|
{
|
||||||
|
graphics.textShape[12].y = 450;
|
||||||
|
|
||||||
|
graphics.blitText(8);
|
||||||
|
graphics.blitText(9);
|
||||||
|
graphics.blitText(10);
|
||||||
|
graphics.blitText(11);
|
||||||
|
graphics.blitText(12);
|
||||||
|
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
void createCheatMenu()
|
||||||
|
{
|
||||||
|
if (engine.cheatShield)
|
||||||
|
graphics.textSurface(18, "UNLIMITED SHIELD - ON", -1, 350, FONT_WHITE);
|
||||||
|
else
|
||||||
|
graphics.textSurface(18, "UNLIMITED SHIELD - OFF", -1, 350, FONT_WHITE);
|
||||||
|
|
||||||
|
if (engine.cheatAmmo)
|
||||||
|
graphics.textSurface(19, "UNLIMITED AMMO - ON", -1, 370, FONT_WHITE);
|
||||||
|
else
|
||||||
|
graphics.textSurface(19, "UNLIMITED AMMO - OFF", -1, 370, FONT_WHITE);
|
||||||
|
|
||||||
|
if (engine.cheatCash)
|
||||||
|
graphics.textSurface(20, "UNLIMITED CASH - ON", -1, 390, FONT_WHITE);
|
||||||
|
else
|
||||||
|
graphics.textSurface(20, "UNLIMITED CASH - OFF", -1, 390, FONT_WHITE);
|
||||||
|
|
||||||
|
if (engine.cheatTime)
|
||||||
|
graphics.textSurface(21, "UNLIMITED TIME - ON", -1, 410, FONT_WHITE);
|
||||||
|
else
|
||||||
|
graphics.textSurface(21, "UNLIMITED TIME - OFF", -1, 410, FONT_WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
signed char showCheatMenu()
|
||||||
|
{
|
||||||
|
graphics.textShape[12].y = 450;
|
||||||
|
|
||||||
|
graphics.blitText(18);
|
||||||
|
graphics.blitText(19);
|
||||||
|
graphics.blitText(20);
|
||||||
|
graphics.blitText(21);
|
||||||
|
graphics.blitText(12);
|
||||||
|
|
||||||
|
return 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is the main title screen, with the stars whirling past and the
|
||||||
|
"Parallel Realities, Present..." text. Nothing too special.
|
||||||
|
*/
|
||||||
|
int doTitle()
|
||||||
|
{
|
||||||
|
newGame();
|
||||||
|
|
||||||
|
engine.gameSection = SECTION_TITLE;
|
||||||
|
|
||||||
|
graphics.flushBuffer();
|
||||||
|
graphics.freeGraphics();
|
||||||
|
resetLists();
|
||||||
|
|
||||||
|
// required to stop the title screen crashing
|
||||||
|
currentGame.system = 0;
|
||||||
|
currentGame.area = 0;
|
||||||
|
|
||||||
|
loadGameGraphics();
|
||||||
|
|
||||||
|
graphics.clearScreen(graphics.black);
|
||||||
|
graphics.updateScreen();
|
||||||
|
graphics.clearScreen(graphics.black);
|
||||||
|
SDL_Delay(1000);
|
||||||
|
|
||||||
|
signed char continueSaveSlot = initSaveSlots();
|
||||||
|
|
||||||
|
loadMusic("music/Platinum.mod");
|
||||||
|
|
||||||
|
loadBackground("gfx/spirit.jpg");
|
||||||
|
|
||||||
|
SDL_Surface *prlogo, *sflogo;
|
||||||
|
prlogo = loadImage("gfx/prlogo.gif");
|
||||||
|
sflogo = loadImage("gfx/sflogo.gif");
|
||||||
|
|
||||||
|
int prx = ((800 - prlogo->w) / 2);
|
||||||
|
int pry = ((600 - prlogo->h) / 2);
|
||||||
|
|
||||||
|
int sfx = ((800 - sflogo->w) / 2);
|
||||||
|
int sfy = ((600 - sflogo->h) / 2);
|
||||||
|
|
||||||
|
graphics.textSurface(0, "PRESENTS", -1, 300, FONT_WHITE);
|
||||||
|
graphics.textSurface(1, "AN SDL GAME", -1, 300, FONT_WHITE);
|
||||||
|
graphics.textSurface(2, "START NEW GAME", -1, 350, FONT_WHITE);
|
||||||
|
graphics.textSurface(3, "LOAD GAME", -1, 370, FONT_WHITE);
|
||||||
|
graphics.textSurface(4, "CONTINUE CURRENT GAME", -1, 390, FONT_WHITE);
|
||||||
|
graphics.textSurface(5, "OPTIONS", -1, 410, FONT_WHITE);
|
||||||
|
graphics.textSurface(6, "CHEAT OPTIONS", -1, 430, FONT_WHITE);
|
||||||
|
graphics.textSurface(7, "QUIT", -1, 430, FONT_WHITE);
|
||||||
|
|
||||||
|
createOptionsMenu();
|
||||||
|
graphics.textSurface(12, "BACK TO MAIN MENU", -1, 0, FONT_WHITE);
|
||||||
|
|
||||||
|
createCheatMenu();
|
||||||
|
|
||||||
|
// Set the star motion
|
||||||
|
engine.ssx = -0.5;
|
||||||
|
engine.ssy = 0;
|
||||||
|
|
||||||
|
int then = SDL_GetTicks();
|
||||||
|
int now;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 15 ; i++)
|
||||||
|
{
|
||||||
|
enemy[i] = defEnemy[rand() % 3];
|
||||||
|
if ((rand() % 5) == 0)
|
||||||
|
enemy[i] = defEnemy[CD_TRANSPORTSHIP];
|
||||||
|
if ((rand() % 5) == 0)
|
||||||
|
enemy[i] = defEnemy[CD_MINER];
|
||||||
|
enemy[i].x = rand() % 800;
|
||||||
|
enemy[i].y = rand() % 560;
|
||||||
|
enemy[i].dx = 1 + rand() % 3;
|
||||||
|
enemy[i].face = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int redGlow = 255;
|
||||||
|
signed char redDir = -2;
|
||||||
|
char buildVersion[25];
|
||||||
|
sprintf(buildVersion, "Version "VERSION);
|
||||||
|
|
||||||
|
SDL_Rect optionRec;
|
||||||
|
|
||||||
|
optionRec.x = 290;
|
||||||
|
optionRec.y = 345;
|
||||||
|
optionRec.h = 22;
|
||||||
|
optionRec.w = 215;
|
||||||
|
|
||||||
|
signed char selectedOption = 1;
|
||||||
|
if (continueSaveSlot > 0)
|
||||||
|
{selectedOption = 3; optionRec.y += 40;}
|
||||||
|
|
||||||
|
signed char skip = 0;
|
||||||
|
signed char listLength = 5; // menu list length
|
||||||
|
signed char menuType = 0;
|
||||||
|
|
||||||
|
graphics.drawBackGround();
|
||||||
|
unsigned long frameLimit = SDL_GetTicks();
|
||||||
|
|
||||||
|
engine.done = 0;
|
||||||
|
flushInput();
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = 0;
|
||||||
|
|
||||||
|
if ((currentGame.useMusic) && (engine.useAudio))
|
||||||
|
Mix_PlayMusic(engine.music, 1);
|
||||||
|
|
||||||
|
while (!engine.done)
|
||||||
|
{
|
||||||
|
graphics.updateScreen();
|
||||||
|
graphics.unBuffer();
|
||||||
|
|
||||||
|
now = SDL_GetTicks();
|
||||||
|
|
||||||
|
doStarfield();
|
||||||
|
doExplosions();
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 15 ; i++)
|
||||||
|
{
|
||||||
|
addEngine(&enemy[i]);
|
||||||
|
enemy[i].x += enemy[i].dx;
|
||||||
|
graphics.blit(enemy[i].image[0], (int)enemy[i].x, (int)enemy[i].y);
|
||||||
|
if (enemy[i].x > 830)
|
||||||
|
{
|
||||||
|
enemy[i].x = -10;
|
||||||
|
enemy[i].y = rand() % 580;
|
||||||
|
enemy[i].dx = 1 + rand() % 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((now - then > 2000) && (now - then < 8000) && (!skip))
|
||||||
|
{
|
||||||
|
graphics.blit(prlogo, prx, pry);
|
||||||
|
}
|
||||||
|
else if ((now - then > 9000) && (now - then < 15000) && (!skip))
|
||||||
|
{
|
||||||
|
graphics.blitText(0);
|
||||||
|
}
|
||||||
|
else if ((now - then > 16000) && (now - then < 21000) && (!skip))
|
||||||
|
{
|
||||||
|
graphics.blitText(1);
|
||||||
|
}
|
||||||
|
else if ((now - then > 25500) || (skip))
|
||||||
|
{
|
||||||
|
graphics.blit(sflogo, sfx, sfy);
|
||||||
|
|
||||||
|
if ((now - then >= 27500) || (skip))
|
||||||
|
{
|
||||||
|
graphics.addBuffer(280, 345, 235, 145);
|
||||||
|
|
||||||
|
graphics.blevelRect(optionRec.x, optionRec.y, optionRec.w, optionRec.h, redGlow, 0x00, 0x00);
|
||||||
|
|
||||||
|
switch(menuType)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
listLength = showGameMenu(continueSaveSlot);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
listLength = showLoadMenu();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
listLength = showOptionsMenu();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
listLength = showCheatMenu();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
redGlow += redDir;
|
||||||
|
if (redGlow <= 0) {redDir = 2; redGlow = 0;}
|
||||||
|
if (redGlow >= 255) {redDir = -2; redGlow = 255;}
|
||||||
|
|
||||||
|
if (engine.keyState[SDLK_UP])
|
||||||
|
{
|
||||||
|
engine.keyState[SDLK_UP] = 0;
|
||||||
|
Math::wrapChar(&(--selectedOption), 1, listLength);
|
||||||
|
if (menuType == 0)
|
||||||
|
if ((selectedOption == 2) || (selectedOption == 3))
|
||||||
|
if (continueSaveSlot == 0)
|
||||||
|
selectedOption = 1;
|
||||||
|
}
|
||||||
|
if (engine.keyState[SDLK_DOWN])
|
||||||
|
{
|
||||||
|
engine.keyState[SDLK_DOWN] = 0;
|
||||||
|
Math::wrapChar(&(++selectedOption), 1, listLength);
|
||||||
|
if (menuType == 0)
|
||||||
|
if ((selectedOption == 2) || (selectedOption == 3))
|
||||||
|
if (continueSaveSlot == 0)
|
||||||
|
selectedOption = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
optionRec.y = 326 + (20 * selectedOption);
|
||||||
|
if (menuType > 0)
|
||||||
|
if (selectedOption == listLength)
|
||||||
|
optionRec.y += 20;
|
||||||
|
|
||||||
|
if (!skip)
|
||||||
|
{
|
||||||
|
graphics.drawString("Copyright Parallel Realities 2003", 5, 580, FONT_WHITE, graphics.background);
|
||||||
|
graphics.drawString(buildVersion, 695, 580, FONT_WHITE, graphics.background);
|
||||||
|
graphics.addBuffer(0, 580, 800, 20);
|
||||||
|
skip = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getPlayerInput();
|
||||||
|
|
||||||
|
// if someone has invoked the credits cheat
|
||||||
|
if (engine.cheatCredits)
|
||||||
|
{
|
||||||
|
doCredits();
|
||||||
|
engine.cheatCredits = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((engine.keyState[SDLK_LCTRL]) || (engine.keyState[SDLK_RCTRL]) || (engine.keyState[SDLK_SPACE]))
|
||||||
|
{
|
||||||
|
if ((now - then <= 27500) && (!skip))
|
||||||
|
{
|
||||||
|
graphics.drawString("Copyright Parallel Realities 2003", 5, 580, FONT_WHITE, graphics.background);
|
||||||
|
graphics.drawString(buildVersion, 695, 580, FONT_WHITE, graphics.background);
|
||||||
|
graphics.addBuffer(0, 580, 800, 20);
|
||||||
|
skip = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch(menuType)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if ((selectedOption == 1) || (selectedOption == 3))
|
||||||
|
engine.done = 1;
|
||||||
|
else if (selectedOption == 2)
|
||||||
|
{menuType = 1; selectedOption = 1;}
|
||||||
|
else if (selectedOption == 4)
|
||||||
|
{menuType = 2; selectedOption = 1;}
|
||||||
|
else if (selectedOption == 5)
|
||||||
|
{
|
||||||
|
if (engine.cheat)
|
||||||
|
{menuType = 3; selectedOption = 1;}
|
||||||
|
else
|
||||||
|
engine.done = 1;
|
||||||
|
}
|
||||||
|
else if (selectedOption == 6)
|
||||||
|
engine.done = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
if (selectedOption != listLength)
|
||||||
|
{engine.done = 1; continueSaveSlot = selectedOption; selectedOption = 3;}
|
||||||
|
else
|
||||||
|
{menuType = 0; selectedOption = 1;}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if ((selectedOption == 1) && (engine.useAudio))
|
||||||
|
currentGame.useSound = 1 - currentGame.useSound;
|
||||||
|
else if ((selectedOption == 2) && (engine.useAudio))
|
||||||
|
{
|
||||||
|
currentGame.useMusic = 1 - currentGame.useMusic;
|
||||||
|
|
||||||
|
if (currentGame.useMusic)
|
||||||
|
{
|
||||||
|
if (Mix_PausedMusic() == 1)
|
||||||
|
Mix_ResumeMusic();
|
||||||
|
else
|
||||||
|
Mix_PlayMusic(engine.music, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Mix_PauseMusic();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (selectedOption == 3)
|
||||||
|
{
|
||||||
|
currentGame.fullScreen = 1 - currentGame.fullScreen;
|
||||||
|
#if LINUX
|
||||||
|
SDL_WM_ToggleFullScreen(graphics.screen);
|
||||||
|
#else
|
||||||
|
if (currentGame.fullScreen)
|
||||||
|
graphics.screen = SDL_SetVideoMode(800, 600, 16, SDL_HWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN);
|
||||||
|
else
|
||||||
|
graphics.screen = SDL_SetVideoMode(800, 600, 0, SDL_HWSURFACE|SDL_HWPALETTE);
|
||||||
|
|
||||||
|
graphics.drawBackground();
|
||||||
|
flushBuffer();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else if (selectedOption == 4)
|
||||||
|
Math::wrapChar(&(++currentGame.autoSaveSlot), -1, 4);
|
||||||
|
else if (selectedOption == listLength)
|
||||||
|
{menuType = 0; selectedOption = 1;}
|
||||||
|
createOptionsMenu();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
if (selectedOption == 1)
|
||||||
|
engine.cheatShield = 1 - engine.cheatShield;
|
||||||
|
else if (selectedOption == 2)
|
||||||
|
engine.cheatAmmo = 1 - engine.cheatAmmo;
|
||||||
|
else if (selectedOption == 3)
|
||||||
|
engine.cheatCash = 1 - engine.cheatCash;
|
||||||
|
else if (selectedOption == 4)
|
||||||
|
engine.cheatTime = 1 - engine.cheatTime;
|
||||||
|
else if (selectedOption == listLength)
|
||||||
|
{menuType = 0; selectedOption = 1;}
|
||||||
|
createCheatMenu();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
if (selectedOption == listLength)
|
||||||
|
{menuType = 0; selectedOption = 1;}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = engine.keyState[SDLK_SPACE] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (SDL_GetTicks() < (frameLimit + 16)){}
|
||||||
|
frameLimit = SDL_GetTicks();
|
||||||
|
}
|
||||||
|
|
||||||
|
Mix_HaltMusic();
|
||||||
|
|
||||||
|
SDL_FreeSurface(prlogo);
|
||||||
|
SDL_FreeSurface(sflogo);
|
||||||
|
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = engine.keyState[SDLK_SPACE] = 0;
|
||||||
|
|
||||||
|
resetLists();
|
||||||
|
|
||||||
|
if (selectedOption == 1)
|
||||||
|
selectedOption = 2; // go straight to mission 0
|
||||||
|
|
||||||
|
if (selectedOption == 3)
|
||||||
|
{
|
||||||
|
newGame();
|
||||||
|
selectedOption = loadGame(continueSaveSlot);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send back a negative number...
|
||||||
|
if (selectedOption > 4)
|
||||||
|
{
|
||||||
|
selectedOption = -1;
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return selectedOption;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Scrolls the intro text up the screen and nothing else. The text will be placed
|
||||||
|
into a data file when the game is finished.
|
||||||
|
*/
|
||||||
|
void showStory()
|
||||||
|
{
|
||||||
|
graphics.freeGraphics();
|
||||||
|
|
||||||
|
int y = 620;
|
||||||
|
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
#if USEPACK
|
||||||
|
int dataLocation = locateDataInPak("data/intro.txt", 1);
|
||||||
|
fp = fopen(PACKLOCATION, "rb");
|
||||||
|
fseek(fp, dataLocation, SEEK_SET);
|
||||||
|
#else
|
||||||
|
fp = fopen("data/intro.txt", "rb");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
int nextPos = -1;
|
||||||
|
char string[255];
|
||||||
|
|
||||||
|
fscanf(fp, "%d ", &nextPos);
|
||||||
|
|
||||||
|
while (nextPos != -1)
|
||||||
|
{
|
||||||
|
fscanf(fp, "%[^\n]%*c", string);
|
||||||
|
|
||||||
|
y += nextPos;
|
||||||
|
graphics.textSurface(i, string, -1, y, FONT_WHITE);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
|
||||||
|
fscanf(fp, "%d ", &nextPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
loadBackground("gfx/startUp.jpg");
|
||||||
|
graphics.blit(graphics.background, 0, 0);
|
||||||
|
graphics.flushBuffer();
|
||||||
|
|
||||||
|
unsigned long frameLimit = SDL_GetTicks();
|
||||||
|
|
||||||
|
flushInput();
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = engine.keyState[SDLK_SPACE] = 0;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
graphics.updateScreen();
|
||||||
|
graphics.unBuffer();
|
||||||
|
|
||||||
|
getPlayerInput();
|
||||||
|
|
||||||
|
if ((engine.keyState[SDLK_LCTRL]) || (engine.keyState[SDLK_RCTRL]) || (engine.keyState[SDLK_SPACE]))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (graphics.textShape[8].y > 450)
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < 9 ; i++)
|
||||||
|
{
|
||||||
|
graphics.textShape[i].y -= 0.25;
|
||||||
|
graphics.blitText(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SDL_Delay(3000);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (SDL_GetTicks() < (frameLimit + 16)){}
|
||||||
|
frameLimit = SDL_GetTicks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The game over screen :(
|
||||||
|
*/
|
||||||
|
void gameover()
|
||||||
|
{
|
||||||
|
graphics.flushBuffer();
|
||||||
|
graphics.freeGraphics();
|
||||||
|
SDL_FillRect(graphics.background, NULL, graphics.black);
|
||||||
|
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = engine.keyState[SDLK_SPACE] = 0;
|
||||||
|
engine.gameSection = SECTION_INTERMISSION;
|
||||||
|
|
||||||
|
loadMusic("music/Wybierak.mod");
|
||||||
|
|
||||||
|
SDL_Surface *gameover = loadImage("gfx/gameover.png");
|
||||||
|
|
||||||
|
graphics.clearScreen(graphics.black);
|
||||||
|
graphics.updateScreen();
|
||||||
|
graphics.clearScreen(graphics.black);
|
||||||
|
SDL_Delay(1000);
|
||||||
|
|
||||||
|
if ((currentGame.useMusic) && (engine.useAudio))
|
||||||
|
{
|
||||||
|
Mix_VolumeMusic(100);
|
||||||
|
Mix_PlayMusic(engine.music, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int x = (800 - gameover->w) / 2;
|
||||||
|
int y = (600 - gameover->h) / 2;
|
||||||
|
|
||||||
|
unsigned long frameLimit = SDL_GetTicks();
|
||||||
|
graphics.updateScreen();
|
||||||
|
|
||||||
|
flushInput();
|
||||||
|
engine.keyState[SDLK_LCTRL] = engine.keyState[SDLK_RCTRL] = engine.keyState[SDLK_SPACE] = 0;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
getPlayerInput();
|
||||||
|
|
||||||
|
if ((engine.keyState[SDLK_LCTRL]) || (engine.keyState[SDLK_RCTRL]) || (engine.keyState[SDLK_SPACE]))
|
||||||
|
break;
|
||||||
|
|
||||||
|
graphics.updateScreen();
|
||||||
|
|
||||||
|
graphics.unBuffer();
|
||||||
|
x = ((800 - gameover->w) / 2) - Math::rrand(-2, 2);
|
||||||
|
y = ((600 - gameover->h) / 2) - Math::rrand(-2, 2);
|
||||||
|
graphics.blit(gameover, x, y);
|
||||||
|
|
||||||
|
// Limit us to 60 frame a second
|
||||||
|
while (SDL_GetTicks() < (frameLimit + 16)){}
|
||||||
|
frameLimit = SDL_GetTicks();
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_FreeSurface(gameover);
|
||||||
|
|
||||||
|
if ((currentGame.useMusic) && (engine.useAudio))
|
||||||
|
Mix_HaltMusic();
|
||||||
|
|
||||||
|
graphics.flushBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void doCredits()
|
||||||
|
{
|
||||||
|
loadBackground("gfx/credits.jpg");
|
||||||
|
graphics.flushBuffer();
|
||||||
|
graphics.freeGraphics();
|
||||||
|
|
||||||
|
if ((currentGame.useMusic) && (engine.useAudio))
|
||||||
|
loadMusic("music/Solace.s3m");
|
||||||
|
|
||||||
|
FILE *fp;
|
||||||
|
int numberOfCredits = 0;
|
||||||
|
int lastCredit = 0;
|
||||||
|
|
||||||
|
int yPos = 0;
|
||||||
|
int yPos2 = 510;
|
||||||
|
char text[255];
|
||||||
|
|
||||||
|
textObject *credit;
|
||||||
|
|
||||||
|
graphics.clearScreen(graphics.black);
|
||||||
|
graphics.updateScreen();
|
||||||
|
graphics.clearScreen(graphics.black);
|
||||||
|
SDL_Delay(1000);
|
||||||
|
|
||||||
|
graphics.drawBackGround();
|
||||||
|
|
||||||
|
#if USEPACK
|
||||||
|
int dataLocation = locateDataInPak("data/credits.txt", 1);
|
||||||
|
fp = fopen(PACKLOCATION, "rb");
|
||||||
|
fseek(fp, dataLocation, SEEK_SET);
|
||||||
|
#else
|
||||||
|
fp = fopen("data/credits.txt", "rb");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (int i = 0 ; i < 6 ; i++)
|
||||||
|
{
|
||||||
|
fscanf(fp, "%[^\n]%*c", text);
|
||||||
|
graphics.drawString(text, -1, 240 + (i * 20), FONT_WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
fscanf(fp, "%d%*c", &numberOfCredits);
|
||||||
|
|
||||||
|
credit = (textObject*) malloc(sizeof(textObject) * numberOfCredits);
|
||||||
|
|
||||||
|
for (int i = 0 ; i < numberOfCredits ; i++)
|
||||||
|
{
|
||||||
|
fscanf(fp, "%d %[^\n]%*c", &yPos, text);
|
||||||
|
credit[i].image = graphics.textSurface(text, FONT_WHITE);
|
||||||
|
credit[i].x = (800 - credit[i].image->w) / 2;
|
||||||
|
yPos2 += yPos;
|
||||||
|
credit[i].y = yPos2;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
if ((currentGame.useMusic) && (engine.useAudio))
|
||||||
|
{
|
||||||
|
Mix_VolumeMusic(100);
|
||||||
|
Mix_PlayMusic(engine.music, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Delay(3000);
|
||||||
|
|
||||||
|
graphics.updateScreen();
|
||||||
|
SDL_Delay(10000);
|
||||||
|
graphics.drawBackGround();
|
||||||
|
|
||||||
|
unsigned long frameLimit = SDL_GetTicks();
|
||||||
|
engine.done = 0;
|
||||||
|
|
||||||
|
lastCredit = numberOfCredits - 1;
|
||||||
|
|
||||||
|
SDL_Rect r1 = {0, 80, 800, 20};
|
||||||
|
SDL_Rect r2 = {0, 500, 800, 20};
|
||||||
|
|
||||||
|
engine.keyState[SDLK_ESCAPE] = 0;
|
||||||
|
flushInput();
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
graphics.updateScreen();
|
||||||
|
graphics.unBuffer();
|
||||||
|
|
||||||
|
getPlayerInput();
|
||||||
|
if (engine.keyState[SDLK_ESCAPE])
|
||||||
|
break;
|
||||||
|
|
||||||
|
for (int i = 0 ; i < numberOfCredits ; i++)
|
||||||
|
{
|
||||||
|
if ((credit[i].y > 80) && (credit[i].y < 500))
|
||||||
|
graphics.blit(credit[i].image, (int)credit[i].x, (int)credit[i].y);
|
||||||
|
if (credit[lastCredit].y > 400)
|
||||||
|
credit[i].y -= 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_FillRect(graphics.screen, &r1, graphics.black);
|
||||||
|
SDL_FillRect(graphics.screen, &r2, graphics.black);
|
||||||
|
|
||||||
|
while (SDL_GetTicks() < (frameLimit + 16)){}
|
||||||
|
frameLimit = SDL_GetTicks();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < numberOfCredits ; i++)
|
||||||
|
{
|
||||||
|
SDL_FreeSurface(credit[i].image);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(credit);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern SDL_Surface *loadImage(char *filename);
|
||||||
|
extern void unpack(char *file);
|
||||||
|
extern void loadMusic(char *filename);
|
||||||
|
extern void doStarfield();
|
||||||
|
extern void doExplosions();
|
||||||
|
extern void addEngine(object *craft);
|
||||||
|
extern void getPlayerInput();
|
||||||
|
extern void resetLists();
|
||||||
|
extern signed char loadGame(int slot);
|
||||||
|
extern int initSaveSlots();
|
||||||
|
extern void newGame();
|
||||||
|
extern void loadGameGraphics();
|
||||||
|
extern void loadBackground(char *filename);
|
||||||
|
extern void doCredits();
|
||||||
|
extern int locateDataInPak(char *file, signed char required);
|
||||||
|
extern void flushInput();
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
||||||
|
extern devVariables dev;
|
||||||
|
extern object defEnemy[MAX_DEFALIENS];
|
||||||
|
extern object enemy[MAX_ALIENS];
|
||||||
|
extern Game currentGame;
|
||||||
|
extern Graphics graphics;
|
|
@ -0,0 +1,161 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "unpack.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Searches the pak file for the required data. When
|
||||||
|
it is found, the data is read into a character buffer.
|
||||||
|
*/
|
||||||
|
void unpack(char *file, signed char fileType)
|
||||||
|
{
|
||||||
|
unsigned char *packBuffer;
|
||||||
|
char packFilename[60];
|
||||||
|
int packFSize;
|
||||||
|
|
||||||
|
FILE *pak;
|
||||||
|
FILE *fp = NULL; // music has to be read-written-read!
|
||||||
|
char musicFilename[PATH_MAX];
|
||||||
|
|
||||||
|
strcpy(packFilename, "");
|
||||||
|
|
||||||
|
pak = fopen(PACKLOCATION, "rb");
|
||||||
|
if (pak == NULL)
|
||||||
|
{
|
||||||
|
printf("Couldn't access the Project: Starfighter data file!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fseek(pak, 4, SEEK_SET);
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (!fread(packFilename, 1, 56, pak))
|
||||||
|
{
|
||||||
|
fclose(pak);
|
||||||
|
if (fileType != PAK_FONT)
|
||||||
|
{
|
||||||
|
showErrorAndExit(0, file);
|
||||||
|
}
|
||||||
|
exit(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fread(&packFSize, 4, 1, pak);
|
||||||
|
packFSize = SDL_SwapLE32(packFSize);
|
||||||
|
|
||||||
|
if (strcmp(packFilename, file) == 0)
|
||||||
|
{
|
||||||
|
if ((fileType == PAK_MOD) || (fileType == PAK_S3M))
|
||||||
|
{
|
||||||
|
if (fileType == PAK_MOD)
|
||||||
|
{
|
||||||
|
sprintf(musicFilename, "%smusic.mod", engine.userHomeDirectory);
|
||||||
|
fp = fopen(musicFilename, "wb");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sprintf(musicFilename, "%smusic.s3m", engine.userHomeDirectory);
|
||||||
|
fp = fopen(musicFilename, "wb");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fp == NULL)
|
||||||
|
showErrorAndExit(1, "");
|
||||||
|
}
|
||||||
|
packBuffer = (unsigned char*) malloc(packFSize);
|
||||||
|
fread(packBuffer, 1, packFSize, pak);
|
||||||
|
if ((fileType == PAK_MOD) || (fileType == PAK_S3M))
|
||||||
|
{
|
||||||
|
fwrite(packBuffer, 1, packFSize, fp);
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fseek(pak, packFSize, SEEK_CUR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fileType != PAK_MOD) && (fileType != PAK_S3M))
|
||||||
|
engine.sdlrw = SDL_RWFromMem(packBuffer, packFSize);
|
||||||
|
|
||||||
|
//printf("Extracted: %s\n", file);
|
||||||
|
|
||||||
|
fclose(pak);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Search the data package for the required file.
|
||||||
|
When it is found, return the location.
|
||||||
|
*/
|
||||||
|
int locateDataInPak(char *file, signed char required)
|
||||||
|
{
|
||||||
|
//printf("Looking for %s...", file);
|
||||||
|
|
||||||
|
char packFilename[60];
|
||||||
|
int packFSize;
|
||||||
|
int location = 0;
|
||||||
|
|
||||||
|
FILE *pak;
|
||||||
|
|
||||||
|
strcpy(packFilename, "");
|
||||||
|
|
||||||
|
pak = fopen(PACKLOCATION, "rb");
|
||||||
|
if (pak == NULL)
|
||||||
|
{
|
||||||
|
printf("Couldn't access the Project: Starfighter data file!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
fseek(pak, 4, SEEK_SET);
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (!fread(packFilename, 1, 56, pak))
|
||||||
|
{
|
||||||
|
fclose(pak);
|
||||||
|
if (required)
|
||||||
|
{
|
||||||
|
showErrorAndExit(0, file);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fread(&packFSize, 4, 1, pak);
|
||||||
|
packFSize = SDL_SwapLE32(packFSize);
|
||||||
|
|
||||||
|
if (strcmp(packFilename, file) == 0)
|
||||||
|
{
|
||||||
|
location = ftell(pak);
|
||||||
|
fclose(pak);
|
||||||
|
|
||||||
|
//printf("found it!\n");
|
||||||
|
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fseek(pak, packFSize, SEEK_CUR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("not found (skipping)\n");
|
||||||
|
|
||||||
|
return -1; // we only get this if it isn't required
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
#include "SDL/SDL_endian.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
|
||||||
|
extern void showErrorAndExit(int errorId, char *name);
|
||||||
|
|
||||||
|
extern globalEngineVariables engine;
|
|
@ -0,0 +1 @@
|
||||||
|
|
|
@ -0,0 +1,261 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "weapons.h"
|
||||||
|
|
||||||
|
void setWeaponShapes()
|
||||||
|
{
|
||||||
|
for (int i = 0 ; i < MAX_WEAPONS ; i++)
|
||||||
|
{
|
||||||
|
weapon[i].image[0] = graphics.shape[weapon[i].imageIndex[0]];
|
||||||
|
weapon[i].image[1] = graphics.shape[weapon[i].imageIndex[1]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if USEPACK
|
||||||
|
|
||||||
|
void loadWeapons()
|
||||||
|
{
|
||||||
|
int dataLocation = locateDataInPak("data/weapons.dat", 1);
|
||||||
|
int id, ammo, damage, reload, speed, image1, image2, flags;
|
||||||
|
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
fp = fopen(PACKLOCATION, "rb");
|
||||||
|
fseek(fp, dataLocation, SEEK_SET);
|
||||||
|
|
||||||
|
for (int i = 0 ; i < MAX_WEAPONS ; i++)
|
||||||
|
{
|
||||||
|
fscanf(fp, "%d", &id);
|
||||||
|
fscanf(fp, "%d", &ammo);
|
||||||
|
fscanf(fp, "%d", &damage);
|
||||||
|
fscanf(fp, "%d", &reload);
|
||||||
|
fscanf(fp, "%d", &speed);
|
||||||
|
fscanf(fp, "%d", &image1);
|
||||||
|
fscanf(fp, "%d", &image2);
|
||||||
|
fscanf(fp, "%d", &flags);
|
||||||
|
|
||||||
|
weapon[i].id = id;
|
||||||
|
weapon[i].ammo[0] = ammo;
|
||||||
|
weapon[i].damage = damage;
|
||||||
|
weapon[i].reload[0] = reload;
|
||||||
|
weapon[i].speed = speed;
|
||||||
|
weapon[i].imageIndex[0] = image1;
|
||||||
|
weapon[i].imageIndex[1] = image2;
|
||||||
|
weapon[i].flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void initWeapons() {loadWeapons();}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void saveWeapons()
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
|
||||||
|
fp = fopen("data/weapons.dat", "wb");
|
||||||
|
if (fp == NULL)
|
||||||
|
{
|
||||||
|
printf("Unable to write Weapon Data File\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0 ; i < MAX_WEAPONS ; i++)
|
||||||
|
{
|
||||||
|
fprintf(fp, "%d ", weapon[i].id);
|
||||||
|
fprintf(fp, "%d ", weapon[i].ammo[0]);
|
||||||
|
fprintf(fp, "%d ", weapon[i].damage);
|
||||||
|
fprintf(fp, "%d ", weapon[i].reload[0]);
|
||||||
|
fprintf(fp, "%d ", weapon[i].speed);
|
||||||
|
fprintf(fp, "%d ", weapon[i].imageIndex[0]);
|
||||||
|
fprintf(fp, "%d ", weapon[i].imageIndex[1]);
|
||||||
|
fprintf(fp, "%d\n", weapon[i].flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put an extra line for the PAK file "just in case"
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
A list of predefined weaponary. Will most probably
|
||||||
|
be placed into a data file in the final build.
|
||||||
|
*/
|
||||||
|
void initWeapons()
|
||||||
|
{
|
||||||
|
// Player's weapon (this NEVER allocated to anything else)
|
||||||
|
weapon[W_PLAYER_WEAPON].id = WT_PLASMA;
|
||||||
|
weapon[W_PLAYER_WEAPON].ammo[0] = 1;
|
||||||
|
weapon[W_PLAYER_WEAPON].damage = 1;
|
||||||
|
weapon[W_PLAYER_WEAPON].reload[0] = 15;
|
||||||
|
weapon[W_PLAYER_WEAPON].speed = 10;
|
||||||
|
weapon[W_PLAYER_WEAPON].imageIndex[0] = 0;
|
||||||
|
weapon[W_PLAYER_WEAPON].imageIndex[1] = 0;
|
||||||
|
weapon[W_PLAYER_WEAPON].flags = WF_STRAIGHT;
|
||||||
|
|
||||||
|
// Nor is this one!
|
||||||
|
weapon[W_PLAYER_WEAPON2] = weapon[W_PLAYER_WEAPON];
|
||||||
|
|
||||||
|
// Single Shot
|
||||||
|
weapon[W_SINGLE_SHOT].id = WT_PLASMA;
|
||||||
|
weapon[W_SINGLE_SHOT].ammo[0] = 1;
|
||||||
|
weapon[W_SINGLE_SHOT].damage = 1;
|
||||||
|
weapon[W_SINGLE_SHOT].reload[0] = 15;
|
||||||
|
weapon[W_SINGLE_SHOT].speed = 10;
|
||||||
|
weapon[W_SINGLE_SHOT].imageIndex[0] = 0;
|
||||||
|
weapon[W_SINGLE_SHOT].imageIndex[1] = 1;
|
||||||
|
weapon[W_SINGLE_SHOT].flags = WF_STRAIGHT;
|
||||||
|
|
||||||
|
// Double Shot
|
||||||
|
weapon[W_DOUBLE_SHOT] = weapon[W_SINGLE_SHOT];
|
||||||
|
weapon[W_DOUBLE_SHOT].ammo[0] = 2;
|
||||||
|
|
||||||
|
// Triple Shot
|
||||||
|
weapon[W_TRIPLE_SHOT] = weapon[W_SINGLE_SHOT];
|
||||||
|
weapon[W_TRIPLE_SHOT].ammo[0] = 3;
|
||||||
|
|
||||||
|
// Rockets
|
||||||
|
weapon[W_ROCKETS].id = WT_ROCKET;
|
||||||
|
weapon[W_ROCKETS].ammo[0] = 1;
|
||||||
|
weapon[W_ROCKETS].damage = 15;
|
||||||
|
weapon[W_ROCKETS].reload[0] = 45;
|
||||||
|
weapon[W_ROCKETS].speed = 20;
|
||||||
|
weapon[W_ROCKETS].flags = WF_STRAIGHT;
|
||||||
|
weapon[W_ROCKETS].imageIndex[0] = 2;
|
||||||
|
weapon[W_ROCKETS].imageIndex[1] = 3;
|
||||||
|
|
||||||
|
// Double Rockets (uses ROCKETS as base)
|
||||||
|
weapon[W_DOUBLE_ROCKETS] = weapon[W_ROCKETS];
|
||||||
|
weapon[W_DOUBLE_ROCKETS].ammo[0] = 2;
|
||||||
|
weapon[W_DOUBLE_ROCKETS].reload[0] = 80;
|
||||||
|
|
||||||
|
// Micro Rockets
|
||||||
|
weapon[W_MICRO_ROCKETS].id = WT_ROCKET;
|
||||||
|
weapon[W_MICRO_ROCKETS].ammo[0] = 5;
|
||||||
|
weapon[W_MICRO_ROCKETS].damage = 3;
|
||||||
|
weapon[W_MICRO_ROCKETS].reload[0] = 30;
|
||||||
|
weapon[W_MICRO_ROCKETS].speed = 15;
|
||||||
|
weapon[W_MICRO_ROCKETS].flags = WF_STRAIGHT + WF_VARIABLE_SPEED;
|
||||||
|
weapon[W_MICRO_ROCKETS].imageIndex[0] = 2;
|
||||||
|
weapon[W_MICRO_ROCKETS].imageIndex[1] = 3;
|
||||||
|
|
||||||
|
// Energy Ray
|
||||||
|
weapon[W_ENERGYRAY].id = WT_ENERGYRAY;
|
||||||
|
weapon[W_ENERGYRAY].ammo[0] = 255;
|
||||||
|
weapon[W_ENERGYRAY].damage = 1;
|
||||||
|
weapon[W_ENERGYRAY].reload[0] = 25; // reload for energy ray is never used
|
||||||
|
weapon[W_ENERGYRAY].speed = 15;
|
||||||
|
weapon[W_ENERGYRAY].flags = WF_STRAIGHT;
|
||||||
|
|
||||||
|
// Laser
|
||||||
|
weapon[W_LASER].id = WT_LASER;
|
||||||
|
weapon[W_LASER].ammo[0] = 1;
|
||||||
|
weapon[W_LASER].damage = 3;
|
||||||
|
weapon[W_LASER].reload[0] = 1;
|
||||||
|
weapon[W_LASER].speed = 10;
|
||||||
|
weapon[W_LASER].imageIndex[0] = 1;
|
||||||
|
weapon[W_LASER].imageIndex[1] = 1;
|
||||||
|
weapon[W_LASER].flags = WF_STRAIGHT;
|
||||||
|
|
||||||
|
// Beam up weapon
|
||||||
|
weapon[W_CHARGER].id = WT_CHARGER;
|
||||||
|
weapon[W_CHARGER].ammo[0] = 1;
|
||||||
|
weapon[W_CHARGER].damage = 1;
|
||||||
|
weapon[W_CHARGER].reload[0] = 0;
|
||||||
|
weapon[W_CHARGER].speed = 12;
|
||||||
|
weapon[W_CHARGER].flags = WF_STRAIGHT;
|
||||||
|
weapon[W_CHARGER].imageIndex[0] = 33;
|
||||||
|
weapon[W_CHARGER].imageIndex[1] = 34;
|
||||||
|
|
||||||
|
// Homing missile
|
||||||
|
weapon[W_HOMING_MISSILE].id = WT_ROCKET;
|
||||||
|
weapon[W_HOMING_MISSILE].ammo[0] = 1;
|
||||||
|
weapon[W_HOMING_MISSILE].damage = 15;
|
||||||
|
weapon[W_HOMING_MISSILE].reload[0] = 35;
|
||||||
|
weapon[W_HOMING_MISSILE].speed = 10;
|
||||||
|
weapon[W_HOMING_MISSILE].flags = WF_STRAIGHT + WF_HOMING;
|
||||||
|
weapon[W_HOMING_MISSILE].imageIndex[0] = 4;
|
||||||
|
weapon[W_HOMING_MISSILE].imageIndex[1] = 4;
|
||||||
|
|
||||||
|
// Double homing missile
|
||||||
|
weapon[W_DOUBLE_HOMING_MISSILES] = weapon[W_HOMING_MISSILE];
|
||||||
|
weapon[W_DOUBLE_HOMING_MISSILES].ammo[0] = 2;
|
||||||
|
weapon[W_DOUBLE_HOMING_MISSILES].reload[0] = 65;
|
||||||
|
weapon[W_DOUBLE_HOMING_MISSILES].imageIndex[0] = 4;
|
||||||
|
weapon[W_DOUBLE_HOMING_MISSILES].imageIndex[1] = 4;
|
||||||
|
|
||||||
|
// Micro homing missiles
|
||||||
|
weapon[W_MICRO_HOMING_MISSILES].id = WT_ROCKET;
|
||||||
|
weapon[W_MICRO_HOMING_MISSILES].ammo[0] = 5;
|
||||||
|
weapon[W_MICRO_HOMING_MISSILES].damage = 12;
|
||||||
|
weapon[W_MICRO_HOMING_MISSILES].reload[0] = 65;
|
||||||
|
weapon[W_MICRO_HOMING_MISSILES].speed = 3;
|
||||||
|
weapon[W_MICRO_HOMING_MISSILES].flags = WF_STRAIGHT + WF_HOMING;
|
||||||
|
weapon[W_MICRO_HOMING_MISSILES].imageIndex[0] = 4;
|
||||||
|
weapon[W_MICRO_HOMING_MISSILES].imageIndex[1] = 4;
|
||||||
|
|
||||||
|
// Aimed plasma bolt (2x damage)
|
||||||
|
weapon[W_AIMED_SHOT].id = WT_DIRECTIONAL;
|
||||||
|
weapon[W_AIMED_SHOT].ammo[0] = 1;
|
||||||
|
weapon[W_AIMED_SHOT].damage = 2;
|
||||||
|
weapon[W_AIMED_SHOT].reload[0] = 15;
|
||||||
|
weapon[W_AIMED_SHOT].speed = 0;
|
||||||
|
weapon[W_AIMED_SHOT].flags = WF_STRAIGHT + WF_AIMED;
|
||||||
|
weapon[W_AIMED_SHOT].imageIndex[0] = 33;
|
||||||
|
weapon[W_AIMED_SHOT].imageIndex[1] = 34;
|
||||||
|
|
||||||
|
// 3 way spread weapon
|
||||||
|
weapon[W_SPREADSHOT].id = WT_SPREAD;
|
||||||
|
weapon[W_SPREADSHOT].ammo[0] = 3;
|
||||||
|
weapon[W_SPREADSHOT].damage = 1;
|
||||||
|
weapon[W_SPREADSHOT].reload[0] = 10;
|
||||||
|
weapon[W_SPREADSHOT].speed = 10;
|
||||||
|
weapon[W_SPREADSHOT].flags = WF_THIN_SPREAD;
|
||||||
|
weapon[W_SPREADSHOT].imageIndex[0] = 0;
|
||||||
|
weapon[W_SPREADSHOT].imageIndex[1] = 1;
|
||||||
|
|
||||||
|
// Sid's ion cannon like weapon
|
||||||
|
weapon[W_IONCANNON].id = WT_PLASMA;
|
||||||
|
weapon[W_IONCANNON].ammo[0] = 1;
|
||||||
|
weapon[W_IONCANNON].damage = 1;
|
||||||
|
weapon[W_IONCANNON].reload[0] = 2;
|
||||||
|
weapon[W_IONCANNON].speed = 10;
|
||||||
|
weapon[W_IONCANNON].flags = WF_STRAIGHT + WF_DISABLE + WF_AIMED;
|
||||||
|
weapon[W_IONCANNON].imageIndex[0] = 35;
|
||||||
|
weapon[W_IONCANNON].imageIndex[1] = 35;
|
||||||
|
|
||||||
|
// Directional Shock Missile - Used by Kline in final battle
|
||||||
|
weapon[W_DIRSHOCKMISSILE].id = WT_ROCKET;
|
||||||
|
weapon[W_DIRSHOCKMISSILE].ammo[0] = 5;
|
||||||
|
weapon[W_DIRSHOCKMISSILE].damage = 20;
|
||||||
|
weapon[W_DIRSHOCKMISSILE].reload[0] = 60;
|
||||||
|
weapon[W_DIRSHOCKMISSILE].speed = 0;
|
||||||
|
weapon[W_DIRSHOCKMISSILE].flags = WF_STRAIGHT + WF_AIMED + WF_TIMEDEXPLOSION;
|
||||||
|
weapon[W_DIRSHOCKMISSILE].imageIndex[0] = 4;
|
||||||
|
weapon[W_DIRSHOCKMISSILE].imageIndex[1] = 4;
|
||||||
|
|
||||||
|
saveWeapons();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2003 Parallel Realities
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "SDL/SDL.h"
|
||||||
|
#include "SDL/SDL_image.h"
|
||||||
|
#include "SDL/SDL_mixer.h"
|
||||||
|
|
||||||
|
#include "defs.h"
|
||||||
|
#include "structs.h"
|
||||||
|
#include "classes.h"
|
||||||
|
|
||||||
|
extern int locateDataInPak(char *file, signed char required);
|
||||||
|
|
||||||
|
extern Graphics graphics;
|
||||||
|
extern object weapon[MAX_WEAPONS];
|
||||||
|
|
|
@ -0,0 +1,339 @@
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
|
||||||
|
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Library General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
Appendix: How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) 19yy <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Library General
|
||||||
|
Public License instead of this License.
|
|
@ -0,0 +1,368 @@
|
||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||||
|
<HTML>
|
||||||
|
<HEAD>
|
||||||
|
<TITLE></TITLE>
|
||||||
|
<META NAME="Generator" CONTENT="TextPad 4.0">
|
||||||
|
<META NAME="Author" CONTENT="?">
|
||||||
|
<META NAME="Keywords" CONTENT="?">
|
||||||
|
<META NAME="Description" CONTENT="?">
|
||||||
|
|
||||||
|
<STYLE>
|
||||||
|
a {color: #499FFF; text-decoration: none; font-family: helvetica;}
|
||||||
|
a:hover {color: #499FFF; text-decoration: underline}
|
||||||
|
body {color: #FFFFFF; background: #000000; font: 10pt helvetica;}
|
||||||
|
table {color: #FFFFFF; font: 10pt helvetica;}
|
||||||
|
td {color: #FFFFFF;}
|
||||||
|
</STYLE>
|
||||||
|
|
||||||
|
</HEAD>
|
||||||
|
|
||||||
|
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#FF0000" VLINK="#800000" ALINK="#FF00FF">
|
||||||
|
|
||||||
|
<CENTER>
|
||||||
|
<IMG SRC="sflogo.gif">
|
||||||
|
<H3>Gameplay Manual</H3>
|
||||||
|
</CENTER>
|
||||||
|
<P></P>
|
||||||
|
|
||||||
|
<TABLE BGCOLOR="#000099" WIDTH="100%"><TR><TD><B>License Agreement</B></TR></TR></TABLE>
|
||||||
|
<P>Project: Starfighter<BR>
|
||||||
|
Copyright Parallel Realities 2003<BR>
|
||||||
|
All Rights Reserved
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
This program is free software; you can redistribute it and/or<BR>
|
||||||
|
modify it under the terms of the GNU General Public License<BR>
|
||||||
|
as published by the Free Software Foundation; either version 2<BR>
|
||||||
|
of the License, or (at your option) any later version.<BR>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
This program is distributed in the hope that it will be useful,<BR>
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of<BR>
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.<BR>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
See the GNU General Public License for more details.<BR>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
You should have received a copy of the GNU General Public License<BR>
|
||||||
|
along with this program; if not, write to the Free Software<BR>
|
||||||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.<BR>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<TABLE BGCOLOR="#000099" WIDTH="100%"><TR><TD><B>Introduction</B></TR></TR></TABLE>
|
||||||
|
<P>
|
||||||
|
Project: Starfighter is an old school 2D shoot 'em up. In the game you take on the role of a
|
||||||
|
rebel pilot called Chris, who is attempting to overthrow a military corporation called Weapco. Weapco
|
||||||
|
has seized control of the known universe and currently rules it with an iron fist. Chris can no longer
|
||||||
|
stand back and watch as millions of people suffer and die. He steals an experimental craft known
|
||||||
|
as "Firefly" and begins his mission to fight his way to Sol, freeing key systems along the way. The
|
||||||
|
game opens with Chris attempting to escape a Weapco patrol that has intercepted him.
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<TABLE BGCOLOR="#000099" WIDTH="100%"><TR><TD><B>Installation</B></TD></TR></TABLE>
|
||||||
|
<P>Binary files are provided for both Windows and Linux*.</P>
|
||||||
|
<P>Installation under Windows</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
Unzip the archive into a suitable directory and then double click the Starfighter.exe
|
||||||
|
file to begin. Games and settings will be saved into this directory.
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P>Installation under Linux</P>
|
||||||
|
|
||||||
|
<PRE>
|
||||||
|
tar zxf starfighter.tar.gz
|
||||||
|
cd Starfighter
|
||||||
|
make
|
||||||
|
make install
|
||||||
|
</PRE>
|
||||||
|
|
||||||
|
<P>When the game is first run it will attempt to create</P>
|
||||||
|
|
||||||
|
<PRE>
|
||||||
|
~/.parallelrealities/starfighter/
|
||||||
|
</PRE>
|
||||||
|
|
||||||
|
<P>Should this fail the game will not run.</P>
|
||||||
|
|
||||||
|
<P><I>* x86 binary compiled with g++ on Mandrake 9. Source and makefile are provided for Linux users
|
||||||
|
who need to recompile</I></P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<TABLE BGCOLOR="#000099" WIDTH="100%"><TR><TD><B>Controls</B></TD></TR></TABLE>
|
||||||
|
|
||||||
|
<P>Menus</P>
|
||||||
|
<UL>
|
||||||
|
Arrow Keys - Highlight option<BR>
|
||||||
|
Left Control / Space - Select menu option<BR>
|
||||||
|
</UL>
|
||||||
|
|
||||||
|
<P>Intermission Screen</P>
|
||||||
|
<UL>
|
||||||
|
Mouse - Move cursor<BR>
|
||||||
|
Left Mouse Button - Selected option<BR>
|
||||||
|
Right Mouse Button - Toggle planet orbit On / Off<BR>
|
||||||
|
</UL>
|
||||||
|
|
||||||
|
<P>In Game</P>
|
||||||
|
<UL>
|
||||||
|
Arrow Keys - Control Firefly<BR>
|
||||||
|
Left Ctrl - Fire primary weapon<BR>
|
||||||
|
Space - Fire secondary weapon<BR>
|
||||||
|
Shift - Toggle Primary Weapon Concentrate / Spread (see Weaponry)<BR>
|
||||||
|
T - Targetting Arrow On /Off<BR>
|
||||||
|
P - Pause / Unpause<BR>
|
||||||
|
Escape - Flee (not possible until all primary missions completed)<BR>
|
||||||
|
Escape whilst paused - Quit to title screen<BR>
|
||||||
|
</UL>
|
||||||
|
|
||||||
|
<P>Note - Keys cannot be changed</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<TABLE BGCOLOR="#000099" WIDTH="100%"><TR><TD><B>How to Play</B></TD></TR></TABLE>
|
||||||
|
<P>When first starting Project: Starfighter you will see the text scrolling introduction. You can
|
||||||
|
either wait for this to finish or you can skip it by pressing ctrl or space.</P>
|
||||||
|
<P>The title sequence will begin. Once the menu is shown (or you opt to skip to it by pressing
|
||||||
|
space or ctrl) you may select from the options shown</P>
|
||||||
|
|
||||||
|
<TABLE>
|
||||||
|
<TR><TD BGCOLOR="#FF0000"><CENTER> Start New Game </CENTER></TD></TR>
|
||||||
|
<TR><TD BGCOLOR="#FF0000"><CENTER> Load Game* </CENTER></TD></TR>
|
||||||
|
<TR><TD BGCOLOR="#FF0000"><CENTER> Continue Current Game* </CENTER></TD></TR>
|
||||||
|
<TR><TD BGCOLOR="#FF0000"><CENTER> Options </CENTER></TD></TR>
|
||||||
|
<TR><TD BGCOLOR="#FF0000"><CENTER> Quit </CENTER></TD></TR>
|
||||||
|
</TABLE>
|
||||||
|
|
||||||
|
<P><I>* will only be shown if there are saved games available</I></P>
|
||||||
|
|
||||||
|
<P><B>Start New Game</B><BR>
|
||||||
|
This will start a new game
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P><B>Load Game</B><BR>
|
||||||
|
This will bring up a list of currently available games to be loaded, along with the planet that
|
||||||
|
the game was saved in. This option is only shown when there is at least one saved game available.
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P><B>Continue Current Game</B><BR>
|
||||||
|
This will automatically load the most recently saved game. This option is only shown when there is
|
||||||
|
at least one saved game available.
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P><B>Options</B><BR>
|
||||||
|
This will show a list of game options. Options for sound, music and an auto save slot can be changed.
|
||||||
|
Music and Sound can be switched to either On or Off. The Auto Save Slot allows the player to select
|
||||||
|
a save slot that will automatically be updated when the player finishes a mission. This can be
|
||||||
|
switched from None to 1, 2, 3, 4 or 5. When this option is set to a number, that save slot will be
|
||||||
|
used to save a game at the end of a mission. Note that any currently existing game will be
|
||||||
|
automatically overwritten.
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P><B>Quit</B><BR>
|
||||||
|
This will quit the game. Quitting is immediate, without prompting (the game can also be quit at
|
||||||
|
anytime by clicking the close button of the window).
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<TABLE BGCOLOR="#000099" WIDTH="100%"><TR><TD><B>Loading and Saving Games</B></TD></TR></TABLE>
|
||||||
|
<P>Games can be loaded from the title screen. When there are saved games available, the option "Load
|
||||||
|
Game" will be shown. Selecting this will show a list of available games to be loaded. Select a game
|
||||||
|
from the list to load, you will then be taken to the Intermission screen. To go back, selected
|
||||||
|
Back to Main Menu.</P>
|
||||||
|
<P>Games can be saved in two ways. The first way is to save a game on the Intermission screen. Move
|
||||||
|
the cursor to the Save Game icon and select it. You will see a list of five game slots that can be
|
||||||
|
used to save a game to. Click one of these and then click the "Save" button to save the game. The
|
||||||
|
second way is to use the Auto Save function. This will automatically save your game after you have
|
||||||
|
successfully completed a mission. To make use of this feature you must choose a save slot that
|
||||||
|
you wish to auto save into. This can be done on the title screen in the options section or on
|
||||||
|
the intermission screen at the options section.</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<TABLE BGCOLOR="#000099" WIDTH="100%"><TR><TD><B>Getting Missions</B></TD></TR></TABLE>
|
||||||
|
<P>In each System, the player can get missions by going to the Comms section of the Intermission
|
||||||
|
screen. Here allies will inform you of tasks that need to be performed and what planet these tasks
|
||||||
|
apply to. Once the player has decided which task they will perform, they must go to the corresponding
|
||||||
|
planet in the system (see Moving Around for more details). Once stationed at the planet
|
||||||
|
click "Start Mission" to proceed to the mission briefing screen. The "Start Mission" icon will not
|
||||||
|
be shown if the mission of the planet has been completed.</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<TABLE BGCOLOR="#000099" WIDTH="100%"><TR><TD><B>Mission Briefing</B></TD></TR></TABLE>
|
||||||
|
<P>Before the beginning of each mission you will be presented with a mission briefing screen. This
|
||||||
|
will outline the mission's primary and (if any) secondary objectives. It will also inform you of
|
||||||
|
mission restrictions, such as time limits. Once you have read this, press ctrl or space to
|
||||||
|
continue</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<TABLE BGCOLOR="#000099" WIDTH="100%"><TR><TD><B>Completing Missions</B></TD></TR></TABLE>
|
||||||
|
<P>Each mission in the game has one or more objectives tied to it. These objectives are either
|
||||||
|
Primary or Secondary objectives. In order to complete the mission, the player must complete all the
|
||||||
|
primary mission objectives. For example, when the game begins Chris is fleeing a WEAPCO patrol. The
|
||||||
|
primary objective for this mission is to destroy all the enemy fighters. Once this is achieved the
|
||||||
|
Firefly will leave the sector and the mission will be marked as a success.</P>
|
||||||
|
<P>One thing to note is that some missions will have both Primary and Secondary objectives. In this
|
||||||
|
case, the Firefly does not leave the sector if all primary mission objectives are complete and
|
||||||
|
secondary objectives remain. The player may then attempt to complete remaining secondary
|
||||||
|
objectives or press Escape to leave the sector. Secondary objectives are optional.</P>
|
||||||
|
<P>During the mission you will see messages appearing at the bottom of the screen. These messages
|
||||||
|
can be related to items that you pick up, as well as mission related information.<P>
|
||||||
|
<P>
|
||||||
|
<FONT COLOR="#FFFFFF">White messages</FONT> are standard for picking up items such as cash and
|
||||||
|
power ups<BR>
|
||||||
|
<FONT COLOR="#00FF00">Green messages</FONT> signify successful completion of mission objectives<BR>
|
||||||
|
<FONT COLOR="#00FFFF">Light Blue messages </FONT>give further details about Primary mission
|
||||||
|
requirements<BR>
|
||||||
|
<FONT COLOR="#FF0000">Red messages</FONT> indicate mission failures, warnings and wing mate
|
||||||
|
ejections<BR>
|
||||||
|
<FONT COLOR="#FFFF00">Yellow messages</FONT> give further details about Secondary mission requirements
|
||||||
|
<BR>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<TABLE BGCOLOR="#000099" WIDTH="100%"><TR><TD><B>The Target Arrow</B></TD></TR></TABLE>
|
||||||
|
<P>
|
||||||
|
<IMG SRC="targetArrow.png" ALIGN="LEFT">
|
||||||
|
The Target Arrow can be used to locate enemies and point you in the direction that the enemy craft
|
||||||
|
is. You can toggle the Target Arrow on or off by pressing "T" on the keyboard. This arrow is very
|
||||||
|
useful for finding enemies that are evasive (such as transports) on missions that require you to
|
||||||
|
destroy all present craft. Simply follow the arrow to find the enemy. The arrow will not be displayed
|
||||||
|
when you are within the immediate vacinity of the target. On certain missions (such as Bosses) the
|
||||||
|
arrow will initially point towards a certain target that is part of the mission objective. The
|
||||||
|
target's current remaining shield is also displayed in the bottom right hand corner of the screen.
|
||||||
|
Please note that due to the nature of the game, the target arrow cannot be cycled through enemies.
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<TABLE BGCOLOR="#000099" WIDTH="100%"><TR><TD><B>Moving Around Systems</B></TD></TR></TABLE>
|
||||||
|
<P>To play a mission in Starfighter you must be stationed at the relevant planet. To get to the
|
||||||
|
planet you require, you will need to click on the planet whilst viewing it on the Show System section
|
||||||
|
of the Intermission screen. Travelling between planets can be dangerous, but luckily Spirit is a
|
||||||
|
peaceful place and there are no chances of interceptions, so travel is instantaneous.</P>
|
||||||
|
<P>Other systems are not as friendly and whilst travelling to a new destination the player runs
|
||||||
|
the risk of being intercepted by a WEAPCO patrol. After Spirit the player will select a planet
|
||||||
|
to travel to by clicking on it with the mouse. "Destination", followed by the planet's name
|
||||||
|
will appear in the bottom right hand corner of the screen. A new icon labelled "Go To Destination"
|
||||||
|
will also appear. Clicking this icon will make the player travel to the destination planet.</P>
|
||||||
|
<P>Travelling to new planets is represented at the bottom of the screen by the two planets (the
|
||||||
|
one being travelled from and the one being travelled to). A red bar will fill up as the journey
|
||||||
|
progresses. The speed the bar fills up will vary occurring to how far away the planets are from
|
||||||
|
one another. At any point during this time the planet can be intercepted (see Interceptions).
|
||||||
|
Once the red bar has filled up completely the journey will be completed and you will be
|
||||||
|
stationed that the new planet.</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<TABLE BGCOLOR="#000099" WIDTH="100%"><TR><TD><B>Interceptions</B></TD></TR></TABLE>
|
||||||
|
<P>Interceptions can take place whilst travelling between two planets within a system. When the
|
||||||
|
player is intercepted they will go directly into a mission-like scenario. The objective of this
|
||||||
|
interception is to clear all attacking forces. Once this is done, the player will be free to
|
||||||
|
leave.</P>
|
||||||
|
<P>Interceptions also serve other purposes - Sometimes the WEAPCO patrol may have slave
|
||||||
|
transports with them. One of the objectives of a later system is to rescue a certain amount of
|
||||||
|
slaves. This is only possible during interceptions.</P>
|
||||||
|
<P>One important thing to remember is that any damage the player receives during an interception
|
||||||
|
will NOT be repaired until they have reached the destination planet. Therefore if the player
|
||||||
|
is heavily damaged during one interception that damage will still be present if they are
|
||||||
|
attacked again. This can make interceptions very dangerous.</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<TABLE BGCOLOR="#000099" WIDTH="100%"><TR><TD><B>Weaponry and Upgrades</B></TD></TR></TABLE>
|
||||||
|
<P>During the course of the game you will receive money. Money is gained from destroying enemy craft
|
||||||
|
and picking up cash spheres in game (please be aware that due to the nature of the game cash is not
|
||||||
|
earned for destroying ships during Interceptions).</P>
|
||||||
|
<P>Money can be used to upgrade the Firefly and purchase additional ammunition for weapons. Items
|
||||||
|
can be purchased from a shop on the Intermission screen.</P>
|
||||||
|
|
||||||
|
<P><B>Temporary Upgrades</B>
|
||||||
|
<UL>Temporary upgrades are used to boost the Firefly's ability to be powered up. For example, at
|
||||||
|
the start of the game the Firefly can only be powered up to fire two plasma bolts are once. By
|
||||||
|
purchasing an upgrade for the Firefly, you can allow for power ups to enable you to fire a maximum
|
||||||
|
of up to five plasma bolts at once. Note that this only affects power ups and these will still be
|
||||||
|
ammunition limited. To upgrade your default weapon, you will need permanent power ups (see below).
|
||||||
|
</UL>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P><B>Permanent Upgrades</B></P>
|
||||||
|
<UL>These power ups are more expensive than temporary upgrades, but are permanent. Whereas a temporary
|
||||||
|
upgrade requires you to make use of power ups on an ammunition limited base, permanent power ups are
|
||||||
|
not limited. This is highly useful when facing heavily shielded and tough opponents, with no means
|
||||||
|
of getting plasma ammo or transports in sight! When you power up your permanent weapon, your
|
||||||
|
powered up weapon level will also be automatically upgraded if it is less powerful than your new
|
||||||
|
current power up level.<P/>
|
||||||
|
When the Firefly's Primary Weapon has been upgraded to its maximum output (3 plasma cannons) the
|
||||||
|
player can toggle the output type by pressing Shift. The output type can either be Concentrate (the
|
||||||
|
default firing type) or Spread. Various situations can call for varying the output type.
|
||||||
|
</UL>
|
||||||
|
|
||||||
|
<P><B>Secondary Weapons</B></P>
|
||||||
|
<UL>
|
||||||
|
As well as primary weapons and temporary upgrades, the Firefly is also capable of using a
|
||||||
|
secondary weapon. At the start of the game this is a rocket launcher. Like the other weapons in the
|
||||||
|
game this can be upgraded by purchasing a new weapon from the shop. At the start of the game, a
|
||||||
|
Double Rocket Launcher and Micro Rocket Launcher are available for purchase. Secondary weapons are
|
||||||
|
used in the same way the rocket launcher is used (Space to fire). However the Laser Cannon and
|
||||||
|
Charge Cannon work differently.<P/>
|
||||||
|
Neither the Charge Cannon or the Laser Cannon are ammunition limited (unlike the other rocket based
|
||||||
|
weapons). The Charge Cannon works by the player holding down the Space bar and releasing it. A
|
||||||
|
meter at the bottom of the screen shows how much charge has been built up. The Laser Cannon works
|
||||||
|
by the player holding down the Space bar to fire a stream of laser fire. It is prone to over heating
|
||||||
|
and must be allowed to cool after usage.
|
||||||
|
</UL>
|
||||||
|
|
||||||
|
<P>Certain weapons and upgrades will not be available to you until later in the game, so remember
|
||||||
|
to save your money for them</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<TABLE BGCOLOR="#000099" WIDTH="100%"><TR><TD><B>Item Spheres</B></TD></TR></TABLE>
|
||||||
|
<P>When an enemy craft is destroyed they will sometimes release ammo and cash spheres. Certain
|
||||||
|
enemy craft will release power up spheres that can give your weapon a temporary boost. The following
|
||||||
|
are spheres that can be picked up during missions,</P>
|
||||||
|
<TABLE>
|
||||||
|
<TR><TD><IMG SRC="cash.gif"></TD><TD><B>Cash Sphere</B> - Provides you with an additional cash bonus</TD></TR>
|
||||||
|
<TR><TD><IMG SRC="ammo.gif"></TD><TD><B>Plasma Ammo Sphere</B> - Increases your current plasma ammo</TD></TR>
|
||||||
|
<TR><TD><IMG SRC="rocketAmmo.png"></TD><TD><B>Rocket Ammo Sphere</B> - Increases your current rocket ammo</TD></TR>
|
||||||
|
<TR><TD><IMG SRC="plasmaDamage.png"></TD><TD><B>Power Sphere</B> - Boosts your plasma power</TD></TR>
|
||||||
|
<TR><TD><IMG SRC="plasmaAmmo.png"></TD><TD><B>Output Sphere</B> - Boosts the amount of plasma shots you can fire</TD></TR>
|
||||||
|
<TR><TD><IMG SRC="plasmaRate.png"></TD><TD><B>Cooler Sphere</B> - Increases your plasma firing rate</TD></TR>
|
||||||
|
<TR><TD><IMG SRC="superCharge.png"></TD><TD><B>Super Sphere</B> - Three / Five way spread, full power and cooling (Rare)</TD></TR>
|
||||||
|
</TABLE>
|
||||||
|
</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<TABLE BGCOLOR="#000099" WIDTH="100%"><TR><TD><B>Cut Scenes</B></TD></TR></TABLE>
|
||||||
|
<P>During the course of the game mini cut scenes will be shown after certain missions. These scenes
|
||||||
|
serve to extend the plot of the game and provide the player with gameplay tips. If you wish to
|
||||||
|
skip a cut scene press Escape. It is advised that you only skip cut scenes if you have already seen
|
||||||
|
them.</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<TABLE BGCOLOR="#000099" WIDTH="100%"><TR><TD><B>Ending the Game</B></TD></TR></TABLE>
|
||||||
|
<P>The game is over when the Firefly's shield units are reduced to 0 (zero), or a Primary Mission
|
||||||
|
objective is failed. At this point, you will see the Game Over screen. To continue, press Ctrl
|
||||||
|
or Space. You will then be taken back to the title screen. In certain missions the game will end
|
||||||
|
if Sid Wilson is killed.</P>
|
||||||
|
|
||||||
|
<P>
|
||||||
|
<TABLE BGCOLOR="#000099" WIDTH="100%"><TR><TD><B>About</B></TD></TR></TABLE>
|
||||||
|
|
||||||
|
<P>Parallel Realities started off writing games on the Amiga using AMOS and then, later, Blitz Basic
|
||||||
|
2. Games written included the BOTSS Trilogy and most notably TANX Squadron. TANX Squadron was awarded
|
||||||
|
Amiga Format's contributor prize of the month in the summer of 1999. Project: Starfighter originally
|
||||||
|
started life on the Amiga but was never completed. Development began again for Linux in 2002 with this
|
||||||
|
being our first C program. The game matured quickly from the initial ideas and this is the finished
|
||||||
|
product. We do hope you enjoy playing it.</P>
|
||||||
|
|
||||||
|
<P>Project: Starfighter<BR>
|
||||||
|
Copyright Parallel Realities 2003<BR>
|
||||||
|
All Rights Reserved</P>
|
||||||
|
<P>Created using the <A HREF="http://www.libsdl.org">SDL library</A></P>
|
||||||
|
|
||||||
|
<P ALIGN="RIGHT"><A HREF="http://www.parallelrealities.co.uk">www.parallelrealities.co.uk</A></P>
|
||||||
|
|
||||||
|
</BODY>
|
||||||
|
</HTML>
|
|
@ -0,0 +1,37 @@
|
||||||
|
CFLAGS = `sdl-config --cflags` -Wall -DLINUX
|
||||||
|
LIBS = `sdl-config --libs` -lSDL_mixer -lSDL_image
|
||||||
|
OBJS = ai.o aliens.o audio.o bullets.o cargo.o collectable.o comms.o debris.o events.o explosions.o game.o globals.o graphics.o init.o intermission.o loadSave.o messages.o misc.o missions.o player.o resources.o script.o shop.o Starfighter.o title.o unpack.o weapons.o
|
||||||
|
|
||||||
|
VERSION = 1.1
|
||||||
|
PROG = starfighter
|
||||||
|
PACK = starfighter.pak
|
||||||
|
DOCS = docs/*
|
||||||
|
|
||||||
|
BINDIR = /usr/games/
|
||||||
|
DATADIR = /usr/share/games/parallelrealities/
|
||||||
|
DOCDIR = /usr/share/doc/starfighter/
|
||||||
|
# top-level rule to create the program.
|
||||||
|
all: $(PROG)
|
||||||
|
|
||||||
|
# compiling other source files.
|
||||||
|
%.o: code/%.cpp code/%.h code/structs.h code/defs.h code/classes.h
|
||||||
|
$(CXX) $(CFLAGS) -c -O3 -DVERSION=\"$(VERSION)\" -DPACKLOCATION=\"$(DATADIR)$(PACK)\" $<
|
||||||
|
|
||||||
|
# linking the program.
|
||||||
|
$(PROG): $(OBJS)
|
||||||
|
$(CXX) $(LIBS) $(OBJS) -o $(PROG)
|
||||||
|
|
||||||
|
# cleaning everything that can be automatically recreated with "make".
|
||||||
|
clean:
|
||||||
|
$(RM) $(OBJS)
|
||||||
|
|
||||||
|
distclean:
|
||||||
|
$(RM) $(PROG)
|
||||||
|
|
||||||
|
# install
|
||||||
|
install:
|
||||||
|
mkdir -p $(DATADIR)
|
||||||
|
strip $(PROG)
|
||||||
|
install -o root -g games -m 755 $(PROG) $(BINDIR)$(PROG)
|
||||||
|
install -o root -g games -m 644 $(PACK) $(DATADIR)$(PACK)
|
||||||
|
cp $(DOCS) $(DOCDIR)
|
Loading…
Reference in New Issue