Added Alien Blaster project with SDL for Android

This commit is contained in:
pelya
2009-12-01 11:29:28 +02:00
parent 2134f8a8fa
commit a73d367531
1336 changed files with 345356 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
APP_PROJECT_PATH := $(call my-dir)/project
APP_MODULES := stlport sdl alienblaster sdl_mixer tremor

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.schwardtnet.alienblaster"
android:versionCode="1"
android:versionName="1.0">
<application android:label="@string/app_name">
<activity android:name=".DemoActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="4" />
</manifest>

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="DemoActivity" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked in in Version
Control Systems. -->
<property file="local.properties" />
<!-- The build.properties file can be created by you and is never touched
by the 'android' tool. This is the place to change some of the default property values
used by the Ant rules.
Here are some properties you may want to change/update:
application.package
the name of your application package as defined in the manifest. Used by the
'uninstall' rule.
source.dir
the name of the source directory. Default is 'src'.
out.dir
the name of the output directory. Default is 'bin'.
Properties related to the SDK location or the project target should be updated
using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your application and
should be checked in in Version Control Systems.
-->
<property file="build.properties" />
<!-- The default.properties file is created and updated by the 'android' tool, as well
as ADT.
This file is an integral part of the build system for your application and
should be checked in in Version Control Systems. -->
<property file="default.properties" />
<!-- Custom Android task to deal with the project target, and import the proper rules.
This requires ant 1.6.0 or above. -->
<path id="android.antlibs">
<pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
<pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
<pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
<pathelement path="${sdk.dir}/tools/lib/apkbuilder.jar" />
<pathelement path="${sdk.dir}/tools/lib/jarutils.jar" />
</path>
<taskdef name="setup"
classname="com.android.ant.SetupTask"
classpathref="android.antlibs" />
<!-- Execute the Android Setup task that will setup some properties specific to the target,
and import the build rules files.
The rules file is imported from
<SDK>/platforms/<target_platform>/templates/android_rules.xml
To customize some build steps for your project:
- copy the content of the main node <project> from android_rules.xml
- paste it in this build.xml below the <setup /> task.
- disable the import by changing the setup task below to <setup import="false" />
This will ensure that the properties are setup correctly but that your customized
build steps are used.
-->
<setup />
</project>

View File

@@ -0,0 +1,13 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "build.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-4
# Indicates whether an apk should be generated for each density.
split.density=false

View File

@@ -0,0 +1,12 @@
# The namespace in Java file, with dots replaced with underscores
SDL_JAVA_PACKAGE_PATH := de_schwardtnet_alienblaster
# Path to files with application data - they should be downloaded from Internet on first app run inside
# Java sources, or unpacked from resources (TODO)
# Typically /sdcard/alienblaster
# Or /data/data/de.schwardtnet.alienblaster/files if you're planning to unpack data in application private folder
# Your application will just set current directory there
SDL_CURDIR_PATH := /sdcard/alienblaster
include $(call all-subdir-makefiles)

View File

@@ -0,0 +1,29 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := alienblaster
CG_SUBDIRS := \
src \
# Add more subdirs here, like src/subdir1 src/subdir2
LOCAL_CFLAGS := $(foreach D, $(CG_SUBDIRS), -I$(CG_SRCDIR)/$(D)) \
-I$(LOCAL_PATH)/../sdl/include \
-I$(LOCAL_PATH)/../sdl_mixer \
-I$(LOCAL_PATH)/../stlport/stlport \
#Change C++ file extension as appropriate
LOCAL_CPP_EXTENSION := .cpp
LOCAL_SRC_FILES := $(foreach F, $(CG_SUBDIRS), $(addprefix $(F)/,$(notdir $(wildcard $(LOCAL_PATH)/$(F)/*.cpp))))
# Uncomment to also add C sources
LOCAL_SRC_FILES += $(foreach F, $(CG_SUBDIRS), $(addprefix $(F)/,$(notdir $(wildcard $(LOCAL_PATH)/$(F)/*.c))))
LOCAL_STATIC_LIBRARIES := sdl_mixer sdl tremor stlport
LOCAL_LDLIBS := -lGLESv1_CM -ldl -llog
include $(BUILD_SHARED_LIBRARY)

View File

@@ -0,0 +1,66 @@
# game name
GAME_NAME=alienBlaster
# the compiler to use
COMPILER=g++
# include path
INCLUDE_PATH=-I.
#OPTIMIZATION=-g -pg -fprofile-arcs
#OPTIMIZATION=-O3
OPTIMIZATION=-g
#OPTIMIZATION=
# SDL library
SDL_LIBS=$(shell sdl-config --libs)
SDL_FLAGS=$(shell sdl-config --cflags)
# game flags
GAME_FLAGS=-D_GNU_SOURCE -Wall -Winline -finline-functions $(SDL_FLAGS) $(OPTIMIZATION)
GAME_LIBS=-lSDL_mixer $(SDL_LIBS) $(OPTIMIZATION)
# all objectfiles
OBJECT_FILES=main.o surfaceDB.o soundDB.o options.o geometry.o video.o game.o \
racer.o racers.o shots.o shot.o boundingBox.o items.o item.o font.o \
explosion.o explosions.o mixer.o enemys.o enemy.o wrecks.o wreck.o \
settings.o intro.o setDifficulty.o global.o formation.o infoscreen.o \
menuArcadeMode.o sonic.o banners.o banner.o smokePuff.o smokePuffs.o \
shieldGlow.o background.o input.o
.PHONY: all game clean realclean rebuild tgz
all: depend $(GAME_NAME)
clean:
rm -f *.o *.da
realclean:
rm -f *.o *.da *~ Makefile.dep
rebuild: realclean game
.SUFFIXES: .cc
# How to compile a c++ programm
$(GAME_NAME): $(OBJECT_FILES)
@echo ""
@echo ""
@echo "Linking $@"
@$(COMPILER) $(GAME_LIBS) -o $(GAME_NAME) $(OBJECT_FILES)
mv $(GAME_NAME) ../
%.o: %.cc
@echo ""
@echo ""
@echo "Compiling $<"
@$(COMPILER) $(GAME_FLAGS) $(INCLUDE_PATH) -c $< -o $@
depend: dep
dep:
-touch Makefile.dep
-makedepend $(INCLUDE_PATH) -Y -f Makefile.dep *.cc 2> /dev/null
-rm -f Makefile.dep.bak
-include Makefile.dep

View File

@@ -0,0 +1,32 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef _AS_STRING_H_
#define _AS_STRING_H_
#include <sstream>
template<typename T> std::string asString(const T& obj) {
std::ostringstream t;
t << obj;
std::string res(t.str());
return res;
}
#endif

View File

@@ -0,0 +1,138 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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 "background.h"
#include "global.h"
#include "surfaceDB.h"
#include "SDL.h"
#include <iostream>
using namespace std;
Background::Background() {
minTileWidth = 9999999;
minTileHeight = 9999999;
tilesPerLine = 0;
tilesPerColumn = 0;
step = 0;
}
void Background::clearTileList() {
tileNames.clear();
tilesPerLine = 0;
tilesPerColumn = 0;
}
void Background::addTile( string tilename ) {
tileNames.push_back( tilename );
}
void Background::generateBackground( int length ) {
tileSurfaces.clear();
minTileWidth = 9999999;
minTileHeight = 9999999;
// load all tiles
vector< SDL_Surface* > tmpTiles;
for(int i=tileNames.size()-1; i>=0; i--) {
SDL_Surface *tile = surfaceDB.loadSurface( tileNames[i] );
if (tile != NULL) {
tmpTiles.push_back( tile );
if (tile->w < minTileWidth) {
minTileWidth = tile->w;
}
if (tile->h < minTileHeight) {
minTileHeight = tile->h;
}
}
}
// calculate tiles per line and tiles per row
tilesPerLine = SCREEN_WIDTH / minTileWidth;
if (SCREEN_WIDTH % minTileWidth) {
tilesPerLine++;
}
tilesPerColumn = SCREEN_HEIGHT / minTileHeight;
if (SCREEN_HEIGHT % minTileHeight) {
tilesPerColumn++;
}
int rows = length / minTileHeight;
if (length % minTileHeight) {
rows++;
}
// cout << "Background: minTileWidth=" << minTileWidth << " minTileHeight=" << minTileHeight << " rows=" << rows << endl;
// generate random background
for(int i=rows*tilesPerLine; i; i--) {
tileSurfaces.push_back( tmpTiles[ rand() % tmpTiles.size() ] );
}
}
void Background::draw( SDL_Surface* screen ) {
step = (step+1) % (tilesPerColumn*minTileHeight);
draw( screen, step );
}
void Background::draw( SDL_Surface* screen, int step ) {
if (step < 0) {
step *= -1;
}
int startLine = (step / minTileHeight);
int offset = (step % minTileHeight);
SDL_Rect srcRect;
srcRect.x = 0;
srcRect.y = 0;
SDL_Rect dstRect;
for(int y = 0; y < tilesPerColumn+1; y++) {
for(int x = 0; x < tilesPerLine; x++) {
int diffX = SCREEN_WIDTH - x * minTileWidth;
if ( diffX >= minTileWidth ) {
srcRect.w = minTileWidth;
} else {
srcRect.w = diffX;
}
dstRect.w = srcRect.w;
if (y==0) {
int diffY = -(offset - minTileHeight);
srcRect.h = diffY;
} else {
srcRect.h = minTileHeight;
}
dstRect.h = srcRect.h;
dstRect.x = x * minTileWidth;
dstRect.y = SCREEN_HEIGHT + offset - (y+1) * minTileHeight;
SDL_BlitSurface( tileSurfaces[ ((y+startLine)*tilesPerLine+x) % tileSurfaces.size()] , &srcRect, screen, &dstRect );
}
}
}

View File

@@ -0,0 +1,51 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef _BACKGROUND_H_
#define _BACKGROUND_H_
#include <vector>
#include <string>
class SDL_Surface;
class Background {
public:
Background();
void clearTileList();
void addTile( std::string tilename );
void generateBackground( int length );
void draw( SDL_Surface* screen );
void draw( SDL_Surface* screen, int step );
private:
int minTileWidth;
int minTileHeight;
int tilesPerLine;
int tilesPerColumn;
int step;
std::vector< std::string > tileNames;
std::vector< SDL_Surface* > tileSurfaces;
};
#endif

View File

@@ -0,0 +1,122 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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 "banner.h"
#include "surfaceDB.h"
#include <iostream>
Banner::Banner( BannerTexts text, BannerModes mode, BannerBoni bonus ) {
sprite = surfaceDB.loadSurface( FN_BANNER_TEXTS[ text ], true );
this->mode = mode;
if ( this->mode == BANNER_MODE_RANDOM ) {
this->mode = (BannerModes)(rand() % NR_BANNER_MODES);
}
this->bonus = bonus;
if ( this->bonus != BANNER_BONUS_NONE ) {
spriteBonus = surfaceDB.loadSurface( FN_BANNER_BONUS[ bonus ], true );
}
pos = Vector2D( -1000, -1000 );
if ( mode == BANNER_MODE_ITEM_COLLECTED_SINGLE_PLAYER ) {
pos = Vector2D( 10, SCREEN_HEIGHT - 20 - sprite->h );
} else if ( mode == BANNER_MODE_ITEM_COLLECTED_PLAYER_ONE ) {
pos = Vector2D( 10, SCREEN_HEIGHT - 20 - sprite->h );
} else if ( mode == BANNER_MODE_ITEM_COLLECTED_PLAYER_TWO ) {
pos = Vector2D( SCREEN_WIDTH - sprite->w - 10,
SCREEN_HEIGHT - 20 - sprite->h );
}
timeLived = 0;
}
Banner::~Banner() {}
bool Banner::isExpired() {
return timeLived > BANNER_MODE_LIFETIME[ mode ];
}
void Banner::update( int dT ) {
timeLived += dT;
switch ( mode ) {
case BANNER_MODE_FLY_FROM_LEFT:
{
if ( timeLived < 1000 ) {
pos = Vector2D( -(sprite->w) + ((SCREEN_WIDTH + sprite->w)/ 2) * (timeLived / 1000.0),
200 - sprite->h / 2 );
} else if ( 1000 < timeLived && timeLived < 3000 ) {
pos = Vector2D( ( SCREEN_WIDTH - sprite->w ) / 2,
200 - sprite->h / 2 );
} else {
pos = Vector2D( ((SCREEN_WIDTH - sprite->w)/2) +
((SCREEN_WIDTH + sprite->w)/2)*((timeLived-3000)/2000.0),
200 - sprite->h / 2 );
}
break;
}
case BANNER_MODE_FROM_TOP:
{
if ( timeLived < 1000 ) {
pos = Vector2D( (SCREEN_WIDTH - sprite->w)/2,
-(sprite->h) + (200 + sprite->h/2) * (timeLived / 1000.0) );
} else if ( 1000 < timeLived && timeLived < 3000 ) {
pos = Vector2D( (SCREEN_WIDTH - sprite->w)/2,
200 - (sprite->h / 2 ) );
} else {
pos = Vector2D( (SCREEN_WIDTH - sprite->w)/2,
200 - (sprite->h / 2) +
(200 + (sprite->h / 2))*((timeLived-3000)/2000.0) );
}
break;
}
case BANNER_MODE_ITEM_COLLECTED_SINGLE_PLAYER:
case BANNER_MODE_ITEM_COLLECTED_PLAYER_ONE:
case BANNER_MODE_ITEM_COLLECTED_PLAYER_TWO:
{
break;
}
default:
{
break;
}
}
}
bool Banner::movingAway() {
return ( 3000 <= timeLived );
}
void Banner::draw(SDL_Surface *screen) {
SDL_Rect r;
r.x = lroundf(pos.getX());
r.y = lroundf(pos.getY());
r.w = sprite->w;
r.h = sprite->h;
SDL_BlitSurface( sprite, 0, screen, &r );
if ( bonus != BANNER_BONUS_NONE &&
1000 < timeLived && timeLived < 3000 ) {
r.x = SCREEN_WIDTH / 2 - spriteBonus->w / 2;
r.y = 250;
r.w = spriteBonus->w;
r.h = spriteBonus->h;
SDL_BlitSurface( spriteBonus, 0, screen, &r );
}
}

View File

@@ -0,0 +1,50 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef BANNER_H
#define BANNER_H
#include "SDL.h"
#include <string>
#include "geometry.h"
#include "global.h"
class Banner {
SDL_Surface *sprite;
SDL_Surface *spriteBonus;
int sound;
Vector2D pos;
int timeLived;
BannerModes mode;
BannerBoni bonus;
public:
Banner( BannerTexts text, BannerModes mode, BannerBoni bonus );
~Banner();
void update( int dT );
void draw( SDL_Surface *screen );
bool isExpired();
bool movingAway();
};
#endif

View File

@@ -0,0 +1,90 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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 "banners.h"
#include "banner.h"
using namespace std;
Banners::Banners() {}
Banners::~Banners() {
vector<Banner *>::iterator i;
for (i = banners.begin(); i != banners.end(); ++i) {
delete *i;
}
}
void Banners::addBanner( BannerTexts bannerText, BannerModes mode,
BannerBoni bonus ) {
Banner *newBanner = new Banner( bannerText, mode, bonus );
banners.push_back( newBanner );
}
void Banners::expireBanners() {
unsigned int i = 0;
while ( i < banners.size() ) {
if ( banners[i]->isExpired() ) {
delete banners[i];
banners.erase(banners.begin() + i);
} else {
i++;
}
}
}
void Banners::deleteAllBanners() {
unsigned int i = 0;
while ( i < banners.size() ) {
delete banners[i];
i++;
}
banners.clear();
}
void Banners::update( int dT ) {
switch ( banners.size() ) {
case 0: break;
case 1: banners[0]->update( dT ); break;
default:
{
banners[0]->update( dT );
if ( banners[0]->movingAway() ) {
banners[1]->update( dT );
}
break;
}
}
}
void Banners::draw(SDL_Surface *screen) {
switch ( banners.size() ) {
case 0: break;
case 1: banners[0]->draw( screen ); break;
default:
{
banners[0]->draw( screen );
if ( banners[0]->movingAway() ) {
banners[1]->draw( screen );
}
break;
}
}
}

View File

@@ -0,0 +1,46 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef BANNERS_H
#define BANNERS_H
#include "SDL.h"
#include "global.h"
#include <vector>
#include <string>
class Banner;
class Banners {
std::vector<Banner *> banners;
public:
Banners();
~Banners();
void addBanner( BannerTexts bannerText, BannerModes mode=BANNER_MODE_RANDOM,
BannerBoni bonus=ARCADE_BONUS_FOR_FORMATION_DESTRUCTION );
void expireBanners();
void deleteAllBanners();
void update( int dT );
void draw(SDL_Surface *screen);
};
#endif

View File

@@ -0,0 +1,123 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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 "boundingBox.h"
/*
void setX(Uint16 newX) {box.x = newX;}
void setY(Uint16 newY) {box.y = newY;}
void setWidth(Uint16 newWidth) {box.w = newWidth;}
void setHeight(Uint16 newHeight) {box.h = newHeight;}
*/
BoundingBox::BoundingBox(int x, int y, int width, int height) {
box.x = x;
box.y = y;
box.w = width;
box.h = height;
}
int BoundingBox::getUpperBound() {
return box.y;
}
int BoundingBox::getLowerBound() {
return box.y + box.h;
}
int BoundingBox::getLeftBound() {
return box.x;
}
int BoundingBox::getRightBound() {
return box.x + box.w;
}
bool BoundingBox::overlaps(BoundingBox *other) {
return ( !(getUpperBound() > other->getLowerBound()) &&
!(getLowerBound() < other-> getUpperBound()) &&
!(getLeftBound() > other->getRightBound()) &&
!(getRightBound() < other->getLeftBound()) );
}
bool BoundingBox::overlaps(const Vector2D &startOfLine, const Vector2D &endOfLine) {
// FIXME: optimize me!
RectangleGeo rect( Vector2D( box.x, box.y ),
Vector2D( box.x + box.w, box.y + box.h ) );
// FIXME: optimize me!
bool overlaps = false;
overlaps = rect.isInside( endOfLine );
if ( overlaps ) return true;
overlaps = rect.isInside( startOfLine );
if ( overlaps ) return true;
// check some points between the two end points
Vector2D delta((endOfLine.getX() - startOfLine.getX()) / 4.0,
(endOfLine.getY() - startOfLine.getY()) / 4.0);
Vector2D actPoint = startOfLine + delta;
int i = 1;
while (!overlaps && i <= 3 ) {
overlaps = rect.isInside(actPoint);
actPoint += delta;
i++;
}
return overlaps;
}
bool BoundingBox::overlaps(const Circle &circle) {
RectangleGeo rect( Vector2D( box.x, box.y ),
Vector2D( box.x + box.w, box.y + box.h ) );
return (rect.isInside(circle.getCenter()) ||
circle.isInside(rect.getPosLeftTop()) ||
circle.isInside(rect.getPosRightBottom()) ||
circle.isInside(Vector2D( box.x, box.y + box.h )) ||
circle.isInside(Vector2D( box.x + box.w, box.y )));
}
void BoundingBox::modifyX(int value) {
box.x += value;
}
void BoundingBox::modifyY(int value) {
box.y += value;
}
void BoundingBox::moveUpperBound(int upperBound) {
box.y = upperBound;
}
void BoundingBox::moveLowerBound(int lowerBound) {
box.y = lowerBound - box.h;
}
void BoundingBox::moveLeftBound(int leftBound) {
box.x = leftBound;
}
void BoundingBox::moveRightBound(int rightBound) {
box.x = rightBound - box.w;
}
/*
SDL_Rect *BoundingBox::getRect() {
return &box;
}
*/

View File

@@ -0,0 +1,54 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef BOUNDING_BOX_H
#define BOUNDING_BOX_H
#include "SDL.h"
#include "geometry.h"
struct MyRect {
int x, y, w, h;
};
class BoundingBox {
private:
//SDL_Rect box;
MyRect box;
public:
BoundingBox(int x, int y, int width, int height);
int getUpperBound();
int getLowerBound();
int getLeftBound();
int getRightBound();
bool overlaps(BoundingBox *other);
bool overlaps(const Vector2D &startOfLine, const Vector2D &endOfLine);
bool overlaps(const Circle &circle);
void modifyX(int value);
void modifyY(int value);
void moveUpperBound(int upperBound);
void moveLowerBound(int lowerBound);
void moveLeftBound(int leftBound);
void moveRightBound(int rightBound);
// SDL_Rect *getRect();
};
#endif

View File

@@ -0,0 +1,537 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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 "enemy.h"
#include "SDL.h"
#include "surfaceDB.h"
#include "boundingBox.h"
#include "mixer.h"
#include "shots.h"
#include "shot.h"
#include "racers.h"
#include "racer.h"
#include "items.h"
#include "item.h"
#include "wrecks.h"
#include "wreck.h"
#include "global.h"
#include "explosions.h"
#include "explosion.h"
#include "options.h"
Enemy::Enemy( Vector2D pos, Vector2D vel, EnemyTypes whichEnemyType,
bool isInFormation, bool fireByFormation ) {
this->isInFormation = isInFormation;
this->fireByFormation = fireByFormation;
enemyType = whichEnemyType;
hitpoints = ENEMY_HITPOINTS[ enemyType ];
this->pos = pos;
this->vel = vel;
relTargetPos = Vector2D(0,0);
switch ( enemyType ) {
case FIGHTER:
{
string fn = LVL_ENEMY_FIGHTER;
levelConf->getStr( LVL_ENEMY_FIGHTER, fn );
spriteEnemy = surfaceDB.loadSurface( fn );
fn = LVL_ENEMY_FIGHTER_SHADOW;
levelConf->getStr( LVL_ENEMY_FIGHTER_SHADOW, fn );
spriteShadow = surfaceDB.loadSurface( fn, true );
break;
}
case BOMBER:
{
string fn = LVL_ENEMY_BOMBER;
levelConf->getStr( LVL_ENEMY_BOMBER, fn );
spriteEnemy = surfaceDB.loadSurface( fn );
fn = LVL_ENEMY_BOMBER_SHADOW;
levelConf->getStr( LVL_ENEMY_BOMBER_SHADOW, fn );
spriteShadow = surfaceDB.loadSurface( fn, true );
break;
}
case TANK:
{
string fn = LVL_ENEMY_TANK;
levelConf->getStr( LVL_ENEMY_TANK, fn );
spriteEnemy = surfaceDB.loadSurface( fn );
break;
}
case BOSS_1_MAIN_GUN:
{
string fn = LVL_ENEMY_BOSS_1_MAIN_GUN;
levelConf->getStr( LVL_ENEMY_BOSS_1_MAIN_GUN, fn );
spriteEnemy = surfaceDB.loadSurface( fn );
break;
}
case BOSS_1_ROCKET_LAUNCHER:
{
string fn = LVL_ENEMY_BOSS_1_ROCKET_LAUNCHER;
levelConf->getStr( LVL_ENEMY_BOSS_1_ROCKET_LAUNCHER, fn );
spriteEnemy = surfaceDB.loadSurface( fn );
break;
}
case BOSS_1_SHOT_BATTERY_LEFT:
{
string fn = LVL_ENEMY_BOSS_1_SHOT_BATTERY_LEFT;
levelConf->getStr( LVL_ENEMY_BOSS_1_SHOT_BATTERY_LEFT, fn );
spriteEnemy = surfaceDB.loadSurface( fn );
break;
}
case BOSS_1_SHOT_BATTERY_RIGHT:
{
string fn = LVL_ENEMY_BOSS_1_SHOT_BATTERY_RIGHT;
levelConf->getStr( LVL_ENEMY_BOSS_1_SHOT_BATTERY_RIGHT, fn );
spriteEnemy = surfaceDB.loadSurface( fn );
break;
}
case BOSS_2:
{
spriteEnemy = surfaceDB.loadSurface( FN_ENEMY_BOSS_2 );
spriteShadow = surfaceDB.loadSurface( FN_ENEMY_BOSS_2_SHADOW, true );
boss2PointReached = false;
boss2TargetPos = Vector2D(SCREEN_WIDTH / 2, 100);
break;
}
default:
{
string fn = LVL_ENEMY_FIGHTER;
levelConf->getStr( LVL_ENEMY_FIGHTER, fn );
spriteEnemy = surfaceDB.loadSurface( fn );
break;
}
}
boundingBox = new BoundingBox( lroundf(pos.getX() - spriteEnemy->w * 0.45),
lroundf(pos.getY() - spriteEnemy->h * 0.45),
lroundf(spriteEnemy->w * 0.9),
lroundf(spriteEnemy->h * 0.9) );
nextShotPrimary = rand() % (ENEMY_RAND_WAIT_PRIMARY[ enemyType ]+1);
nextShotSecondary = rand() % (ENEMY_RAND_WAIT_SECONDARY[ enemyType ]+1);
sndShotPrimary = mixer.loadSample( FN_SOUND_SHOT_PRIMARY );
sndShotSecondary = mixer.loadSample( FN_SOUND_SHOT_SECONDARY );
}
Enemy::~Enemy() {
delete boundingBox;
}
bool Enemy::isExpired() {
return ( hitpoints <= 0 ||
pos.getY() < -500 ||
pos.getY() > SCREEN_HEIGHT + 500 ||
pos.getX() < -500 ||
pos.getX() > SCREEN_WIDTH + 500 );
}
void Enemy::expire() {
hitpoints = -1;
}
Circle Enemy::getBoundingCircle() {
return Circle( pos, min(spriteEnemy->w / 2, spriteEnemy->h / 2) );
}
BoundingBox *Enemy::getBoundingBox() {
return boundingBox;
}
bool Enemy::collidesWith( const Vector2D &shotPosOld, const Vector2D &shotPosNew ) {
return boundingBox->overlaps(shotPosOld, shotPosNew);
}
bool Enemy::collidesWith( BoundingBox *box ) {
return boundingBox->overlaps( box );
}
bool Enemy::collidesWith( const Circle &circle ) {
return boundingBox->overlaps( circle );
}
bool Enemy::collidesWithAsCircle( const Circle &circle ) {
return ( circle.getRadius() + spriteEnemy->w / 2 > circle.getCenter().distanceTo( pos ) );
}
bool Enemy::collidesWithAsCircle( BoundingBox *box ) {
return ( box->overlaps( Circle( pos, min( spriteEnemy->h / 2, spriteEnemy->w / 2 ) ) ) );
}
void Enemy::update( int dT ) {
move( dT );
if ( !fireByFormation ) {
shootPrimary( dT );
shootSecondary( dT );
}
}
void Enemy::move( int dT ) {
switch ( enemyType ) {
case FIGHTER:
case BOMBER:
{
if ( scrollingOn ) pos += vel * dT / 1000.0;
else pos += (vel - SCROLL_SPEED) * dT / 1000.0;
if ( isInFormation && relTargetPos != Vector2D(0,0) ) {
Vector2D addMovement =
Vector2D( 40, relTargetPos.getDirection(), POLAR ) * dT / 1000.0;
if ( addMovement.getLength() > relTargetPos.getLength() ) {
addMovement.setLength( relTargetPos.getLength() );
}
pos += addMovement;
relTargetPos -= addMovement;
}
updateBoundingBox();
break;
}
case TANK: {
if ( scrollingOn ) pos += vel * dT / 1000.0;
updateBoundingBox();
break;
}
case BOSS_1_MAIN_GUN:
case BOSS_1_ROCKET_LAUNCHER:
case BOSS_1_SHOT_BATTERY_LEFT:
case BOSS_1_SHOT_BATTERY_RIGHT: {
if ( scrollingOn ) {
pos += Vector2D( 0, SCROLL_SPEED * dT / 1000.0 );
updateBoundingBox();
if ( pos.getY() >= BOSS_1_END_Y ) {
scrollingOn = false;
pos.setY( BOSS_1_END_Y );
}
}
break;
}
case BOSS_2: {
if ( boss2PointReached ) {
boss2TargetPos = Vector2D( (rand() % (SCREEN_WIDTH - spriteEnemy->w)) + spriteEnemy->w / 2, rand() % 100 + spriteEnemy->h );
boss2PointReached = false;
} else {
pos += (boss2TargetPos - pos) / 50;
}
if ( pos.distanceTo(boss2TargetPos) < 15.0 ) boss2PointReached = true;
updateBoundingBox();
break;
}
default: cout << "enemys.cc::move(): unknown enemyType" << endl; break;
}
}
void Enemy::updateBoundingBox() {
boundingBox->moveUpperBound( lroundf(pos.getY() - spriteEnemy->h * 0.45) );
boundingBox->moveLeftBound( lroundf(pos.getX() - spriteEnemy->w * 0.45) );
}
void Enemy::firePrimary() {
switch (enemyType) {
case FIGHTER:
{
Shot *shot =
new Shot( ENEMY_SHOT_NORMAL, 666,
pos + Vector2D( 0, spriteEnemy->h / 2 ),
90 );
shots->addShot( shot );
mixer.playSample( sndShotPrimary, 0 );
break;
}
case BOMBER:
{
Shot *shot =
new Shot( ENEMY_SHOT_NORMAL, 666,
pos + Vector2D( -7, spriteEnemy->h / 2 ),
100 );
shots->addShot( shot );
shot =
new Shot( ENEMY_SHOT_NORMAL, 666,
pos + Vector2D( +7, spriteEnemy->h / 2 ),
80 );
shots->addShot( shot );
mixer.playSample( sndShotPrimary, 0 );
break;
}
case TANK:
{
Shot *shot =
new Shot( ENEMY_SHOT_NORMAL, 666,
pos,
(rand() % 360) - 180 );
shots->addShot( shot );
mixer.playSample( sndShotPrimary, 0 );
break;
}
case BOSS_1_MAIN_GUN:
{
Shot *shot =
new Shot( ENEMY_SHOT_NORMAL, 666,
pos,
(rand() % 20) + 80 );
shots->addShot( shot );
mixer.playSample( sndShotPrimary, 0 );
break;
}
case BOSS_1_SHOT_BATTERY_LEFT:
{
Shot *shot =
new Shot( ENEMY_SHOT_NORMAL, 666,
pos,
(rand() % 120) + 30 );
shots->addShot( shot );
mixer.playSample( sndShotPrimary, 0 );
break;
}
case BOSS_1_SHOT_BATTERY_RIGHT:
{
Shot *shot =
new Shot( ENEMY_SHOT_NORMAL, 666,
pos,
(rand() % 120) + 30 );
shots->addShot( shot );
mixer.playSample( sndShotPrimary, 0 );
break;
}
case BOSS_1_ROCKET_LAUNCHER:
{
unsigned int racerIdx = rand() % racers->getNrRacers();
float angle = (racers->getRacer( racerIdx )->getPos() - pos).getDirection();
Shot *shot =
new Shot( ENEMY_SHOT_TANK_ROCKET, 666, pos, angle );
shots->addShot( shot );
mixer.playSample( sndShotSecondary, 0 );
break;
}
case BOSS_2:
{
unsigned int racerIdx = rand() % racers->getNrRacers();
float angle = (racers->getRacer( racerIdx )->getPos() - pos).getDirection();
Shot *shot = new Shot( ENEMY_SHOT_NORMAL, 666, pos, angle );
shots->addShot( shot );
mixer.playSample( sndShotPrimary, 0 );
break;
}
default:
{
break;
}
}
}
void Enemy::shootPrimary( int dT ) {
nextShotPrimary -= dT;
if ( nextShotPrimary < 0 ) {
firePrimary();
nextShotPrimary =
(rand() % (ENEMY_RAND_WAIT_PRIMARY[ enemyType ]+1)) + ENEMY_COOLDOWN_PRIMARY[ enemyType ];
}
}
void Enemy::fireSecondary() {
switch (enemyType) {
case TANK:
{
unsigned int racerIdx = rand() % racers->getNrRacers();
float angle = (racers->getRacer( racerIdx )->getPos() - pos).getDirection();
Shot *shot =
new Shot( ENEMY_SHOT_TANK_ROCKET, 666, pos, angle );
shots->addShot( shot );
mixer.playSample( sndShotSecondary, 0 );
break;
}
case BOSS_2:
{
unsigned int racerIdx = rand() % racers->getNrRacers();
float angle = (racers->getRacer( racerIdx )->getPos() - pos).getDirection();
Shot *shot = new Shot( ENEMY_SHOT_TANK_ROCKET, 666, pos - Vector2D(-80,0), angle );
shots->addShot( shot );
shot = new Shot( ENEMY_SHOT_TANK_ROCKET, 666, pos - Vector2D(+80,0), angle );
shots->addShot( shot );
mixer.playSample( sndShotSecondary, 0 );
break;
}
default:
{
break;
}
}
}
void Enemy::shootSecondary( int dT ) {
nextShotSecondary -= dT;
if ( nextShotSecondary < 0 ) {
fireSecondary();
nextShotSecondary =
(rand() % (ENEMY_RAND_WAIT_SECONDARY[ enemyType ]+1)) +
ENEMY_COOLDOWN_SECONDARY[ enemyType ];
}
}
void Enemy::doDamage( ShotTypes shotType, int fromWhichPlayer ) {
bool allreadyDead = isExpired();
switch (shotType) {
case SHOT_NORMAL: hitpoints -= DAMAGE_SHOT_NORMAL; break;
case SHOT_NORMAL_HEAVY: hitpoints -= DAMAGE_SHOT_NORMAL_HEAVY; break;
case SHOT_DOUBLE: hitpoints -= DAMAGE_SHOT_DOUBLE; break;
case SHOT_DOUBLE_HEAVY: hitpoints -= DAMAGE_SHOT_DOUBLE_HEAVY; break;
case SHOT_TRIPLE: hitpoints -= DAMAGE_SHOT_TRIPLE; break;
case SHOT_HF_NORMAL: hitpoints -= DAMAGE_SHOT_HF_NORMAL; break;
case SHOT_HF_DOUBLE: hitpoints -= DAMAGE_SHOT_HF_DOUBLE; break;
case SHOT_HF_TRIPLE: hitpoints -= DAMAGE_SHOT_HF_TRIPLE; break;
case SHOT_HF_QUATTRO: hitpoints -= DAMAGE_SHOT_HF_QUATTRO; break;
case SHOT_HF_QUINTO: hitpoints -= DAMAGE_SHOT_HF_QUINTO; break;
case SHOT_DUMBFIRE: hitpoints -= DAMAGE_SHOT_DUMBFIRE; break;
case SHOT_DUMBFIRE_DOUBLE: hitpoints -= DAMAGE_SHOT_DUMBFIRE_DOUBLE; break;
case SHOT_KICK_ASS_ROCKET: hitpoints -= DAMAGE_SHOT_KICK_ASS_ROCKET; break;
case SHOT_HELLFIRE: hitpoints -= DAMAGE_SHOT_HELLFIRE; break;
case SHOT_MACHINE_GUN: hitpoints -= DAMAGE_SHOT_MACHINE_GUN; break;
case SHOT_ENERGY_BEAM: hitpoints -= DAMAGE_SHOT_ENERGY_BEAM; break;
case SHOT_HF_DUMBFIRE: hitpoints -= DAMAGE_SHOT_HF_DUMBFIRE; break;
case SHOT_HF_DUMBFIRE_DOUBLE: hitpoints -= DAMAGE_SHOT_HF_DUMBFIRE_DOUBLE; break;
case SHOT_HF_KICK_ASS_ROCKET: hitpoints -= DAMAGE_SHOT_HF_KICK_ASS_ROCKET; break;
case SHOT_HF_LASER: hitpoints -= DAMAGE_SHOT_HF_LASER; break;
case SPECIAL_SHOT_HEATSEEKER: hitpoints -= DAMAGE_SPECIAL_SHOT_HEATSEEKER; break;
case SPECIAL_SHOT_NUKE: hitpoints -= DAMAGE_SPECIAL_SHOT_NUKE; break;
default:
{
cout << "Enemy::doDamage: unexpected shotType: " << shotType << endl;
break;
}
}
if ( enemyType < NR_ENEMY_TYPES_NORMAL ) {
// the enemy just died -> explode, generate item,
if ( (!allreadyDead) && isExpired() ) {
// the player gets points, who did the final shot
if ( 0 <= fromWhichPlayer && fromWhichPlayer < (int)racers->getNrRacers() ) {
racers->getRacer( fromWhichPlayer )->receivePoints( ENEMY_POINTS_FOR_DEST[ enemyType ]);
}
// explode
Explosion *newExplosion =
new Explosion( FN_EXPLOSION_ENEMY, pos, vel, EXPLOSION_NORMAL_AIR );
explosions->addExplosion( newExplosion );
// generate wreck
Wreck *newWreck = new Wreck( pos, WRECK_FOR_ENEMYTYPE[ enemyType ]);
wrecks->addWreck( newWreck );
// generate item
if ( rand() % ENEMY_DIES_ITEM_APPEAR_CHANCE[ enemyType ] == 0 ) {
items->generateItemNow( pos, vel / 10.0 );
}
}
}
// it's a boss!!!
else {
if ( (!allreadyDead) && isExpired() ) {
// explode
Explosion *newExplosion;
for(int i = 0; i < 10; i++){
newExplosion = new Explosion(
FN_EXPLOSION_ENEMY,
pos + Vector2D(rand() % spriteEnemy->w - spriteEnemy->w / 2, rand() % spriteEnemy->h - spriteEnemy->h / 2),
vel + Vector2D(rand() % 100 - 50, rand() % 100 - 50) / 5.0,
EXPLOSION_NORMAL_GROUND );
explosions->addExplosion( newExplosion );
}
// generate wreck
Wreck *newWreck = new Wreck( pos, WRECK_FOR_ENEMYTYPE[ enemyType ]);
wrecks->addWreck( newWreck );
}
}
}
void Enemy::drawGroundEnemy( SDL_Surface *screen ) {
if ( ENEMY_FLYING[ enemyType ] ) return;
SDL_Rect destR;
destR.x = lroundf(pos.getX()) - spriteEnemy->w / 2;
destR.y = lroundf(pos.getY()) - spriteEnemy->h / 2;
destR.w = spriteEnemy->w;
destR.h = spriteEnemy->h;
SDL_BlitSurface( spriteEnemy, 0, screen, &destR );
}
void Enemy::drawAirEnemy( SDL_Surface *screen ) {
if ( !ENEMY_FLYING[ enemyType ] ) return;
SDL_Rect destR;
destR.x = lroundf(pos.getX()) - spriteEnemy->w / 2;
destR.y = lroundf(pos.getY()) - spriteEnemy->h / 2;
destR.w = spriteEnemy->w;
destR.h = spriteEnemy->h;
SDL_BlitSurface( spriteEnemy, 0, screen, &destR );
}
void Enemy::drawShadow( SDL_Surface *screen ) {
if ( !ENEMY_FLYING[ enemyType ] ) return;
SDL_Rect destR;
destR.x = lroundf(pos.getX()) - spriteShadow->w / 2 - ENEMY_FLYING_HEIGHT[ enemyType ];
destR.y = lroundf(pos.getY()) - spriteShadow->h / 2 + ENEMY_FLYING_HEIGHT[ enemyType ];
destR.w = spriteShadow->w;
destR.h = spriteShadow->h;
SDL_BlitSurface( spriteShadow, 0, screen, &destR );
}
void Enemy::drawStats( SDL_Surface *screen ) {
// draw status of the bosses
float pixPerHP = spriteEnemy->w / (float)(ENEMY_HITPOINTS[ enemyType ]);
SDL_Rect destR;
// draw damage
destR.x = lroundf(pos.getX()) - spriteEnemy->w / 2;
destR.y = lroundf(pos.getY()) - spriteEnemy->h / 2 - 4;
float damageToDraw = min( (float)ENEMY_HITPOINTS[ enemyType ] / 2, hitpoints );
destR.w = lroundf(pixPerHP * damageToDraw);
destR.h = 3;
SDL_FillRect( screen, &destR, SDL_MapRGB(screen->format, 255, 0, 0) );
// draw shields
destR.x = lroundf(pos.getX());
destR.y = lroundf(pos.getY()) - spriteEnemy->h / 2 - 4;
float shieldToDraw = min( (float)ENEMY_HITPOINTS[ enemyType ] / 2,
hitpoints - ENEMY_HITPOINTS[ enemyType ] / 2 );
if ( shieldToDraw < 1 ) destR.w = 0;
else destR.w = lroundf(pixPerHP * shieldToDraw);
destR.h = 3;
SDL_FillRect(screen, &destR, SDL_MapRGB(screen->format, 0, 255, 0) );
}

View File

@@ -0,0 +1,124 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef ENEMY_HH
#define ENEMY_HH
#include "SDL.h"
#include "geometry.h"
#include <string>
#include "shot.h"
#include "global.h"
class Shot;
class Shots;
class BoundingBox;
class Enemy {
private:
SDL_Surface *spriteEnemy;
SDL_Surface *spriteShadow;
// for collision with racers or shots.
// A rectangle with racersize * 0.9 is used.
BoundingBox *boundingBox;
// Movement-System
Vector2D pos; // absolute position
Vector2D vel; // the velocity vector
Vector2D relTargetPos;
// needed for cooldown
int nextShotPrimary;
int nextShotSecondary;
int sndShotPrimary;
int sndShotSecondary;
float hitpoints;
EnemyTypes enemyType;
bool isInFormation;
bool fireByFormation;
bool boss2PointReached;
Vector2D boss2TargetPos;
public:
Enemy( Vector2D pos, Vector2D vel, EnemyTypes whichEnemyType, bool isInFormation=false,
bool fireByFormation=false );
~Enemy();
bool isExpired();
void expire();
bool isDead() { return ( hitpoints <= 0 ); }
EnemyTypes getType() { return enemyType; }
void update( int dT );
void firePrimary();
void fireSecondary();
// The enemy will make an additional movement of newRelTargetPos.
// This is used, when the enemy is part of a formation and should move
// to another position in the formation.
void setNewRelTargetPos( Vector2D newRelTargetPos ) { relTargetPos = newRelTargetPos; }
void setPos(Vector2D newPos);
Vector2D getPos() { return pos; }
Vector2D getVel() { return vel; }
Vector2D setVel(Vector2D newVel); // returns old vel
private:
// fire the Guns!
void shootPrimary( int dT );
void shootSecondary( int dT );
// moves the enemy according to his velocity
void move( int dT );
// move the boundingBox accordingly to the movement
void updateBoundingBox();
public:
void drawGroundEnemy( SDL_Surface *screen );
void drawAirEnemy( SDL_Surface *screen );
void drawShadow( SDL_Surface *screen );
void drawStats( SDL_Surface *screen );
// collision system
// return if the line between the two points collides with the boundingBox
bool collidesWith( const Vector2D &shotPosOld, const Vector2D &shotPosNew );
// return if the racers boundingBox overlaps with box
bool collidesWith( BoundingBox *box );
// return if the racers boundingBox overlaps with circle
bool collidesWith( const Circle &circle );
// returns if a inner circle around the racer overlaps with circle
bool collidesWithAsCircle( const Circle &circle );
// returns if a inner circle around the racer overlaps with circle
bool collidesWithAsCircle( BoundingBox *box );
// returns the boundingBox of the racer
BoundingBox *getBoundingBox();
Circle getBoundingCircle();
// the enemy got hit -> do the damage according to the shotType
void doDamage( ShotTypes shotType, int fromWhichPlayer );
};
#endif

View File

@@ -0,0 +1,374 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
using namespace std;
#include <iostream>
#include <math.h>
#include "global.h"
#include "enemys.h"
#include "enemy.h"
#include "racers.h"
#include "racer.h"
#include "wrecks.h"
#include "wreck.h"
#include "surfaceDB.h"
#include "formation.h"
#include "banners.h"
#include "options.h"
Enemys::Enemys() {
timeToNextEnemy = GENERATE_ENEMY_DELAY + (rand() % (GENERATE_ENEMY_RAND_DELAY+1));
timeToNextFormation =
GENERATE_FORMATION_DELAY + (rand() % (GENERATE_FORMATION_RAND_DELAY + 1));
bossActive = 0;
enemysKilled = 0;
enemysGenerated = 0;
}
Enemys::~Enemys() {
vector<Enemy *>::iterator i;
for (i = enemys.begin(); i != enemys.end(); ++i) {
delete *i;
}
vector<Formation *>::iterator f;
for (f = formations.begin(); f != formations.end(); ++f) {
delete *f;
}
}
void Enemys::addEnemy( Enemy *newEnemy ) {
if ( newEnemy ) {
enemys.push_back( newEnemy );
enemysGenerated++;
}
}
bool Enemys::minibossDead(){
for ( unsigned int i = 0; i < enemys.size(); i++ ) {
if ( enemys[ i ]->getType() == BOSS_2 ) return false;
}
return true;
}
bool Enemys::bossDead() {
bool dead = true;
for ( unsigned int i = 0; i < enemys.size(); i++ ) {
if ( enemys[ i ]->getType() >= NR_ENEMY_TYPES_NORMAL ) {
dead = false;
break;
}
}
if (dead) bossActive = 0;
return dead;
}
void Enemys::bossTime( int bossNr ) {
bossActive = bossNr;
Enemy *boss;
Wreck *wreck;
switch (bossNr) {
// Final boss
case 1:
{
wreck = new Wreck( Vector2D( SCREEN_WIDTH / 2 , -120 ), WRECK_BOSS_1_BACKGROUND );
wrecks->addWreck( wreck );
boss = new Enemy( Vector2D( 321, -102 ), Vector2D( 0, SCROLL_SPEED ), BOSS_1_MAIN_GUN );
addEnemy( boss );
boss = new Enemy( Vector2D( 248, -73 ), Vector2D( 0, SCROLL_SPEED ),
BOSS_1_SHOT_BATTERY_LEFT );
addEnemy( boss );
boss = new Enemy( Vector2D( 393, -73 ), Vector2D( 0, SCROLL_SPEED ),
BOSS_1_SHOT_BATTERY_RIGHT );
addEnemy( boss );
boss = new Enemy( Vector2D( 50, -85 ), Vector2D( 0, SCROLL_SPEED ),
BOSS_1_ROCKET_LAUNCHER );
addEnemy( boss );
boss = new Enemy( Vector2D( 590, -85 ), Vector2D( 0, SCROLL_SPEED ),
BOSS_1_ROCKET_LAUNCHER );
addEnemy( boss );
break;
}
// Miniboss
case 2:
{
boss = new Enemy( Vector2D( SCREEN_WIDTH / 2 , -100 ),
Vector2D( 0, SCROLL_SPEED ), BOSS_2 );
addEnemy( boss );
break;
}
default:
{
cout << "Enemys::bossTime: unexpected bossNr: " << bossNr << endl;
break;
}
}
}
void Enemys::generateEnemys( int dT ) {
if ( bossActive != 0 ) return;
timeToNextFormation -= dT;
if ( timeToNextFormation < 0 ) {
FormationTypes whichFormation = (FormationTypes)(rand() % NR_FORMATION_TYPES);
int flags = 0;
if ( rand() % 2 == 0 ) flags = flags | FORMATION_CHANGE_ON_KILL;
if ( rand() % 2 == 0 ) {
flags = flags | FORMATION_CHANGE_SPONTANEOUS;
if ( rand() % 2 == 0 ) flags = flags | FORMATION_CHANGE_OFTEN;
else flags = flags | FORMATION_CHANGE_SELDOM;
}
FormationShotPatterns shotPattern =
(FormationShotPatterns)getRandValue( FORMATION_SP_CHANCES, NR_FORMATION_SP );
Formation *newV =
new Formation( whichFormation,
Vector2D( 80 + (rand() % (SCREEN_WIDTH - 160)), -100 ),
Vector2D( 0, 40 ),
FORMATION_MAX_NR_ENEMYS[ whichFormation ] - (rand() % 3),
(FormationEnemySets)(rand() % NR_FORMATION_ENEMY_SETS),
flags, shotPattern );
formations.push_back( newV );
timeToNextFormation =
GENERATE_FORMATION_DELAY + (rand() % (GENERATE_FORMATION_RAND_DELAY + 1));
}
timeToNextEnemy -= dT;
if ( timeToNextEnemy < 0 ) {
int enemyType = getRandValue( ENEMY_APPEAR_CHANCES, NR_ENEMY_TYPES_NORMAL );
Enemy *newOne = 0;
switch ((EnemyTypes)enemyType) {
case FIGHTER:
{
bool collides;
float xpos;
for ( int i = 0; i < 10; i++ ) {
collides = false;
xpos = 20 + rand() % (SCREEN_WIDTH - 40);
// check if collides with a formation
for ( unsigned int f = 0; f < formations.size(); f++ ) {
Vector2D formationCenter = formations[ f ]->getCenter();
collides =
formationCenter.getY() < 150 &&
fabs(xpos - formationCenter.getX()) < 150;
if (collides) break;
}
}
if ( !collides ) {
newOne = new Enemy( Vector2D( xpos, -20 ), // position
Vector2D( (rand() % 5) - 2, rand() % 7 + 3 ) * 10, // velocity
FIGHTER );
}
break;
}
case BOMBER:
{
bool collides;
float xpos;
for ( int i = 0; i < 10; i++ ) {
collides = false;
xpos = 20 + rand() % (SCREEN_WIDTH - 40);
// check if collides with a formation
for ( unsigned int f = 0; f < formations.size(); f++ ) {
Vector2D formationCenter = formations[ f ]->getCenter();
collides =
formationCenter.getY() < 150 &&
fabs(xpos - formationCenter.getX()) < 150;
if (collides) break;
}
}
if ( !collides ) {
newOne = new Enemy( Vector2D( xpos, -20 ), // position
Vector2D( (rand() % 5) - 2, rand() % 3 + 3 ) * 10, // velocity
BOMBER );
}
break;
}
case TANK:
{
// SDL_Surface *spriteTank = surfaceDB.loadSurface( FN_ENEMY_TANK );
// SDL_Surface *spriteTankWreck = surfaceDB.loadSurface( FN_WRECK_TANK );
string fn1, fn2;
levelConf->getStr( LVL_ENEMY_TANK, fn1 );
levelConf->getStr( LVL_WRECK_TANK, fn2 );
SDL_Surface *spriteTank = surfaceDB.loadSurface( fn1 );
SDL_Surface *spriteTankWreck = surfaceDB.loadSurface( fn2 );
int halfWidthTank = spriteTank->w / 2;
int halfHeightTank = spriteTank->h / 2;
int halfWidthTankWreck = spriteTankWreck->w / 2;
int halfHeightTankWreck = spriteTankWreck->h / 2;
int xPos;
for ( int i = 0; i < 10; i++ ) {
bool collides = false;
xPos = halfWidthTank + rand() % (SCREEN_WIDTH - spriteTank->w);
// check if collides with another tank
for ( unsigned int t = 0; t < enemys.size(); t++ ) {
if ( enemys[ t ]->getType() == TANK ) {
Vector2D enemyTankPos = enemys[ t ]->getPos();
collides =
!(enemyTankPos.getX() - halfWidthTank > xPos + halfWidthTank) &&
!(enemyTankPos.getX() + halfWidthTank < xPos - halfWidthTank) &&
!(enemyTankPos.getY() - halfHeightTank > 0);
if (collides) break;
}
}
if (!collides) {
// check if collides with an old wreck
for ( unsigned int w = 0; w < wrecks->getNrWrecks(); w++ ) {
if ( wrecks->getWreck( w )->getType() == WRECK_TANK ) {
Vector2D wreckPos = wrecks->getWreck(w)->getPos();
collides =
!(wreckPos.getX() - halfWidthTankWreck > xPos + halfWidthTank) &&
!(wreckPos.getX() + halfWidthTankWreck < xPos - halfWidthTank) &&
!(wreckPos.getY() - halfHeightTankWreck > 0);
if (collides) break;
}
}
}
// no collision -> generate this enemy
if ( !collides ) {
// the tank and the background have to be at the same pixel-fraction
// to avoid a waggle-effect
float correlateToBackground = actBackgroundPos - truncf(actBackgroundPos);
newOne = new Enemy( Vector2D( xPos, -halfHeightTank - correlateToBackground ),
Vector2D (0, SCROLL_SPEED), // tanks are not moving
TANK );
break;
}
}
break;
}
default:
{
cout << "generateEnemys(): unexpected enemyType: " << enemyType << endl;
break;
}
}
addEnemy( newOne );
// +1 for security
timeToNextEnemy = GENERATE_ENEMY_DELAY + (rand() % (GENERATE_ENEMY_RAND_DELAY+1));
}
}
void Enemys::updateEnemys( int dT ) {
vector<Formation *>::iterator f;
for (f = formations.begin(); f != formations.end(); ++f) {
(*f)->update( dT );
}
vector<Enemy *>::iterator i;
for (i = enemys.begin(); i != enemys.end(); ++i) {
(*i)->update( dT );
}
}
void Enemys::doNukeDamage() {
vector<Enemy *>::iterator i;
for (i = enemys.begin(); i != enemys.end(); ++i) {
(*i)->doDamage( SPECIAL_SHOT_NUKE, -1 );
}
}
void Enemys::deleteExpiredEnemys() {
unsigned int i = 0;
while ( i < enemys.size() ) {
if ( enemys[i]->isExpired() ) {
if ( enemys[i]->isDead() ) {
enemysKilled++;
if ( arcadeGame ) {
if ( enemysKilled % 50 == 0 ) {
banners->addBanner( BANNER_ENEMYS_KILLED,
BANNER_MODE_RANDOM,
ARCADE_BONUS_FOR_ENEMYS_KILLED );
racers->receivePointsArcade( ARCADE_POINTS_FOR_ENEMYS_KILLED );
}
}
}
for ( unsigned int f = 0; f < formations.size(); f++ ) {
formations[f]->enemyKilled( enemys[i] );
}
delete enemys[i];
enemys.erase(enemys.begin() + i);
} else {
i++;
}
}
unsigned int f = 0;
while ( f < formations.size() ) {
if ( formations[f]->isExpired() ) {
// assert, that the formation is not deleted, because all
// enemys in the formation flew out of the screen
if ( arcadeGame && formations[f]->getCenter().getY() < SCREEN_HEIGHT + 400 ) {
banners->addBanner( (BannerTexts)(rand() % NR_BANNER_TEXTS),
BANNER_MODE_RANDOM,
ARCADE_BONUS_FOR_FORMATION_DESTRUCTION );
racers->receivePointsArcade( ARCADE_POINTS_FOR_FORMATION_DESTRUCTION );
}
delete formations[f];
formations.erase(formations.begin() + f);
} else {
f++;
}
}
}
void Enemys::drawGroundEnemys(SDL_Surface *screen) {
vector<Enemy *>::iterator i;
for (i = enemys.begin(); i != enemys.end(); ++i) {
(*i)->drawGroundEnemy(screen);
}
}
void Enemys::drawAirEnemys(SDL_Surface *screen) {
vector<Enemy *>::iterator i;
for (i = enemys.begin(); i != enemys.end(); ++i) {
(*i)->drawAirEnemy(screen);
}
}
void Enemys::drawShadows(SDL_Surface *screen) {
vector<Enemy *>::iterator i;
for (i = enemys.begin(); i != enemys.end(); ++i) {
(*i)->drawShadow(screen);
}
}
void Enemys::drawBossStats( SDL_Surface *screen ) {
for ( unsigned int i = 0; i < enemys.size(); i++ ) {
if ( enemys[ i ]->getType() >= NR_ENEMY_TYPES_NORMAL ) {
enemys[ i ]->drawStats( screen );
}
}
}
void Enemys::drawAllStats( SDL_Surface *screen ) {
for ( unsigned int i = 0; i < enemys.size(); i++ ) {
enemys[ i ]->drawStats( screen );
}
}

View File

@@ -0,0 +1,77 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef ENEMYS_H
#define ENEMYS_H
#include <vector>
#include "SDL.h"
class Enemy;
class Formation;
class Enemys {
std::vector<Enemy *> enemys;
std::vector<Formation *> formations;
int timeToNextEnemy;
int timeToNextFormation;
// if != 0, only the enemys for this boss are generated
int bossActive;
int enemysGenerated;
int enemysKilled;
public:
Enemys();
~Enemys();
void addEnemy( Enemy *newEnemy );
bool minibossDead();
bool bossDead();
void bossTime( int bossNr );
void generateEnemys( int dT );
void deleteExpiredEnemys();
inline Enemy *getEnemy(unsigned int i) { return enemys[i]; }
inline unsigned int getNrEnemys() { return enemys.size(); }
inline int getNrEnemysKilled() { return enemysKilled; }
inline int getNrEnemysGenerated() { return enemysGenerated; }
// move and shoot
void updateEnemys( int dT );
// a nuke exploded -> damage all enemys
void doNukeDamage();
// draws the enemys.
void drawGroundEnemys( SDL_Surface *screen );
void drawAirEnemys( SDL_Surface *screen );
void drawShadows( SDL_Surface *screen );
void drawBossStats( SDL_Surface *screen );
void drawAllStats( SDL_Surface *screen );
};
#endif

View File

@@ -0,0 +1,109 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
using namespace std;
#include "explosion.h"
#include "surfaceDB.h"
#include "mixer.h"
#include "global.h"
Explosion::Explosion(string fn, const Vector2D &position,
const Vector2D &velocity, const ExplosionTypes &explosionType) {
sprite = surfaceDB.loadSurface(fn);
nrAnimStages = sprite->w / sprite->h;
expired = false;
sndExplosion = mixer.loadSample( FN_SOUND_EXPLOSION_NORMAL );
mixer.playSample( sndExplosion, 0 );
this->explosionType = explosionType;
pos = position;
vel = velocity;
switch (explosionType) {
case EXPLOSION_NORMAL_AIR:
case EXPLOSION_NORMAL_GROUND:
{
timePerStage = LIFETIME_EXPL_NORMAL / nrAnimStages;
break;
}
default:
{
timePerStage = 0;
actAnimStage = nrAnimStages;
break;
}
}
actAnimStage = 0;
timeLived = 0;
timeNextAnimStage = timePerStage;
}
Explosion::~Explosion() {}
void Explosion::update( int dT ) {
if ( scrollingOn ) pos += vel * dT / 1000.0;
timeLived += dT;
if ( timeLived > timeNextAnimStage ) {
timeNextAnimStage += timePerStage;
actAnimStage++;
if (actAnimStage == nrAnimStages) expired = true;
}
}
void Explosion::drawAirExplosion(SDL_Surface *screen) {
if (expired) return;
if ( ! ( explosionType == EXPLOSION_NORMAL_AIR ) ) return;
SDL_Rect dest;
dest.x = lroundf(pos.getX()) - sprite->w / (2*nrAnimStages);
dest.y = lroundf(pos.getY()) - sprite->h / 2;
dest.w = sprite->w / nrAnimStages;
dest.h = sprite->h;
SDL_Rect src;
src.x = actAnimStage * sprite->w / nrAnimStages;
src.y = 0;
src.w = sprite->w / nrAnimStages;
src.h = sprite->h;
SDL_BlitSurface( sprite, &src, screen, &dest );
}
void Explosion::drawGroundExplosion(SDL_Surface *screen) {
if (expired) return;
if ( ! ( explosionType == EXPLOSION_NORMAL_GROUND ) ) return;
SDL_Rect dest;
dest.x = lroundf(pos.getX()) - sprite->w / (2*nrAnimStages);
dest.y = lroundf(pos.getY()) - sprite->h / 2;
dest.w = sprite->w / nrAnimStages;
dest.h = sprite->h;
SDL_Rect src;
src.x = actAnimStage * sprite->w / nrAnimStages;
src.y = 0;
src.w = sprite->w / nrAnimStages;
src.h = sprite->h;
SDL_BlitSurface( sprite, &src, screen, &dest );
}

View File

@@ -0,0 +1,65 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef EXPLOSION_H
#define EXPLOSION_H
#include "SDL.h"
#include "geometry.h"
#include <string>
#include "global.h"
class Explosion {
// a sprite, that contains horizontally all animationframes of the explosion.
// it is assumed, that every frame is quadratic.
SDL_Surface *sprite;
// how many frames does this explosion have?
int nrAnimStages;
// which frame is now?
int actAnimStage;
// how long should one frame last (ms)
int timePerStage;
// how long is the current explosion already active
int timeLived;
// at what timeLived starts the next frame?
int timeNextAnimStage;
// the explosion can be deleted
bool expired;
int sndExplosion;
Vector2D pos;
Vector2D vel; // the explosion moves - yeah
ExplosionTypes explosionType;
public:
Explosion(string fn, const Vector2D &position,
const Vector2D &velocity, const ExplosionTypes &explosionType);
~Explosion();
// updates the position and the counters
void update( int dT );
void drawAirExplosion(SDL_Surface *screen);
void drawGroundExplosion(SDL_Surface *screen);
bool isExpired() { return expired; }
};
#endif

View File

@@ -0,0 +1,72 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
using namespace std;
#include "explosions.h"
#include "explosion.h"
Explosions::Explosions() {
}
Explosions::~Explosions() {
vector<Explosion *>::iterator i;
for (i = explosions.begin(); i != explosions.end(); ++i) {
delete *i;
}
}
void Explosions::addExplosion(Explosion *explosion) {
if (explosion) {
explosions.push_back(explosion);
}
}
void Explosions::drawAirExplosions(SDL_Surface *screen) {
vector<Explosion *>::iterator i;
for (i = explosions.begin(); i != explosions.end(); ++i) {
(*i)->drawAirExplosion(screen);
}
}
void Explosions::drawGroundExplosions(SDL_Surface *screen) {
vector<Explosion *>::iterator i;
for (i = explosions.begin(); i != explosions.end(); ++i) {
(*i)->drawGroundExplosion(screen);
}
}
void Explosions::updateExplosions( int dT ) {
vector<Explosion *>::iterator i;
for (i = explosions.begin(); i != explosions.end(); ++i) {
(*i)->update( dT );
}
}
void Explosions::expireExplosions() {
unsigned int i = 0;
while ( i < explosions.size() ) {
if ( explosions[i]->isExpired() ) {
delete explosions[i];
explosions.erase(explosions.begin() + i);
} else {
i++;
}
}
}

View File

@@ -0,0 +1,48 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef EXPLOSIONS_H
#define EXPLOSIONS_H
#include <vector>
#include "SDL.h"
class Explosion;
/* manages the explosion-objects */
class Explosions {
vector<Explosion *> explosions;
public:
Explosions();
~Explosions();
inline unsigned int getNrExplosions() { return explosions.size(); }
void addExplosion( Explosion *explosion );
// moves the explosions and updates the counters
void updateExplosions( int dT );
// deletes the explosions, that have timed out
void expireExplosions();
// draws all explosions
void drawAirExplosions( SDL_Surface *screen );
void drawGroundExplosions( SDL_Surface *screen );
};
#endif

View File

@@ -0,0 +1,157 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
using namespace std;
#include "font.h"
#include "global.h"
#include "surfaceDB.h"
#include <iostream>
Font::Font(string fn) {
sprite = surfaceDB.loadSurface( fn );
charset = " ABCDEFGHIJKLMNOPQRSTUVWXYZÜÄÖabcdefghijklmnopqrstuvwxyzüäöß0123456789!\"§$%&/()=?*+'#,.-;:_@°\\";
// 94 Zeichen
charWidth = sprite->w / 94;
charHeight = sprite->h;
}
Font::~Font() {
;
}
void Font::setCharWidth(int width) {
charWidth = width;
}
int Font::getCharWidth() {
return charWidth;
}
int Font::getCharHeight() {
return sprite->h;
}
void Font::drawInt(SDL_Surface *screen, int posx, int posy, int val, int alignDigitCnt, int flags) {
int indent = 0;
int digitCnt = 1;
int i=1;
while ( val >= i*10 ) {
digitCnt++;
i *= 10;
}
// cout << endl << "drawInt.val=" << val << endl;
// cout << "drawInt.digitCnt=" << digitCnt << endl;
// cout << "drawInt.alignDigitCnt-old=" << alignDigitCnt << endl;
if (alignDigitCnt < digitCnt) {
alignDigitCnt = digitCnt;
}
// cout << "drawInt.alignDigitCnt-new=" << alignDigitCnt << endl;
if (flags & FONT_ALIGN_CENTERED) {
indent = -(alignDigitCnt * charWidth) / 2;
}
if (flags & FONT_ALIGN_RIGHT) {
indent = -(alignDigitCnt * charWidth);
}
SDL_Rect destR;
SDL_Rect srcR;
while (alignDigitCnt > 0) {
if ((digitCnt > 0) ||
((flags & FONT_ALIGN_FILL_ZERO) != 0)) {
destR.x = indent + posx + (alignDigitCnt-1) * charWidth;
destR.y = posy;
destR.w = charWidth;
destR.h = charHeight;
unsigned int charsetpos = charset.find( (char)((val % 10) + '0') );
if (charsetpos != string::npos ) {
srcR.x = charsetpos * charWidth;
} else {
srcR.x = charWidth;
}
// srcR.x = (1 + 2*26 + (val % 10)) * charWidth;
srcR.y = 0;
srcR.w = charWidth;
srcR.h = charHeight;
SDL_BlitSurface( sprite, &srcR, screen, &destR );
}
val /= 10;
digitCnt--;
alignDigitCnt--;
}
}
void Font::drawStr(SDL_Surface *screen, int posx, int posy, const string &text, int flags) {
int indent = 0;
if ( flags & (FONT_ALIGN_CENTERED | FONT_ALIGN_RIGHT) ) {
for(unsigned int i=0; i < text.size(); ++i) {
if (!(flags & FONT_MONOSPACE) && text[i] == ' ') {
indent += ((charWidth * 2) / 3);
} else {
indent += charWidth;
}
}
if (flags & FONT_ALIGN_CENTERED) {
indent = -indent / 2;
} else {
indent = -indent;
}
}
SDL_Rect destR;
SDL_Rect srcR;
int x = 0;
unsigned int charsetpos;
for(unsigned int i=0; i < text.size(); ++i) {
x = 0;
charsetpos = charset.find(text[i]);
if (charsetpos != string::npos ) {
x = charsetpos * charWidth;
}
destR.x = posx + indent;
destR.y = posy;
destR.w = charWidth;
destR.h = sprite->h;
srcR.x = x;
srcR.y = 0;
srcR.w = charWidth;
srcR.h = sprite->h;
SDL_BlitSurface( sprite, &srcR, screen, &destR );
if (!(flags & FONT_MONOSPACE) && text[i] == ' ') {
posx += ((charWidth * 2) / 3);
} else {
posx += charWidth;
}
}
}

View File

@@ -0,0 +1,77 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef FONT_H
#define FONT_H
#include "SDL.h"
#include <string>
// *** Code ***
//
// font->drawStr( screen, 150, 260, "Zeile 1" );
// font->drawStr( screen, 150, 290, "Zeile 2", FONT_ALIGN_CENTERED );
// font->drawStr( screen, 150, 320, "Zeile 3", FONT_ALIGN_RIGHT );
// font->drawInt( screen, 150, 350, 123, 0 );
// font->drawInt( screen, 150, 380, 123, 0, FONT_ALIGN_FILL_ZERO );
// font->drawInt( screen, 150, 410, 123, 6 );
// font->drawInt( screen, 150, 440, 123, 6, FONT_ALIGN_FILL_ZERO );
// font->drawInt( screen, 150, 400, 123, 6, FONT_ALIGN_CENTERED );
// font->drawInt( screen, 150, 425, 123, 6, FONT_ALIGN_CENTERED | FONT_ALIGN_FILL_ZERO );
// font->drawInt( screen, 150, 350, 123, 6, FONT_ALIGN_RIGHT );
// font->drawInt( screen, 150, 375, 123, 6, FONT_ALIGN_RIGHT | FONT_ALIGN_FILL_ZERO );
//
// *** Result ***
//
// Zeile 1
// Zeile 2
// Zeile 3
// 123
// 123
// 123
// 000123
// 123
// 000123
// 123
// 000123
const int FONT_ALIGN_FILL_ZERO = (1<<0); // fill with leading zeros
const int FONT_ALIGN_CENTERED = (1<<1); // text centered around posx/posy
const int FONT_ALIGN_RIGHT = (1<<2); // text aligned right (on the left side of posx)
const int FONT_MONOSPACE = (1<<3);
class Font {
private:
SDL_Surface *sprite;
int charWidth;
int charHeight;
std::string charset;
public:
Font(std::string fn);
~Font();
void setCharWidth(int width);
int getCharWidth();
int getCharHeight();
void drawInt(SDL_Surface *screen, int posx, int posy, int val, int alignDigitCnt, int flags = 0);
void drawStr(SDL_Surface *screen, int posx, int posy, const std::string &text, int flags = 0);
};
#endif

View File

@@ -0,0 +1,645 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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 "formation.h"
#include "enemy.h"
#include "enemys.h"
#include <iostream>
using namespace std;
Formation::Formation( FormationTypes whichFormation, Vector2D centerAtStart,
Vector2D startVel, int nrEnemys,
FormationEnemySets enemyTypes,
int flagsFormationChangePolicy,
FormationShotPatterns shotPattern ) {
formationType = whichFormation;
formationCenter = centerAtStart;
formationSpeed = startVel;
changeOnKill = flagsFormationChangePolicy & FORMATION_CHANGE_ON_KILL;
changeSpontaneous = flagsFormationChangePolicy & FORMATION_CHANGE_SPONTANEOUS;
changeOften = flagsFormationChangePolicy & FORMATION_CHANGE_OFTEN;
changeSeldom = flagsFormationChangePolicy & FORMATION_CHANGE_SELDOM;
if ( changeSpontaneous && !changeSeldom && !changeOften ) changeSeldom = true;
if ( changeOften ) {
nextFormationChange =
FORMATION_CHANGE_OFTEN_DELAY +
rand() % (FORMATION_CHANGE_OFTEN_RAND_DELAY+1);
} else if ( changeSeldom ) {
nextFormationChange =
FORMATION_CHANGE_SELDOM_DELAY +
rand() % (FORMATION_CHANGE_SELDOM_RAND_DELAY+1);
}
if ( nrEnemys > FORMATION_MAX_NR_ENEMYS[ formationType ] )
nrInvolved = FORMATION_MAX_NR_ENEMYS[ formationType ];
else if ( nrEnemys < 0 ) nrInvolved = 0;
else nrInvolved = nrEnemys;
this->shotPattern = shotPattern;
actShootingEnemy = 0;
if ( shotPattern == FORMATION_SP_NONE ) formationFires = false;
else formationFires = true;
vector<Vector2D> targetPos;
fillTargetPos( targetPos );
for ( int i = 0; i < nrInvolved; i++ ) {
Enemy *newOne;
switch ( enemyTypes ) {
case FORMATION_ENEMY_SET_DEFAULT:
case FORMATION_ENEMY_SET_FIGHTER:
{
newOne = new Enemy( formationCenter + targetPos[ i ], formationSpeed, FIGHTER,
true, formationFires );
break;
}
case FORMATION_ENEMY_SET_BOMBER:
{
newOne = new Enemy( formationCenter + targetPos[ i ], formationSpeed, BOMBER,
true, formationFires );
break;
}
case FORMATION_ENEMY_SET_FIGHTER_BOMBER:
{
newOne =
new Enemy( formationCenter + targetPos[ i ], formationSpeed,
(EnemyTypes)(FIGHTER + (i % 2)),
true, formationFires );
break;
}
}
enemys->addEnemy( newOne );
involvedEnemys.push_back( newOne );
}
enemyWasKilled = false;
// wait at least 100 ms before the first shot
nextFirePrimary = 100;
nextFireSecondary = 100;
// cout << "Type: " << formationType << " SP: " << shotPattern << endl;
}
Formation::~Formation() {}
void Formation::enemyKilled( Enemy *killedEnemy ) {
for ( int i = 0; i < nrInvolved; i++ ) {
if ( involvedEnemys[i] == killedEnemy ) {
enemyWasKilled = true;
involvedEnemys.erase( involvedEnemys.begin() + i );
nrInvolved--;
break;
}
}
}
void Formation::update( int dT ) {
if ( changeSpontaneous ) handleSpontaneousFormationChange( dT );
if ( enemyWasKilled ) {
// change the formation?
if ( changeOnKill && (rand() % 100 < 70) ) chooseNewFormationType();
moveEnemyInFormation();
enemyWasKilled = false;
}
formationCenter += formationSpeed * dT / 1000.0;
shoot( dT );
}
void Formation::handleSpontaneousFormationChange( int dT ) {
nextFormationChange -= dT;
if ( changeSpontaneous && nextFormationChange < 0 ) {
chooseNewFormationType();
moveEnemyInFormation();
if ( changeOften ) {
nextFormationChange =
FORMATION_CHANGE_OFTEN_DELAY +
rand() % (FORMATION_CHANGE_OFTEN_RAND_DELAY+1);
} else if ( changeSeldom ) {
nextFormationChange =
FORMATION_CHANGE_SELDOM_DELAY +
rand() % (FORMATION_CHANGE_SELDOM_RAND_DELAY+1);
}
}
}
void Formation::moveEnemyInFormation() {
// calc the target positions in the new formation (relative to the center of the formation)
vector<Vector2D> targetPos;
fillTargetPos( targetPos );
// choose the best mapping from enemy to targetPosition
// (shortest way for enemy to its position is best)
vector<Vector2D> relPosForEnemies;
getBestMapping( targetPos, relPosForEnemies );
// give the enemy its order
for ( int i = 0; i < nrInvolved; i++ ) {
involvedEnemys[i]->setNewRelTargetPos( relPosForEnemies[ i ] );
}
}
void Formation::chooseNewFormationType() {
bool found = false;
int i = 0;
while ( i < 10 && !found ) {
FormationTypes newFormationType = (FormationTypes)(rand() % (NR_FORMATION_TYPES-1));
if ( formationType == newFormationType ) {
newFormationType = (FormationTypes)(NR_FORMATION_TYPES - 1);
}
if ( nrInvolved <= FORMATION_MAX_NR_ENEMYS[ newFormationType ] ) {
formationType = newFormationType;
found = true;
}
i++;
}
}
void Formation::fillTargetPos( vector<Vector2D> &targetPos ) {
switch ( formationType ) {
case FORMATION_V:
{
fillTargetPosFormationV( targetPos );
break;
}
case FORMATION_REVERSE_V:
{
fillTargetPosFormationReverseV( targetPos );
break;
}
case FORMATION_BLOCK:
{
fillTargetPosFormationBlock( targetPos );
break;
}
case FORMATION_LINE:
{
fillTargetPosFormationLine( targetPos );
break;
}
default:
{
for ( int i = 0; i < nrInvolved; i++ ) {
targetPos.push_back( Vector2D(0,0) );
}
break;
}
}
}
void Formation::fillTargetPosFormationV( vector<Vector2D> &targetPos ) {
switch ( nrInvolved ) {
case 1:
{
targetPos.push_back( Vector2D(0,0) );
break;
}
case 2:
{
targetPos.push_back( Vector2D(-30,0) );
targetPos.push_back( Vector2D(30,0) );
break;
}
case 3:
{
targetPos.push_back( Vector2D(-50,25) );
targetPos.push_back( Vector2D(0,-25) );
targetPos.push_back( Vector2D(50,25) );
break;
}
case 4:
{
targetPos.push_back( Vector2D(-80,25) );
targetPos.push_back( Vector2D(-30,-25) );
targetPos.push_back( Vector2D(30,-25) );
targetPos.push_back( Vector2D(80,25) );
break;
}
case 5:
{
targetPos.push_back( Vector2D(-100,50) );
targetPos.push_back( Vector2D(-50,0) );
targetPos.push_back( Vector2D(0,-50) );
targetPos.push_back( Vector2D(50,0) );
targetPos.push_back( Vector2D(100,50) );
break;
}
case 6:
{
targetPos.push_back( Vector2D(-130,50) );
targetPos.push_back( Vector2D(-80,0) );
targetPos.push_back( Vector2D(-30,-50) );
targetPos.push_back( Vector2D(30,-50) );
targetPos.push_back( Vector2D(80,0) );
targetPos.push_back( Vector2D(130,50) );
break;
}
case 7:
{
targetPos.push_back( Vector2D(-150,75) );
targetPos.push_back( Vector2D(-100,25) );
targetPos.push_back( Vector2D(-50,-25) );
targetPos.push_back( Vector2D(0,-75) );
targetPos.push_back( Vector2D(50,-25) );
targetPos.push_back( Vector2D(100,25) );
targetPos.push_back( Vector2D(150,75) );
break;
}
default:
{
cout << "fillTargetPosFormationV: too many enemys involved: " << nrInvolved << endl;
for ( int i = 0; i < nrInvolved; i++ ) {
targetPos.push_back( Vector2D(0,0) );
}
break;
}
}
}
void Formation::fillTargetPosFormationReverseV( vector<Vector2D> &targetPos ) {
switch ( nrInvolved ) {
case 1:
{
targetPos.push_back( Vector2D(0,0) );
break;
}
case 2:
{
targetPos.push_back( Vector2D(-30,0) );
targetPos.push_back( Vector2D(30,0) );
break;
}
case 3:
{
targetPos.push_back( Vector2D(-50,-25) );
targetPos.push_back( Vector2D(0,25) );
targetPos.push_back( Vector2D(50,-25) );
break;
}
case 4:
{
targetPos.push_back( Vector2D(-80,-25) );
targetPos.push_back( Vector2D(-30,25) );
targetPos.push_back( Vector2D(30,25) );
targetPos.push_back( Vector2D(80,-25) );
break;
}
case 5:
{
targetPos.push_back( Vector2D(-100,-50) );
targetPos.push_back( Vector2D(-50,0) );
targetPos.push_back( Vector2D(0,50) );
targetPos.push_back( Vector2D(50,0) );
targetPos.push_back( Vector2D(100,-50) );
break;
}
case 6:
{
targetPos.push_back( Vector2D(-130,-50) );
targetPos.push_back( Vector2D(-80,0) );
targetPos.push_back( Vector2D(-30,50) );
targetPos.push_back( Vector2D(30,50) );
targetPos.push_back( Vector2D(80,0) );
targetPos.push_back( Vector2D(130,-50) );
break;
}
case 7:
{
targetPos.push_back( Vector2D(-150,-75) );
targetPos.push_back( Vector2D(-100,-25) );
targetPos.push_back( Vector2D(-50,25) );
targetPos.push_back( Vector2D(0,75) );
targetPos.push_back( Vector2D(50,25) );
targetPos.push_back( Vector2D(100,-25) );
targetPos.push_back( Vector2D(150,-75) );
break;
}
default:
{
cout << "fillTargetPosFormationReverseV: too many enemys involved: "
<< nrInvolved << endl;
for ( int i = 0; i < nrInvolved; i++ ) {
targetPos.push_back( Vector2D(0,0) );
}
break;
}
}
}
void Formation::fillTargetPosFormationBlock( vector<Vector2D> &targetPos ) {
switch ( nrInvolved ) {
case 1:
{
targetPos.push_back( Vector2D(0,0) );
break;
}
case 2:
{
targetPos.push_back( Vector2D(-30,0) );
targetPos.push_back( Vector2D(30,0) );
break;
}
case 3:
{
targetPos.push_back( Vector2D(-30,25) );
targetPos.push_back( Vector2D(0,-25) );
targetPos.push_back( Vector2D(30,25) );
break;
}
case 4:
{
targetPos.push_back( Vector2D(-30,-25) );
targetPos.push_back( Vector2D(-30,25) );
targetPos.push_back( Vector2D(30,-25) );
targetPos.push_back( Vector2D(30,25) );
break;
}
case 5:
{
targetPos.push_back( Vector2D(-40,-30) );
targetPos.push_back( Vector2D(-40,30) );
targetPos.push_back( Vector2D(0,0) );
targetPos.push_back( Vector2D(40,-30) );
targetPos.push_back( Vector2D(40,30) );
break;
}
case 6:
{
targetPos.push_back( Vector2D(-60,-30) );
targetPos.push_back( Vector2D(-60,30) );
targetPos.push_back( Vector2D(0,-30) );
targetPos.push_back( Vector2D(0,30) );
targetPos.push_back( Vector2D(60,-30) );
targetPos.push_back( Vector2D(60,30) );
break;
}
case 7:
{
targetPos.push_back( Vector2D(-60,-50) );
targetPos.push_back( Vector2D(-60,0) );
targetPos.push_back( Vector2D(0,-50) );
targetPos.push_back( Vector2D(0,0) );
targetPos.push_back( Vector2D(0,50) );
targetPos.push_back( Vector2D(60,-50) );
targetPos.push_back( Vector2D(60,0) );
break;
}
default:
{
cout << "fillTargetPosFormationBlock: too many enemys involved: " << nrInvolved << endl;
for ( int i = 0; i < nrInvolved; i++ ) {
targetPos.push_back( Vector2D(0,0) );
}
break;
}
}
}
void Formation::fillTargetPosFormationLine( vector<Vector2D> &targetPos ) {
switch ( nrInvolved ) {
case 1:
{
targetPos.push_back( Vector2D(0,0) );
break;
}
case 2:
{
targetPos.push_back( Vector2D(-30,0) );
targetPos.push_back( Vector2D(30,0) );
break;
}
case 3:
{
targetPos.push_back( Vector2D(-60,0) );
targetPos.push_back( Vector2D(0,0) );
targetPos.push_back( Vector2D(60,0) );
break;
}
case 4:
{
targetPos.push_back( Vector2D(-90,0) );
targetPos.push_back( Vector2D(-30,0) );
targetPos.push_back( Vector2D(30,0) );
targetPos.push_back( Vector2D(90,0) );
break;
}
case 5:
{
targetPos.push_back( Vector2D(-120,0) );
targetPos.push_back( Vector2D(-60,0) );
targetPos.push_back( Vector2D(0,0) );
targetPos.push_back( Vector2D(60,0) );
targetPos.push_back( Vector2D(120,0) );
break;
}
case 6:
{
targetPos.push_back( Vector2D(-150,0) );
targetPos.push_back( Vector2D(-90,0) );
targetPos.push_back( Vector2D(-30,0) );
targetPos.push_back( Vector2D(30,0) );
targetPos.push_back( Vector2D(90,0) );
targetPos.push_back( Vector2D(150,0) );
break;
}
default:
{
cout << "fillTargetPosFormationLine: too many enemys involved: " << nrInvolved << endl;
for ( int i = 0; i < nrInvolved; i++ ) {
targetPos.push_back( Vector2D(0,0) );
}
break;
}
}
}
///////////////////////////////////////////////
void Formation::getBestMapping( vector<Vector2D> &targetPos,
vector<Vector2D> &relPosForFighters ) {
int actPerm[nrInvolved];
vector<Vector2D> *bestMapping = new vector<Vector2D>();
vector<Vector2D> *testMapping = new vector<Vector2D>();
for ( int i = 0; i < nrInvolved; i++ ) {
bestMapping->push_back( Vector2D( 0,0 ) );
testMapping->push_back( Vector2D( 0,0 ) );
actPerm[ i ] = i;
}
float mapCost = 1000000;
int nrPerm = factorial( nrInvolved );
for ( int perm = 0; perm < nrPerm; perm++ ) {
calcNextPerm( actPerm );
float testMappingCost = calcTestMapping( actPerm, targetPos, testMapping );
if ( mapCost > testMappingCost ) {
vector<Vector2D> *tmpMapping = bestMapping;
bestMapping = testMapping;
testMapping = tmpMapping;
mapCost = testMappingCost;
}
}
for ( int e = 0; e < nrInvolved; e++ ) {
relPosForFighters.push_back( (*bestMapping)[e] );
}
delete bestMapping;
delete testMapping;
}
void Formation::calcNextPerm( int *perm ) {
int n = nrInvolved;
int i = n-1;
int j = n;
int tmp;
while ( i != 0 && perm[ i-1 ] >= perm[ i ] ) {
i--;
}
if ( i == 0 ) {
for ( int k = 0; k < n/2; k++ ) {
tmp = perm[ k ];
perm[ k ] = perm[ n - k - 1 ];
perm[ n - k - 1 ] = tmp;
}
return;
}
while ( perm[ j-1 ] <= perm[ i-1 ] ) {
--j;
}
tmp = perm[ i-1 ];
perm[ i-1 ] = perm[ j-1 ];
perm[ j-1 ] = tmp;
i++;
j = n;
while ( i < j ) {
tmp = perm[ i-1 ];
perm[ i-1 ] = perm[ j-1 ];
perm[ j-1 ] = tmp;
i++;
j--;
}
}
float Formation::calcTestMapping( int *perm, vector<Vector2D> &targetPos,
vector<Vector2D> *mapping ) {
float cost = 0;
for ( int i = 0; i < nrInvolved; i++ ) {
// enemy i shall fly to the position targetPos[perm[i]]
// save the vector from its actual pos to its new targetpos in mapping
(*mapping)[ i ] =
targetPos[ perm[i] ] + formationCenter -
involvedEnemys[ i ]->getPos();
if ( cost < (*mapping)[ i ].getLength() ) {
cost = (*mapping)[ i ].getLength();
}
}
return cost;
}
int Formation::factorial( int n ) {
int result = 1;
for ( int i = 2; i <= n; i++ ) {
result *= i;
}
return result;
}
void Formation::shoot( int dT ) {
if ( shotPattern == FORMATION_SP_NONE ) return;
nextFirePrimary -= dT;
// nextFireSecondary -= dT;
float enemyRatio = FORMATION_MAX_NR_ENEMYS[ formationType ] / (float)nrInvolved;
while ( nextFirePrimary < 0 ) {
switch ( shotPattern ) {
case FORMATION_SP_VOLLEY_FAST:
case FORMATION_SP_VOLLEY_MEDIUM:
case FORMATION_SP_VOLLEY_SLOW:
{
for ( int i = 0; i < nrInvolved; i++ ) {
involvedEnemys[ i ]->firePrimary();
}
break;
}
case FORMATION_SP_RAND_FAST:
case FORMATION_SP_RAND_MEDIUM:
case FORMATION_SP_RAND_SLOW:
{
involvedEnemys[ rand() % nrInvolved ]->firePrimary();
break;
}
case FORMATION_SP_LEFT_RIGHT_FAST:
case FORMATION_SP_LEFT_RIGHT_MEDIUM:
{
actShootingEnemy = (actShootingEnemy + 1) % nrInvolved;
involvedEnemys[ actShootingEnemy ]->firePrimary();
break;
}
case FORMATION_SP_RIGHT_LEFT_FAST:
case FORMATION_SP_RIGHT_LEFT_MEDIUM:
{
actShootingEnemy--;
if ( actShootingEnemy < 0 ) actShootingEnemy = nrInvolved-1;
involvedEnemys[ actShootingEnemy ]->firePrimary();
break;
}
default:
{
break;
}
}
nextFirePrimary +=
lroundf( (FORMATION_SP_PRIMARY_DELAY[ shotPattern ] +
rand() % (FORMATION_SP_PRIMARY_RAND_DELAY[ shotPattern ] + 1)) * enemyRatio );
}
}

View File

@@ -0,0 +1,85 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef FORMATION_H
#define FORMATION_H
#include <vector>
#include "global.h"
#include "geometry.h"
class Enemy;
class Formation {
private:
std::vector<Enemy *> involvedEnemys;
int nrInvolved;
FormationTypes formationType;
Vector2D formationCenter;
Vector2D formationSpeed;
bool enemyWasKilled;
bool formationFires;
int nextFirePrimary;
int nextFireSecondary;
bool changeOnKill, changeSpontaneous, changeOften, changeSeldom;
int nextFormationChange;
FormationShotPatterns shotPattern;
int actShootingEnemy;
void chooseNewFormationType();
void handleSpontaneousFormationChange( int dT );
void moveEnemyInFormation();
void fillTargetPos( vector<Vector2D> &targetPos );
void fillTargetPosFormationV( vector<Vector2D> &targetPos );
void fillTargetPosFormationReverseV( vector<Vector2D> &targetPos );
void fillTargetPosFormationBlock( vector<Vector2D> &targetPos );
void fillTargetPosFormationLine( vector<Vector2D> &targetPos );
void getBestMapping( vector<Vector2D> &targetPos,
vector<Vector2D> &relPosForFighters );
void calcNextPerm( int *perm );
float calcTestMapping( int *perm, vector<Vector2D> &targetPos,
vector<Vector2D> *mapping );
int factorial( int n );
void shoot( int dT );
public:
Formation( FormationTypes whichFormation, Vector2D centerAtStart,
Vector2D startVel, int nrEnemys=66,
FormationEnemySets enemyTypes=FORMATION_ENEMY_SET_DEFAULT,
int flagsFormationChangePolicy=0,
FormationShotPatterns shotPattern=FORMATION_SP_NONE );
~Formation();
Vector2D getCenter() { return formationCenter; }
void enemyKilled( Enemy *killedEnemy );
void update( int dT );
bool isExpired() { return (nrInvolved == 0); }
};
#endif

View File

@@ -0,0 +1,927 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
using namespace std;
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "SDL.h"
#include "SDL_mixer.h"
#include "game.h"
#include "surfaceDB.h"
#include "racers.h"
#include "racer.h"
#include "video.h"
#include "shots.h"
#include "shot.h"
#include "items.h"
#include "explosions.h"
#include "explosion.h"
#include "enemys.h"
#include "font.h"
#include "mixer.h"
#include "input.h"
#include "wrecks.h"
#include "wreck.h"
#include "global.h"
#include "settings.h"
#include "intro.h"
#include "setDifficulty.h"
#include "menuArcadeMode.h"
#include "asstring.h"
#include "sonic.h"
#include "banners.h"
#include "banner.h"
#include "smokePuffs.h"
#include "background.h"
#include "options.h"
Racers *racers = NULL;
Enemys *enemys = NULL;
Shots *shots = NULL;
Explosions *explosions = NULL;
Items *items = NULL;
Wrecks *wrecks = NULL;
Banners *banners = NULL;
SmokePuffs *smokePuffs = NULL;
Options *levelConf = NULL;
bool scrollingOn;
bool nukeIsInPlace;
bool playMusicOn;
bool onePlayerGame;
bool arcadeGame;
int difficultyLevel;
float actBackgroundPos;
Game::Game() {
videoserver = new Video();
screen = 0;
screen = videoserver->init();
settings = new Settings();
intro = new Intro( screen );
setDifficulty = new SetDifficulty( screen );
menuArcadeMode = new MenuArcadeMode( screen );
pauseSprite = surfaceDB.loadSurface( FN_PAUSED );
youLoseSprite = surfaceDB.loadSurface( FN_YOU_LOSE );
youWinSprite = surfaceDB.loadSurface( FN_YOU_WIN );
// for arcadeMode
gameOverSprite = surfaceDB.loadSurface( FN_GAME_OVER );
nukeEffectSurface = surfaceDB.loadSurface( FN_NUKE_EFFECT );
bossAlarm = mixer.loadSample( FN_SOUND_BOSS_ALARM, 60 );
fontTime = new Font( FN_FONT_NUMBERS_TIME );
fontSizeTime = fontTime->getCharWidth();
racers = 0;
explosions = 0;
enemys = 0;
shots = 0;
items = 0;
wrecks = 0;
banners = 0;
smokePuffs = 0;
// needed for calculating fps
frameCnt = 0;
tickCnt = 0;
gameState = GS_INTRO;
paused = true;
sdlTicks = SDL_GetTicks();
gameActRuntime = 0;
timeNukeEnd = 0;
timePauseOn = 0;
timeMinibossOn = 0;
scrollingOn = true;
showAllShipStats = false;
playMusicOn = true;
onePlayerGame = false;
arcadeGame = false;
difficultyLevel = 1;
sonic1 = new Sonic();
sonic2 = new Sonic();
background = new Background();
loadLevel( FN_LEVEL_ONE_PLAYER );
SDL_Surface *loadingSprite = surfaceDB.loadSurface( FN_LOADING );
SDL_Rect dest;
dest.x = (SCREEN_WIDTH - loadingSprite->w ) / 2;
dest.y = (SCREEN_HEIGHT - loadingSprite->h ) / 2;
dest.w = loadingSprite->w;
dest.h = loadingSprite->h;
SDL_BlitSurface( loadingSprite, 0, screen, &dest );
SDL_Flip( screen );
initAllSurfaces();
}
Game::~Game(){
if (videoserver) delete videoserver;
if (settings) delete settings;
if (intro) delete intro;
if (setDifficulty) delete setDifficulty;
if (racers) delete racers;
if (shots) delete shots;
if (explosions) delete explosions;
if (enemys) delete enemys;
if (items) delete items;
if (wrecks) delete wrecks;
if (fontTime) delete fontTime;
if (sonic1) delete sonic1;
if (sonic2) delete sonic2;
if (banners) delete banners;
if (smokePuffs) delete smokePuffs;
}
void Game::initNewGame() {
parseGlobalConfigValues( difficultyLevel );
if (racers) delete racers;
if (shots) delete shots;
if (explosions) delete explosions;
if (enemys) delete enemys;
if (items) delete items;
if (wrecks) delete wrecks;
if (sonic1) delete sonic1;
if (sonic2) delete sonic2;
if (banners) delete banners;
if (smokePuffs) delete smokePuffs;
banners = new Banners();
smokePuffs = new SmokePuffs();
racers = new Racers();
Racer *racer;
if ( !arcadeGame ) {
if ( onePlayerGame ) {
loadLevel( FN_LEVEL_ONE_PLAYER );
if ( setDifficulty->getPlayerOneLightFighter() ) {
racer = new Racer( FN_LIGHT_FIGHTER_1, 0,
Vector2D(320,350), LIGHT_FIGHTER );
} else {
racer = new Racer( FN_HEAVY_FIGHTER_1, 0,
Vector2D(320,350), HEAVY_FIGHTER );
}
racers->addRacer(racer);
}
// two players
else {
loadLevel( FN_LEVEL_TWO_PLAYER );
if ( setDifficulty->getPlayerOneLightFighter() ) {
racer = new Racer( FN_LIGHT_FIGHTER_1, 0,
Vector2D(250,350), LIGHT_FIGHTER );
} else {
racer = new Racer( FN_HEAVY_FIGHTER_1, 0,
Vector2D(250,350), HEAVY_FIGHTER );
}
racers->addRacer(racer);
if ( setDifficulty->getPlayerTwoLightFighter() ) {
racer = new Racer( FN_LIGHT_FIGHTER_2, 1,
Vector2D(390,350), LIGHT_FIGHTER );
} else {
racer = new Racer( FN_HEAVY_FIGHTER_2, 1,
Vector2D(390,350), HEAVY_FIGHTER );
}
racers->addRacer(racer);
}
}
// arcade game
else {
loadLevel( FN_LEVEL_ARCADEMODE );
if ( menuArcadeMode->getPlayerOneLightFighter() ) {
racer = new Racer( FN_LIGHT_FIGHTER_1, 0,
Vector2D(320,350), LIGHT_FIGHTER );
} else {
racer = new Racer( FN_HEAVY_FIGHTER_1, 0,
Vector2D(320,350), HEAVY_FIGHTER );
}
racers->addRacer(racer);
}
racers->getKeyActionMaps();
explosions = new Explosions();
enemys = new Enemys();
shots = new Shots();
items = new Items();
wrecks = new Wrecks();
gameActRuntime = 0;
paused = true;
bossTime = false;
bossNukeEffect = false;
bossExplosion = mixer.loadSample( FN_SOUND_EXPLOSION_BOSS );
minibossAlreadyKilled = false;
minibossTime = false;
timeMinibossOn = SDL_GetTicks();
timeLastUpdate = SDL_GetTicks();
timeNukeEnd = SDL_GetTicks();
timePauseOn = SDL_GetTicks();
actBackgroundPos = 0;
scrollingOn = true;
nukeIsInPlace = false;
sonic1 = new Sonic();
sonic2 = new Sonic();
sonic1->setActive( false );
sonic2->setActive( false );
}
void Game::run(){
while( gameState != GS_QUIT ) {
switch (gameState) {
case GS_SCREENSHOTS:
{
intro->showScreenshots();
gameState = GS_INTRO;
break;
}
case GS_INTRO:
{
intro->run( gameState );
break;
}
case GS_SET_DIFFICULTY:
{
setDifficulty->run( gameState, onePlayerGame);
break;
}
case GS_ARCADE_MODE_SETUP:
{
menuArcadeMode->run( gameState );
break;
}
case GS_ARCADE_MODE_FINISHED:
{
menuArcadeMode->run( gameState, racers->getPointsArcadeMode() );
break;
}
case GS_OPTIONS:
{
options();
break;
}
case GS_ROUNDFINISHED:
{
roundFinished();
break;
}
case GS_BOSS_KILLED:
{
bossKilled();
break;
}
case GS_PLAYON:
{
initNewGame();
if ( playMusicOn ) mixer.playMusic( MUSIC_PLAYON, -1, 1000 );
playOn();
break;
}
default: break;
}
}
}
/*********************************/
/**** PlayOn *********************/
/*********************************/
void Game::playOn() {
int A = SDL_GetTicks();
frameCnt = 0;
tickCnt = 0;
cout << "frameCnt: " << frameCnt << " tickCnt: " << tickCnt
<< " SDL_GetTicks()=" << A << endl;
while ( gameState == GS_PLAYON ) {
handleEventsPlayOn();
if (!paused) {
updateGameState();
}
drawPlayOn();
// miniboss
if ( minibossTime && enemys->minibossDead() ) minibossAlreadyKilled = true;
if (!minibossAlreadyKilled && !arcadeGame && !paused && !minibossTime &&
(unsigned int)GAME_LENGTH / 2 <= gameActRuntime) {
generateMiniboss();
}
if ( minibossTime && enemys->bossDead() ) minibossKilled();
// endboss
if (!arcadeGame && !paused && !bossTime && !minibossTime &&
(unsigned int)GAME_LENGTH < gameActRuntime) {
enemys->bossTime(1); // generates the boss
bossTime = true;
mixer.playSample( bossAlarm , 0, true );
if ( playMusicOn ) mixer.playMusic( MUSIC_BOSS1, -1, 0 );
}
if ( bossTime && enemys->bossDead() ) gameState = GS_BOSS_KILLED;
if ( racers->bothPlayersLost() ) gameState = GS_ROUNDFINISHED;
}
int B = SDL_GetTicks();
cout << "frameCnt: " << frameCnt << " tickCnt: " << tickCnt
<< " SDL_GetTicks()=" << B << endl;
cout << "Miliseconds: " << B-A << endl;
cout << "Frames/sec : " << (float)frameCnt / ((float)(B-A) / 1000.0) << endl;
cout << "ms/Frame : " << (float)tickCnt / (float)frameCnt << endl;
}
void Game::pause() {
if (paused) {
Uint32 timePaused = SDL_GetTicks() - timePauseOn;
timeLastUpdate += timePaused;
} else {
timePauseOn = SDL_GetTicks();
}
paused = !paused;
}
void Game::handleEventsPlayOn() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_JOYBUTTONDOWN:
case SDL_KEYDOWN: {
if (paused) pause();
racers->handleEvent(input.translate(event), input.isPressed(event));
break;
}
case SDL_KEYUP: {
switch(event.key.keysym.sym) {
case SDLK_F10: {
pause();
break;
}
case SDLK_F5: {
videoserver->toggleFullscreen();
break;
}
case SDLK_F6: {
showAllShipStats = !showAllShipStats;
break;
}
case SDLK_ESCAPE: {
gameState = GS_INTRO;
break;
}
case SDLK_F1: {
if (!paused) pause();
settings->settingsDialog(screen);
racers->getKeyActionMaps();
pause();
break;
}
case SDLK_F7: {
if ( playMusicOn ) {
playMusicOn = false;
mixer.stopMusic();
} else {
playMusicOn = true;
if ( bossTime ) mixer.playMusic( MUSIC_BOSS1, -1, 1000 );
else mixer.playMusic( MUSIC_PLAYON, -1, 1000 );
}
break;
}
default: break;
}
}
case SDL_JOYAXISMOTION:
case SDL_JOYBUTTONUP:
racers->handleEvent(input.translate(event), input.isPressed(event));
break;
case SDL_QUIT: {
gameState = GS_QUIT;
break;
}
default: break;
}
}
}
// what to do in one tick
void Game::updateGameState() {
int dT = SDL_GetTicks() - timeLastUpdate;
timeLastUpdate += dT;
if ( !minibossTime ) gameActRuntime += dT;
if ( nukeIsInPlace ) handleNuke();
enemys->generateEnemys( dT );
explosions->updateExplosions( dT );
smokePuffs->update( dT );
shots->moveAndCollide( dT );
wrecks->updateWrecks( dT );
enemys->updateEnemys( dT );
if ( !arcadeGame ) items->generate( dT );
items->update( dT );
racers->moveAndCollide( dT );
racers->pickUpItems();
racers->shoot();
if ( !arcadeGame ) racers->rechargeShield( dT );
enemys->deleteExpiredEnemys();
shots->expireShots();
items->expireItems();
explosions->expireExplosions();
wrecks->expireWrecks();
racers->expireRacers();
smokePuffs->expireSmokePuffs();
sonicDeflectorEffect();
banners->update( dT );
banners->expireBanners();
if ( scrollingOn ) actBackgroundPos -= SCROLL_SPEED * dT / 1000.0;
if ( arcadeGame ) {
racers->receivePointsArcade( ARCADE_POINTS_PER_TEN_SECONDS * dT / 10000.0 );
}
}
void Game::handleNuke() {
sonic1->setActive( false );
sonic2->setActive( false );
enemys->doNukeDamage();
shots->deleteAllShots();
timeNukeEnd = SDL_GetTicks() + NUKE_EFFECT_DURATION;
nukeIsInPlace = false;
}
void Game::sonicDeflectorEffect() {
for ( unsigned int i = 0; i < racers->getNrRacers(); i++) {
if ( racers->getRacer(i)->getShipType() == LIGHT_FIGHTER ) {
Shot* nearestRocket = shots->getNearestRocket( racers->getRacer(i)->getPos() );
// a rocket exists and it is in range of the sonic
if ( nearestRocket != NULL &&
(nearestRocket->getPos() - racers->getRacer(i)->getPos()).getLength() <
RACER_SONIC_ACTIVATION_DIST ) {
// activate the correct sonic
if (i == 0) {
sonic1->setPos( racers->getRacer(i)->getPos(), nearestRocket->getPos() );
nearestRocket->deflectedBySonicFromPlayer1 = true;
} else {
sonic2->setPos( racers->getRacer(i)->getPos(), nearestRocket->getPos() );
nearestRocket->deflectedBySonicFromPlayer2 = true;
}
// no rocket is in sonic-range
} else {
// deactivate the sonic
if (i == 0) {
sonic1->setActive( false );
} else {
sonic2->setActive( false );
}
}
}
}
}
void Game::drawPlayOn() {
drawBackground();
wrecks->draw(screen);
enemys->drawGroundEnemys(screen);
shots->drawShadows(screen);
racers->drawShadows(screen);
enemys->drawShadows(screen);
explosions->drawGroundExplosions(screen);
smokePuffs->draw(screen);
sonic1->draw(screen);
sonic2->draw(screen);
shots->drawGroundShots(screen);
shots->drawGroundAirShots(screen);
items->draw(screen);
enemys->drawAirEnemys(screen);
racers->drawRacers(screen);
shots->drawAirShots(screen);
explosions->drawAirExplosions(screen);
if ( showAllShipStats ) enemys->drawAllStats(screen);
else {
if ( bossTime ) {
enemys->drawBossStats(screen);
fontTime->drawStr( screen, (screen->w / 2), 5, "BOSS", FONT_ALIGN_CENTERED );
}
}
if ( SDL_GetTicks() < timeNukeEnd ) {
drawNukeEffect();
}
racers->drawStats(screen);
banners->draw(screen);
if ( !arcadeGame && !bossTime && !minibossTime ) drawTime();
else {
if ( bossTime || minibossTime ) {
fontTime->drawStr( screen, (screen->w / 2), 5, "BOSS", FONT_ALIGN_CENTERED );
}
else {
drawPointsArcadeMode();
}
}
if (paused) drawPaused();
SDL_Flip( screen );
frameCnt++;
}
void Game::drawBackground() {
background->draw(screen, (int) (actBackgroundPos + 0.5) );
}
void Game::drawTime() {
Uint32 timeToDraw;
timeToDraw = (GAME_LENGTH - gameActRuntime) / 1000;
if ( timeToDraw > 0 ) {
int digitCnt = 1;
Uint32 i=1;
while ( timeToDraw >= i*10 ) {
digitCnt++;
i *= 10;
}
fontTime->drawInt(screen, (screen->w / 2) - (fontSizeTime * digitCnt) / 2, 5,
timeToDraw, digitCnt, 0);
}
}
void Game::drawPointsArcadeMode() {
int pointsToDraw = racers->getPointsArcadeMode();
if ( pointsToDraw < 0 ) return;
int digitCnt = 1;
int i=1;
while ( pointsToDraw >= i*10 ) {
digitCnt++;
i *= 10;
}
fontTime->drawInt( screen, (screen->w / 2) - (fontSizeTime * digitCnt) / 2, 10,
pointsToDraw, digitCnt, 0);
}
void Game::drawPaused() {
SDL_Rect r;
r.x = screen->w/2 - pauseSprite->w/2;
r.y = screen->h/2 - pauseSprite->h/2;
r.w = pauseSprite->w;
r.h = pauseSprite->h;
SDL_BlitSurface( pauseSprite, 0, screen, &r );
}
void Game::drawNukeEffect() {
// effect-process: transparent -> nearly opaque -> transparent
int timeFromMaximum = (NUKE_EFFECT_DURATION / 2) - (timeNukeEnd - SDL_GetTicks());
timeFromMaximum = abs(timeFromMaximum);
SDL_SetAlpha( nukeEffectSurface, SDL_SRCALPHA | SDL_RLEACCEL,
lroundf(((NUKE_EFFECT_DURATION / 2) - timeFromMaximum) * 128.0 /
(NUKE_EFFECT_DURATION / 2)) );
SDL_BlitSurface( nukeEffectSurface, 0, screen, 0 );
int randRange = (int)
(( ((NUKE_EFFECT_DURATION / 2.0) - timeFromMaximum) * NUKE_QUAKE_EFFECT /
(NUKE_EFFECT_DURATION / 2.0 ) ) + 0.5);
int randX, randY;
if ( randRange == 0 ) randRange = 1;
randX = (rand() % randRange) - randRange / 2;
randY = (rand() % randRange) - randRange / 2;
SDL_Rect src, dest;
if ( randX < 0 ) {
src.x = -randX;
src.w = screen->w + randX;
dest.x = 0;
dest.w = screen->w + randX;
} else {
src.x = 0;
src.w = screen->w - randX;
dest.x = randX;
dest.w = screen->w - randX;
}
if ( randY < 0 ) {
src.y = -randY;
src.h = screen->h + randY;
dest.y = 0;
dest.h = screen->h + randY;
} else {
src.y = 0;
src.h = screen->h - randY;
dest.y = randY;
dest.h = screen->h - randY;
}
SDL_BlitSurface( screen, &src, screen, &dest );
}
// not in use - not needed anymore
void Game::timeManagement() {
Uint32 sdlTicksNew = SDL_GetTicks();
tickCnt += sdlTicksNew - sdlTicks;
// 25 Frames per Second is wanted
// we needed less than 40 ms -> wait till the 40 ms are over
while ( sdlTicks + 40 > sdlTicksNew ) {
sdlTicksNew = SDL_GetTicks();
}
sdlTicks = sdlTicksNew;
}
/***********************************/
/** Options ************************/
/***********************************/
void Game::options() {}
/************************************/
/** Round Finished ******************/
/************************************/
void Game::roundFinished() {
drawRoundFinished();
SDL_Flip( screen );
while (gameState == GS_ROUNDFINISHED ) {
handleEventsRoundFinished();
}
}
void Game::handleEventsRoundFinished() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYUP:
{
switch(event.key.keysym.sym) {
case SDLK_ESCAPE:
case SDLK_SPACE:
case SDLK_RETURN:
{
if ( arcadeGame ) gameState = GS_ARCADE_MODE_FINISHED;
else gameState = GS_INTRO;
break;
}
case SDLK_F5:
{
videoserver->toggleFullscreen();
break;
}
default:
{
break;
}
}
break;
}
case SDL_QUIT:
{
if ( arcadeGame ) gameState = GS_ARCADE_MODE_FINISHED;
else gameState = GS_INTRO;
break;
}
default: break;
}
}
}
void Game::drawRoundFinished() {
SDL_Rect r;
if ( arcadeGame ) {
r.x = screen->w/2 - gameOverSprite->w / 2;
r.y = screen->h/2 - gameOverSprite->h / 2;
r.w = gameOverSprite->w;
r.h = gameOverSprite->h;
SDL_BlitSurface( gameOverSprite, 0, screen, &r );
fontTime->drawStr( screen, screen->w/2, screen->h/2 + gameOverSprite->h/2 + 50,
"SCORE: " + asString( racers->getPointsArcadeMode() ),
FONT_ALIGN_CENTERED );
fontTime->drawStr( screen, screen->w/2, screen->h/2 + gameOverSprite->h/2 + 100,
"Kill Rate: " + asString(enemys->getNrEnemysKilled())
+ "/" + asString(enemys->getNrEnemysGenerated()),
FONT_ALIGN_CENTERED );
}
// normal game
else {
if ( racers->bothPlayersLost() ) {
r.x = screen->w/2 - youLoseSprite->w / 2;
r.y = screen->h/2 - youLoseSprite->h / 2;
r.w = youLoseSprite->w;
r.h = youLoseSprite->h;
SDL_BlitSurface( youLoseSprite, 0, screen, &r );
} else {
r.x = screen->w/2 - youWinSprite->w / 2;
r.y = screen->h/2 - youWinSprite->h / 2;
r.w = youWinSprite->w;
r.h = youWinSprite->h;
SDL_BlitSurface( youWinSprite, 0, screen, &r );
fontTime->drawStr(screen, screen->w/2, screen->h/2 + youWinSprite->h/2 + 50,
"Kill Rate: " + asString(enemys->getNrEnemysKilled())
+ ":" + asString(enemys->getNrEnemysGenerated()),
FONT_ALIGN_CENTERED);
}
}
}
/************************************/
/** Miniboss ***********************/
/************************************/
void Game::generateMiniboss() {
scrollingOn = false;
minibossTime = true;
enemys->bossTime(2); // generates the miniboss
mixer.playSample( bossAlarm , 0, true );
if ( playMusicOn ) mixer.playMusic( MUSIC_BOSS1, -1, 0 );
}
void Game::minibossKilled() {
scrollingOn = true;
minibossTime = false;
if ( playMusicOn ) mixer.playMusic( MUSIC_PLAYON, -1, 0 );
}
/************************************/
/** Boss Killed *********************/
/************************************/
void Game::bossKilled() {
int BOSS_EXPLOSION_DURATION = 3000;
int startOfBossExplosion = SDL_GetTicks();
int actualTime;
bool bossExplosionSound = false;
timeNukeEnd = SDL_GetTicks() + BOSS_EXPLOSION_DURATION + NUKE_EFFECT_DURATION;
while ( gameState == GS_BOSS_KILLED ) {
actualTime = SDL_GetTicks();
updateBossKilled();
if ( (actualTime - startOfBossExplosion) < BOSS_EXPLOSION_DURATION ) {
// explosions
Explosion *newExplosion =
new Explosion( FN_EXPLOSION_ENEMY,
Vector2D( rand() % SCREEN_WIDTH, rand() % 150 ),
Vector2D( 0, 0 ),
EXPLOSION_NORMAL_GROUND );
explosions->addExplosion( newExplosion );
}
else if ( (actualTime - startOfBossExplosion) < (BOSS_EXPLOSION_DURATION + NUKE_EFFECT_DURATION) ) {
// nuke effect
if ( !bossExplosionSound ) {
mixer.playSample( bossExplosion, 0, true );
bossExplosionSound = false;
enemys->doNukeDamage();
enemys->deleteExpiredEnemys();
shots->deleteAllShots();
items->deleteAllItems();
wrecks->deleteAllWrecks();
Wreck *newWreck = new Wreck( Vector2D( SCREEN_WIDTH / 2, 70 ), WRECK_BOSS_1_DESTROYED);
wrecks->addWreck( newWreck );
bossNukeEffect = true;
}
}
else {
bossNukeEffect = false;
}
if ( (actualTime - startOfBossExplosion) > (BOSS_EXPLOSION_DURATION + NUKE_EFFECT_DURATION + 4000) ) {
gameState = GS_ROUNDFINISHED;
}
drawBossKilled();
handleEventsBossKilled();
}
}
void Game::handleEventsBossKilled() {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYUP: {
switch(event.key.keysym.sym) {
case SDLK_ESCAPE:
case SDLK_SPACE:
case SDLK_RETURN:
{
gameState = GS_INTRO;
break;
}
case SDLK_F5:
{
videoserver->toggleFullscreen();
break;
}
default: break;
}
break;
}
case SDL_QUIT:
{
gameState = GS_INTRO;
break;
}
default: break;
}
}
}
void Game::drawBossKilled() {
drawBackground();
wrecks->draw(screen);
enemys->drawGroundEnemys(screen);
shots->drawShadows(screen);
racers->drawShadows(screen);
enemys->drawShadows(screen);
explosions->drawGroundExplosions(screen);
shots->drawGroundShots(screen);
shots->drawGroundAirShots(screen);
items->draw(screen);
enemys->drawAirEnemys(screen);
racers->drawRacers(screen);
shots->drawAirShots(screen);
explosions->drawAirExplosions(screen);
if ( bossNukeEffect ) drawNukeEffect();
racers->drawStats(screen);
SDL_Flip( screen );
}
void Game::updateBossKilled() {
int dT = SDL_GetTicks() - timeLastUpdate;
timeLastUpdate += dT;
explosions->updateExplosions( dT );
explosions->expireExplosions();
}
void Game::loadLevel( string fn ) {
if (levelConf) {
delete levelConf;
}
levelConf = new Options( fn );
// load background tiles
background->clearTileList();
int cnt = 0;
if (!levelConf->getInt( LVL_BACKG_TILE_CNT, cnt )) {
cout << "ERROR: " << fn << " contains no '" << LVL_BACKG_TILE_CNT << "' keyword!" << endl;
exit(0);
}
for(int i=0; i < cnt; i++) {
string tilename;
if (levelConf->getStr( LVL_BACKG_TILE + asString( i ), tilename ) ) {
background->addTile( tilename );
}
}
int len = SCREEN_WIDTH;
levelConf->getInt( LVL_BACKG_LENGTH, len );
background->generateBackground( len );
}

View File

@@ -0,0 +1,142 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef GAME_HH
#define GAME_HH
#include "SDL.h"
#include <string>
class Video;
class SurfaceDB;
class Racers;
class Shots;
class Explosions;
class Enemys;
class Items;
class Font;
class Intro;
class SetDifficulty;
class MenuArcadeMode;
class Sonic;
class Background;
class Options;
enum GameStates { GS_QUIT, GS_SCREENSHOTS, GS_INTRO, GS_SET_DIFFICULTY,
GS_OPTIONS, GS_ARCADE_MODE_SETUP, GS_ARCADE_MODE_FINISHED,
GS_PLAYON, GS_ROUNDFINISHED, GS_BOSS_KILLED };
/* The big class, that has to control the gamelogic and keep track of all the
game objects and their dependencies. */
class Game {
// Video system
SDL_Surface *screen;
SDL_Surface *pauseSprite;
SDL_Surface *youLoseSprite;
SDL_Surface *youWinSprite;
SDL_Surface *gameOverSprite;
SDL_Surface *nukeEffectSurface;
SDL_Surface *hud;
// Time system
Font *fontTime;
int fontSizeTime;
Uint32 frameCnt;
Uint32 tickCnt;
Uint32 sdlTicks;
Uint32 gameActRuntime;
Uint32 timePauseOn;
Uint32 timeMinibossOn;
Uint32 timeLastUpdate;
Uint32 timeNukeEnd;
bool paused;
bool showAllShipStats;
Background *background;
// is the game in playon or in intro or somewhere else?
GameStates gameState;
Intro *intro;
SetDifficulty *setDifficulty;
MenuArcadeMode *menuArcadeMode;
// boss specific
bool bossTime;
bool minibossTime;
bool minibossAlreadyKilled;
bool bossNukeEffect;
int bossExplosion;
int bossAlarm;
Sonic *sonic1;
Sonic *sonic2;
public:
// for access from main()
Game();
~Game();
// the outer game loop
void run();
private:
// starts a new game
void initNewGame();
/* Methods for GS_PLAYON */
// the inner loop when the race is going on
void playOn();
void handleEventsPlayOn();
// toggles the pause state (takes into account the corresponding time problems)
void pause();
void updateGameState();
void handleNuke();
void sonicDeflectorEffect();
void drawPlayOn();
void drawBackground();
void drawTime();
void drawPointsArcadeMode();
void drawPaused();
void drawNukeEffect();
void timeManagement(); // not needed and used any more
/* Methods for GS_OPTIONS (not implemented by now) */
void options();
void loadLevel( std::string fn );
/* Methods for GS_ROUNDFINISHED (the time is up -> display the winner) */
void roundFinished();
void drawRoundFinished();
void handleEventsRoundFinished();
void generateMiniboss();
void minibossKilled();
void bossKilled();
void updateBossKilled();
void drawBossKilled();
void handleEventsBossKilled();
};
#endif //#ifndef GAME_HH

View File

@@ -0,0 +1,793 @@
/*
Copyright (c) 2000,2001, Jelle Kok, University of Amsterdam
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University of Amsterdam nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**************************************************************************************
* goemetry.cc
*
* implements:
* class Vector2D
* namespace Geometry
* class Line
* class Circle
* class Rectangle
*
* requires:
*
* Maintainer: wenns
*
* Changelog:
*
*************************************************************************************/
//Furthermore it contains some goniometric functions to work with sine, cosine
//and tangent functions using degrees and some utility functions to return
//the maximum and the minimum of two values.
#include "geometry.h"
#include <algorithm> // max and min
#include <stdio.h> // needed for sprintf
AngDeg Rad2Deg ( AngRad x ) { return ( x * 180 / M_PI ); }
AngRad Deg2Rad ( AngDeg x ) { return ( x * M_PI / 180 ); }
float cosDeg ( AngDeg x ) { return ( cos( Deg2Rad( x ) ) ); }
float sinDeg ( AngDeg x ) { return ( sin( Deg2Rad( x ) ) ); }
float tanDeg ( AngDeg x ) { return ( tan( Deg2Rad( x ) ) ); }
AngDeg atanDeg ( float x ) { return ( Rad2Deg( atan( x ) ) ); }
float atan2Deg( float x, float y ){
if( fabs( x ) < EPSILON && fabs( y ) < EPSILON )
return ( 0.0 );
return ( Rad2Deg( atan2( x, y ) ) );
}
AngDeg acosDeg( float x ){
if( x >= 1 )
return ( 0.0 );
else if( x <= -1 )
return ( 180.0 );
return ( Rad2Deg( acos( x ) ) );
}
AngDeg asinDeg( float x ){
if( x >= 1 )
return ( 90.0 );
else if ( x <= -1 )
return ( -90.0 );
return ( Rad2Deg( asin( x ) ) );
}
float normalizeTo180Deg(float angle){
while( angle > 180.0 ) angle -= 360.0;
while( angle < -180.0 ) angle += 360.0;
return ( angle );
}
bool isAngInInterval( AngDeg ang, AngDeg angMin, AngDeg angMax ){
// convert all angles to interval 0..360
if( ( ang + 360 ) < 360 ) ang += 360;
if( ( angMin + 360 ) < 360 ) angMin += 360;
if( ( angMax + 360 ) < 360 ) angMax += 360;
if( angMin < angMax ) // 0 ---false-- angMin ---true-----angMax---false--360
return angMin < ang && ang < angMax ;
else // 0 ---true--- angMax ---false----angMin---true---360
return !( angMax < ang && ang < angMin );
}
AngDeg getBisectorTwoAngles( AngDeg angMin, AngDeg angMax ){
// separate sine and cosine part to circumvent boundary problem
//return Vector2D::normalizeAngle(
return normalizeTo180Deg( //wenns changed
atan2Deg( (sinDeg( angMin) + sinDeg( angMax ) )/2.0,
(cosDeg( angMin) + cosDeg( angMax ) )/2.0 ) );
}
AngDeg getAngleDifference( AngDeg ang1, AngDeg ang2 ){
return (normalizeTo180Deg( ang1 - ang2 ));
}
AngDeg getAbsAngleDifference( AngDeg ang1, AngDeg ang2 ){
return fabs(normalizeTo180Deg( ang1 - ang2 ));
}
/******************************************************************************/
/******************** CLASS VECTOR2D **************************************/
/******************************************************************************/
Vector2D::Vector2D( float x, float y, CoordSystemT cs ){
setVector2D( x, y, cs );
}
ostream& operator <<( ostream &os, Vector2D v ){
return ( os << "( " << v.x << ", " << v.y << " )" );
}
void Vector2D::show( CoordSystemT cs ){
if( cs == CARTESIAN )
cout << *this << endl;
else
cout << "( r: " << getLength( ) << ", phi: " << getDirection( ) << " )";
}
/*
bool Vector2D::isInvalid() const {
return (isUndefined(x) || (isUndefined(y))
// || (fabs(x) >= 100000.0) || (fabs(y) >= 100000.0)
|| isinf(x) || isinf(y) || isnan(x) || isnan(y));
}
*/
void Vector2D::setVector2D( float dX, float dY, CoordSystemT cs){
if( cs == CARTESIAN ) { x = dX; y = dY; }
else *this = getVector2DFromPolar( dX, dY );
}
Vector2D Vector2D::setLength( float d ){
if( getLength( ) > EPSILON )
( *this ) *= ( d / getLength( ) );
return ( *this );
}
Vector2D Vector2D::rotate( AngDeg angle ){
// determine the polar representation of the current Vector2D
float dMag = this->getLength( );
float dNewDir = this->getDirection( ) + angle; // add rotation angle to phi
setVector2D( dMag, dNewDir, POLAR ); // convert back to Cartesian
return ( *this );
}
Vector2D Vector2D::globalToRelative( Vector2D origin, AngDeg ang ){
// convert global coordinates into relative coordinates by aligning relative
// frame and world frame. First perform translation to make origins of both
// frames coincide. Then perform rotation to make axes of both frames coincide
// (use negative angle since you rotate relative frame to world frame).
*this -= origin;
return ( rotate( -ang ) );
}
Vector2D Vector2D::relativeToGlobal( Vector2D origin, AngDeg ang ){
// convert relative coordinates into global coordinates by aligning world
// frame and relative frame. First perform rotation to make axes of both
// frames coincide (use positive angle since you rotate world frame to
// relative frame). Then perform translation to make origins of both frames
// coincide.
rotate( ang );
*this += origin;
return ( *this );
}
Vector2D Vector2D::getVector2DOnLineFraction( Vector2D &p,
float dFrac ){
// determine point on line that lies at fraction dFrac of whole line
// example: this --- 0.25 --------- p
// formula: this + dFrac * ( p - this ) = this - dFrac * this + dFrac * p =
// ( 1 - dFrac ) * this + dFrac * p
return ( ( *this ) * ( 1.0 - dFrac ) + ( p * dFrac ) );
}
Vector2D Vector2D::getVector2DFromPolar( float dMag, AngDeg ang ){
// cos(phi) = x/r <=> x = r*cos(phi); sin(phi) = y/r <=> y = r*sin(phi)
return ( Vector2D( dMag * cosDeg( ang ), dMag * sinDeg( ang ) ) );
}
/******************************************************************************/
/*********************** NAMESPACE GEOMETRY ***************************************/
/******************************************************************************/
float Geometry::getLengthGeomSeries( float dFirst, float dRatio, float dSum ){
if( dRatio < 0 )
cerr << "(Geometry:getLengthGeomSeries): negative ratio" << endl;
// s = a + ar + ar^2 + .. + ar^n-1 and thus sr = ar + ar^2 + .. + ar^n
// subtract: sr - s = - a + ar^n) => s(1-r)/a + 1 = r^n = temp
// log r^n / n = n log r / log r = n = length
float temp = (dSum * ( dRatio - 1 ) / dFirst) + 1;
if( temp <= 0 )
return -1.0;
return log( temp ) / log( dRatio ) ;
}
float Geometry::getSumGeomSeries( float dFirst, float dRatio, float dLength){
// s = a + ar + ar^2 + .. + ar^n-1 and thus sr = ar + ar^2 + .. + ar^n
// subtract: s - sr = a - ar^n) => s = a(1-r^n)/(1-r)
return dFirst * ( 1 - pow( dRatio, dLength ) ) / ( 1 - dRatio ) ;
}
float Geometry::getSumInfGeomSeries( float dFirst, float dRatio ){
if( dRatio > 1 )
cerr << "(Geometry:CalcLengthGeomSeries): series does not converge" << endl;
// s = a(1-r^n)/(1-r) with n->inf and 0<r<1 => r^n = 0
return dFirst / ( 1 - dRatio );
}
float Geometry::getFirstGeomSeries( float dSum, float dRatio, float dLength){
// s = a + ar + ar^2 + .. + ar^n-1 and thus sr = ar + ar^2 + .. + ar^n
// subtract: s - sr = a - ar^n) => s = a(1-r^n)/(1-r) => a = s*(1-r)/(1-r^n)
return dSum * ( 1 - dRatio )/( 1 - pow( dRatio, dLength ) ) ;
}
float Geometry::getFirstInfGeomSeries( float dSum, float dRatio ){
if( dRatio > 1 )
cerr << "(Geometry:getFirstInfGeomSeries):series does not converge" << endl;
// s = a(1-r^n)/(1-r) with r->inf and 0<r<1 => r^n = 0 => a = s ( 1 - r)
return dSum * ( 1 - dRatio );
}
int Geometry::abcFormula(float a, float b, float c, float *s1, float *s2){
float dDiscr = b*b - 4*a*c; // discriminant is b^2 - 4*a*c
if (fabs(dDiscr) < EPSILON ) // if discriminant = 0
{
*s1 = -b / (2 * a); // only one solution
return 1;
}
else if (dDiscr < 0) // if discriminant < 0
return 0; // no solutions
else // if discriminant > 0
{
dDiscr = sqrt(dDiscr); // two solutions
*s1 = (-b + dDiscr ) / (2 * a);
*s2 = (-b - dDiscr ) / (2 * a);
return 2;
}
}
/******************************************************************************/
/********************** CLASS CIRCLE ******************************************/
/******************************************************************************/
Circle::Circle( Vector2D pos, float dR ){
setCircle( pos, dR );
}
Circle::Circle( ){
setCircle( Vector2D(-1000.0,-1000.0), 0);
}
void Circle::show( ostream& os) const {
os << "c:" << posCenter << ", r:" << radius;
}
bool Circle::setCircle( const Vector2D &pos, float dR ){
setCenter( pos );
return setRadius( dR );
}
bool Circle::setRadius( float dR ){
if( dR > 0 ){
radius = dR;
return true;
}
else{
radius = 0.0;
return false;
}
}
int Circle::getIntersectionPoints( const Circle &c, Vector2D *p1,
Vector2D *p2) const {
float x0, y0, r0;
float x1, y1, r1;
x0 = getCenter( ).getX();
y0 = getCenter( ).getY();
r0 = getRadius( );
x1 = c.getCenter( ).getX();
y1 = c.getCenter( ).getY();
r1 = c.getRadius( );
float d, dx, dy, h, a, x, y, p2_x, p2_y;
// first calculate distance between two centers circles P0 and P1.
dx = x1 - x0;
dy = y1 - y0;
d = sqrt(dx*dx + dy*dy);
// normalize differences
dx /= d; dy /= d;
// a is distance between p0 and point that is the intersection point P2
// that intersects P0-P1 and the line that crosses the two intersection
// points P3 and P4.
// Define two triangles: P0,P2,P3 and P1,P2,P3.
// with distances a, h, r0 and b, h, r1 with d = a + b
// We know a^2 + h^2 = r0^2 and b^2 + h^2 = r1^2 which then gives
// a^2 + r1^2 - b^2 = r0^2 with d = a + b ==> a^2 + r1^2 - (d-a)^2 = r0^2
// ==> r0^2 + d^2 - r1^2 / 2*d
a = (r0*r0 + d*d - r1*r1) / (2.0 * d);
// h is then a^2 + h^2 = r0^2 ==> h = sqrt( r0^2 - a^2 )
float arg = r0*r0 - a*a;
h = (arg > 0.0) ? sqrt(arg) : 0.0;
// First calculate P2
p2_x = x0 + a * dx;
p2_y = y0 + a * dy;
// and finally the two intersection points
x = p2_x - h * dy;
y = p2_y + h * dx;
p1->setVector2D( x, y );
x = p2_x + h * dy;
y = p2_y - h * dx;
p2->setVector2D( x, y );
return (arg < 0.0) ? 0 : ((arg == 0.0 ) ? 1 : 2);
}
float Circle::getIntersectionArea( const Circle &c ) const {
Vector2D pos1, pos2, pos3;
float d, h, dArea;
AngDeg ang;
d = getCenter().distanceTo( c.getCenter() ); // dist between two centers
if( d > c.getRadius() + getRadius() ) // larger than sum radii
return 0.0; // circles do not intersect
if( d <= fabs(c.getRadius() - getRadius() ) ) // one totally in the other
{
float dR = min( c.getRadius(), getRadius() );// return area smallest circle
return M_PI*dR*dR;
}
int iNrSol = getIntersectionPoints( c, &pos1, &pos2 );
if( iNrSol != 2 )
return 0.0;
// the intersection area of two circles can be divided into two segments:
// left and right of the line between the two intersection points p1 and p2.
// The outside area of each segment can be calculated by taking the part
// of the circle pie excluding the triangle from the center to the
// two intersection points.
// The pie equals pi*r^2 * rad(2*ang) / 2*pi = 0.5*rad(2*ang)*r^2 with ang
// the angle between the center c of the circle and one of the two
// intersection points. Thus the angle between c and p1 and c and p3 where
// p3 is the point that lies halfway between p1 and p2.
// This can be calculated using ang = asin( d / r ) with d the distance
// between p1 and p3 and r the radius of the circle.
// The area of the triangle is 2*0.5*h*d.
pos3 = pos1.getVector2DOnLineFraction( pos2, 0.5 );
d = pos1.distanceTo( pos3 );
h = pos3.distanceTo( getCenter() );
ang = asin( d / getRadius() );
dArea = ang*getRadius()*getRadius();
dArea = dArea - d*h;
// and now for the other segment the same story
h = pos3.distanceTo( c.getCenter() );
ang = asin( d / c.getRadius() );
dArea = dArea + ang*c.getRadius()*c.getRadius();
dArea = dArea - d*h;
return dArea;
}
bool Circle::calcTangentIntersectionPoints(const Vector2D startPoint, Vector2D &point1, Vector2D &point2){
if(isInside(startPoint)){
// Startpoint is inside circle -> there are no tangent interception points
return(false);
}
//float d = posCenter.getLength()-startPoint.getLength();
float d = (posCenter-startPoint).getLength();
float r = radius;
float alphaRad = asin(r/d);
float p = sqrt(d*d-r*r);
point1.setX(cos(alphaRad)*p);
point1.setY(sin(alphaRad)*p);
point2.setX(cos(-alphaRad)*p);
point2.setY(sin(-alphaRad)*p);
point1=point1.rotate((posCenter-startPoint).getDirection());
point2=point2.rotate((posCenter-startPoint).getDirection());
point1+=startPoint;
point2+=startPoint;
return(true);
}
/******************************************************************************/
/*********************** CLASS LINE *******************************************/
/******************************************************************************/
Line::Line( float dA, float dB, float dC ){
a = dA;
b = dB;
c = dC;
}
Line::Line() {
a = 666.66;
b = 666.66;
c = 666.66;
}
ostream& operator <<(ostream & os, Line l){
float a = l.getACoefficient();
float b = l.getBCoefficient();
float c = l.getCCoefficient();
// ay + bx + c = 0 -> y = -b/a x - c/a
if( a == 0 )
os << "x = " << -c/b;
else{
os << "y = ";
if( b != 0 )
os << -b/a << "x ";
if( c > 0 )
os << "- " << fabs(c/a);
else if( c < 0 )
os << "+ " << fabs(c/a);
}
return os;
}
void Line::show( ostream& os){
os << *this;
}
Vector2D Line::getIntersection( Line line ){
Vector2D pos(666.66,666.66);
float x, y;
if( (b == line.getBCoefficient())&&(b!=-a) ) { // lines are parallel, no intersection
return pos;
}
if( a == 0 ){ // bx + c = 0 and a2*y + b2*x + c2 = 0 ==> x = -c/b
x = -c/b; // calculate x using the current line
y = line.getYGivenX(x); // and calculate the y using the second line
}
// ay + bx + c = 0 and b2*x + c2 = 0 ==> x = -c2/b2
// calculate x using 2nd line and calculate y using current line
else if( line.getACoefficient() == 0 ){
x = -line.getCCoefficient()/line.getBCoefficient();
y = getYGivenX(x);
}
// ay + bx + c = 0 and a2y + b2*x + c2 = 0
// y = (-b2/a2)x - c2/a2
// bx = -a*y - c => bx = -a*(-b2/a2)x -a*(-c2/a2) - c ==>
// ==> a2*bx = a*b2*x + a*c2 - a2*c ==> x = (a*c2 - a2*c)/(a2*b - a*b2)
// calculate x using the above formula and the y using the current line
else{
x = (a*line.getCCoefficient() - line.getACoefficient()*c)/
(line.getACoefficient()*b - a*line.getBCoefficient());
y = getYGivenX(x);
}
return Vector2D( x, y );
}
int Line::getCircleIntersectionPoints( Circle circle,
Vector2D *posSolution1, Vector2D *posSolution2 ){
int iSol;
float dSol1, dSol2;
float h = circle.getCenter().getX();
float k = circle.getCenter().getY();
// line: x = -c/b (if a = 0)
// circle: (x-h)^2 + (y-k)^2 = r^2, with h = center.x and k = center.y
// fill in:(-c/b-h)^2 + y^2 -2ky + k^2 - r^2 = 0
// y^2 -2ky + (-c/b-h)^2 + k^2 - r^2 = 0
// and determine solutions for y using abc-formula
if( fabs(a) < EPSILON ){
iSol = Geometry::abcFormula( 1, -2*k, ((-c/b) - h)*((-c/b) - h)
+ k*k - circle.getRadius()*circle.getRadius(), &dSol1, &dSol2);
posSolution1->setVector2D( (-c/b), dSol1 );
posSolution2->setVector2D( (-c/b), dSol2 );
return iSol;
}
// ay + bx + c = 0 => y = -b/a x - c/a, with da = -b/a and db = -c/a
// circle: (x-h)^2 + (y-k)^2 = r^2, with h = center.x and k = center.y
// fill in:x^2 -2hx + h^2 + (da*x-db)^2 -2k(da*x-db) + k^2 - r^2 = 0
// x^2 -2hx + h^2 + da^2*x^2 + 2da*db*x + db^2 -2k*da*x -2k*db
// + k^2 - r^2 = 0
// (1+da^2)*x^2 + 2(da*db-h-k*da)*x + h2 + db^2 -2k*db + k^2 - r^2 = 0
// and determine solutions for x using abc-formula
// fill in x in original line equation to get y coordinate
float da = -b/a;
float db = -c/a;
float dA = 1 + da*da;
float dB = 2*( da*db - h - k*da );
float dC = h*h + db*db - 2*k*db + k*k - circle.getRadius()*circle.getRadius();
iSol = Geometry::abcFormula( dA, dB, dC, &dSol1, &dSol2 );
posSolution1->setVector2D( dSol1, da*dSol1 + db );
posSolution2->setVector2D( dSol2, da*dSol2 + db );
return iSol;
}
Line Line::getTangentLine( Vector2D pos ){ // Senkrechte errichten, nix mit Tangente
// ay + bx + c = 0 -> y = (-b/a)x + (-c/a)
// tangent: y = (a/b)*x + C1 -> by - ax + C2 = 0 => C2 = ax - by
// with pos.y = y, pos.x = x
return Line( b, -a, a*pos.getX() - b*pos.getY() );
}
Vector2D Line::getPointOnLineClosestTo( Vector2D pos ){
Line l2 = getTangentLine( pos ); // get tangent line
return getIntersection( l2 ); // and intersection between the two lines
}
float Line::distanceToPoint( Vector2D pos ){
return pos.distanceTo( getPointOnLineClosestTo( pos ) );
}
bool Line::isInBetween( Vector2D pos, Vector2D point1, Vector2D point2){
pos = getPointOnLineClosestTo( pos ); // get closest point
float dDist = point1.distanceTo( point2 ); // get distance between 2 pos
// if the distance from both points to the projection is smaller than this
// dist, the pos lies in between.
return pos.distanceTo( point1 ) <= dDist &&
pos.distanceTo( point2 ) <= dDist;
}
float Line::getYGivenX( float x ){
if( a == 0 ){
cerr << "(Line::getYGivenX) Cannot calculate Y coordinate: " ;
show( cerr );
cerr << endl;
return 0;
}
// ay + bx + c = 0 ==> ay = -(b*x + c)/a
return -(b*x+c)/a;
}
float Line::getXGivenY( float y ){
if( b == 0 ){
cerr << "(Line::getXGivenY) Cannot calculate X coordinate\n" ;
return 0;
}
// ay + bx + c = 0 ==> bx = -(a*y + c)/a
return -(a*y+c)/b;
}
Line Line::makeLineFromTwoPoints( Vector2D pos1, Vector2D pos2 ){
// 1*y + bx + c = 0 => y = -bx - c
// with -b the direction coefficient (or slope)
// and c = - y - bx
float dA=1.0, dB, dC;
float dTemp = pos2.getX() - pos1.getX(); // determine the slope
if( fabs(dTemp) < EPSILON ){
// ay + bx + c = 0 with vertical slope=> a = 0, b = 1
dA = 0.0;
dB = 1.0;
}
else{
// y = (-b)x -c with -b the slope of the line
dA = 1.0;
dB = -(pos2.getY() - pos1.getY())/dTemp;
}
// ay + bx + c = 0 ==> c = -a*y - b*x
dC = - dA*pos2.getY() - dB * pos2.getX();
return Line( dA, dB, dC );
}
Line Line::makeLineFromPositionAndAngle( Vector2D vec, AngDeg angle ){
// calculate point somewhat further in direction 'angle' and make
// line from these two points.
return makeLineFromTwoPoints( vec, vec+Vector2D(1,angle,POLAR));
}
/******************************************************************************/
/********************** CLASS RECTANGLE ***************************************/
/******************************************************************************/
RectangleGeo::RectangleGeo( Vector2D pos, Vector2D pos2 ){
setRectanglePoints( pos, pos2 );
}
void RectangleGeo::setRectanglePoints( Vector2D pos1, Vector2D pos2 ){
posLeftTop.setX ( min( pos1.getX(), pos2.getX() ) );
posLeftTop.setY ( min( pos1.getY(), pos2.getY() ) );
posRightBottom.setX( max( pos1.getX(), pos2.getX() ) );
posRightBottom.setY( max( pos1.getY(), pos2.getY() ) );
}
void RectangleGeo::show( ostream& os ) const {
os << "rect(" << posLeftTop << " " << posRightBottom << ")";
}
bool RectangleGeo::isInside( Vector2D pos ) const {
return ( (getPosLeftTop().getX() <= pos.getX()) &&
(pos.getX() <= getPosRightBottom().getX()) &&
(getPosLeftTop().getY() <= pos.getY()) &&
(pos.getY() <= getPosRightBottom().getY()) );
}
/******************************************************************************/
/********************** CLASS CONE ********************************************/
/******************************************************************************/
Cone::Cone( Vector2D peak,
float fstAngle, float sndAngle,
float maxDistance, float minDistance ) {
setPeak( peak );
setAngles( fstAngle, sndAngle );
setMaxDistance( maxDistance );
setMinDistance( minDistance );
}
void Cone::show( ostream& os ) const {
os << "(p:" << peak << " fst:" << fstAngle << " snd:" << sndAngle
<< " maxDist:" << maxDistance << " minDist:" << minDistance << ")";
}
bool Cone::isInside( Vector2D pos ) const {
float dist = pos.distanceTo( peak );
float angle = (pos - peak).getDirection();
return ( ( minDistance <= dist && dist <= maxDistance &&
isAngInInterval( angle, fstAngle, sndAngle ) ) ||
( dist == 0 && minDistance == 0) );
}
/******************************************************************************/
/********************** TESTING PURPOSES *************************************/
/******************************************************************************/
/*
#include<iostream.h>
int main( void ){
float dFirst = 1.0;
float dRatio = 2.5;
float dSum = 63.4375;
float dLength = 4.0;
printf( "sum: %f\n", Geometry::getSumGeomSeries( dFirst, dRatio, dLength));
printf( "length: %f\n", Geometry::getLengthGeomSeries( dFirst, dRatio, dSum));
}
int main( void ){
Line l1(1,-1,3 );
Line l2(1,-0.2,10 );
Line l3 = Line::makeLineFromTwoPoints( Vector2D(1,-1), Vector2D(2,-2) );
l3.show();
cout << endl;
l1.show();
l2.show();
l1.getIntersection( l2 ).show();
}
int main( void ){
Line l( 1, -1, 0 );
Vector2D s1, s2;
int i = l.getCircleIntersectionPoints( Circle( Vector2D(1,1), 1 ), &s1, &s2 );
printf( "number of solutions: %d\n", i );
if( i == 2 ){
cout << s1 << " " << s2 ;
}
else if( i == 1 ){
cout << s1;
}
cout << "line: " << l << endl;
}
int main( void ){
Circle c11( Vector2D( 10, 0 ), 10);
Circle c12( Vector2D( 40, 3 ), 40 );
Circle c21( Vector2D( 0,0 ), 5);
Circle c22( Vector2D( 3,0 ), 40 );
Vector2D p1, p2;
cout << c11.getIntersectionArea( c21 ) << endl;
cout << c12.getIntersectionArea( c21 ) << endl;
cout << c22.getIntersectionArea( c11 ) << endl;
cout << c12.getIntersectionArea( c22 ) << endl;
return 0;
}
int main( void ){
cout << getBisectorTwoAngles( -155.3, 179.0 ) << endl;
cout << getBisectorTwoAngles( -179.3, 179.0 ) << endl;
}
int main( ) {
Vector2D pos = Vector2D::getVector2DFromPolar(10, 45);
cout << pos << endl;
cout << pos.getDirection() << endl;
cout << pos.getLength() << endl;
//Vector2D pos = Vector2D(10, 0);
//cout << pos << endl;
//cout << pos.getDirection() << endl;
//pos.rotate(90);
//cout << pos << endl;
//cout << pos.getDirection() << endl;
}
int main( ) {
Cone c( Vector2D(-10,-10), -170, -150, 50 );
c.show();
cout << endl
<< "isInside( Vector2D(0,0)): " << c.isInside( Vector2D(0,0) ) << endl
<< "isInside( Vector2D(0,-5)): " << c.isInside( Vector2D(0,-5) ) << endl
<< "isInside( Vector2D(-12,-11)): " << c.isInside( Vector2D(-12,-11) ) << endl;
}
*/

View File

@@ -0,0 +1,863 @@
/*
Copyright (c) 2000,2001, Jelle Kok, University of Amsterdam
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the University of Amsterdam nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**************************************************************************************
* geometry.hh
*
* implements:
* class Vector2D
* namespace Geometry
* class Line
* class Circle
* class Rectangle
* class Cone
*
* requires:
*
* Maintainer: wenns, pagra
*
* Changelog:
*
* Note:
*************************************************************************************/
#ifndef GEOMETRY_HH
#define GEOMETRY_HH
#include <math.h> // needed for M_PI constant
#include <iostream>
using namespace std;
const float EPSILON = 0.001;
typedef float AngRad; /**< Type definition for angles in degrees. */
typedef float AngDeg; /**< Type definition for angles in radians. */
/**
* Converts an angle in radians to the corresponding angle in degrees.
* @param x an angle in radians
* @return the corresponding angle in degrees
*/
AngDeg Rad2Deg ( AngRad x );
/**
* Converts an angle in degrees to the corresponding angle in radians.
* @param x an angle in degrees
* @return the corresponding angle in radians
*/
AngRad Deg2Rad ( AngDeg x );
/**
* Returns the cosine of a given angle in degrees using the
* built-in cosine function that works with angles in radians.
* @param x an angle in degrees
* @return the cosine of the given angle
*/
float cosDeg ( AngDeg x );
/**
* Returns the sine of a given angle in degrees using the
* built-in sine function that works with angles in radians.
* @param x an angle in degrees
* @return the sine of the given angle
*/
float sinDeg ( AngDeg x );
/**
* Returns the tangent of a given angle in degrees using the
* built-in tangent function that works with angles in radians.
* @param x an angle in degrees
* @return the tangent of the given angle
*/
float tanDeg ( AngDeg x );
/**
* Rreturns the principal value of the arc tangent of x in degrees
* using the built-in arc tangent function which returns this value in radians.
* @param x a float value
* @return the arc tangent of the given value in degrees
*/
AngDeg atanDeg ( float x );
/**
* Returns the principal value of the arc tangent of y/x in
* degrees using the signs of both arguments to determine the quadrant of the
* return value. For this the built-in 'atan2' function is used which returns
* this value in radians.
* @param x a float value
* @param y a float value
* @return the arc tangent of y/x in degrees taking the signs of x and y into
* account
*/
float atan2Deg ( float x, float y );
/**
* Returns the principal value of the arc cosine of x in degrees
* using the built-in arc cosine function which returns this value in radians.
* @param x a float value
* @return the arc cosine of the given value in degrees
*/
AngDeg acosDeg ( float x );
/**
* Returns the principal value of the arc sine of x in degrees
* using the built-in arc sine function which returns this value in radians.
* @param x a float value
* @return the arc sine of the given value in degrees
*/
AngDeg asinDeg ( float x );
/**
* Returns a boolean value which indicates whether the value
* 'ang' (from interval [-180..180] lies in the interval [angMin..angMax].
* Examples: isAngInInterval( -100, 4, -150) returns false
* isAngInInterval( 45, 4, -150) returns true
* @param ang angle that should be checked
* @param angMin minimum angle in interval
* @param angMax maximum angle in interval
* @return boolean indicating whether ang lies in [angMin..angMax]
*/
bool isAngInInterval ( AngDeg ang, AngDeg angMin, AngDeg angMax );
/**
* Returns the bisector (average) of two angles. It deals
* with the boundary problem, thus when 'angMin' equals 170 and 'angMax'
* equals -100, -145 is returned.
* @param angMin minimum angle [-180,180]
* @param angMax maximum angle [-180,180]
* @return average of angMin and angMax.
*/
AngDeg getBisectorTwoAngles( AngDeg angMin, AngDeg angMax );
/**
* Returns the difference of two angles in degrees [-180,180]
* @param ang1 first angle [-180,180]
* @param ang2 second angle [-180,180]
*/
AngDeg getAngleDifference( AngDeg ang1, AngDeg ang2 );
/**
* Returns the absolute difference of two angles in degrees [0,180]
* @param ang1 first angle [-180,180]
* @param ang2 second angle [-180,180]
*/
AngDeg getAbsAngleDifference( AngDeg ang1, AngDeg ang2 );
/**
* Normalizes an arbitrary angle in 180 Deg System
* @param angle: the angle to normalize
* @return float (-180..180]
*/
float normalizeTo180Deg(float angle);
/**
* CoordSystem is an enumeration of the different specified coordinate systems.
* The two possibilities are CARTESIAN or POLAR. These values are for instance
* used in the initializing a Vector2D. The CoordSystem indicates whether
* the supplied arguments represent the position in cartesian or in polar
* coordinates.
*/
enum CoordSystemT {
CARTESIAN,
POLAR
};
/******************************************************************************/
/******************** CLASS VECTOR2D **************************************/
/******************************************************************************/
/**
* This class contains an x- and y-coordinate of a position (x,y) as member
* data and methods which operate on this position. The standard arithmetic
* operators are overloaded and can thus be applied to positions (x,y). It is
* also possible to represent a position in polar coordinates (r,phi), since
* the class contains a method to convert these into cartesian coordinates (x,y).
*/
class Vector2D {
private:
float x; /**< x-coordinate of this position */
float y; /**< y-coordinate of this position */
public:
/**
* Constructor for the Vector2D class. When the supplied Coordinate System
* type equals CARTESIAN, the arguments x and y denote the x- and y-coordinates
* of the new position. When it equals POLAR however, the arguments x and y
* denote the polar coordinates of the new position; in this case x is thus
* equal to the distance r from the origin and y is equal to the angle phi that
* the polar vector makes with the x-axis.
* @param x the x-coordinate of the new position when cs == CARTESIAN; the
* distance of the new position from the origin when cs = POLAR
* @param y the y-coordinate of the new position when cs = CARTESIAN; the
* angle that the polar vector makes with the x-axis when cs = POLAR
* @param cs a CoordSystemT indicating whether x and y denote cartesian
* coordinates or polar coordinates
* @return the Vector2D corresponding to the given arguments
*/
Vector2D ( float x = 0,
float y = 0,
CoordSystemT cs = CARTESIAN);
//////////////////// overloaded arithmetic operators /////////////////////////////
/*
* Note: all operators parametrized with float values apply these values to both
* coordinates of the vector
*/
/**
* Overloaded version of unary minus operator for Vector2Ds. The current Vector2D
* itself is left unchanged.
* @return a negated version of the current Vector2D
*/
Vector2D operator - ( ) { return ( Vector2D( -x, -y ) ); }
Vector2D operator + ( const float &d ) const { return ( Vector2D( x + d, y + d ) ); }
Vector2D operator + ( const Vector2D &p ) const { return ( Vector2D( x + p.x, y + p.y ) ); }
Vector2D operator - ( const float &d ) const { return ( Vector2D( x - d, y - d ) ); }
Vector2D operator - ( const Vector2D &p ) const { return ( Vector2D( x - p.x, y - p.y ) ); }
Vector2D operator * ( const float &d ) const { return ( Vector2D( x * d, y * d ) ); }
Vector2D operator * ( const Vector2D &p ) const { return ( Vector2D( x * p.x, y * p.y ) ); }
Vector2D operator / ( const float &d ) const { return ( Vector2D( x / d, y / d ) ); }
Vector2D operator / ( const Vector2D &p ) const { return ( Vector2D( x / p.x, y / p.y ) ); }
void operator = ( const float &d ) { x = d; y = d; }
void operator += ( const Vector2D &p ) { x += p.x; y += p.y; }
void operator += ( const float &d ) { x += d; y += d; }
void operator -= ( const Vector2D &p ) { x -= p.x; y -= p.y; }
void operator -= ( const float &d ) { x -= d; y -= d; }
void operator *= ( const Vector2D &p ) { x *= p.x; y *= p.y; }
void operator *= ( const float &d ) { x *= d; y *= d; }
void operator /= ( const Vector2D &p ) { x /= p.x; y /= p.y; }
void operator /= ( const float &d ) { x /= d; y /= d; }
bool operator != ( const Vector2D &p ) const { return ( ( x != p.x ) || ( y != p.y ) ); }
bool operator != ( const float &d ) const { return ( ( x != d ) || ( y != d ) ); }
bool operator == ( const Vector2D &p ) const { return ( ( x == p.x ) && ( y == p.y ) ); }
bool operator == ( const float &d ) const { return ( ( x == d ) && ( y == d ) ); }
//////////////////////// methods for producing output ////////////////////////////
friend ostream& operator << ( ostream &os,
Vector2D p );
/**
* Writes the current Vector2D to standard output. It can also print a polar
* representation of the current Vector2D.
* @param cs a CoordSystemtT indicating whether a POLAR or CARTESIAN
* representation of the current Vector2D should be printed
*/
void show ( CoordSystemT cs = CARTESIAN );
// accessors
void setX ( float newX ) { x = newX; }
float getX ( ) const { return x; }
void setY ( float newY ) { y = newY; }
float getY ( ) const { return y; }
/**
* decides if the Vector2D is invalid
* @return true, if the Vector2D is invalid, false otherwise
*/
bool isInvalid() const;
/**
* (re)sets the coordinates of the current Vector2D. The given
* coordinates can either be polar or Cartesian coordinates.
* @param newX a float value indicating either a new Cartesian x-coordinate when
* cs=CARTESIAN or a new polar r-coordinate (distance) when cs=POLAR
* @param newY a float value indicating either a new Cartesian y-coordinate when
* cs=CARTESIAN or a new polar phi-coordinate (angle) when cs=POLAR
* @param cs a CoordSystemT indicating whether x and y denote cartesian
* coordinates or polar coordinates
*/
void setVector2D ( float newX = 0,
float newY = 0,
CoordSystemT cs = CARTESIAN);
//wenns: temp workaround
//void setVector2D_Orig( float dX, float dY, CoordSystemT cs);
/**
* Determines the distance between the current Vector2D and a
* given Vector2D.
* @param p a Vector2D
* @return the distance between the current Vector2D and the given
* Vector2D
*/
inline float distanceTo ( const Vector2D &p ) const
{ return ( ( *this - p ).getLength( ) ); }
/**
* Adjusts the coordinates of the current Vector2D in such a way
* that the length of the corresponding vector equals the float value which
* is supplied as an argument.
* @param f a float value representing a new length
* @return the result of scaling the vector corresponding with the current
* Vector2D to the given length thus yielding a different Vector2D
*/
Vector2D setLength ( float f );
/**
* This method determines the length of Vector2D using the formula of Pythagoras.
* @return the length of the Vector2D
*/
inline float getLength ( ) const { return ( sqrt( x * x + y * y ) ); }
/**
* This method determines the direction of the current Vector2D (the phi-coordinate
* in polar representation)
* @return the direction in degrees of the current Vector2D
*/
inline AngDeg getDirection ( ) const { return ( atan2Deg( y, x ) ); }
/////////////////////// comparison methods for positions ///////////////////////////
/**
* Determines whether the current Vector2D is in front of a
* given Vector2D, i.e. whether the x-coordinate of the current Vector2D
* is larger than the x-coordinate of the given Vector2D.
* @param p a Vector2D to which the current Vector2D must be compared
* @return true when the current Vector2D is in front of the given
* Vector2D; false otherwise
*/
bool isInFrontOf ( const Vector2D &p )
{ return ( ( x > p.getX( ) ) ? true : false ); }
/**< similar as above */
bool isInFrontOf ( const float &d ) { return ( ( x > d ) ? true : false ); }
/**
* Determines whether the current Vector2D is behind a given
* Vector2D, i.e. whether the x-coordinate of the current Vector2D is
* smaller than the x-coordinate of the given Vector2D.
* @param p a Vector2D to which the current Vector2D must be compared
* @return true when the current Vector2D is behind the given Vector2D;
* false otherwise
*/
bool isBehindOf ( const Vector2D &p )
{ return ( ( x < p.getX( ) ) ? true : false ); }
/**< similar as above */
bool isBehindOf ( const float &d ) { return ( ( x < d ) ? true : false ); }
/**
* Determines whether the current Vector2D is to the left of a
* given Vector2D, i.e. whether the y-coordinate of the current Vector2D
* is smaller than the y-coordinate of the given Vector2D.
* @param p a Vector2D to which the current Vector2D must be compared
* @return true when the current Vector2D is to the left of the given
* Vector2D; false otherwise
*/
bool isLeftOf ( const Vector2D &p )
{ return ( ( y < p.getY( ) ) ? true : false ); }
/**< similar as above */
bool isLeftOf ( const float &d ) { return ( ( y < d ) ? true : false ); }
/**
* This method determines whether the current Vector2D is to the right of a
* given Vector2D, i.e. whether the y-coordinate of the current Vector2D
* is larger than the y-coordinate of the given Vector2D.
* @param p a Vector2D to which the current Vector2D must be compared
* @return true when the current Vector2D is to the right of the given
* Vector2D; false otherwise
*/
bool isRightOf ( const Vector2D &p )
{ return ( ( y > p.getY( ) ) ? true : false ); }
/**< similar as above */
bool isRightOf ( const float &d ) { return ( ( y > d ) ? true : false ); }
/**
* Determines whether the current Vector2D is in between two
* given Vector2Ds when looking in the x-direction, i.e. whether the current
* Vector2D is in front of the first argument and behind the second.
* @param p1 a Vector2D to which the current Vector2D must be compared
* @param p2 a Vector2D to which the current Vector2D must be compared
* @return true when the current Vector2D is in between the two given
* Vector2Ds when looking in the x-direction; false otherwise
*/
inline bool isBetweenX ( const Vector2D &p1,
const Vector2D &p2 )
{ return ( ( isInFrontOf( p1 ) && isBehindOf( p2 ) ) ? true : false ); }
/**< similar as above */
inline bool isBetweenX ( const float &d1,
const float &d2 )
{ return ( ( isInFrontOf( d1 ) && isBehindOf( d2 ) ) ? true : false ); }
/**
* Determines whether the current Vector2D is in between two
* given Vector2Ds when looking in the y-direction, i.e. whether the current
* Vector2D is to the right of the first argument and to the left of the
* second.
* @param p1 a Vector2D to which the current Vector2D must be compared
* @param p2 a Vector2D to which the current Vector2D must be compared
* @return true when the current Vector2D is in between the two given
* Vector2Ds when looking in the y-direction; false otherwise
*/
bool isBetweenY ( const Vector2D &p1,
const Vector2D &p2 )
{ return ( ( isRightOf( p1 ) && isLeftOf( p2 ) ) ? true : false ); }
/**< similar as above */
bool isBetweenY ( const float &d1,
const float &d2 )
{ return ( ( isRightOf( d1 ) && isLeftOf( d2 ) ) ? true : false ); }
/////////////////// conversion methods for positions ////////////////////////////
/**
* Normalizes a Vector2D by setting the length of the
* corresponding vector to 1.
* @return the result of normalizing the current Vector2D
*/
inline Vector2D normalize ( ) { return ( setLength( 1.0 ) ); }
/**
* Rotates the current Vector2D over a given angle .
* @param angle an angle in degrees over which the current Vector2D must be rotated
* @return the result of rotating the current Vector2D over the given angle
*/
Vector2D rotate ( AngDeg angle );
/**
* Converts the coordinates of the current Vector2D (which are represented in an
* global coordinate system with the origin at (0,0)) into relative coordinates
* in a different coordinate system (e.g. relative to a player). The new coordinate
* system is defined by the arguments to the method.
* @param origin the origin of the relative coordinate frame
* @param ang the angle between the world frame and the relative frame
* (reasoning from the world frame)
* @return the result of converting the current global Vector2D into a
* relative Vector2D
*/
Vector2D globalToRelative ( Vector2D orig,
AngDeg ang );
/**< similar to above */
Vector2D relativeToGlobal ( Vector2D orig,
AngDeg ang );
/**
* Returns a Vector2D that lies somewhere on the vector between
* the current Vector2D and a given Vector2D. The desired position is
* specified by a given fraction of this vector (e.g. 0.5 means exactly in
* the middle of the vector).
* @param p a Vector2D which defines the vector to the current Vector2D
* @param dFrac float representing the fraction of the connecting vector at
* which the desired Vector2D lies.
* @return the Vector2D which lies at fraction dFrac on the vector
* connecting p and the current Vector2D
*/
Vector2D getVector2DOnLineFraction( Vector2D &p,
float dFrac );
/**
* Converts a polar representation of a Vector2D into a Cartesian.
* @param dMag a float representing the polar r-coordinate, i.e. the distance
* from the point to the origin
* @param ang the angle that the polar vector makes with the x-axis, i.e. the
* polar phi-coordinate
* @return the result of converting the given polar representation into a
* Cartesian representation thus yielding a Cartesian Vector2D
*/
//static Vector2D getVector2DFromPolar( float dMag,
// AngDeg ang );
//wenns: temp workaround
static Vector2D getVector2DFromPolar/*_Orig*/( float dMag, AngDeg ang );
};
/******************************************************************************/
/********************* NAMESPACE GEOMETRY *********************************/
/******************************************************************************/
namespace Geometry {
///////////////////////////// geometric series //////////////////////////////////
/*
* A geometric series is one in which there is a constant ratio between each
* element and the one preceding it.
* Normally: s = a + ar + ar^2 + ... + ar^n
* Now: Sum = First + First*Ratio + First*Ratio^2 + .. + Fist*Ratio^n
*/
/**
* Determines the length of a geometric series given its first element, the sum
* of the elements in the series and the constant ratio between the elements.
* @param first first term of the series
* @param ratio ratio with which the the first term is multiplied
* @param sum the total sum of all the serie
* @return the length(n in above example) of the series
*/
float getLengthGeomSeries (float first, float ratio, float sum );
/**
* Determines the sum of a geometric series given its first element, the ratio and
* the number of steps in the series
* @param first first term of the series
* @param ratio ratio with which the the first term is multiplied
* @param length the number of steps to be taken into account
* @return the sum of the series
*/
float getSumGeomSeries ( float first, float ratio, float length );
/**
* Determines the sum of an infinite geometric series given its first element and
* the constant ratio between the elements. Note that such an infinite series will
* only converge when 0<r<1.
* @param first first term of the series
* @param ratio ratio with which the the first term is multiplied
* @return the sum of the series
*/
float getSumInfGeomSeries ( float first, float ratio );
/**
* Determines the first element of a geometric series given its element, the ratio
* and the number of steps in the series
* @param sum sum of the series
* @param ratio ratio with which the the first term is multiplied
* @param length the number of steps to be taken into account
* @return the first element (a) of a serie
*/
float getFirstGeomSeries ( float sum, float ratio, float length );
/**
* Determines the first element of an infinite geometric series given its first
* element and the constant ratio between the elements. Note that such an infinite
* series will only converge when 0<r<1.
* @param sum sum of the series
* @param ratio ratio with which the the first term is multiplied
* @return the first term of the series
*/
float getFirstInfGeomSeries ( float sum, float ratio );
/////////////////////////////// Pythagoras' Theorem ////////////////////////////////
/**
* Performs the abc formula (Pythagoras' Theorem) on the given parameters and puts
* the result in *s1 en *s2. It returns the number of found coordinates.
* @param a a parameter in abc formula
* @param b b parameter in abc formula
* @param c c parameter in abc formula
* @param *s1 first result of abc formula
* @param *s2 second result of abc formula
* @return number of found x-coordinates
*/
int abcFormula ( float a, float b, float c, float *s1, float *s2 );
};
/******************************************************************************/
/********************** CLASS CIRCLE ******************************************/
/******************************************************************************/
/**
* This class represents a circle. A circle is defined by one Vector2D
* (which denotes the center) and its radius.
*/
class Circle{
Vector2D posCenter; /**< Center of the circle */
float radius; /**< Radius of the circle */
public:
Circle( );
Circle( Vector2D pos, float r );
void show ( ostream& os = cout ) const;
// accessors
/**
* Sets the values of the circle.
* @param pos new center of the circle
* @param r new radius of the circle ( > 0 )
* @return bool indicating whether radius was set
*/
bool setCircle ( const Vector2D &pos, float r );
/**
* Sets the radius of the circle.
* @param r new radius of the circle ( > 0 )
* @return bool indicating whether radius was set
*/
bool setRadius ( const float r );
void setCenter ( const Vector2D &pos ) { posCenter = pos; }
float getRadius () const { return radius; }
Vector2D getCenter () const { return posCenter; }
float getCircumference () const { return 2.0*M_PI*getRadius(); }
float getArea () const { return M_PI*getRadius()*getRadius(); }
/**
* Returns a boolean that indicates whether 'pos' is located inside the circle.
* @param pos position of which should be checked whether it is located in the
* circle
* @return bool indicating whether pos lies inside the circle
*/
bool isInside ( const Vector2D &pos ) const
{ return posCenter.distanceTo( pos ) < getRadius(); }
/**
* Returns the two possible intersection points between two circles. This method
* returns the number of solutions that were found.
* @param c circle with which intersection should be found
* @param p1 will be filled with first solution
* @param p2 will be filled with second solution
* @return number of solutions.
*/
int getIntersectionPoints ( const Circle &c, Vector2D *p1, Vector2D *p2) const;
/**
* Returns the size of the intersection area of two circles.
* @param c circle with which intersection should be determined
* @return size of the intersection area.
*/
float getIntersectionArea ( const Circle &c ) const ;
bool calcTangentIntersectionPoints(const Vector2D, Vector2D &point1, Vector2D &point2);
};
/******************************************************************************/
/*********************** CLASS LINE *******************************************/
/******************************************************************************/
/**
* This class contains the representation of a line. A line is defined
* by the formula ay + bx + c = 0. The coefficients a, b and c are stored
* and used in the calculations.
*/
class Line {
// a line is defined by the formula: ay + bx + c = 0
float a; /**< This is the a coefficient in the line ay + bx + c = 0 */
float b; /**< This is the b coefficient in the line ay + bx + c = 0 */
float c; /**< This is the c coefficient in the line ay + bx + c = 0 */
public:
Line( float a, float b, float c );
Line();
//accessors
float getACoefficient ( ) const { return a; }
float getBCoefficient ( ) const { return b; }
float getCCoefficient ( ) const { return c; }
// print methods
void show( ostream& os = cout );
friend ostream& operator << (ostream & os, Line l);
/**
* Returns the intersection point between the current Line and the specified line.
* @param line line with which the intersection should be calculated.
* @return Vector2D position that is the intersection point.
*/
Vector2D getIntersection ( Line line );
/**
* This method calculates the intersection points between the current line
* and the circle specified with as center 'posCenter' and radius 'radius'.
* The number of solutions are returned and the corresponding points are put
* in the third and fourth argument of the method
* @param c circle with which intersection points should be found
* @param posSolution1 first intersection (if any)
* @param posSolution2 second intersection (if any)
*/
int getCircleIntersectionPoints( Circle circle,
Vector2D *posSolution1,
Vector2D *posSolution2 );
/**
* Returns the tangent line to a Vector2D. This is the line between the specified
* position and the closest point on the line to this position.
* @param pos Vector2D point with which tangent line is calculated.
* @return Line line tangent to this position
*/
Line getTangentLine ( Vector2D pos );
/**
* Returns the closest point on a line to a given position.
* @param pos point to which closest point should be determined
* @return Vector2D closest point on line to 'pos'.
*/
Vector2D getPointOnLineClosestTo ( Vector2D pos );
/**
* Returns the distance between a specified position and the closest point on
* the given line.
* @param pos position to which distance should be calculated
* @return float indicating the distance to the line.
*/
float distanceToPoint ( Vector2D pos );
/**
* Determines whether the projection of a point on the current line lies between
* two other points ('point1' and 'point2') that lie on the same line.
* @param pos point of which projection is checked.
* @param point1 first point on line
* @param point2 second point on line
* @return true when projection of 'pos' lies between 'point1' and 'point2'.
*/
bool isInBetween ( Vector2D pos,
Vector2D point1,
Vector2D point2 );
/**
* Calculates the y coordinate given the x coordinate
* @param x coordinate
* @return y coordinate on this line
*/
float getYGivenX ( float x );
/**
* Calculates the x coordinate given the y coordinate
* @param y coordinate
* @return x coordinate on this line
*/
float getXGivenY ( float y );
/////// static methods to make a line using an easier representation ////////
/**
* Creates a line given two points.
* @param pos1 first point
* @param pos2 second point
* @return line that passes through the two specified points.
*/
static Line makeLineFromTwoPoints ( Vector2D pos1,
Vector2D pos2 );
/**
* Creates a line given a position and an angle.
* @param vec position through which the line passes
* @param angle direction of the line.
* @return line that goes through position 'vec' with angle 'angle'.
*/
static Line makeLineFromPositionAndAngle ( Vector2D vec,
AngDeg angle );
};
/******************************************************************************/
/********************** CLASS RECTANGLE ***************************************/
/******************************************************************************/
/**
* This class represents a rectangle. A rectangle is defined by two Vector2Ds
* the one at the upper left corner and the one at the right bottom.
*/
class RectangleGeo {
Vector2D posLeftTop; /**< top left position of the rectangle */
Vector2D posRightBottom; /**< bottom right position of the rectangle */
public:
/**
* This is the constructor of a Rectangle. Two points will be given. The
* order does not matter as long as two opposite points are given (left
* top and right bottom or right top and left bottom).
* @param pos first point that defines corner of rectangle
* @param pos2 second point that defines other corner of rectangle
* @return rectangle with 'pos' and 'pos2' as opposite corners.
*/
RectangleGeo ( Vector2D pos, Vector2D pos2 );
void show ( ostream& os = cout ) const;
/**
* Determines whether the given position lies inside the current rectangle.
* @param pos position which is checked whether it lies in rectangle
* @return true when 'pos' lies in the rectangle, false otherwise
*/
bool isInside ( Vector2D pos ) const;
/**
* Sets the upper left and right bottom point of the current rectangle.
* @param pos first point that defines corner of rectangle
* @param pos2 second point that defines other corner of rectangle
*/
void setRectanglePoints( Vector2D pos1,
Vector2D pos2 );
void setPosLeftTop ( Vector2D pos ) { posLeftTop = pos; }
void setPosRightBottom ( Vector2D pos ) { posRightBottom = pos; }
Vector2D getPosLeftTop () const { return posLeftTop; }
Vector2D getPosRightBottom () const { return posRightBottom; }
};
/******************************************************************************/
/********************** CLASS CONE **** ***************************************/
/******************************************************************************/
/**
* This class represents a cone. A cone is defined by one point,
* two angles (-180 to 180), a maximum and a minimum distance.
* The point gives the peak of the cone. A point that lies in the cone
* is at least minimum distance and at most maximum distance away from
* the peak. Additionally the point must lie in the segment between
* the first angle (the left edge) and the second angle (the other edge).
* The area is defined by rotating the first edge (given by the first angle)
* clockwise (mit dem Uhrzeigersinn) till the second angle is reached.
*/
class Cone {
Vector2D peak; /**< peak of the cone */
float fstAngle; /**< the left edge. Start of clockwise rotation. */
float sndAngle; /**< the right edge. End of clockwise rotation. */
float maxDistance; /**< the max. distance a point on the cone can be away from the peak. */
float minDistance; /**< the min. distance a point on the cone must be away from the peak. */
public:
/**
* This is the constructor of a Cone. The cone lies between fstAngle and sndAngle,
* where sndAngle is interpreted as being clockwise rotated in relation
* to fstAngle.
* @param peak first point that defines top of the cone
* @param fstAngle absolute angle of the first edge
* @param sndAngle absolute angle of the second edge.
* @param maxDistance max. distance a point on the cone can be away from the peak
* @param minDistance min. distance a point on the cone must be away from the peak
*/
Cone( Vector2D peak,
float fstAngle, float sndAngle,
float maxDistance, float minDistance = 0 );
void show( ostream& os = cout ) const;
/**
* Determines whether the given position lies inside the current cone.
* @param pos position which is checked whether it lies in cone
* @return true when 'pos' lies in the cone, false otherwise
*/
bool isInside( Vector2D pos ) const;
inline void setPeak( Vector2D newPeak ) { peak = newPeak; }
inline void setAngles( float newFstAngle, float newSndAngle ) {
fstAngle = newFstAngle, sndAngle = newSndAngle;
}
inline void setFstAngle( float newFstAngle ) { fstAngle = newFstAngle; }
inline void setSndAngle( float newSndAngle ) { sndAngle = newSndAngle; }
inline void setMaxDistance( float newMaxDistance) { maxDistance = newMaxDistance; }
inline void setMinDistance( float newMinDistance) { minDistance = newMinDistance; }
};
#endif //Geometry.hh

View File

@@ -0,0 +1,380 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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 "global.h"
#include "options.h"
#include "asstring.h"
#include <iostream>
#include "SDL.h"
#include "surfaceDB.h"
using namespace std;
int GAME_LENGTH = 300000; // ms
int ITEM_LIFETIME = 20000; // ms
int ITEM_APPEAR_DELAY = 10000; // ms
int ITEM_APPEAR_RAND_DELAY = 20000; // ms
int ITEM_HEALTH_REPAIR_AMOUNT = 100;
int ITEM_HEATSEEKER_AMMO = 70;
int ITEM_NUKE_AMMO = 2;
int ITEM_DEFLECTOR_AMMO = 1;
int ITEM_DEFLECTOR_ACTIVATION_DIST = 200;
int ITEM_DEFLECTOR_POWER = 100;
int ITEM_DEFLECTOR_DURATION = 15000;
int ITEM_APPEAR_CHANCES[] = { 50, 20, 30, 30, 30, 50, 20, 20, 30, 20, 20 };
int GENERATE_ENEMY_DELAY = 100;
int GENERATE_ENEMY_RAND_DELAY = 2000;
int LIGHT_FIGHTER_MAX_SHIELD = 200;
int HEAVY_FIGHTER_MAX_SHIELD = 500;
int LIGHT_FIGHTER_MAX_DAMAGE = 200;
int HEAVY_FIGHTER_MAX_DAMAGE = 500;
int LIGHT_FIGHTER_SHIELD_RECHARGE = 80;
int HEAVY_FIGHTER_SHIELD_RECHARGE = 110;
int RACER_DEFLECTOR_ACTIVATION_DIST = 150;
int RACER_DEFLECTOR_POWER = 50;
int RACER_SONIC_ACTIVATION_DIST = 200;
int RACER_SONIC_POWER = 50;
int ENEMY_HITPOINTS[] = { 80, 120, 150, 2000, 1500, 1000, 1000, 3000 };
int ENEMY_COLLISION_DAMAGE[] = {20, 40, 0, 0, 0, 0, 0, 2000};
int ENEMY_DIES_ITEM_APPEAR_CHANCE[] = {15, 12, 8, 0, 0, 0, 0, 1};
int ENEMY_APPEAR_CHANCES[] = {40, 40, 10, 0, 0, 0, 0, 0};
int ENEMY_COOLDOWN_PRIMARY[] = {400, 400, 400, 50, 500, 100, 100, 300};
int ENEMY_COOLDOWN_SECONDARY[] = {0, 0, 2000, 0, 0, 0, 0, 600};
int ENEMY_RAND_WAIT_PRIMARY[] = {1500, 1000, 300, 80, 1000, 200, 200, 2000};
int ENEMY_RAND_WAIT_SECONDARY[] = {0, 0, 10000, 0, 0, 0, 0, 400};
int GENERATE_FORMATION_DELAY = 5000;
int GENERATE_FORMATION_RAND_DELAY = 20000;
int FORMATION_MAX_NR_ENEMYS[] = {7,7,7,6};
int FORMATION_SP_CHANCES[] = { 10, 10, 5, 5, 20, 10, 5, 20, 10, 20, 10 };
int FORMATION_SP_PRIMARY_DELAY[] = {0, 80, 120, 160,
500, 800, 1100,
150, 250, 150, 250};
int FORMATION_SP_PRIMARY_RAND_DELAY[] = { 0, 80, 120, 160,
1000, 1500, 2000,
0, 0, 0, 0 };
void parseGlobalConfigValues( int difficultyLevel ) {
Options *op = 0;
op = new Options( FN_DIFFICULTY_CONFIG +
asString(difficultyLevel) +
FN_DIFFICULTY_CONFIG_SUFFIX );
op->getInt( "GAME_LENGTH", GAME_LENGTH );
op->getInt( "ITEM_LIFETIME", ITEM_LIFETIME );
op->getInt( "ITEM_APPEAR_DELAY", ITEM_APPEAR_DELAY );
op->getInt( "ITEM_APPEAR_RAND_DELAY", ITEM_APPEAR_RAND_DELAY );
op->getInt( "ITEM_HEALTH_REPAIR_AMOUNT", ITEM_HEALTH_REPAIR_AMOUNT );
op->getInt( "ITEM_HEATSEEKER_AMMO", ITEM_HEATSEEKER_AMMO );
op->getInt( "ITEM_NUKE_AMMO", ITEM_NUKE_AMMO );
op->getInt( "ITEM_DEFLECTOR_AMMO", ITEM_DEFLECTOR_AMMO );
op->getInt( "ITEM_DEFLECTOR_DURATION", ITEM_DEFLECTOR_DURATION );
op->getInt( "ITEM_DEFLECTOR_ACTIVATION_DIST", ITEM_DEFLECTOR_ACTIVATION_DIST );
op->getInt( "ITEM_DEFLECTOR_POWER", ITEM_DEFLECTOR_POWER );
op->getInt( "GENERATE_ENEMY_DELAY", GENERATE_ENEMY_DELAY );
op->getInt( "GENERATE_ENEMY_RAND_DELAY", GENERATE_ENEMY_RAND_DELAY );
op->getInt( "LIGHT_FIGHTER_MAX_SHIELD", LIGHT_FIGHTER_MAX_SHIELD );
op->getInt( "HEAVY_FIGHTER_MAX_SHIELD", HEAVY_FIGHTER_MAX_SHIELD );
op->getInt( "LIGHT_FIGHTER_MAX_DAMAGE", LIGHT_FIGHTER_MAX_DAMAGE );
op->getInt( "HEAVY_FIGHTER_MAX_DAMAGE", HEAVY_FIGHTER_MAX_DAMAGE );
op->getInt( "LIGHT_FIGHTER_SHIELD_RECHARGE", LIGHT_FIGHTER_SHIELD_RECHARGE );
op->getInt( "HEAVY_FIGHTER_SHIELD_RECHARGE", HEAVY_FIGHTER_SHIELD_RECHARGE );
op->getInt( "HEAVY_FIGHTER_DEFLECTOR_ACTIVATION_DIST",
RACER_DEFLECTOR_ACTIVATION_DIST );
op->getInt( "HEAVY_FIGHTER_DEFLECTOR_POWER",
RACER_DEFLECTOR_POWER );
op->getInt( "FIGHTER_HITPOINTS", ENEMY_HITPOINTS[ FIGHTER ] );
op->getInt( "BOMBER_HITPOINTS", ENEMY_HITPOINTS[ BOMBER ] );
op->getInt( "TURRET_HITPOINTS", ENEMY_HITPOINTS[ TANK ] );
op->getInt( "BOSS1_MAIN_GUN_HITPOINTS", ENEMY_HITPOINTS[ BOSS_1_MAIN_GUN ] );
op->getInt( "BOSS1_ROCKET_LAUNCHER_HITPOINTS", ENEMY_HITPOINTS[ BOSS_1_ROCKET_LAUNCHER ] );
op->getInt( "BOSS1_SHOT_BATTERY_LEFT_HITPOINTS",
ENEMY_HITPOINTS[ BOSS_1_SHOT_BATTERY_LEFT ] );
op->getInt( "BOSS1_SHOT_BATTERY_RIGHT_HITPOINTS",
ENEMY_HITPOINTS[ BOSS_1_SHOT_BATTERY_RIGHT ] );
op->getInt( "COLLISION_DAMAGE_FIGHTER", ENEMY_COLLISION_DAMAGE[ FIGHTER ] );
op->getInt( "COLLISION_DAMAGE_BOMBER", ENEMY_COLLISION_DAMAGE[ BOMBER ] );
op->getInt( "ENEMY_DIES_ITEM_APPEAR_CHANCE_FIGHTER",
ENEMY_DIES_ITEM_APPEAR_CHANCE[ FIGHTER ] );
op->getInt( "ENEMY_DIES_ITEM_APPEAR_CHANCE_BOMBER",
ENEMY_DIES_ITEM_APPEAR_CHANCE[ BOMBER ] );
op->getInt( "ENEMY_DIES_ITEM_APPEAR_CHANCE_TURRET",
ENEMY_DIES_ITEM_APPEAR_CHANCE[ TANK ] );
op->getInt( "ENEMY_APPEAR_CHANCE_FIGHTER",
ENEMY_APPEAR_CHANCES[ FIGHTER ] );
op->getInt( "ENEMY_APPEAR_CHANCE_BOMBER",
ENEMY_APPEAR_CHANCES[ BOMBER ] );
op->getInt( "ENEMY_APPEAR_CHANCE_TURRET",
ENEMY_APPEAR_CHANCES[ TANK ] );
op->getInt( "ENEMY_COOLDOWN_FIGHTER",
ENEMY_COOLDOWN_PRIMARY[ FIGHTER ] );
op->getInt( "ENEMY_COOLDOWN_BOMBER",
ENEMY_COOLDOWN_PRIMARY[ BOMBER ] );
op->getInt( "ENEMY_COOLDOWN_TURRET",
ENEMY_COOLDOWN_PRIMARY[ TANK ] );
op->getInt( "ENEMY_COOLDOWN_BOSS1_MAIN_GUN",
ENEMY_COOLDOWN_PRIMARY[ BOSS_1_MAIN_GUN ] );
op->getInt( "ENEMY_COOLDOWN_BOSS1_ROCKET_LAUNCHER",
ENEMY_COOLDOWN_PRIMARY[ BOSS_1_ROCKET_LAUNCHER] );
op->getInt( "ENEMY_COOLDOWN_BOSS1_SHOT_BATTERY_LEFT",
ENEMY_COOLDOWN_PRIMARY[ BOSS_1_SHOT_BATTERY_LEFT] );
op->getInt( "ENEMY_COOLDOWN_BOSS1_SHOT_BATTERY_RIGHT",
ENEMY_COOLDOWN_PRIMARY[ BOSS_1_SHOT_BATTERY_RIGHT ] );
op->getInt( "ENEMY_COOLDOWN_SECONDARY_TURRET", ENEMY_COOLDOWN_SECONDARY[ TANK ] );
op->getInt( "ENEMY_RAND_WAIT_FIGHTER",
ENEMY_RAND_WAIT_PRIMARY[ FIGHTER ] );
op->getInt( "ENEMY_RAND_WAIT_BOMBER",
ENEMY_RAND_WAIT_PRIMARY[ BOMBER ] );
op->getInt( "ENEMY_RAND_WAIT_TURRET",
ENEMY_RAND_WAIT_PRIMARY[ TANK ] );
op->getInt( "ENEMY_RAND_WAIT_BOSS1_MAIN_GUN",
ENEMY_RAND_WAIT_PRIMARY[ BOSS_1_MAIN_GUN ] );
op->getInt( "ENEMY_RAND_WAIT_BOSS1_ROCKET_LAUNCHER",
ENEMY_RAND_WAIT_PRIMARY[ BOSS_1_ROCKET_LAUNCHER ] );
op->getInt( "ENEMY_RAND_WAIT_BOSS1_SHOT_BATTERY_LEFT",
ENEMY_RAND_WAIT_PRIMARY[ BOSS_1_SHOT_BATTERY_LEFT ] );
op->getInt( "ENEMY_RAND_WAIT_BOSS1_SHOT_BATTERY_RIGHT",
ENEMY_RAND_WAIT_PRIMARY[ BOSS_1_SHOT_BATTERY_RIGHT ] );
op->getInt( "ENEMY_RAND_WAIT_SECONDARY_TURRET",
ENEMY_RAND_WAIT_SECONDARY[ TANK ] );
op->getInt( "ITEM_APPEAR_CHANCE_PRIMARY_UPGRADE",
ITEM_APPEAR_CHANCES[ ITEM_PRIMARY_UPGRADE ] );
op->getInt( "ITEM_APPEAR_CHANCE_DUMBRIFE_DOUBLE",
ITEM_APPEAR_CHANCES[ ITEM_DUMBFIRE_DOUBLE ] );
op->getInt( "ITEM_APPEAR_CHANCE_KICK_ASS_ROCKET",
ITEM_APPEAR_CHANCES[ ITEM_KICK_ASS_ROCKET ] );
op->getInt( "ITEM_APPEAR_CHANCE_HELLFIRE",
ITEM_APPEAR_CHANCES[ ITEM_HELLFIRE ] );
op->getInt( "ITEM_APPEAR_CHANCE_MACHINE_GUN",
ITEM_APPEAR_CHANCES[ ITEM_MACHINE_GUN ] );
op->getInt( "ITEM_APPEAR_CHANCE_HEALTH",
ITEM_APPEAR_CHANCES[ ITEM_HEALTH ] );
op->getInt( "ITEM_APPEAR_CHANCE_HEATSEEKER",
ITEM_APPEAR_CHANCES[ ITEM_HEATSEEKER ] );
op->getInt( "ITEM_APPEAR_CHANCE_NUKE",
ITEM_APPEAR_CHANCES[ ITEM_NUKE ] );
op->getInt( "ITEM_APPEAR_CHANCE_DEFLECTOR",
ITEM_APPEAR_CHANCES[ ITEM_DEFLECTOR ] );
op->getInt( "ITEM_APPEAR_CHANCE_ENERGY_BEAM",
ITEM_APPEAR_CHANCES[ ITEM_ENERGY_BEAM ] );
op->getInt( "ITEM_APPEAR_CHANCE_LASER",
ITEM_APPEAR_CHANCES[ ITEM_LASER ] );
op->getInt( "GENERATE_FORMATION_DELAY", GENERATE_FORMATION_DELAY );
op->getInt( "GENERATE_FORMATION_RAND_DELAY", GENERATE_FORMATION_RAND_DELAY );
op->getInt( "FORMATION_MAX_NR_ENEMYS_V",
FORMATION_MAX_NR_ENEMYS[ FORMATION_V ] );
op->getInt( "FORMATION_MAX_NR_ENEMYS_REVERSE_V",
FORMATION_MAX_NR_ENEMYS[ FORMATION_REVERSE_V ] );
op->getInt( "FORMATION_MAX_NR_ENEMYS_BLOCK",
FORMATION_MAX_NR_ENEMYS[ FORMATION_BLOCK ] );
op->getInt( "FORMATION_MAX_NR_ENEMYS_LINE",
FORMATION_MAX_NR_ENEMYS[ FORMATION_LINE ] );
for ( int i = 0; i < NR_FORMATION_TYPES; i++ ) {
if ( FORMATION_MAX_NR_ENEMYS[ i ] > FORMATION_MAX_NR_ENEMYS_HARD_LIMIT[ i ] )
FORMATION_MAX_NR_ENEMYS[ i ] = FORMATION_MAX_NR_ENEMYS_HARD_LIMIT[ i ];
}
op->getInt( "FORMATION_SP_CHANCE_NONE",
FORMATION_SP_CHANCES[ FORMATION_SP_NONE ] );
op->getInt( "FORMATION_SP_CHANCE_RAND_FAST",
FORMATION_SP_CHANCES[ FORMATION_SP_RAND_FAST ] );
op->getInt( "FORMATION_SP_CHANCE_RAND_MEDIUM",
FORMATION_SP_CHANCES[ FORMATION_SP_RAND_MEDIUM ] );
op->getInt( "FORMATION_SP_CHANCE_RAND_SLOW",
FORMATION_SP_CHANCES[ FORMATION_SP_RAND_SLOW ] );
op->getInt( "FORMATION_SP_CHANCE_VOLLEY_FAST",
FORMATION_SP_CHANCES[ FORMATION_SP_VOLLEY_FAST ] );
op->getInt( "FORMATION_SP_CHANCE_VOLLEY_MEDIUM",
FORMATION_SP_CHANCES[ FORMATION_SP_VOLLEY_MEDIUM ] );
op->getInt( "FORMATION_SP_CHANCE_VOLLEY_SLOW",
FORMATION_SP_CHANCES[ FORMATION_SP_VOLLEY_SLOW ] );
op->getInt( "FORMATION_SP_CHANCE_LEFT_RIGHT_FAST",
FORMATION_SP_CHANCES[ FORMATION_SP_LEFT_RIGHT_FAST ] );
op->getInt( "FORMATION_SP_CHANCE_LEFT_RIGHT_MEDIUM",
FORMATION_SP_CHANCES[ FORMATION_SP_LEFT_RIGHT_MEDIUM ] );
op->getInt( "FORMATION_SP_CHANCE_RIGHT_LEFT_FAST",
FORMATION_SP_CHANCES[ FORMATION_SP_RIGHT_LEFT_FAST ] );
op->getInt( "FORMATION_SP_CHANCE_RIGHT_LEFT_MEDIUM",
FORMATION_SP_CHANCES[ FORMATION_SP_RIGHT_LEFT_MEDIUM ] );
op->getInt( "FORMATION_SP_PRIM_DELAY_RAND_FAST",
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_RAND_FAST ] );
op->getInt( "FORMATION_SP_PRIM_DELAY_RAND_MEDIUM",
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_RAND_MEDIUM ] );
op->getInt( "FORMATION_SP_PRIM_DELAY_RAND_SLOW",
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_RAND_SLOW ] );
op->getInt( "FORMATION_SP_PRIM_DELAY_VOLLEY_FAST",
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_VOLLEY_FAST ] );
op->getInt( "FORMATION_SP_PRIM_DELAY_VOLLEY_MEDIUM",
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_VOLLEY_MEDIUM ] );
op->getInt( "FORMATION_SP_PRIM_DELAY_VOLLEY_SLOW",
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_VOLLEY_SLOW ] );
op->getInt( "FORMATION_SP_PRIM_DELAY_LEFT_RIGHT_FAST",
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_LEFT_RIGHT_FAST ] );
op->getInt( "FORMATION_SP_PRIM_DELAY_LEFT_RIGHT_MEDIUM",
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_LEFT_RIGHT_MEDIUM ] );
op->getInt( "FORMATION_SP_PRIM_DELAY_RIGHT_LEFT_FAST",
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_RIGHT_LEFT_FAST ] );
op->getInt( "FORMATION_SP_PRIM_DELAY_RIGHT_LEFT_MEDIUM",
FORMATION_SP_PRIMARY_DELAY[ FORMATION_SP_RIGHT_LEFT_MEDIUM ] );
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_RAND_FAST",
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_RAND_FAST ] );
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_RAND_MEDIUM",
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_RAND_MEDIUM ] );
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_RAND_SLOW",
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_RAND_SLOW ] );
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_VOLLEY_FAST",
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_VOLLEY_FAST ] );
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_VOLLEY_MEDIUM",
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_VOLLEY_MEDIUM ] );
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_VOLLEY_SLOW",
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_VOLLEY_SLOW ] );
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_LEFT_RIGHT_FAST",
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_LEFT_RIGHT_FAST ] );
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_LEFT_RIGHT_MEDIUM",
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_LEFT_RIGHT_MEDIUM ] );
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_RIGHT_LEFT_FAST",
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_RIGHT_LEFT_FAST ] );
op->getInt( "FORMATION_SP_PRIM_RAND_DELAY_RIGHT_LEFT_MEDIUM",
FORMATION_SP_PRIMARY_RAND_DELAY[ FORMATION_SP_RIGHT_LEFT_MEDIUM ] );
delete op;
}
/////////////////////
int getRandValue( const int *choicesWeights, int nrChoices, int sumWeights ) {
int sum = 0;
if ( sumWeights != 0 ) sum = sumWeights;
else for ( int i = 0; i < nrChoices; i++ ) sum += choicesWeights[ i ];
if ( sum == 0 ) {
cout << "Error in getRandValue: sum==0!" << endl;
exit(1);
}
int val = rand() % sum;
int idx = 0;
int tmpSum = 0;
while ( idx < nrChoices ) {
tmpSum += choicesWeights[ idx ];
if ( val < tmpSum ) {
return idx;
}
idx++;
}
cout << "Error in getRandValue: val: " << val << endl;
exit(1);
}
/////////////////////////////
void initAllSurfaces() {
surfaceDB.loadSurface("./images/fighter.bmp" );
surfaceDB.loadSurface("./images/fighterShadow.bmp", true);
surfaceDB.loadSurface("./images/bomber.bmp");
surfaceDB.loadSurface("./images/bomberShadow.bmp", true);
surfaceDB.loadSurface("./images/tank.bmp");
surfaceDB.loadSurface("./images/boss1MainGun.bmp");
surfaceDB.loadSurface("./images/boss1RocketLauncher.bmp");
surfaceDB.loadSurface("./images/boss1ShotBatteryLeft.bmp");
surfaceDB.loadSurface("./images/boss1ShotBatteryRight.bmp");
surfaceDB.loadSurface("./images/wreckFighter.bmp");
surfaceDB.loadSurface("./images/wreckBomber.bmp");
surfaceDB.loadSurface("./images/wreckTank.bmp");
surfaceDB.loadSurface("./images/wreckBoss1.bmp");
surfaceDB.loadSurface("./images/wreckBossBackground.bmp");
surfaceDB.loadSurface("./images/boss.bmp");
surfaceDB.loadSurface("./images/normalShot.bmp");
surfaceDB.loadSurface("./images/heavyShot.bmp");
surfaceDB.loadSurface("./images/normalShotHF.bmp");
surfaceDB.loadSurface("./images/dumbfire.bmp");
surfaceDB.loadSurface("./images/kickAssRocket.bmp");
surfaceDB.loadSurface("./images/kickAssRocketShadow.bmp", true);
surfaceDB.loadSurface("./images/hellfire.bmp");
surfaceDB.loadSurface("./images/hellfireShadow.bmp", true);
surfaceDB.loadSurface("./images/machineGun.bmp");
surfaceDB.loadSurface("./images/energyBeam.bmp", true);
surfaceDB.loadSurface("./images/laser.bmp");
surfaceDB.loadSurface("./images/enemyShotNormal.bmp");
surfaceDB.loadSurface("./images/tankRocket.bmp");
surfaceDB.loadSurface("./images/tankRocketShadow.bmp", true);
surfaceDB.loadSurface("./images/heatseeker.bmp");
surfaceDB.loadSurface("./images/shotNuke.bmp");
surfaceDB.loadSurface("./images/shotNukeShadow.bmp", true);
surfaceDB.loadSurface("./images/nukeEffect.bmp");
surfaceDB.loadSurface("./images/sonic.bmp");
surfaceDB.loadSurface("./images/itemPrimaryUpgrade.bmp");
surfaceDB.loadSurface("./images/itemDumbfireDouble.bmp");
surfaceDB.loadSurface("./images/itemKickAssRocket.bmp");
surfaceDB.loadSurface("./images/itemHellfire.bmp");
surfaceDB.loadSurface("./images/itemMachineGun.bmp");
surfaceDB.loadSurface("./images/itemHealth.bmp");
surfaceDB.loadSurface("./images/itemHeatseeker.bmp");
surfaceDB.loadSurface("./images/itemNuke.bmp");
surfaceDB.loadSurface("./images/itemDeflector.bmp");
surfaceDB.loadSurface("./images/itemEnergyBeam.bmp");
surfaceDB.loadSurface("./images/itemLaser.bmp");
surfaceDB.loadSurface("./images/background.bmp");
surfaceDB.loadSurface("./images/lightFighterShieldDamaged.bmp");
surfaceDB.loadSurface("./images/heavyFighterShieldDamaged.bmp");
surfaceDB.loadSurface("./images/heavyFighterDeflector.bmp", true);
surfaceDB.loadSurface("./images/font-20red.bmp");
surfaceDB.loadSurface("./images/font-20blue.bmp");
surfaceDB.loadSurface("./images/explosion.bmp");
surfaceDB.loadSurface("./images/explosionEnemy.bmp");
surfaceDB.loadSurface("./images/bannerExcellent.bmp", true);
surfaceDB.loadSurface("./images/bannerYouRule.bmp", true);
surfaceDB.loadSurface("./images/bannerHeiho.bmp", true);
surfaceDB.loadSurface("./images/bannerHealth.bmp", true);
surfaceDB.loadSurface("./images/bannerEnemysKilled.bmp", true);
surfaceDB.loadSurface("./images/bannerBonus100.bmp", true);
surfaceDB.loadSurface("./images/bannerBonus200.bmp", true);
}

View File

@@ -0,0 +1,691 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef GLOBAL_H
#define GLOBAL_H
#include <string>
class Racers;
class Enemys;
class Shots;
class Explosions;
class Items;
class Wrecks;
class Banners;
class SmokePuffs;
class Options;
extern Racers *racers;
extern Enemys *enemys;
extern Shots *shots;
extern Explosions *explosions;
extern Items *items;
extern Wrecks *wrecks;
extern Banners *banners;
extern SmokePuffs *smokePuffs;
extern Options *levelConf;
extern int GAME_LENGTH;
extern bool scrollingOn;
extern bool nukeIsInPlace;
extern bool playMusicOn;
extern bool onePlayerGame;
extern bool arcadeGame;
extern int difficultyLevel;
extern float actBackgroundPos;
void parseGlobalConfigValues( int difficultyLevel );
int getRandValue( const int *choicesWeights, int nrChoices, int sumWeights=0 );
void initAllSurfaces();
// screen options
const int SCREEN_WIDTH = 320;
const int SCREEN_HEIGHT = 430;
const int BIT_DEPTH = 16;
const int MAX_PLAYER_CNT = 2;
// the speed of the background scrolling
const float SCROLL_SPEED = 20;
// where is the absolute border of no return for the heatseeker?
// they have a chance to return within SCREEN_BORDER pixels outside the screen...
// outside this area shots are deleted
const int SHOT_SCREEN_BORDER = 50;
/********************************* ARCADE MODE ***********************************/
const int ARCADE_DIFFICULTY_LEVEL = 4;
const int ARCADE_POINTS_PER_TEN_SECONDS = 30;
// BANNER_RANDOM: no real mode, just the value to choose one randomly
enum BannerModes { BANNER_MODE_FLY_FROM_LEFT=0,
BANNER_MODE_FROM_TOP,
BANNER_MODE_ITEM_COLLECTED_SINGLE_PLAYER,
BANNER_MODE_ITEM_COLLECTED_PLAYER_ONE,
BANNER_MODE_ITEM_COLLECTED_PLAYER_TWO,
BANNER_MODE_RANDOM=1000 };
const int BANNER_MODE_LIFETIME[] = { 5000, 5000, 2000, 2000, 2000 };
const int NR_BANNER_MODES = 2;
enum BannerTexts { BANNER_EXCELLENT=0, BANNER_YOU_RULE, BANNER_HEIHO,
BANNER_HEALTH, BANNER_ENEMYS_KILLED,
BANNER_ITEM_HEALTH_COLLECTED,
BANNER_ITEM_PRIMARY_UPGRADE_COLLECTED,
BANNER_ITEM_DUMBFIRE_DOUBLE_COLLECTED,
BANNER_ITEM_KICK_ASS_ROCKET_COLLECTED,
BANNER_ITEM_HELLFIRE_COLLECTED,
BANNER_ITEM_MACHINE_GUN_COLLECTED,
BANNER_ITEM_HEATSEEKER_COLLECTED,
BANNER_ITEM_NUKE_COLLECTED,
BANNER_ITEM_DEFLECTOR_COLLECTED,
BANNER_ITEM_ENERGY_BEAM_COLLECTED,
BANNER_ITEM_LASER_COLLECTED };
const std::string FN_BANNER_TEXTS[] =
{ "./images/bannerExcellent.bmp",
"./images/bannerYouRule.bmp",
"./images/bannerHeiho.bmp",
"./images/bannerHealth.bmp",
"./images/bannerEnemysKilled.bmp",
"./images/bannerItemHealthCollected.bmp",
"./images/bannerItemPrimaryUpgradeCollected.bmp",
"./images/bannerItemDumbfireDoubleCollected.bmp",
"./images/bannerItemKickAssRocketCollected.bmp",
"./images/bannerItemHellfireCollected.bmp",
"./images/bannerItemMachineGunCollected.bmp",
"./images/bannerItemHeatseekerCollected.bmp",
"./images/bannerItemNukeCollected.bmp",
"./images/bannerItemDeflectorCollected.bmp",
"./images/bannerItemEnergyBeamCollected.bmp",
"./images/bannerItemLaserCollected.bmp" };
const int NR_BANNER_TEXTS = 3;
enum BannerBoni { BANNER_BONUS_100=0,
BANNER_BONUS_200,
BANNER_BONUS_NONE=1000 };
const std::string FN_BANNER_BONUS[] =
{ "./images/bannerBonus100.bmp",
"./images/bannerBonus200.bmp" };
const int NR_BANNER_BONI = 2;
const float ARCADE_POINTS_FOR_FORMATION_DESTRUCTION = 100;
const BannerBoni ARCADE_BONUS_FOR_FORMATION_DESTRUCTION = BANNER_BONUS_100;
const float ARCADE_POINTS_FOR_ENEMYS_KILLED = 200;
const BannerBoni ARCADE_BONUS_FOR_ENEMYS_KILLED = BANNER_BONUS_200;
const int NR_ARCACE_POINTS_FOR_HEALTH_ITEM = 7;
const float ARCADE_POINTS_FOR_HEALTH_ITEM[ NR_ARCACE_POINTS_FOR_HEALTH_ITEM ] =
{ 2000, 5000, 10000, 15000, 25000, 35000, 50000 };
/********************************** ITEMS ****************************************/
enum ItemTypes { ITEM_PRIMARY_UPGRADE=0,
ITEM_DUMBFIRE_DOUBLE,
ITEM_KICK_ASS_ROCKET,
ITEM_HELLFIRE,
ITEM_MACHINE_GUN,
ITEM_HEALTH,
ITEM_HEATSEEKER,
ITEM_NUKE,
ITEM_DEFLECTOR,
ITEM_LASER,
ITEM_ENERGY_BEAM };
const int NR_ITEM_TYPES = 11;
extern int ITEM_LIFETIME; // ms
extern int ITEM_APPEAR_DELAY; // ms
extern int ITEM_APPEAR_RAND_DELAY; // ms
// ITEM_HEALTH_REPAIR_AMOUNT points are restored, if collected
extern int ITEM_HEALTH_REPAIR_AMOUNT;
// if collected by heavy fighter the amount will be multiplied by this factor
const float ITEM_HEALTH_REPAIR_FACTOR_HEAVY_FIGHTER = 2.0;
// if collected ITEM_HEATSEEKER_AMMO rockets can be fired
extern int ITEM_HEATSEEKER_AMMO;
extern int ITEM_NUKE_AMMO;
extern int ITEM_DEFLECTOR_AMMO;
extern int ITEM_DEFLECTOR_DURATION;
extern int ITEM_DEFLECTOR_ACTIVATION_DIST;
extern int ITEM_DEFLECTOR_POWER;
// the items have different probabilities to appear.
// bigger number -> greater chance
extern int ITEM_APPEAR_CHANCES[];
enum ExplosionTypes { EXPLOSION_NORMAL_AIR=0, EXPLOSION_NORMAL_GROUND };
const int NR_EXPLOSION_TYPES = 2;
const int LIFETIME_EXPL_NORMAL = 1500;
const int NUKE_EFFECT_DURATION = 1000;
const int NUKE_QUAKE_EFFECT = 40;
enum ShipTypes { LIGHT_FIGHTER=0, HEAVY_FIGHTER };
const int NR_SHIPS = 2;
/*********************************** SHOTS ********************************/
enum ShotTypes { SHOT_NORMAL=0,
SHOT_NORMAL_HEAVY,
SHOT_DOUBLE,
SHOT_DOUBLE_HEAVY,
SHOT_TRIPLE,
SHOT_HF_NORMAL,
SHOT_HF_DOUBLE,
SHOT_HF_TRIPLE,
SHOT_HF_QUATTRO,
SHOT_HF_QUINTO,
SHOT_DUMBFIRE=100,
SHOT_DUMBFIRE_DOUBLE,
SHOT_KICK_ASS_ROCKET,
SHOT_HELLFIRE,
SHOT_MACHINE_GUN,
SHOT_ENERGY_BEAM,
SHOT_HF_DUMBFIRE,
SHOT_HF_DUMBFIRE_DOUBLE,
SHOT_HF_KICK_ASS_ROCKET,
SHOT_HF_LASER,
ENEMY_SHOT_NORMAL=1000,
ENEMY_SHOT_TANK_ROCKET,
SPECIAL_SHOT_HEATSEEKER=10000,
SPECIAL_SHOT_NUKE };
const int NR_SECONDARY_WEAPONS = 10;
enum SpecialTypes { SPECIAL_NONE=0, SPECIAL_NUKE, SPECIAL_HEATSEEKER, SPECIAL_DEFLECTOR };
const int NR_SPECIALS = 4;
// after that many ms the shot is expired
const int LIFETIME_SHOT_NORMAL = 5000;
const int LIFETIME_SHOT_NORMAL_HEAVY = 5000;
const int LIFETIME_SHOT_DOUBLE = 5000;
const int LIFETIME_SHOT_DOUBLE_HEAVY = 5000;
const int LIFETIME_SHOT_TRIPLE = 5000;
const int LIFETIME_SHOT_HF_NORMAL = 6000;
const int LIFETIME_SHOT_HF_DOUBLE = 6000;
const int LIFETIME_SHOT_HF_TRIPLE = 6000;
const int LIFETIME_SHOT_HF_QUATTRO = 6000;
const int LIFETIME_SHOT_HF_QUINTO = 6000;
const int LIFETIME_SHOT_DUMBFIRE = 6000;
const int LIFETIME_SHOT_DUMBFIRE_DOUBLE = 6000;
const int LIFETIME_SHOT_KICK_ASS_ROCKET = 7000;
const int LIFETIME_SHOT_HELLFIRE = 6000;
const int LIFETIME_SHOT_MACHINE_GUN = 5000;
const int LIFETIME_SHOT_ENERY_BEAM = 5000;
const int LIFETIME_SHOT_HF_DUMBFIRE = 6000;
const int LIFETIME_SHOT_HF_DUMBFIRE_DOUBLE = 6000;
const int LIFETIME_SHOT_HF_KICK_ASS_ROCKET = 7000;
const int LIFETIME_SHOT_HF_LASER = 2000;
const int LIFETIME_SPECIAL_SHOT_HEATSEEKER = 10000;
const int LIFETIME_SPECIAL_SHOT_NUKE = 10000;
const int VEL_SHOT_NORMAL = 150;
const int VEL_SHOT_NORMAL_HEAVY = 150;
const int VEL_SHOT_DOUBLE = 150;
const int VEL_SHOT_DOUBLE_HEAVY = 150;
const int VEL_SHOT_TRIPLE = 150;
const int VEL_SHOT_HF_NORMAL = 180;
const int VEL_SHOT_HF_DOUBLE = 180;
const int VEL_SHOT_HF_TRIPLE = 180;
const int VEL_SHOT_HF_QUATTRO = 180;
const int VEL_SHOT_HF_QUINTO = 180;
const int VEL_SHOT_DUMBFIRE = 100;
const int VEL_SHOT_DUMBFIRE_DOUBLE = 100;
const int VEL_SHOT_KICK_ASS_ROCKET = 80;
const int VEL_SHOT_HELLFIRE = 110;
const int VEL_SHOT_MACHINE_GUN = 130;
const int VEL_SHOT_ENERGY_BEAM = 105;
const int VEL_SHOT_HF_DUMBFIRE = 160;
const int VEL_SHOT_HF_DUMBFIRE_DOUBLE = 160;
const int VEL_SHOT_HF_KICK_ASS_ROCKET = 80;
const int VEL_SHOT_HF_LASER = 600;
const int VEL_SPECIAL_SHOT_HEATSEEKER = 130;
const int VEL_SPECIAL_SHOT_NUKE = 180;
const float DAMAGE_SHOT_NORMAL = 5;
const float DAMAGE_SHOT_NORMAL_HEAVY = 8;
const float DAMAGE_SHOT_DOUBLE = 5;
const float DAMAGE_SHOT_DOUBLE_HEAVY = 8;
const float DAMAGE_SHOT_TRIPLE = 7;
const int DAMAGE_SHOT_HF_NORMAL = 20;
const int DAMAGE_SHOT_HF_DOUBLE = 20;
const int DAMAGE_SHOT_HF_TRIPLE = 20;
const int DAMAGE_SHOT_HF_QUATTRO = 20;
const int DAMAGE_SHOT_HF_QUINTO = 20;
const float DAMAGE_SHOT_DUMBFIRE = 40;
const float DAMAGE_SHOT_DUMBFIRE_DOUBLE = 30;
const float DAMAGE_SHOT_KICK_ASS_ROCKET = 151; // should kill a tank/turret with one shot
const float DAMAGE_SHOT_HELLFIRE = 50;
const float DAMAGE_SHOT_MACHINE_GUN = 8;
const float DAMAGE_SHOT_ENERGY_BEAM = 80;
const int DAMAGE_SHOT_HF_DUMBFIRE = 40;
const int DAMAGE_SHOT_HF_DUMBFIRE_DOUBLE = 40;
const int DAMAGE_SHOT_HF_KICK_ASS_ROCKET = 151;
const int DAMAGE_SHOT_HF_LASER = 70;
const float DAMAGE_SPECIAL_SHOT_HEATSEEKER = 20;
const float DAMAGE_SPECIAL_SHOT_NUKE = 250;
const int SPREAD_ANGLE_SHOT_NORMAL = 6;
const int LIFETIME_ENEMY_SHOT_NORMAL = 6000;
const int LIFETIME_ENEMY_SHOT_TANK_ROCKET = 10000;
const int VEL_ENEMY_SHOT_NORMAL = 130;
const int VEL_ENEMY_SHOT_TANK_ROCKET = 70;
const float DAMAGE_ENEMY_SHOT_NORMAL = 8;
const float DAMAGE_ENEMY_SHOT_TANK_ROCKET = 25;
/***************************** SMOKE PUFFS ***************************/
enum SmokePuffTypes { SMOKE_PUFF_SMALL=0, SMOKE_PUFF_MEDIUM };
const int NR_SMOKE_PUFF_TYPES = 2;
const std::string FN_SMOKE_PUFF[ NR_SMOKE_PUFF_TYPES ] =
{ "./images/smokePuffSmall.bmp",
"./images/smokePuffMedium.bmp" };
const int LIFETIME_SMOKE_PUFF[ NR_SMOKE_PUFF_TYPES ] = { 500, 1000 };
const int SMOKE_PUFF_DELAY_TO_NEXT_PUFF[ NR_SMOKE_PUFF_TYPES ] = { 100, 100 };
const float SMOKE_PUFF_VELOCITY_FACTOR = 0.3;
const bool SMOKE_PUFF_ALPHA_BLENDING = true;
/********************************** ENEMIES ********************************/
enum EnemyTypes {
FIGHTER=0,
BOMBER,
TANK,
BOSS_1_MAIN_GUN,
BOSS_1_ROCKET_LAUNCHER,
BOSS_1_SHOT_BATTERY_RIGHT,
BOSS_1_SHOT_BATTERY_LEFT,
BOSS_2};
const int NR_ENEMY_TYPES = 8;
const int NR_ENEMY_TYPES_NORMAL = 3;
const int NR_ENEMY_TYPES_BOSS_1 = 4;
const float BOSS_1_END_Y = 110;
enum WreckTypes {
WRECK_FIGHTER=0,
WRECK_BOMBER,
WRECK_TANK,
WRECK_BOSS_1_MAIN_GUN,
WRECK_BOSS_1_ROCKET_LAUNCHER,
WRECK_BOSS_1_BATTERY_RIGHT,
WRECK_BOSS_1_BATTERY_LEFT,
WRECK_BOSS_1_BACKGROUND,
WRECK_BOSS_1_DESTROYED,
WRECK_BOSS_2_DESTROYED };
const int NR_WRECK_TYPES = 10;
const WreckTypes WRECK_FOR_ENEMYTYPE[] = {
WRECK_FIGHTER,
WRECK_BOMBER,
WRECK_TANK,
WRECK_BOSS_1_MAIN_GUN,
WRECK_BOSS_1_ROCKET_LAUNCHER,
WRECK_BOSS_1_BATTERY_RIGHT,
WRECK_BOSS_1_BATTERY_LEFT,
WRECK_BOSS_2_DESTROYED };
extern int GENERATE_ENEMY_DELAY;
extern int GENERATE_ENEMY_RAND_DELAY;
extern int ENEMY_HITPOINTS[];
//const float ENEMY_HITPOINTS[] = { 80, 120, 150, 10, 10, 10, 10 };
const bool ENEMY_FLYING[] = {true, true, false, false, false, false, false, true};
// determines the difference between shadow and enemy plane
const int ENEMY_FLYING_HEIGHT[] = {10, 15, 0, 0, 0, 0, 0, 10};
const int ENEMY_POINTS_FOR_DEST[] = {10,20,20,0,0,0,0,0};
extern int ENEMY_COLLISION_DAMAGE[];
// the enemys have different probabilities to appear in the different levels.
// bigger number -> greater chance
extern int ENEMY_APPEAR_CHANCES[];
// on average one of that many enemys carries an item
extern int ENEMY_DIES_ITEM_APPEAR_CHANCE[];
// minimal waittime (ms) between two shots
extern int ENEMY_COOLDOWN_PRIMARY[];
extern int ENEMY_COOLDOWN_SECONDARY[];
// random additional waittime between two shots
extern int ENEMY_RAND_WAIT_PRIMARY[];
extern int ENEMY_RAND_WAIT_SECONDARY[];
/******************************** FORMATION ***************************************/
enum FormationTypes { FORMATION_V=0, FORMATION_REVERSE_V,
FORMATION_BLOCK,
FORMATION_LINE };
const int NR_FORMATION_TYPES = 4;
const int FORMATION_MAX_NR_ENEMYS_HARD_LIMIT[] = {7,7,7,6};
extern int FORMATION_MAX_NR_ENEMYS[];
enum FormationEnemySets { FORMATION_ENEMY_SET_DEFAULT=0,
FORMATION_ENEMY_SET_FIGHTER,
FORMATION_ENEMY_SET_BOMBER,
FORMATION_ENEMY_SET_FIGHTER_BOMBER };
const int NR_FORMATION_ENEMY_SETS = 4;
const int FORMATION_CHANGE_ON_KILL = 1;
const int FORMATION_CHANGE_SPONTANEOUS = 2;
const int FORMATION_CHANGE_SELDOM = 4;
const int FORMATION_CHANGE_OFTEN = 8;
const int FORMATION_CHANGE_OFTEN_DELAY = 3000;
const int FORMATION_CHANGE_OFTEN_RAND_DELAY = 8000;
const int FORMATION_CHANGE_SELDOM_DELAY = 4000;
const int FORMATION_CHANGE_SELDOM_RAND_DELAY = 15000;
enum FormationShotPatterns { FORMATION_SP_NONE=0,
FORMATION_SP_RAND_FAST,
FORMATION_SP_RAND_MEDIUM,
FORMATION_SP_RAND_SLOW,
FORMATION_SP_VOLLEY_FAST,
FORMATION_SP_VOLLEY_MEDIUM,
FORMATION_SP_VOLLEY_SLOW,
FORMATION_SP_LEFT_RIGHT_FAST,
FORMATION_SP_LEFT_RIGHT_MEDIUM,
FORMATION_SP_RIGHT_LEFT_FAST,
FORMATION_SP_RIGHT_LEFT_MEDIUM };
const int NR_FORMATION_SP = 11;
extern int FORMATION_SP_CHANCES[];
extern int FORMATION_SP_PRIMARY_DELAY[];
extern int FORMATION_SP_PRIMARY_RAND_DELAY[];
extern int GENERATE_FORMATION_DELAY;
extern int GENERATE_FORMATION_RAND_DELAY;
/************************* RACER *********************************/
// max speed of the racer in pixels per second
const float LIGHT_FIGHTER_VEL_MAX = 90;
const float HEAVY_FIGHTER_VEL_MAX = 60;
// shield recharge points per 100 seconds
extern int LIGHT_FIGHTER_SHIELD_RECHARGE;
extern int HEAVY_FIGHTER_SHIELD_RECHARGE;
// Cooldown rates (in ms) of the weapons
const int RACER_COOLDOWN_SHOT_NORMAL = 100;
const int RACER_COOLDOWN_SHOT_NORMAL_HEAVY = 100;
const int RACER_COOLDOWN_SHOT_DOUBLE = 130;
const int RACER_COOLDOWN_SHOT_DOUBLE_HEAVY = 130;
const int RACER_COOLDOWN_SHOT_TRIPLE = 130;
const int RACER_COOLDOWN_SHOT_HF_NORMAL = 300;
const int RACER_COOLDOWN_SHOT_HF_DOUBLE = 300;
const int RACER_COOLDOWN_SHOT_HF_TRIPLE = 300;
const int RACER_COOLDOWN_SHOT_HF_QUATTRO = 350;
const int RACER_COOLDOWN_SHOT_HF_QUINTO = 400;
const int RACER_COOLDOWN_DUMBFIRE = 600;
const int RACER_COOLDOWN_DUMBFIRE_DOUBLE = 300;
const int RACER_COOLDOWN_KICK_ASS_ROCKET = 1500;
const int RACER_COOLDOWN_HELLFIRE = 600;
const int RACER_COOLDOWN_MACHINE_GUN = 150;
const int RACER_COOLDOWN_ENERGY_BEAM = 500;
const int RACER_COOLDOWN_HF_DUMBFIRE = 600;
const int RACER_COOLDOWN_HF_DUMBFIRE_DOUBLE = 300;
const int RACER_COOLDOWN_HF_KICK_ASS_ROCKET = 1300;
const int RACER_COOLDOWN_HF_LASER = 700;
const int RACER_COOLDOWN_SPECIAL_HEATSEEKER = 400;
const int RACER_COOLDOWN_SPECIAL_NUKE = 3000;
extern int RACER_DEFLECTOR_ACTIVATION_DIST;
extern int RACER_DEFLECTOR_POWER;
extern int RACER_SONIC_ACTIVATION_DIST;
extern int RACER_SONIC_POWER;
// how long (in ms) does the shield glow, when the racer is hit
const int RACER_SHIELD_DAMAGE_LIFETIME = 200;
// shields
extern int LIGHT_FIGHTER_MAX_SHIELD;
extern int HEAVY_FIGHTER_MAX_SHIELD;
// hitpoints
extern int LIGHT_FIGHTER_MAX_DAMAGE;
extern int HEAVY_FIGHTER_MAX_DAMAGE;
const std::string FN_SOUND_SHOT_PRIMARY = "./sound/shotPrimary.wav";
const std::string FN_SOUND_SHOT_SECONDARY = "./sound/shotSecondary.wav";
const std::string FN_SOUND_EXPLOSION_NORMAL = "./sound/explosion.wav";
const std::string FN_SOUND_EXPLOSION_BOSS = "./sound/explosionBoss.wav";
const std::string FN_SOUND_BOSS_ALARM = "./sound/alarm.wav";
const std::string FN_SOUND_ARCADE_CONFIRM = "./sound/alarm.wav";
const std::string FN_SOUND_ARCADE_CHOOSE = "./sound/choose.wav";
const std::string FN_SOUND_INTRO_CONFIRM = "./sound/confirm.wav";
const std::string FN_SOUND_INTRO_CHOOSE = "./sound/choose.wav";
const std::string FN_ENEMY_FIGHTER = "./images/fighter.bmp";
const std::string FN_ENEMY_FIGHTER_SHADOW = "./images/fighterShadow.bmp";
const std::string FN_ENEMY_BOMBER = "./images/bomber.bmp";
const std::string FN_ENEMY_BOMBER_SHADOW = "./images/bomberShadow.bmp";
const std::string FN_ENEMY_TANK = "./images/tank.bmp";
const std::string FN_ENEMY_BOSS_1_MAIN_GUN = "./images/boss1MainGun.bmp";
const std::string FN_ENEMY_BOSS_1_ROCKET_LAUNCHER = "./images/boss1RocketLauncher.bmp";
const std::string FN_ENEMY_BOSS_1_SHOT_BATTERY_LEFT = "./images/boss1ShotBatteryLeft.bmp";
const std::string FN_ENEMY_BOSS_1_SHOT_BATTERY_RIGHT = "./images/boss1ShotBatteryRight.bmp";
const std::string FN_ENEMY_BOSS_2 = "./images/boss2.bmp";
const std::string FN_ENEMY_BOSS_2_SHADOW = "./images/boss2Shadow.bmp";
const std::string FN_WRECK_FIGHTER = "./images/wreckFighter.bmp";
const std::string FN_WRECK_BOMBER = "./images/wreckBomber.bmp";
const std::string FN_WRECK_TANK = "./images/wreckTank.bmp";
const std::string FN_WRECK_BOSS_1 = "./images/wreckBoss1.bmp";
const std::string FN_WRECK_BOSS_1_BACKGROUND = "./images/wreckBossBackground.bmp";
const std::string FN_WRECK_BOSS_1_DESTROYED = "./images/boss.bmp";
const std::string FN_WRECK_BOSS_2_DESTROYED = "./images/wreckBoss2.bmp";
const std::string FN_SHOT_NORMAL = "./images/normalShot.bmp";
const std::string FN_SHOT_NORMAL_HEAVY = "./images/heavyShot.bmp";
const std::string FN_SHOT_DOUBLE = "./images/normalShot.bmp";
const std::string FN_SHOT_DOUBLE_HEAVY = "./images/heavyShot.bmp";
const std::string FN_SHOT_TRIPLE = "./images/heavyShot.bmp";
const std::string FN_SHOT_HF_NORMAL = "./images/normalShotHF.bmp";
const std::string FN_SHOT_HF_DOUBLE = "./images/normalShotHF.bmp";
const std::string FN_SHOT_HF_TRIPLE = "./images/normalShotHF.bmp";
const std::string FN_SHOT_HF_QUATTRO = "./images/normalShotHF.bmp";
const std::string FN_SHOT_HF_QUINTO = "./images/normalShotHF.bmp";
const std::string FN_SHOT_DUMBFIRE = "./images/dumbfire.bmp";
const std::string FN_SHOT_DUMBFIRE_DOUBLE = "./images/dumbfire.bmp";
const std::string FN_SHOT_KICK_ASS_ROCKET = "./images/kickAssRocket.bmp";
const std::string FN_SHOT_KICK_ASS_ROCKET_SHADOW = "./images/kickAssRocketShadow.bmp";
const std::string FN_SHOT_HELLFIRE = "./images/hellfire.bmp";
const std::string FN_SHOT_HELLFIRE_SHADOW = "./images/hellfireShadow.bmp";
const std::string FN_SHOT_MACHINE_GUN = "./images/machineGun.bmp";
const std::string FN_SHOT_ENERGY_BEAM = "./images/energyBeam.bmp";
const std::string FN_SHOT_HF_DUMBFIRE = "./images/dumbfire.bmp";
const std::string FN_SHOT_HF_DUMBFIRE_DOUBLE = "./images/dumbfire.bmp";
const std::string FN_SHOT_HF_KICK_ASS_ROCKET = "./images/kickAssRocket.bmp";
const std::string FN_SHOT_HF_KICK_ASS_ROCKET_SHADOW = "./images/kickAssRocketShadow.bmp";
const std::string FN_SHOT_HF_LASER = "./images/laser.bmp";
const std::string FN_ENEMY_SHOT_NORMAL = "./images/enemyShotNormal.bmp";
const std::string FN_ENEMY_SHOT_TANK_ROCKET = "./images/tankRocket.bmp";
const std::string FN_ENEMY_SHOT_TANK_ROCKET_SHADOW = "./images/tankRocketShadow.bmp";
const std::string FN_SPECIAL_SHOT_HEATSEEKER = "./images/heatseeker.bmp";
const std::string FN_SPECIAL_SHOT_NUKE = "./images/shotNuke.bmp";
const std::string FN_SPECIAL_SHOT_NUKE_SHADOW = "./images/shotNukeShadow.bmp";
const std::string FN_NUKE_EFFECT = "./images/nukeEffect.bmp";
const std::string FN_SONIC_EFFECT = "./images/sonic.bmp";
const std::string FN_ITEM_PRIMARY_UPGRADE = "./images/itemPrimaryUpgrade.bmp";
const std::string FN_ITEM_DUMBFIRE_DOUBLE = "./images/itemDumbfireDouble.bmp";
const std::string FN_ITEM_KICK_ASS_ROCKET = "./images/itemKickAssRocket.bmp";
const std::string FN_ITEM_HELLFIRE = "./images/itemHellfire.bmp";
const std::string FN_ITEM_MACHINE_GUN = "./images/itemMachineGun.bmp";
const std::string FN_ITEM_HEALTH = "./images/itemHealth.bmp";
const std::string FN_ITEM_HEATSEEKER = "./images/itemHeatseeker.bmp";
const std::string FN_ITEM_NUKE = "./images/itemNuke.bmp";
const std::string FN_ITEM_DEFLECTOR = "./images/itemDeflector.bmp";
const std::string FN_ITEM_ENERGY_BEAM = "./images/itemEnergyBeam.bmp";
const std::string FN_ITEM_LASER = "./images/itemLaser.bmp";
const std::string FN_ALIENBLASTER_INTRO = "./images/alienblasterintro.bmp";
const std::string FN_ALIENBLASTER_ICON = "./images/alienblastericon.bmp";
const std::string FN_BACKGROUND = "./images/background.bmp";
const std::string FN_PAUSED = "./images/paused.bmp";
const std::string FN_YOU_LOSE = "./images/youLose.bmp";
const std::string FN_YOU_WIN = "./images/youWin.bmp";
const std::string FN_GAME_OVER = "./images/gameOver.bmp";
const std::string FN_ARCADE_LOGO = "./images/arcadeLogo.bmp";
// numbers of images (animation-frames) per racer
const int RACER_IMAGE_CNT = 9;
const std::string FN_LIGHT_FIGHTER_1 = "./images/lightFighter1.bmp";
const std::string FN_LIGHT_FIGHTER_2 = "./images/lightFighter2.bmp";
const std::string FN_LIGHT_FIGHTER_SHADOW = "./images/lightFighterShadow.bmp";
const std::string FN_LIGHT_FIGHTER_SHIELD_DAMAGED = "./images/lightFighterShieldDamaged.bmp";
const std::string FN_LIGHT_FIGHTER_1_ICON = "./images/lightFighter1Icon.bmp";
const std::string FN_LIGHT_FIGHTER_2_ICON = "./images/lightFighter2Icon.bmp";
const std::string FN_LIGHT_FIGHTER_1_SMALL = "./images/lightFighter1Small.bmp";
const std::string FN_LIGHT_FIGHTER_2_SMALL = "./images/lightFighter2Small.bmp";
const std::string FN_HEAVY_FIGHTER_1 = "./images/heavyFighter1.bmp";
const std::string FN_HEAVY_FIGHTER_2 = "./images/heavyFighter2.bmp";
const std::string FN_HEAVY_FIGHTER_SHADOW = "./images/heavyFighterShadow.bmp";
const std::string FN_HEAVY_FIGHTER_SHIELD_DAMAGED = "./images/heavyFighterShieldDamaged.bmp";
const std::string FN_HEAVY_FIGHTER_DEFLECTOR = "./images/heavyFighterDeflector.bmp";
const std::string FN_HEAVY_FIGHTER_1_ICON = "./images/heavyFighter1Icon.bmp";
const std::string FN_HEAVY_FIGHTER_2_ICON = "./images/heavyFighter2Icon.bmp";
const std::string FN_HEAVY_FIGHTER_1_SMALL = "./images/heavyFighter1Small.bmp";
const std::string FN_HEAVY_FIGHTER_2_SMALL = "./images/heavyFighter2Small.bmp";
const std::string FN_ICONS_SPECIALS = "./images/iconsSpecials.bmp";
const std::string FN_ICONS_SECONDARY_WEAPONS = "./images/iconsSecondaryWeapons.bmp";
const std::string FN_HITPOINTS_STAT = "./images/hpStat.bmp";
const std::string FN_INTRO_SHOW_CHOICE = "./images/menuIcon.bmp";
const std::string FN_FONT_PATH = "./images/";
const std::string FN_FONT_SUFFIX_SURFACE = ".bmp";
const std::string FN_FONT_INTRO = "./images/font-20white.bmp";
const std::string FN_FONT_INTRO_HIGHLIGHTED = "./images/font-20lightblue.bmp";
const std::string FN_FONT_NUMBERS_TIME = "./images/font-20red.bmp";
const std::string FN_FONT_NUMBERS_LEFT = "./images/font-20red.bmp";
const std::string FN_FONT_NUMBERS_RIGHT = "./images/font-20blue.bmp";
const std::string FN_FONT_SETTINGS = "./images/font-20white.bmp";
const std::string FN_FONT_SETTINGS_HIGHLIGHTED = "./images/font-20lightblue.bmp";
const std::string FN_FONT_SETTINGS_SMALL = "./images/font-14white.bmp";
const std::string FN_FONT_SETTINGS_SMALL_BLUE = "./images/font-14lightblue.bmp";
const std::string FN_FONT_SETTINGS_SMALL_HIGHLIGHTED = "./images/font-14red.bmp";
const std::string FN_SETTINGS_BLUE = "./images/bluePlain.bmp";
const std::string FN_SETTINGS_WHITE = "./images/whitePlain.bmp";
const std::string FN_EXPLOSION_NORMAL = "./images/explosion.bmp";
const std::string FN_EXPLOSION_ENEMY = "./images/explosionEnemy.bmp";
const std::string FN_LOADING = "./images/loading.bmp";
const std::string FN_SETTINGS = "./cfg/alienBlaster.cfg";
const std::string FN_DIFFICULTY_CONFIG = "./cfg/alienBlasterDifficulty";
const std::string FN_DIFFICULTY_CONFIG_SUFFIX = ".cfg";
const std::string FN_HIGHSCORE = "./cfg/highscore.dat";
enum MusicTracks { MUSIC_INTRO=0, MUSIC_PLAYON, MUSIC_BOSS1, MUSIC_NONE };
const int NR_MUSIC_TRACKS = 3;
const std::string FN_MUSIC[] = { "./sound/intro.wav",
"./sound/playon.wav",
"./sound/intro.wav" };
const std::string FN_LEVEL_ONE_PLAYER = "./cfg/level1.cfg";
const std::string FN_LEVEL_TWO_PLAYER = "./cfg/level2.cfg";
const std::string FN_LEVEL_ARCADEMODE = "./cfg/levelArcade.cfg";
const std::string FN_SCREENSHOT0 = "./intro/HellShot0.bmp";
const std::string FN_SCREENSHOT1 = "./intro/HellShot1.bmp";
const std::string FN_SCREENSHOT2 = "./intro/HellShot2.bmp";
const std::string FN_SCREENSHOT3 = "./intro/HellShot3.bmp";
const std::string FN_SCREENSHOT4 = "./intro/HellShot5.bmp";
const std::string FN_SCREENSHOT5 = "./intro/HellShot4.bmp";
const std::string FN_SCREENSHOT6 = "./intro/HellShot6.bmp";
const std::string FN_SCREENSHOT7 = "./intro/HellShot7.bmp";
const std::string FN_SCREENSHOT8 = "./intro/HellShot8.bmp";
const std::string FN_SCREENSHOT9 = "./intro/HellShot9.bmp";
const std::string LVL_BACKG_TILE_CNT = "BACKG_TILES";
const std::string LVL_BACKG_TILE = "BACKG_TILE";
const std::string LVL_BACKG_LENGTH = "BACKG_LENGTH";
const std::string LVL_ENEMY_FIGHTER = "ENEMY_FIGHTER";
const std::string LVL_ENEMY_BOMBER = "ENEMY_BOMBER";
const std::string LVL_ENEMY_TANK = "ENEMY_TANK";
const std::string LVL_ENEMY_BOSS_BACKGROUND = "ENEMY_BOSS_BACKGROUND";
const std::string LVL_ENEMY_BOSS_DESTROYED = "ENEMY_BOSS_DESTROYED";
const std::string LVL_WRECK_FIGHTER = "WRECK_FIGHTER";
const std::string LVL_WRECK_BOMBER = "WRECK_BOMBER";
const std::string LVL_WRECK_TANK = "WRECK_TANK";
const std::string LVL_WRECK_BOSS_BACKGROUND = "WRECK_BOSS_BACKGROUND";
const std::string LVL_WRECK_BOSS_DESTROYED = "WRECK_BOSS_DESTROYED";
const std::string LVL_ENEMY_BOSS_1_SHOT_BATTERY_RIGHT = "ENEMY_BOSS_1_SHOT_BATTERY_RIGHT";
const std::string LVL_ENEMY_BOSS_1_SHOT_BATTERY_LEFT = "ENEMY_BOSS_1_SHOT_BATTERY_LEFT";
const std::string LVL_ENEMY_BOSS_1_ROCKET_LAUNCHER = "ENEMY_BOSS_1_ROCKET_LAUNCHER";
const std::string LVL_ENEMY_BOSS_1_MAIN_GUN = "ENEMY_BOSS_1_MAIN_GUN";
const std::string LVL_ENEMY_FIGHTER_SHADOW = "ENEMY_FIGHTER_SHADOW";
const std::string LVL_ENEMY_BOMBER_SHADOW = "ENEMY_BOMBER_SHADOW";
#endif

View File

@@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 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
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) <year> <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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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) year 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.

View File

@@ -0,0 +1,389 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
using namespace std;
#include "infoscreen.h"
#include "global.h"
#include "surfaceDB.h"
#include "mixer.h"
#include "video.h"
#include "font.h"
#include "items.h"
#include "item.h"
Items *infoscreenItems;
Infoscreen::Infoscreen( SDL_Surface *scr ) {
screen = scr;
font = new Font( FN_FONT_INTRO );
fontHighlighted = new Font( FN_FONT_INTRO_HIGHLIGHTED );
activeChoiceSprite = surfaceDB.loadSurface( FN_INTRO_SHOW_CHOICE );
lightFighterIcon1 = surfaceDB.loadSurface( FN_LIGHT_FIGHTER_1_ICON );
lightFighterIcon2 = surfaceDB.loadSurface( FN_LIGHT_FIGHTER_2_ICON );
heavyFighterIcon1 = surfaceDB.loadSurface( FN_HEAVY_FIGHTER_1_ICON );
heavyFighterIcon2 = surfaceDB.loadSurface( FN_HEAVY_FIGHTER_2_ICON );
choose = mixer.loadSample( FN_SOUND_INTRO_CHOOSE, 100 );
confirm = mixer.loadSample( FN_SOUND_INTRO_CONFIRM, 100 );
if (infoscreenItems) delete infoscreenItems;
infoscreenItems = new Items();
activeChoice = 0;
}
Infoscreen::~Infoscreen() {
if (infoscreenItems) delete infoscreenItems;
}
void Infoscreen::run() {
draw();
quitInfoscreen = false;
activeChoice = 0;
while ( !quitInfoscreen ) {
handleEvents();
draw();
SDL_Delay( 50 );
}
}
void Infoscreen::putBitmapAtPosition( int x, int y, SDL_Surface* bitmap ) {
SDL_Rect d;
d.x = x - bitmap->w / 2;
d.y = y - bitmap->h / 2;
d.w = bitmap->w;
d.h = bitmap->h;
SDL_BlitSurface( bitmap, 0, screen, &d );
}
void Infoscreen::draw() {
// clear the screen
videoserver->clearScreen();
// draw vertical green line
SDL_Rect r;
r.x = 250;
r.y = 0;
r.w = 1;
r.h = screen->h;
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0, 255, 0) );
for ( int i = 0; i < NR_INFOSCREEN_CHOICES; i++ ) {
int ypos = 30 + i * 25;
if ( i == INFO_CREDITS ) ypos += 15;
if ( i == INFO_BACK_TO_MAIN_MENU ) ypos += 30;
if( activeChoice == i ) {
putBitmapAtPosition( 15, ypos + 8, activeChoiceSprite );
fontHighlighted->drawStr( screen, 30, ypos, SET_INFOSCREEN_CHOICES[ i ] );
} else {
font->drawStr( screen, 30, ypos, SET_INFOSCREEN_CHOICES[ i ] );
}
}
switch ( activeChoice ) {
case INFO_LIGHT_FIGHTER:
{
putBitmapAtPosition( 386, 50, lightFighterIcon1 );
putBitmapAtPosition( 502, 50, lightFighterIcon2 );
font->drawStr( screen, 270, 100, "The Light Fighter is more");
font->drawStr( screen, 270, 130, "vulnerable but smaller and");
font->drawStr( screen, 270, 160, "faster than the Heavy Fighter.");
font->drawStr( screen, 270, 200, "Possible Updates:");
newItem = new Item( Vector2D ( 270, 240 ) , Vector2D(0,0), ITEM_PRIMARY_UPGRADE );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 230, "Primary Weapon Upgrade");
newItem = new Item( Vector2D ( 270, 270 ) , Vector2D(0,0), ITEM_MACHINE_GUN );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 260, "Machinegun");
newItem = new Item( Vector2D ( 270, 300 ) , Vector2D(0,0), ITEM_DUMBFIRE_DOUBLE );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 290, "Double Dumbfire");
newItem = new Item( Vector2D ( 270, 330 ) , Vector2D(0,0), ITEM_KICK_ASS_ROCKET );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 320, "Kick-Ass Rocket");
newItem = new Item( Vector2D ( 270, 360 ) , Vector2D(0,0), ITEM_HELLFIRE );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 350, "Hellfire Rocket");
newItem = new Item( Vector2D ( 270, 390 ) , Vector2D(0,0), ITEM_HEATSEEKER );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 380, "Heatseeker");
newItem = new Item( Vector2D ( 270, 420 ) , Vector2D(0,0), ITEM_NUKE );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 410, "The Great Nuke");
newItem = new Item( Vector2D ( 270, 450 ) , Vector2D(0,0), ITEM_ENERGY_BEAM );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 440, "Energy Beam");
infoscreenItems->draw( screen );
break;
}
case INFO_HEAVY_FIGHTER:
{
putBitmapAtPosition( 386, 50, heavyFighterIcon1 );
putBitmapAtPosition( 502, 50, heavyFighterIcon2 );
font->drawStr( screen, 270, 100, "The Heavy Fighter has superior");
font->drawStr( screen, 270, 130, "firepower and an energyweapon");
font->drawStr( screen, 270, 160, "deflector. He lacks agility.");
font->drawStr( screen, 270, 200, "Possible Updates:");
newItem = new Item( Vector2D ( 270, 240 ) , Vector2D(0,0), ITEM_PRIMARY_UPGRADE );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 230, "Primary Weapon Upgrade");
newItem = new Item( Vector2D ( 270, 270 ) , Vector2D(0,0), ITEM_KICK_ASS_ROCKET );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 260, "Kick-Ass Rocket");
newItem = new Item( Vector2D ( 270, 300 ) , Vector2D(0,0), ITEM_HEATSEEKER );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 290, "Heatseeker");
newItem = new Item( Vector2D ( 270, 330 ) , Vector2D(0,0), ITEM_NUKE );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 320, "The Great Nuke");
newItem = new Item( Vector2D ( 270, 360 ) , Vector2D(0,0), ITEM_DEFLECTOR );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 350, "Energyweapon Deflector");
newItem = new Item( Vector2D ( 270, 390 ) , Vector2D(0,0), ITEM_LASER );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 380, "Heavy Laser");
infoscreenItems->draw( screen );
break;
}
case INFO_PRIMARY_WEAPON:
{
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_PRIMARY_UPGRADE );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 40, "Primary Weapon Upgrade");
font->drawStr( screen, 270, 100, "The Primary Weapon Upgrade can");
font->drawStr( screen, 270, 130, "be used multiple times and each");
font->drawStr( screen, 270, 160, "time the primary weapon will");
font->drawStr( screen, 270, 190, "gain one extra shot or improve");
font->drawStr( screen, 270, 220, "its damage. The maximum for the");
font->drawStr( screen, 270, 250, "light fighter are three heavy");
font->drawStr( screen, 270, 280, "shots and for the heavy figher");
font->drawStr( screen, 270, 310, "five shots.");
infoscreenItems->draw( screen );
break;
}
case INFO_MACHINE_GUN:
{
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_MACHINE_GUN );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 40, "Machine Gun");
font->drawStr( screen, 270, 100, "The Machine Gun fires a");
font->drawStr( screen, 270, 130, "massive amount of steel per");
font->drawStr( screen, 270, 160, "minute at the enemy on the");
font->drawStr( screen, 270, 190, "ground and in the air.");
font->drawStr( screen, 270, 220, "It has the ability to aim in a");
font->drawStr( screen, 270, 250, "small angle at nearby enemys.");
font->drawStr( screen, 270, 280, "This makes it useful to");
font->drawStr( screen, 270, 310, "attack formations from the");
font->drawStr( screen, 270, 340, "side.");
infoscreenItems->draw( screen );
break;
}
case INFO_DUMBFIRE_DOUBLE:
{
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_DUMBFIRE_DOUBLE );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 40, "Double Dumbfire Rocket");
font->drawStr( screen, 270, 100, "With this upgrade, you get one");
font->drawStr( screen, 270, 130, "extra dumbfire missile for the");
font->drawStr( screen, 270, 160, "light fighter. These rockets");
font->drawStr( screen, 270, 190, "hit targets on the ground and");
font->drawStr( screen, 270, 220, "in the air.");
infoscreenItems->draw( screen );
break;
}
case INFO_KICK_ASS_ROCKET:
{
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_KICK_ASS_ROCKET );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 40, "Kick-Ass Rocket");
font->drawStr( screen, 270, 100, "This is the strongest air to");
font->drawStr( screen, 270, 130, "ground rocket. It takes only");
font->drawStr( screen, 270, 160, "one shot to let a turret");
font->drawStr( screen, 270, 190, "explode but reloading takes");
font->drawStr( screen, 270, 220, "longer.");
infoscreenItems->draw( screen );
break;
}
case INFO_HELLFIRE:
{
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_HELLFIRE );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 40, "Hellfire Rocket");
font->drawStr( screen, 270, 100, "Medium air to ground missiles");
font->drawStr( screen, 270, 130, "that are fired in pairs and");
font->drawStr( screen, 270, 160, "look much better than the");
font->drawStr( screen, 270, 190, "fat clumsy Kick-Ass-Rocket.");
infoscreenItems->draw( screen );
break;
}
// heatseaker (für Paul :-)
case INFO_HEATSEEKER:
{
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_HEATSEEKER );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 40, "Heatseaker Rocket");
font->drawStr( screen, 270, 100, "Just hit the trigger and this");
font->drawStr( screen, 270, 130, "missile will find the enemy");
font->drawStr( screen, 270, 160, "itself. Ground targets as well");
font->drawStr( screen, 270, 190, "as air targets will be hit.");
font->drawStr( screen, 270, 220, "Each item gives 70 of these.");
infoscreenItems->draw( screen );
break;
}
case INFO_NUKE:
{
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_NUKE );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 40, "The Great Nuke");
font->drawStr( screen, 270, 100, "Not much is known about this");
font->drawStr( screen, 270, 130, "weapon because everyone who");
font->drawStr( screen, 270, 160, "saw it exploding was dead in");
font->drawStr( screen, 270, 190, "just that moment.");
infoscreenItems->draw( screen );
break;
}
case INFO_DEFLECTOR:
{
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_DEFLECTOR );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 40, "Energyweapon Deflector");
font->drawStr( screen, 270, 100, "This is a very useful");
font->drawStr( screen, 270, 130, "equipment for the heavy");
font->drawStr( screen, 270, 160, "fighter. It amplifies the");
font->drawStr( screen, 270, 190, "builtin deflector, so that");
font->drawStr( screen, 270, 220, "it is very hard to be hit");
font->drawStr( screen, 270, 250, "by an energy weapon.");
infoscreenItems->draw( screen );
break;
}
case INFO_ENERGY_BEAM:
{
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_ENERGY_BEAM );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 40, "Energy Beam");
font->drawStr( screen, 270, 100, "The Energy Beam was built");
font->drawStr( screen, 270, 130, "for the light fighter and");
font->drawStr( screen, 270, 160, "its devastating power");
font->drawStr( screen, 270, 190, "makes it the best choice");
font->drawStr( screen, 270, 220, "against air targets. In");
font->drawStr( screen, 270, 250, "addition its really hard");
font->drawStr( screen, 270, 280, "to evade this weapon.");
infoscreenItems->draw( screen );
break;
}
case INFO_LASER:
{
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_LASER );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 40, "Heavy Laser");
font->drawStr( screen, 270, 100, "This is the newest type");
font->drawStr( screen, 270, 130, "of equipment for the heavy");
font->drawStr( screen, 270, 160, "fighter. A skilled pilot");
font->drawStr( screen, 270, 190, "can take down two air");
font->drawStr( screen, 270, 220, "enemies at once with this");
font->drawStr( screen, 270, 250, "heavy laser.");
infoscreenItems->draw( screen );
break;
}
case INFO_SHIELD_UP:
{
newItem = new Item( Vector2D ( 270, 50 ) , Vector2D(0,0), ITEM_HEALTH );
infoscreenItems->addItem( newItem );
font->drawStr( screen, 300, 40, "Health Powerup");
font->drawStr( screen, 270, 100, "If your shield goes down");
font->drawStr( screen, 270, 130, "this powerup is especially");
font->drawStr( screen, 270, 160, "useful for instant repairs.");
font->drawStr( screen, 270, 190, "Try to get it as often as");
font->drawStr( screen, 270, 220, "you can.");
infoscreenItems->draw( screen );
break;
}
case INFO_CREDITS:
{
font->drawStr( screen, 445, 40, "Alien Blaster", FONT_ALIGN_CENTERED );
font->drawStr( screen, 270, 100, "Programming:");
font->drawStr( screen, 280, 130, "Arne Hormann, Daniel Kühn,");
font->drawStr( screen, 280, 160, "Paul Grathwohl, Sönke Schwardt");
font->drawStr( screen, 270, 210, "Art Work: Arne Hormann", FONT_MONOSPACE);
font->drawStr( screen, 270, 240, "Music: Paul Grathwohl", FONT_MONOSPACE);
font->drawStr( screen, 620, 440, "Contact: AlienBlaster@gmx.de", FONT_ALIGN_RIGHT);
break;
}
case INFO_BACK_TO_MAIN_MENU:
{
font->drawStr( screen, 445, 220, "GO AND FIGHT !", FONT_ALIGN_CENTERED );
break;
}
}
SDL_Flip( screen );
}
void Infoscreen::handleEvents() {
SDL_Event event;
while ( SDL_PollEvent(&event) ) {
switch(event.type) {
case SDL_KEYDOWN: {
switch ( event.key.keysym.sym ) {
case SDLK_F5: {
videoserver->toggleFullscreen();
break;
}
case SDLK_F7: {
if ( playMusicOn ) {
playMusicOn = false;
mixer.stopMusic();
} else {
playMusicOn = true;
mixer.playMusic( MUSIC_INTRO, -1, 1000 );
}
break;
}
case SDLK_UP: {
mixer.playSample( choose, 0 );
infoscreenItems->deleteAllItems();
activeChoice--;
if ( activeChoice < 0 ) activeChoice = NR_INFOSCREEN_CHOICES - 1;
break;
}
case SDLK_DOWN: {
mixer.playSample( choose, 0 );
infoscreenItems->deleteAllItems();
activeChoice = (activeChoice + 1) % NR_INFOSCREEN_CHOICES;
break;
}
case SDLK_ESCAPE: {
quitInfoscreen = true;
break;
}
case SDLK_RETURN: {
mixer.playSample( confirm, 0 );
switch (activeChoice) {
case INFO_BACK_TO_MAIN_MENU: {
quitInfoscreen = true;
break;
}
}
break;
}
default: break;
}
break;
}
default: break;
}
}
}

View File

@@ -0,0 +1,96 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef INFOSCREEN_H
#define INFOSCREEN_H
#include "SDL.h"
#include <string>
#include "item.h"
class Font;
class Items;
enum INFOSCREEN_CHOICES {
INFO_LIGHT_FIGHTER,
INFO_HEAVY_FIGHTER,
INFO_PRIMARY_WEAPON,
INFO_MACHINE_GUN,
INFO_DUMBFIRE_DOUBLE,
INFO_KICK_ASS_ROCKET,
INFO_HELLFIRE,
INFO_HEATSEEKER,
INFO_NUKE,
INFO_DEFLECTOR,
INFO_ENERGY_BEAM,
INFO_LASER,
INFO_SHIELD_UP,
INFO_CREDITS,
INFO_BACK_TO_MAIN_MENU
};
const std::string SET_INFOSCREEN_CHOICES[] = {
"Light Fighter",
"Heavy Fighter",
"Primary Weapon",
"Machine Gun",
"Double Dumbfire",
"Kick-Ass Rocket",
"Hellfire Rocket",
"Heatseaker Rocket",
"The Great Nuke",
"Deflector",
"Energy Beam",
"Heavy Laser",
"Health Powerup",
"Credits",
"Back To Main Menu"
};
const int NR_INFOSCREEN_CHOICES = 15;
class Infoscreen {
private:
SDL_Surface *screen;
SDL_Surface *activeChoiceSprite;
SDL_Surface *lightFighterIcon1;
SDL_Surface *lightFighterIcon2;
SDL_Surface *heavyFighterIcon1;
SDL_Surface *heavyFighterIcon2;
Font *font;
Font *fontHighlighted;
Item *newItem;
int activeChoice;
bool quitInfoscreen;
// sounds
int choose, confirm;
public:
Infoscreen( SDL_Surface *scr );
~Infoscreen();
void run();
private:
void handleEvents();
void draw();
void putBitmapAtPosition( int x, int y, SDL_Surface* bitmap );
};
#endif

View File

@@ -0,0 +1,112 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
using namespace std;
#include <vector>
#include "input.h"
#include "SDL.h"
Input input;
const int initialSensitivity = 4096;
Input::Input(){
joystick = 0;
getJoystick();
}
Input::~Input(){
freeJoystick();
joystick = 0;
}
void Input::getJoystick() {
if (joystick) return;
if (!SDL_InitSubSystem(SDL_INIT_JOYSTICK)) {
SDL_JoystickEventState(SDL_ENABLE);
if (SDL_NumJoysticks() > 0) {
joystick = SDL_JoystickOpen(0);
} else {
freeJoystick();
}
}
}
void Input::freeJoystick() {
if (joystick) {
SDL_JoystickClose(joystick);
joystick = 0;
}
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
}
#ifdef DEBUG
const bool pressed(const SDL_Event& event) {
if (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_KEYDOWN) return true;
if (event.type == SDL_JOYAXISMOTION) return event.jaxis.value / 3200;
return false;
}
void debugEvent(const SDL_Event& event, const SDLKey code) {
if (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_JOYBUTTONUP) {
printf("Joystick button%d event: %s (%d)\n",
event.jbutton.button, (pressed(event)) ? "pressed" : "released", code);
} else if (event.type == SDL_JOYAXISMOTION && pressed(event)) {
printf("Joystick axis%d event: %s (%d)\n",
event.jaxis.axis, (event.jaxis.value > 0) ? "raised" : "lowered", code);
}
}
const SDLKey translateEvent(const SDL_Event& event) {
if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) {
return event.key.keysym.sym;
}
if (event.type == SDL_JOYAXISMOTION) {
return (SDLKey) (1024 + event.jaxis.axis * 2 + ((event.jaxis.value > 0) ? 1 : 0));
}
if (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_JOYBUTTONUP) {
return (SDLKey) (1040 + event.jbutton.button);
}
return (SDLKey) 0;
}
#endif
const SDLKey Input::translate(const SDL_Event& event) {
#ifdef DEBUG
debugEvent(event, translateEvent(event));
#endif
if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) {
return event.key.keysym.sym;
}
if (event.type == SDL_JOYAXISMOTION) {
return (SDLKey) (1024 + event.jaxis.axis * 2 + ((event.jaxis.value > 0) ? 1 : 0));
}
if (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_JOYBUTTONUP) {
return (SDLKey) (1040 + event.jbutton.button);
}
return (SDLKey) 0;
}
const bool Input::isPressed(const SDL_Event& event) {
/* || event.type == SDL_MOUSEBUTTONDOWN*/
if (event.type == SDL_JOYBUTTONDOWN || event.type == SDL_KEYDOWN) return true;
if (event.type == SDL_JOYAXISMOTION) return event.jaxis.value / initialSensitivity;
return false;
}

View File

@@ -0,0 +1,46 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef INPUT_H
#define INPUT_H
#include "SDL.h"
class Input;
extern Input input;
class Input {
private:
Uint16 currentJoystick;
SDL_Joystick *joystick;
public:
Input();
~Input();
void getJoystick();
void freeJoystick();
const SDLKey translate(const SDL_Event& event);
const bool isPressed(const SDL_Event& event);
static const Input input();
};
#endif //#ifndef INPUT_H

View File

@@ -0,0 +1,232 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
using namespace std;
#include "intro.h"
#include "global.h"
#include "surfaceDB.h"
#include "mixer.h"
#include "video.h"
#include "font.h"
#include "settings.h"
#include "infoscreen.h"
Intro::Intro( SDL_Surface *scr ) {
screen = scr;
introSprite = surfaceDB.loadSurface( FN_ALIENBLASTER_INTRO );
activeChoiceSprite = surfaceDB.loadSurface( FN_INTRO_SHOW_CHOICE );
font = new Font( FN_FONT_INTRO );
fontHighlighted = new Font( FN_FONT_INTRO_HIGHLIGHTED );
activeChoice = 0;
choose = mixer.loadSample( FN_SOUND_INTRO_CHOOSE, 100 );
confirm = mixer.loadSample( FN_SOUND_INTRO_CONFIRM, 100 );
infoscreen = new Infoscreen( screen );
}
Intro::~Intro() {}
void Intro::run( GameStates &gameState ) {
if ( playMusicOn && mixer.whichMusicPlaying() != MUSIC_INTRO ) {
mixer.playMusic( MUSIC_INTRO, -1, 1000 );
}
draw();
while ( gameState == GS_INTRO ) {
handleEvents( gameState );
draw();
SDL_Delay( 50 );
}
}
void Intro::draw() {
videoserver->clearScreen();
SDL_Rect r;
r.x = screen->w / 2 - introSprite->w / 2;
r.y = 0;
r.w = introSprite->w;
r.h = introSprite->h;
SDL_BlitSurface( introSprite, 0, screen, &r );
for ( int i = 0; i < NR_INTRO_CHOICES; i++ ) {
if ( activeChoice == i ) {
r.x = 230 - activeChoiceSprite->w - 8;
r.y = 258 + i * 35;
r.w = activeChoiceSprite->w;
r.h = activeChoiceSprite->h;
SDL_BlitSurface(activeChoiceSprite, 0, screen, &r );
fontHighlighted->drawStr( screen, 230, 260 + i * 35, INTRO_CHOICES[ i ] );
} else {
font->drawStr( screen, 230, 260 + i * 35, INTRO_CHOICES[ i ] );
}
}
SDL_Flip( screen );
}
void Intro::handleEvents( GameStates &gameState ) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYDOWN: {
switch(event.key.keysym.sym) {
case SDLK_F5: {
videoserver->toggleFullscreen();
break;
}
case SDLK_F7: {
if ( playMusicOn ) {
playMusicOn = false;
mixer.stopMusic();
} else {
playMusicOn = true;
mixer.playMusic( MUSIC_INTRO, -1, 1000 );
}
break;
}
case SDLK_UP: {
mixer.playSample( choose, 0 );
activeChoice--;
if ( activeChoice < 0 ) activeChoice = NR_INTRO_CHOICES - 1;
break;
}
case SDLK_DOWN: {
mixer.playSample( choose, 0 );
activeChoice = (activeChoice + 1) % NR_INTRO_CHOICES;
break;
}
case SDLK_ESCAPE: {
gameState = GS_QUIT;
break;
}
case SDLK_RETURN: {
mixer.playSample( confirm, 0 );
switch (activeChoice) {
case ONE_PLAYER_GAME: {
onePlayerGame = true;
arcadeGame = false;
gameState = GS_SET_DIFFICULTY;
break;
}
case TWO_PLAYER_GAME: {
onePlayerGame = false;
arcadeGame = false;
gameState = GS_SET_DIFFICULTY;
break;
}
case ARCADE_GAME: {
onePlayerGame = true;
arcadeGame = true;
gameState = GS_ARCADE_MODE_SETUP;
break;
}
case CONFIGURE_KEYS: {
settings->settingsDialog(screen);
draw();
break;
}
case INFOSCREEN: {
infoscreen->run();
break;
}
case QUIT_AND_DIE: {
gameState = GS_QUIT;
break;
}
}
break;
}
default: break;
}
break;
}
case SDL_QUIT: {
gameState = GS_QUIT;
break;
}
default: break;
}
}
}
void Intro::showScreenshots() {
if ( playMusicOn && mixer.whichMusicPlaying() != MUSIC_INTRO ) {
mixer.playMusic( MUSIC_INTRO, -1, 1000 );
}
SDL_Surface *surfS = SDL_LoadBMP( FN_ALIENBLASTER_INTRO.c_str() );
SDL_Surface *surf0 = SDL_LoadBMP( FN_SCREENSHOT0.c_str() );
SDL_Surface *surf1 = SDL_LoadBMP( FN_SCREENSHOT1.c_str() );
SDL_Surface *surf2 = SDL_LoadBMP( FN_SCREENSHOT2.c_str() );
SDL_Surface *surf3 = SDL_LoadBMP( FN_SCREENSHOT3.c_str() );
SDL_Surface *surf4 = SDL_LoadBMP( FN_SCREENSHOT4.c_str() );
SDL_Surface *surf5 = SDL_LoadBMP( FN_SCREENSHOT5.c_str() );
SDL_Surface *surf6 = SDL_LoadBMP( FN_SCREENSHOT6.c_str() );
SDL_Surface *surf7 = SDL_LoadBMP( FN_SCREENSHOT7.c_str() );
SDL_Surface *surf8 = SDL_LoadBMP( FN_SCREENSHOT8.c_str() );
SDL_Surface *surf9 = SDL_LoadBMP( FN_SCREENSHOT9.c_str() );
SDL_BlitSurface( surfS, 0, screen, 0 );
SDL_Flip(screen);
SDL_Delay(3000);
int sps = 50; // steps per second
if (blendImages( screen, surfS, 0, surf0, 0, sps ))
if (blendImages( screen, surf0, 0, surf1, 0, sps ))
if (blendImages( screen, surf1, 0, surf2, 0, sps ))
if (blendImages( screen, surf2, 0, surf3, 0, sps ))
if (blendImages( screen, surf3, 0, surf4, 0, sps ))
if (blendImages( screen, surf4, 0, surf5, 0, sps ))
if (blendImages( screen, surf5, 0, surf6, 0,sps ))
if (blendImages( screen, surf6, 0, surf7, 0, sps ))
if (blendImages( screen, surf7, 0, surf8, 0, sps ))
blendImages( screen, surf8, 0, surf9, 0, sps );
}
bool Intro::blendImages( SDL_Surface *screen, SDL_Surface *surf0, SDL_Rect *r1, SDL_Surface *surf1, SDL_Rect *r2, int sps ) {
SDL_Event event;
int i = 0;
int t = SDL_GetTicks();
while (i < 255) {
if (i>255) i=255;
SDL_SetAlpha( surf0, SDL_SRCALPHA, 255-i );
SDL_SetAlpha( surf1, SDL_SRCALPHA, i );
SDL_BlitSurface( surf0, 0, screen, r1 );
SDL_BlitSurface( surf1, 0, screen, r2 );
SDL_Flip( screen );
int t2 = SDL_GetTicks();
int dt= SDL_GetTicks() - t;
t = t2;
i += (dt * sps / 1000);
while (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYDOWN: {
return false;
}
default:
break;
}
}
}
return true;
}

View File

@@ -0,0 +1,64 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef INTRO_H
#define INTRO_H
#include <string>
#include "SDL.h"
#include "game.h"
class Font;
class Infoscreen;
enum IntroChoices { ONE_PLAYER_GAME, TWO_PLAYER_GAME, ARCADE_GAME,
CONFIGURE_KEYS, INFOSCREEN, QUIT_AND_DIE };
const std::string INTRO_CHOICES[] = { "1-Player Action", "2-Player Fight",
"Arcade",
"Configure Keys", "Infoscreen", "Quit and Die" };
const int NR_INTRO_CHOICES = 6;
class Intro {
private:
SDL_Surface *screen;
SDL_Surface *introSprite;
SDL_Surface *activeChoiceSprite;
Font *font;
Font *fontHighlighted;
Infoscreen *infoscreen;
int activeChoice;
// sound
int choose;
int confirm;
public:
Intro( SDL_Surface *scr );
~Intro();
void run( GameStates &gameState );
void showScreenshots();
bool blendImages( SDL_Surface *screen, SDL_Surface *surf0, SDL_Rect *r1, SDL_Surface *surf1, SDL_Rect *r2, int sps );
private:
void handleEvents( GameStates &gameState );
void draw();
};
#endif

View File

@@ -0,0 +1,136 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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 <iostream>
#include "item.h"
#include "boundingBox.h"
#include "surfaceDB.h"
#include "global.h"
Item::Item(const Vector2D &position, const Vector2D &velocity, ItemTypes itemType) {
this->itemType = itemType;
pos = position;
vel = velocity;
timeLived = 0;
switch (itemType) {
case ITEM_PRIMARY_UPGRADE:
{
sprite = surfaceDB.loadSurface( FN_ITEM_PRIMARY_UPGRADE );
break;
}
case ITEM_DUMBFIRE_DOUBLE:
{
sprite = surfaceDB.loadSurface( FN_ITEM_DUMBFIRE_DOUBLE );
break;
}
case ITEM_KICK_ASS_ROCKET:
{
sprite = surfaceDB.loadSurface( FN_ITEM_KICK_ASS_ROCKET );
break;
}
case ITEM_HELLFIRE:
{
sprite = surfaceDB.loadSurface( FN_ITEM_HELLFIRE );
break;
}
case ITEM_MACHINE_GUN:
{
sprite = surfaceDB.loadSurface( FN_ITEM_MACHINE_GUN );
break;
}
case ITEM_HEALTH:
{
sprite = surfaceDB.loadSurface( FN_ITEM_HEALTH );
break;
}
case ITEM_HEATSEEKER:
{
sprite = surfaceDB.loadSurface( FN_ITEM_HEATSEEKER );
break;
}
case ITEM_NUKE:
{
sprite = surfaceDB.loadSurface( FN_ITEM_NUKE );
break;
}
case ITEM_DEFLECTOR:
{
sprite = surfaceDB.loadSurface( FN_ITEM_DEFLECTOR );
break;
}
case ITEM_LASER:
{
sprite = surfaceDB.loadSurface( FN_ITEM_LASER );
break;
}
case ITEM_ENERGY_BEAM:
{
sprite = surfaceDB.loadSurface( FN_ITEM_ENERGY_BEAM );
break;
}
default:
{
cout << "Item(): unexpected itemType: " << itemType << endl;
sprite = surfaceDB.loadSurface( FN_ITEM_PRIMARY_UPGRADE );
break;
}
}
boundingBox = new BoundingBox( lroundf(pos.getX() - sprite->w / 2.0),
lroundf(pos.getY() - sprite->h / 2.0),
sprite->w, sprite->h );
}
Item::~Item() {
delete boundingBox;
}
void Item::update( int dT ) {
pos += vel * dT / 1000.0;
updateBoundingBox();
timeLived += dT;
}
void Item::deleteItem() {
timeLived = ITEM_LIFETIME;
}
void Item::updateBoundingBox() {
boundingBox->moveUpperBound( lroundf(pos.getY() - sprite->h * 0.5) );
boundingBox->moveLeftBound( lroundf(pos.getX() - sprite->w * 0.5) );
}
void Item::draw(SDL_Surface *screen) {
SDL_Rect r;
r.x = lroundf(pos.getX()) - sprite->w / 2;
r.y = lroundf(pos.getY()) - sprite->h / 2;
r.w = sprite->w;
r.h = sprite->h;
SDL_BlitSurface( sprite, 0, screen, &r );
}
BoundingBox *Item::getBoundingBox() {
return boundingBox;
}

View File

@@ -0,0 +1,60 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef ITEM_H
#define ITEM_H
#include "SDL.h"
#include "geometry.h"
#include <string>
#include "global.h"
class BoundingBox;
class Item {
SDL_Surface *sprite;
BoundingBox *boundingBox;
Vector2D pos;
Vector2D vel;
ItemTypes itemType;
int timeLived;
void updateBoundingBox();
public:
Item( const Vector2D &position, const Vector2D &velocity, ItemTypes itemType );
~Item();
void update( int dT );
void deleteItem();
void draw(SDL_Surface *screen);
inline bool isExpired() { return (timeLived >= ITEM_LIFETIME); }
inline Vector2D getPos() { return pos; }
inline Vector2D getVel() { return vel; }
inline void pickedUp() { timeLived = ITEM_LIFETIME; }
inline ItemTypes getType() { return itemType; }
BoundingBox *getBoundingBox();
};
#endif

View File

@@ -0,0 +1,131 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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 "item.h"
#include "items.h"
#include "surfaceDB.h"
#include "geometry.h"
#include "global.h"
#include "racers.h"
Items::Items() {
timeNextItemAppear =
ITEM_APPEAR_DELAY +
(rand() % ITEM_APPEAR_RAND_DELAY);
}
Items::~Items() {
vector<Item *>::iterator i;
for (i = items.begin(); i != items.end(); ++i) {
delete *i;
}
}
void Items::addItem(Item *item) {
if (item) {
items.push_back(item);
}
}
void Items::expireItems() {
unsigned int i = 0;
while ( i < items.size() ) {
if ( items[i]->isExpired() ) {
delete items[i];
items.erase(items.begin() + i);
} else {
i++;
}
}
}
void Items::update( int dT ) {
vector<Item *>::iterator i;
for (i = items.begin(); i != items.end(); ++i) {
(*i)->update( dT );
}
}
void Items::draw(SDL_Surface *screen) {
vector<Item *>::iterator i;
for (i = items.begin(); i != items.end(); ++i) {
(*i)->draw(screen);
}
}
Item *Items::getItem(unsigned int idx) {
return items[idx];
}
void Items::generateItemNow( Vector2D pos, Vector2D vel ) {
if ( pos.getX() < 10 ) pos.setX( 10 );
if ( pos.getX() > SCREEN_WIDTH-10 ) pos.setX( SCREEN_WIDTH-10 );
if ( pos.getY() < 100 && vel.getY() < 5 ) vel.setY( 5 );
int itemType;
// 10 tries for a correct item
for ( int i = 0; i < 10; i++ ) {
itemType = getRandValue( ITEM_APPEAR_CHANCES, NR_ITEM_TYPES );
if ( ( racers->isShipTypeActive( LIGHT_FIGHTER ) &&
racers->isShipTypeActive( HEAVY_FIGHTER ) ) ||
( racers->isShipTypeActive( LIGHT_FIGHTER ) &&
( itemType == ITEM_PRIMARY_UPGRADE ||
itemType == ITEM_DUMBFIRE_DOUBLE ||
itemType == ITEM_KICK_ASS_ROCKET ||
itemType == ITEM_HELLFIRE ||
itemType == ITEM_MACHINE_GUN ||
itemType == ITEM_HEALTH ||
itemType == ITEM_HEATSEEKER ||
itemType == ITEM_NUKE ||
itemType == ITEM_ENERGY_BEAM ) ) ||
( racers->isShipTypeActive( HEAVY_FIGHTER ) &&
( itemType == ITEM_PRIMARY_UPGRADE ||
itemType == ITEM_DUMBFIRE_DOUBLE ||
itemType == ITEM_KICK_ASS_ROCKET ||
itemType == ITEM_HEALTH ||
itemType == ITEM_HEATSEEKER ||
itemType == ITEM_NUKE ||
itemType == ITEM_DEFLECTOR ||
itemType == ITEM_LASER ) ) ) {
Item *item = new Item( pos, vel, (ItemTypes)itemType );
addItem( item );
break;
}
}
}
void Items::generate( int dT ) {
timeNextItemAppear -= dT;
if ( timeNextItemAppear < 0 ) {
timeNextItemAppear = ITEM_APPEAR_DELAY + (rand() % ITEM_APPEAR_RAND_DELAY);
generateItemNow( Vector2D( 150 + (rand() % 340), -20 ),
Vector2D( (rand() % lroundf(SCROLL_SPEED)) - SCROLL_SPEED / 2,
SCROLL_SPEED + (rand() % lroundf(SCROLL_SPEED)) ) );
}
}
void Items::deleteAllItems() {
vector<Item *>::iterator i;
for (i = items.begin(); i != items.end(); ++i) {
(*i)->deleteItem();
}
expireItems();
}

View File

@@ -0,0 +1,51 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef ITEMS_H
#define ITEMS_H
#include "SDL.h"
#include <vector>
class Item;
class Vector2D;
class Items {
vector<Item *> items;
int timeNextItemAppear;
public:
Items();
~Items();
void addItem(Item *item);
void generateItemNow( Vector2D pos, Vector2D vel );
void generate( int dT );
void expireItems();
void update( int dT );
void draw(SDL_Surface *screen);
void deleteAllItems();
inline unsigned int getNrItems() { return items.size(); }
Item *getItem(unsigned int idx);
};
#endif

View File

@@ -0,0 +1,33 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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"
#include "SDL.h"
#include <stdlib.h>
using namespace std;
int main(int argc, char *argv[]) {
SDL_Init(0);
srand(0);
Game game;
game.run();
SDL_Quit();
return 0;
}

View File

@@ -0,0 +1,366 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
using namespace std;
#include "menuArcadeMode.h"
#include "global.h"
#include "surfaceDB.h"
#include "mixer.h"
#include "video.h"
#include "font.h"
#include "racer.h"
#include "racers.h"
#include "asstring.h"
#include "options.h"
#include <iostream>
#include <fstream>
MenuArcadeMode::MenuArcadeMode( SDL_Surface *scr ) {
screen = scr;
arcadeSprite = surfaceDB.loadSurface( FN_ARCADE_LOGO );
activeChoiceSprite = surfaceDB.loadSurface( FN_INTRO_SHOW_CHOICE );
font = new Font( FN_FONT_INTRO );
fontHighlighted = new Font( FN_FONT_INTRO_HIGHLIGHTED );
lightFighterIcon1 = surfaceDB.loadSurface( FN_LIGHT_FIGHTER_1_ICON );
heavyFighterIcon1 = surfaceDB.loadSurface( FN_HEAVY_FIGHTER_1_ICON );
choose = mixer.loadSample( FN_SOUND_ARCADE_CHOOSE, 100 );
confirm = mixer.loadSample( FN_SOUND_ARCADE_CONFIRM, 60 );
activeChoice = 0;
playerOneLightFighter = true;
op = new Options( FN_HIGHSCORE );
// check, if the highscore is open
int highscoreTest;
if ( !op->getInt( "POINTS_1", highscoreTest ) ) {
cout << "Creating the highscore..." << endl;
op->setStr( "ALIENBLASTER", "NAME_1" );
op->setInt( 1666, "POINTS_1" );
op->setStr( "GNOSTICAL", "NAME_2" );
op->setInt( 1000, "POINTS_2" );
op->setStr( "SLOBJOK", "NAME_3" );
op->setInt( 1000, "POINTS_3" );
op->setStr( "SNOWBALL", "NAME_4" );
op->setInt( 1000, "POINTS_4" );
op->setStr( "THUNDERBIRD", "NAME_5" );
op->setInt( 1000, "POINTS_5" );
op->setStr( "KaoT", "NAME_6" );
op->setInt( 666, "POINTS_6" );
op->setStr( "SDL", "NAME_7" );
op->setInt( 500, "POINTS_7" );
op->setStr( "DEBIAN", "NAME_8" );
op->setInt( 400, "POINTS_8" );
op->setStr( "DEV-CPP", "NAME_9" );
op->setInt( 300, "POINTS_9" );
op->setStr( "I RULE", "NAME_10" );
op->setInt( 200, "POINTS_10" );
op->saveFile( FN_HIGHSCORE );
}
}
MenuArcadeMode::~MenuArcadeMode() {
op->saveFile( FN_HIGHSCORE );
delete op;
}
void MenuArcadeMode::run( GameStates &gameState, int points ) {
activeChoice = 0;
if ( GS_ARCADE_MODE_FINISHED ) {
updateHighScore( points );
gameState = GS_ARCADE_MODE_SETUP;
}
draw();
while ( gameState == GS_ARCADE_MODE_SETUP ) {
handleEvents( gameState );
draw();
SDL_Delay( 50 );
}
}
bool MenuArcadeMode::getPlayerOneLightFighter() {
return playerOneLightFighter;
}
void MenuArcadeMode::draw() {
videoserver->clearScreen();
SDL_Rect r;
r.x = screen->w / 2 - arcadeSprite->w / 2;
r.y = 0;
r.w = arcadeSprite->w;
r.h = arcadeSprite->h;
SDL_BlitSurface( arcadeSprite, 0, screen, &r );
string name = "UNKNOWN";
int points = 0;
op->getStr( "NAME_1", name );
op->getInt( "POINTS_1", points );
fontHighlighted->drawStr( screen, 230, 60, "1. " + name + ": " + asString(points) );
for ( int i = 2; i <= 10; i++ ) {
op->getStr( "NAME_" + asString( i ), name );
op->getInt( "POINTS_" + asString( i ), points );
font->drawStr( screen, 230, 40 + i * 25,
asString( i ) + ". " + name + ": " + asString(points) );
}
for ( int i = 0; i < NR_MENU_ARCADE_CHOICES; i++ ) {
if ( activeChoice == i ) {
r.x = 230 - activeChoiceSprite->w - 8;
r.y = 338 + i * 40;
r.w = activeChoiceSprite->w;
r.h = activeChoiceSprite->h;
SDL_BlitSurface( activeChoiceSprite, 0, screen, &r );
fontHighlighted->drawStr( screen, 230, 340 + i * 40, STRINGS_MENU_ARCADE_CHOICES[ i ] );
} else {
font->drawStr( screen, 230, 340 + i * 40, STRINGS_MENU_ARCADE_CHOICES[ i ] );
}
}
font->drawStr( screen, 50, 270, "Player 1" );
if ( playerOneLightFighter ) {
r.x = 100 - lightFighterIcon1->w / 2;
r.y = 340 - lightFighterIcon1->h / 2;
r.w = lightFighterIcon1->w;
r.h = lightFighterIcon1->h;
SDL_BlitSurface( lightFighterIcon1, 0, screen, &r );
} else {
r.x = 100 - heavyFighterIcon1->w / 2;
r.y = 340 - heavyFighterIcon1->h / 2;
r.w = heavyFighterIcon1->w;
r.h = heavyFighterIcon1->h;
SDL_BlitSurface( heavyFighterIcon1, 0, screen, &r );
}
fontHighlighted->drawStr( screen, 100, 400, "Press \"1\"", FONT_ALIGN_CENTERED );
fontHighlighted->drawStr( screen, 100, 430, "To Change", FONT_ALIGN_CENTERED );
SDL_Flip( screen );
}
void MenuArcadeMode::handleEvents( GameStates &gameState ) {
SDL_Event event;
while ( SDL_PollEvent(&event) ) {
switch(event.type) {
case SDL_KEYDOWN: {
switch ( event.key.keysym.sym ) {
case SDLK_1: {
playerOneLightFighter = !playerOneLightFighter;
break;
}
case SDLK_F5: {
videoserver->toggleFullscreen();
break;
}
case SDLK_F7: {
if ( playMusicOn ) {
playMusicOn = false;
mixer.stopMusic();
} else {
playMusicOn = true;
mixer.playMusic( MUSIC_INTRO, -1, 1000 );
}
break;
}
case SDLK_UP: {
mixer.playSample( choose, 0 );
activeChoice--;
if ( activeChoice < 0 ) activeChoice = NR_MENU_ARCADE_CHOICES - 1;
break;
}
case SDLK_DOWN: {
mixer.playSample( choose, 0 );
activeChoice = (activeChoice + 1) % NR_MENU_ARCADE_CHOICES;
break;
}
case SDLK_ESCAPE: {
gameState = GS_INTRO;
break;
}
case SDLK_RETURN: {
switch (activeChoice) {
case ARCADE_FIGHT: {
mixer.playSample( confirm, 0 );
difficultyLevel = ARCADE_DIFFICULTY_LEVEL;
gameState = GS_PLAYON;
break;
}
case ARCADE_BACK_TO_MAIN_MENU: {
gameState = GS_INTRO;
break;
}
}
break;
}
default: break;
}
break;
}
case SDL_QUIT: {
gameState = GS_QUIT;
break;
}
default: break;
}
}
}
/**************** read the new name for the highscore ***********************/
void MenuArcadeMode::updateHighScore( int points ) {
int pointTenth = -1;
op->getInt( "POINTS_10", pointTenth );
// the player made it in the hall of fame!
if ( points >= pointTenth ) {
int pointsOfEntry = -1;
int newPos = -1;
for ( int i = 1; i <= 10; i++ ) {
op->getInt( "POINTS_" + asString( i ), pointsOfEntry );
if ( pointsOfEntry <= points ) {
newPos = i;
break;
}
}
if ( newPos != -1 ) {
// move the positions after newPos one position further down
int pointsPrev;
string namePrev;
for ( int i = 10; i > newPos; i-- ) {
op->getInt( "POINTS_" + asString( i-1 ), pointsPrev );
op->getStr( "NAME_" + asString( i-1 ), namePrev );
op->setInt( pointsPrev, "POINTS_" + asString ( i ) );
op->setStr( namePrev, "NAME_" + asString( i ) );
}
op->setInt( points, "POINTS_" + asString( newPos ) );
op->setStr( "? ? ? ?", "NAME_" + asString( newPos ) );
readHighScoreName( newPos );
}
op->saveFile( FN_HIGHSCORE );
}
}
void MenuArcadeMode::readHighScoreName( int pos ) {
videoserver->clearScreen();
SDL_Rect r;
r.x = screen->w / 2 - arcadeSprite->w / 2;
r.y = 0;
r.w = arcadeSprite->w;
r.h = arcadeSprite->h;
SDL_BlitSurface( arcadeSprite, 0, screen, &r );
string name = "UNKNOWN";
int points = 0;
for ( int i = 1; i <= 10; i++ ) {
op->getStr( "NAME_" + asString( i ), name );
op->getInt( "POINTS_" + asString( i ), points );
if ( pos == i ) {
fontHighlighted->drawStr( screen, 230, 40 + i * 25,
asString( i ) + ". " + name + ": " + asString(points) );
} else {
font->drawStr( screen, 230, 40 + i * 25,
asString( i ) + ". " + name + ": " + asString(points) );
}
}
fontHighlighted->drawStr( screen, 320, 340, "CONGRATULATION - Enter your worthy name!",
FONT_ALIGN_CENTERED );
string newName = "";
while ( handleEventsReadName( newName ) ) {
drawReadName( newName );
SDL_Flip( screen );
SDL_Delay( 50 );
}
op->setStr( newName, "NAME_" + asString( pos ) );
}
bool MenuArcadeMode::handleEventsReadName( string &newName ) {
bool moreToRead = true;
SDL_Event event;
while ( SDL_PollEvent(&event) ) {
if ( event.type == SDL_KEYDOWN ) {
switch ( event.key.keysym.sym ) {
case SDLK_F5: {
videoserver->toggleFullscreen();
break;
}
case SDLK_F7:
{
if ( playMusicOn ) {
playMusicOn = false;
mixer.stopMusic();
} else {
playMusicOn = true;
mixer.playMusic( MUSIC_INTRO, -1, 1000 );
}
break;
}
case SDLK_RETURN:
{
moreToRead = false;
break;
}
case SDLK_BACKSPACE:
{
if ( newName.length() > 0 ) {
newName.resize( newName.length() - 1 );
}
break;
}
default:
{
if ( newName.length() <= 15 ) {
if ( SDLK_a <= event.key.keysym.sym &&
event.key.keysym.sym <= SDLK_z ) {
if ( ((SDL_GetModState()) & KMOD_LSHIFT != 0 ) ||
((SDL_GetModState()) & KMOD_RSHIFT != 0 ) ) {
newName += asString( (char)('A' + event.key.keysym.sym - SDLK_a ) );
} else {
newName += asString( (char)('a' + event.key.keysym.sym - SDLK_a ) );
}
} else if ( event.key.keysym.sym == SDLK_SPACE ) {
newName += " ";
}
}
break;
}
}
}
}
return moreToRead;
}
void MenuArcadeMode::drawReadName( string &name ) {
SDL_Rect r;
r.x = 150;
r.y = 380;
r.w = 400;
r.h = 40;
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0, 0, 0) );
fontHighlighted->drawStr( screen, 320, 380, name, FONT_ALIGN_CENTERED );
}

View File

@@ -0,0 +1,72 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef MENU_ARCADE_MODE_H
#define MENU_ARCADE_MODE_H
#include "SDL.h"
#include "game.h"
#include <string>
class Font;
class Options;
enum MENU_ARCADE_CHOICES { ARCADE_FIGHT, ARCADE_BACK_TO_MAIN_MENU };
const std::string STRINGS_MENU_ARCADE_CHOICES[] =
{ "FIGHT",
"Back to Main Menu" };
const int NR_MENU_ARCADE_CHOICES = 2;
class MenuArcadeMode {
private:
SDL_Surface *screen;
SDL_Surface *arcadeSprite;
SDL_Surface *activeChoiceSprite;
SDL_Surface *lightFighterIcon1;
SDL_Surface *heavyFighterIcon1;
Font *font;
Font *fontHighlighted;
Options *op;
int activeChoice;
// sounds
int choose;
int confirm;
bool playerOneLightFighter;
public:
MenuArcadeMode( SDL_Surface *scr );
~MenuArcadeMode();
void run( GameStates &gameState, int points=-1 );
bool getPlayerOneLightFighter();
private:
void updateHighScore( int points );
void readHighScoreName( int pos );
void drawReadName( string &newName );
bool handleEventsReadName( string &newName );
void handleEvents( GameStates &gameState );
void draw();
};
#endif

View File

@@ -0,0 +1,172 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
using namespace std;
#include "mixer.h"
#include "SDL_mixer.h"
#include <string>
#include <fstream>
#include <iostream>
Mixer mixer;
Mixer::Mixer() {
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
printf("Couldn't initialize SDL audio subsystem: %s\n", SDL_GetError());
exit(1);
}
mixChunks = MixChunks(0);
musics = Musics(0);
enabled = false;
initMixer();
lastUsedReservedChannel = 0;
reservedChannels = 0;
musicPlaying = MUSIC_NONE;
}
Mixer::~Mixer() {
if (enabled) {
freeMixer();
}
}
void Mixer::initMixer() {
enabled = (Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 1, 1024) >= 0);
if (enabled) {
Mix_AllocateChannels(MIXER_NUMBER_CHANNELS);
reservedChannels = Mix_ReserveChannels( MIXER_RESERVED_CHANNELS );
if ( MIXER_RESERVED_CHANNELS != reservedChannels )
cout << "reserve channels not successfull: reserved: " << reservedChannels << endl;
lastUsedReservedChannel = 0;
fn2snd.clear();
fn2mus.clear();
playsOn.clear();
}
}
void Mixer::freeMixer() {
if (enabled) {
Mix_ExpireChannel(-1, 0);
for (unsigned int index = 0; index < mixChunks.size(); index++) {
Mix_FreeChunk(mixChunks[index]);
}
for (unsigned int index = 0; index < musics.size(); index++) {
Mix_FreeMusic(musics[index]);
}
}
}
int Mixer::loadSample(string fileName, int volume) {
if (enabled) {
if (fn2snd.find(fileName) == fn2snd.end()) {
// open the file for reading
ifstream inputFile ( fileName.c_str(), ios::in);
if (!inputFile.good()) {
cout << "ERROR: file " << fileName << " does not exist!" << endl;
exit(1);
}
mixChunks.push_back(Mix_LoadWAV(fileName.c_str()));
fn2snd[ fileName ] = mixChunks.size() - 1;
if ( 0 <= volume && volume < 128 ) {
Mix_VolumeChunk( mixChunks[ mixChunks.size() - 1 ], volume );
}
return mixChunks.size() - 1;
}
return fn2snd[ fileName ];
}
return 0;
}
bool Mixer::playSample( int sampleId, int loop, bool withPriority ) {
int ret = -1;
if (enabled) {
if ( !withPriority || reservedChannels == 0 ) {
ret = Mix_PlayChannel(-1, mixChunks[sampleId], loop);
playsOn[ sampleId ] = ret;
} else {
lastUsedReservedChannel = (lastUsedReservedChannel+1) % reservedChannels;
ret = Mix_PlayChannel( lastUsedReservedChannel, mixChunks[sampleId], loop );
playsOn[ sampleId ] = ret;
}
//if ( ret == -1 ) cout << "playSample: error: " << Mix_GetError() << endl;
return ret != -1;
}
return true;
}
bool Mixer::stopSample(int sampleId) {
if (enabled) {
return Mix_HaltChannel( playsOn[sampleId] ) != -1;
}
return true;
}
void Mixer::reset() {
freeMixer();
if (enabled) {
initMixer();
}
}
void Mixer::fadeOut(int mSecs) {
if (enabled) {
Mix_FadeOutChannel(-1, mSecs);
}
}
int Mixer::loadMusic( string fn ) {
if (enabled) {
if (fn2mus.find(fn) == fn2mus.end()) {
// open the file for reading
ifstream inputFile ( fn.c_str(), ios::in);
if (!inputFile.good()) {
cout << "ERROR: file " << fn << " does not exist!" << endl;
exit(1);
}
musics.push_back(Mix_LoadMUS(fn.c_str()));
fn2mus[ fn ] = musics.size() - 1;
return musics.size() - 1;
}
return fn2mus[ fn ];
}
return 0;
}
void Mixer::playMusic( MusicTracks musNum, int loop, int fadeInTime ) {
if (enabled) {
if ( musNum < NR_MUSIC_TRACKS ) {
Mix_FadeInMusic( musics[ loadMusic( FN_MUSIC[ (int)musNum ] ) ], loop, fadeInTime );
musicPlaying = musNum;
}
}
}
void Mixer::stopMusic( int fadeOutTime ) {
if (enabled) {
Mix_FadeOutMusic( fadeOutTime );
}
}
MusicTracks Mixer::whichMusicPlaying() {
return musicPlaying;
}

View File

@@ -0,0 +1,106 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef MIXER_HH
#define MIXER_HH
#include "SDL.h"
#include "SDL_mixer.h"
#include <vector>
#include <map>
#include <string>
#include "global.h"
typedef vector<Mix_Chunk*> MixChunks;
typedef vector<Mix_Music*> Musics;
class Mixer;
extern Mixer mixer;
const int MIXER_NUMBER_CHANNELS = 32;
// reserved for samples, which should play with priority
const int MIXER_RESERVED_CHANNELS = 8;
class Mixer {
private:
MixChunks mixChunks;
Musics musics;
void initMixer();
void freeMixer();
map< string, int > fn2mus;
map< string, int > fn2snd;
map< int, int > playsOn;
bool enabled;
int reservedChannels;
int lastUsedReservedChannel;
MusicTracks musicPlaying;
public:
Mixer();
~Mixer();
/*
Loads a sample, returns an id used for playSample
0 as a return value indicates an error on loading
param volume: use with care: if the sound is loaded
for the first time, its volumevalue will be set to
volume, else it will be ignored. (0..127)
*/
int loadSample(string fileName, int volume=10);
/*
plays the sample with the given id
if withPriority==true the sample will be played in one of the reserved channels
returns true if successfull, false otherwise
*/
bool playSample(int sampleId, int loop, bool withPriority=false);
bool stopSample(int sampleId);
/*
resets the Mixer (frees all samples and channels, inits new ones).
Use with care:
- samples still playing will be apruptly halted
- keep in mind that there is only one mixer
=> it is resetted globally!!!
*/
void reset();
/*
fades out all channels
*/
void fadeOut(int mSecs);
int loadMusic( string fileName );
void playMusic( MusicTracks musNum, int loop, int fadeInTime=0 );
void stopMusic( int fadeOutTime=0 );
MusicTracks whichMusicPlaying();
static const Mixer mixer();
};
#endif //#define MIXER_HH

View File

@@ -0,0 +1,183 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
using namespace std;
#include "options.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <sstream>
Options::Options(const string lFilename) {
if (lFilename == "") {
cout << "Options: no filename given!" << endl;
filename = string("config");
} else {
// save the filename for later use
filename = lFilename;
}
// open the file for reading
ifstream inputFile (filename.c_str(), ios::in);
// TODO FIXME ordentliches Filelocking machen
// fcntl(inputFile.rdbuf()->fd(), F_SETLKW, fileLock(F_RDLCK));
if (inputFile.good()) {
// while still data there
while (!inputFile.eof()) {
string newLine;
getline( inputFile, newLine );
// search delimiter
unsigned int pos = newLine.find("=");
// comment line or no delimiter found
if (( newLine[0] != '#' ) && ( pos != string::npos )) {
string key = newLine.substr(0,pos);
string val = newLine.substr(pos+1);
keymap[ key ] = val;
}
}
}
else {
cout << "Options: Error while opening " << filename << endl;
}
// TODO FIXME ordentliches Filelocking machen
// fcntl(inputFile.rdbuf()->fd(), F_SETLKW, fileLock(F_UNLCK));
inputFile.close();
// if (inputFile.fail()) {
// cout << "Options: Error while closing " << filename << endl;
// }
}
Options::~Options() {
;
}
// flock* Options::fileLock(const short type) {
// static flock ret ;
// ret.l_type = type ;
// ret.l_start = 0 ;
// ret.l_whence = SEEK_SET ;
// ret.l_len = 0 ;
// ret.l_pid = getpid() ;
// return &ret ;
// }
int Options::saveFile( const string lFilename ) {
// alternative filename given ?
if (lFilename != "") {
filename = lFilename;
}
// delete original options-file
remove(filename.c_str());
ofstream outputFile( filename.c_str(), ios::out );
// TODO FIXME ordentliches Filelocking machen
// fcntl(outputFile.rdbuf()->fd(), F_SETLKW, fileLock(F_WRLCK));
if (outputFile.good()) {
map< string, string >::const_iterator iter;
for(iter = keymap.begin(); iter != keymap.end(); iter++){
outputFile << iter->first << "=" << iter->second << endl;
}
}
else {
cout << "Options::saveFile(): error while opening file " << filename << endl;
return -1;
}
// TODO FIXME ordentliches Filelocking machen
// fcntl(outputFile.rdbuf()->fd(), F_SETLKW, fileLock(F_UNLCK));
outputFile.close();
if (!outputFile.good()) {
cout << "Options::saveFile(): error while closing file " << filename << endl;
return -2;
}
return 0; // everything's fine
}
bool Options::exist(const string keyword) {
return (keymap.find(keyword) != keymap.end());
}
bool Options::getStr(const string keyword, string &val) {
if (exist(keyword)) {
val = keymap[keyword];
return true;
}
return false;
}
bool Options::getInt(const string keyword, int &val) {
if (exist(keyword)) {
val = atoi( keymap[keyword].c_str() );
return true;
}
return false;
}
bool Options::getUInt(const string keyword, unsigned int &val) {
if (exist(keyword)) {
val = atoll( keymap[keyword].c_str() );
return true;
}
return false;
}
bool Options::setStr(const string newValue, const string keyword) {
keymap[keyword] = newValue;
return true;
}
bool Options::setInt(const int newValue, const string keyword) {
keymap[keyword] = asString<int>( newValue );
return true;
}
bool Options::setUInt(const unsigned int newValue, const string keyword) {
keymap[keyword] = asString<unsigned int>( newValue );
return true;
}
void Options::printall() {
map< string, string >::const_iterator iter;
for(iter = keymap.begin(); iter != keymap.end(); iter++){
cout << iter->first << "=" << iter->second << endl;
}
}

View File

@@ -0,0 +1,84 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
/**
* @file Options.h
* @brief The Options-class can manage a configuration file.
* @date 23.06.02
* The Options-class can manage a configuration file of this style:
* KEYWORD=value
* Provides easy-access functions for the keywords.
* $Id: options.h,v 1.2 2003/12/08 18:21:21 schwardt Exp $
*/
#ifndef __OPTIONS_H__
#define __OPTIONS_H__
#include <map>
#include <string>
#include <fstream>
#include <unistd.h>
#include <fcntl.h>
#include "asstring.h"
class Options {
private:
std::map< std::string, std::string > keymap;
std::string filename;
public:
/// Constructor. Reads the configurationfile specified by lFilename.
Options( const std::string lFilename );
/// Destructor. Frees all memory allocated.
~Options();
/// Returns structure used for filelocking
// flock* Options::fileLock(const short type); // FIXME
/// Returns true if the given keyword exist
bool exist(const std::string keyword);
/// Returns the int value of keyword.
/// If keyword is not found returns 0.
bool getInt( const std::string keyword, int &val );
/// Returns the unsigned int value of keyword.
/// If keyword is not found returns 0.
bool getUInt( const std::string keyword, unsigned int &val );
/// Returns a copy of the char* value of keyword.
/// If keyword is not found returns NULL.
bool getStr( const std::string keyword, std::string &val );
/// sets the value of the given keyword to newValue
bool setInt( const int newValue, const std::string keyword );
/// sets the value of the given keyword to newValue
bool setUInt( const unsigned int newValue, const std::string keyword );
/// sets the value of the given keyword to newValue
bool setStr( const std::string newValue, const std::string keyword );
/// Stores the config-File to disk (filename as specified in the constructor).
/// You should call this function after changing a value.
int saveFile( const std::string lFilename );
/// Prints all lines of the actual configuration to cout.
void printall();
};
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,195 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef RACER_HH
#define RACER_HH
#include "SDL.h"
#include "geometry.h"
#include <string>
#include "global.h"
#include "settings.h"
class SurfaceDB;
class Gate;
class Track;
class Shot;
class Shots;
class Items;
class Font;
class BoundingBox;
class ShieldGlow;
/* The Racer is the vehicle, that the player can steer. */
class Racer {
SDL_Surface *spriteRacerBase;
SDL_Rect drawRectBase;
SDL_Surface *spriteShadow;
SDL_Surface *spriteDeflector;
SDL_Rect drawRectDeflector;
SDL_Surface *spriteHPStat;
SDL_Surface *spriteFighterIcon;
// for collision with other racers or shots.
// A rectangle with racersize * 0.9 is used.
BoundingBox *boundingBox;
int playerNr;
int shipType;
Font *font; // font used for displaying ammo and lapcnt
int fontSize;
SDL_Surface *spriteSecondaryWeapons;
SDL_Surface *spriteSpecials;
int sndShotPrimary;
int sndShotSecondary;
float points;
// Movement-System
Vector2D pos; // absolute position
float shipAngle; // the orientation
Vector2D vel; // the velocity vector
// the boundary of the world (i.e. the reachable section of the screen)
RectangleGeo *boundaryRect;
// Weapon-System
ShotTypes primaryShotType;
Uint32 timeLastShotPrimary;
ShotTypes activeSecondary;
Uint32 timeLastShotSecondary;
bool secondaryWeaponsAvailability[ NR_SECONDARY_WEAPONS ];
bool lastDumbfireWasLeft;
SpecialTypes activeSpecial;
int specialsAvailability[ NR_SPECIALS ];
Uint32 timeLastNukeUsed;
Uint32 timeLastHeatseekerUsed;
bool lastHeatseekerWasLeft;
bool deflectorActive;
int deflectorTimeLeft;
// Damage-System
float shield;
float damage;
float pixPerHP;
float maxShield;
float maxDamage;
// not used at the moment:
// returns the maximum reachable velocity.
// if damage < 100 the reachable velocity will be reduced linearly
float getActVelMax();
float maxVel;
// needed for displaying the shield glow, when hit
Uint32 shieldDamageEndTime;
bool shieldDamageActive;
ShieldGlow *shieldGlow;
Uint32 timeLastMove;
void repair( float amount );
bool thrust;
bool backwards;
bool left;
bool right;
bool fireWeapons;
bool useSpecial;
void addBannerItemCollected( BannerTexts text );
public:
// Input-System - which keys are pressed at the moment
void handlePlayerEvent( PlayerEvent pEvent, bool keyDown );
Racer( string fnSprite, int whichPlayer, Vector2D startpos, int newShipType );
~Racer();
bool isDeflectorSpecialActive() { return deflectorActive; }
inline int getPlayerNr() { return playerNr; }
inline int getShipType() { return shipType; }
void setPos( const Vector2D &newPos );
inline Vector2D getPos() { return pos; }
inline Vector2D getVel() { return vel; }
Vector2D setVel( const Vector2D &newVel ); // returns old vel
// moves the racer according to his velocity and the pressed keys.
// Already collides with the boundaryRect (the border of the world)
Vector2D move( int dT );
void clipWorld();
// move the boundingBox accordingly to the movement
void updateBoundingBox();
// fire the Guns!
void shootPrimary();
void shootSecondary();
void shootSpecial();
// switch to the next available weapon
// void switchPrimary();
void switchSecondary();
void switchSpecials();
// use the active special, if it should be used _once_ when keyDown-Event occurs
void specialKeyDown();
// switch special, if the activespecial is out of ammo
void specialKeyUp();
void drawRacer( SDL_Surface *screen );
void drawShadow( SDL_Surface *screen );
void drawStats( SDL_Surface *screen );
// collision system
// return if the line between the two points collides with the boundingBox
bool collidesWith( const Vector2D &shotPosOld, const Vector2D &shotPosNew );
// return if the racers boundingBox overlaps with box
bool collidesWith( BoundingBox *box );
// return if the racers boundingBox overlaps with circle
bool collidesWith( const Circle &circle );
// returns if a inner circle around the racer overlaps with circle
bool collidesWithAsCircle( const Circle &circle );
// returns if a inner circle around the racer overlaps with circle
bool collidesWithAsCircle( BoundingBox *box );
// returns the boundingBox of the racer
BoundingBox *getBoundingBox();
// the racer got hit -> do the damage according to the shotType
void doDamage( ShotTypes shotType );
// recharge the shield
void rechargeShield( int dT );
// the racer was hit
void receiveDamage( float amount );
bool isDead();
void receivePoints( float amount );
// picks up items, if flown over
void pickUpItems();
// returns the number of laps completed by the racer
int getPoints() { return (int)(points + 0.5); }
};
#endif

View File

@@ -0,0 +1,204 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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 <iostream>
#include "racer.h"
#include "racers.h"
#include "shots.h"
#include "items.h"
#include "enemys.h"
#include "enemy.h"
#include "explosions.h"
#include "explosion.h"
#include "global.h"
Racers::Racers() {
pointsInArcadeMode = 0;
}
Racers::~Racers() {
vector<Racer *>::iterator i;
for ( i = racers.begin(); i != racers.end(); ++i ) {
delete *i;
}
}
bool Racers::isShipTypeActive( int shipType ) {
vector<Racer *>::iterator i;
for ( i = racers.begin(); i != racers.end(); ++i ) {
if ( (*i)->getShipType() == shipType ) {
return true;
}
}
return false;
}
Racer *Racers::getRacer( unsigned int i ) {
return racers[i];
}
void Racers::addRacer( Racer *racer ) {
if (racer) {
racers.push_back(racer);
}
}
void Racers::deleteRacers() {
racers.clear();
}
void Racers::collideWithEnemys() {
for ( unsigned int i = 0; i < racers.size(); ++i ) {
for ( unsigned int j = 0; j < enemys->getNrEnemys(); ++j ) {
// wurde noch nicht von einem anderen Racer gerammt und fliegt ebenfalls
if ( !(enemys->getEnemy( j )->isExpired()) &&
ENEMY_FLYING[ enemys->getEnemy( j )->getType() ] ) {
// kollidiert
if ( racers[i]->collidesWithAsCircle( enemys->getEnemy( j )->getBoundingCircle() ) ) {
// explosion
Explosion *newExplosion =
new Explosion( FN_EXPLOSION_ENEMY, enemys->getEnemy( j )->getPos(), enemys->getEnemy( j )->getVel(), EXPLOSION_NORMAL_AIR );
explosions->addExplosion( newExplosion );
enemys->getEnemy( j )->expire();
racers[i]->receiveDamage( ENEMY_COLLISION_DAMAGE[ enemys->getEnemy( j )->getType() ]);
}
}
}
}
}
void Racers::moveAndCollide( int dT ) {
for ( unsigned int i = 0; i < racers.size(); ++i ) {
racers[i]->move( dT );
collideWithEnemys();
}
}
void Racers::pickUpItems() {
vector<Racer *>::iterator i;
for ( i = racers.begin(); i != racers.end(); ++i ) {
(*i)->pickUpItems();
}
}
void Racers::shoot() {
for ( unsigned int i = 0; i < racers.size(); i++ ) {
racers[i]->shootPrimary();
racers[i]->shootSecondary();
racers[i]->shootSpecial();
}
}
void Racers::rechargeShield( int dT ) {
vector<Racer *>::iterator i;
for (i = racers.begin(); i != racers.end(); ++i) {
(*i)->rechargeShield( dT );
}
}
void Racers::drawRacers( SDL_Surface *screen ) {
vector<Racer *>::iterator i;
for (i = racers.begin(); i != racers.end(); ++i) {
(*i)->drawRacer(screen);
}
}
void Racers::drawShadows( SDL_Surface *screen ) {
vector<Racer *>::iterator i;
for (i = racers.begin(); i != racers.end(); ++i) {
(*i)->drawShadow(screen);
}
}
void Racers::drawStats( SDL_Surface *screen ) {
vector<Racer *>::iterator i;
for (i = racers.begin(); i != racers.end(); ++i) {
(*i)->drawStats(screen);
}
}
bool Racers::bothPlayersLost() {
bool allLost = true;
for ( unsigned int i = 0; i < racers.size(); ++i) {
if ( !racers[i]->isDead() ) {
allLost = false;
}
}
return allLost;
}
void Racers::receivePointsArcade( float amount ) {
for ( unsigned int i = 0; i < racers.size(); ++i) {
racers[i]->receivePoints( amount );
}
}
int Racers::getPointsArcadeMode() {
if (!arcadeGame) return -1;
if (!racers.empty()) {
return racers[0]->getPoints();
}
else return pointsInArcadeMode;
}
void Racers::expireRacers() {
unsigned int i = 0;
while ( i < racers.size() ) {
if ( racers[i]->isDead() ) {
// explode
Explosion *newExplosion =
new Explosion( FN_EXPLOSION_ENEMY, racers[i]->getPos(),
racers[i]->getVel(), EXPLOSION_NORMAL_AIR );
explosions->addExplosion( newExplosion );
if ( arcadeGame ) pointsInArcadeMode = racers[i]->getPoints();
delete racers[i];
racers.erase(racers.begin() + i);
} else {
i++;
}
}
}
void Racers::getKeyActionMaps() {
playerKeys0 = settings->getPlayerKeys( 0 );
playerKeys1 = settings->getPlayerKeys( 1 );
}
void Racers::handleEvent( const SDLKey key, const bool pressed ) {
PlayerEvent pEvent0 = playerKeys0[ key ];
if ( pEvent0 != PE_UNKNOWN ) {
handlePlayerEvent( pEvent0, 0, pressed );
}
PlayerEvent pEvent1 = playerKeys1[ key ];
if ( pEvent1 != PE_UNKNOWN ) {
handlePlayerEvent( pEvent1, 1, pressed );
}
}
void Racers::handlePlayerEvent( PlayerEvent pEvent, int playerNr, bool keyDown ) {
for ( unsigned int i = 0; i < racers.size(); i++ )
if ( racers[i]->getPlayerNr() == playerNr )
racers[i]->handlePlayerEvent( pEvent, keyDown );
}

View File

@@ -0,0 +1,92 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef RACER_H
#define RACER_H
#include <vector>
#include "SDL.h"
#include "settings.h"
class Racer;
class Shots;
class Items;
class Enemys;
class Explosions;
/* A class, that manages the individual racers.
It is used for everything, that the racers are capable of doing.
*/
class Racers {
vector<Racer *> racers;
// points reached by racer 0 in arcade mode
int pointsInArcadeMode;
void collideWithEnemys();
PlayerKeys playerKeys0;
PlayerKeys playerKeys1;
public:
Racers();
~Racers();
bool isShipTypeActive( int shipType );
void addRacer( Racer *racer );
void deleteRacers();
Racer *getRacer(unsigned int i);
unsigned int getNrRacers() { return racers.size(); }
// Moves the racers. Calculates collisions between the racers and
// collisions between a racer and enemies.
void moveAndCollide( int dT );
// Checks if a racer has picked up an item by flying over it.
void pickUpItems();
// Checks if a racer was at his pitstop and is being repaired.
// void repair( PitStops *pitStops );
// Lets the racers shoot, if they want to.
void shoot();
// recharge the shields
void rechargeShield( int dT );
// draws the racers.
void drawRacers( SDL_Surface *screen );
void drawShadows( SDL_Surface *screen );
void drawStats( SDL_Surface *screen );
// returns, which racer has shot more enemys
//int getWinner();
void expireRacers();
bool bothPlayersLost();
void receivePointsArcade( float amount );
int getPointsArcadeMode();
void getKeyActionMaps();
void handleEvent( const SDLKey key, const bool pressed );
private:
void handlePlayerEvent( PlayerEvent pEvent, int playerNr, bool keyDown );
};
#endif

View File

@@ -0,0 +1,236 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
using namespace std;
#include "setDifficulty.h"
#include "global.h"
#include "surfaceDB.h"
#include "mixer.h"
#include "video.h"
#include "font.h"
#include "settings.h"
#include "racer.h"
#include "racers.h"
SetDifficulty::SetDifficulty( SDL_Surface *scr ) {
screen = scr;
introSprite = surfaceDB.loadSurface( FN_ALIENBLASTER_INTRO );
activeChoiceSprite = surfaceDB.loadSurface( FN_INTRO_SHOW_CHOICE );
font = new Font( FN_FONT_INTRO );
fontHighlighted = new Font( FN_FONT_INTRO_HIGHLIGHTED );
lightFighterIcon1 = surfaceDB.loadSurface( FN_LIGHT_FIGHTER_1_ICON );
lightFighterIcon2 = surfaceDB.loadSurface( FN_LIGHT_FIGHTER_2_ICON );
heavyFighterIcon1 = surfaceDB.loadSurface( FN_HEAVY_FIGHTER_1_ICON );
heavyFighterIcon2 = surfaceDB.loadSurface( FN_HEAVY_FIGHTER_2_ICON );
choose = mixer.loadSample( FN_SOUND_INTRO_CHOOSE, 100 );
confirm = mixer.loadSample( FN_SOUND_INTRO_CONFIRM, 100 );
activeChoice = 0;
playerOneLightFighter = true;
playerTwoLightFighter = false;
}
SetDifficulty::~SetDifficulty() {}
void SetDifficulty::run( GameStates &gameState, bool onePlayerGame ) {
activeChoice = 0;
SetDifficulty::onePlayerGame = onePlayerGame;
draw();
while ( gameState == GS_SET_DIFFICULTY ) {
handleEvents( gameState );
draw();
SDL_Delay( 50 );
}
}
bool SetDifficulty::getPlayerOneLightFighter() {
return playerOneLightFighter;
}
bool SetDifficulty::getPlayerTwoLightFighter() {
return playerTwoLightFighter;
}
void SetDifficulty::draw() {
videoserver->clearScreen();
SDL_Rect r;
r.x = screen->w / 2 - introSprite->w / 2;
r.y = 0;
r.w = introSprite->w;
r.h = introSprite->h;
SDL_BlitSurface( introSprite, 0, screen, &r );
for ( int i = 0; i < NR_DIFFICULTY_CHOICES; i++ ) {
if( activeChoice == i ) {
r.x = 230 - activeChoiceSprite->w - 8;
r.y = 258 + i * 40;
r.w = activeChoiceSprite->w;
r.h = activeChoiceSprite->h;
SDL_BlitSurface( activeChoiceSprite, 0, screen, &r );
fontHighlighted->drawStr( screen, 230, 260 + i * 40, SET_DIFFICULTY_CHOICES[ i ] );
} else {
font->drawStr( screen, 230, 260 + i * 40, SET_DIFFICULTY_CHOICES[ i ] );
}
if( onePlayerGame ) {
font->drawStr( screen, 20, 20, "1-Player" );
font->drawStr( screen, 100, 270, "Player 1", FONT_ALIGN_CENTERED );
if ( playerOneLightFighter ) {
r.x = 100 - lightFighterIcon1->w / 2;
r.y = 340 - lightFighterIcon1->h / 2;
r.w = lightFighterIcon1->w;
r.h = lightFighterIcon1->h;
SDL_BlitSurface( lightFighterIcon1, 0, screen, &r );
} else {
r.x = 100 - heavyFighterIcon1->w / 2;
r.y = 340 - heavyFighterIcon1->h / 2;
r.w = heavyFighterIcon1->w;
r.h = heavyFighterIcon1->h;
SDL_BlitSurface( heavyFighterIcon1, 0, screen, &r );
}
fontHighlighted->drawStr( screen, 100, 400, "Press \"1\"", FONT_ALIGN_CENTERED );
fontHighlighted->drawStr( screen, 100, 430, "To Change", FONT_ALIGN_CENTERED );
}
else {
font->drawStr( screen, 20, 20, "2-Player" );
font->drawStr( screen, 100, 270, "Player 1", FONT_ALIGN_CENTERED );
if ( playerOneLightFighter ) {
r.x = 100 - lightFighterIcon1->w / 2;
r.y = 340 - lightFighterIcon1->h / 2;
r.w = lightFighterIcon1->w;
r.h = lightFighterIcon1->h;
SDL_BlitSurface( lightFighterIcon1, 0, screen, &r );
} else {
r.x = 100 - heavyFighterIcon1->w / 2;
r.y = 340 - heavyFighterIcon1->h / 2;
r.w = heavyFighterIcon1->w;
r.h = heavyFighterIcon1->h;
SDL_BlitSurface( heavyFighterIcon1, 0, screen, &r );
}
fontHighlighted->drawStr( screen, 100, 400, "Press \"1\"", FONT_ALIGN_CENTERED );
fontHighlighted->drawStr( screen, 100, 430, "To Change", FONT_ALIGN_CENTERED );
font->drawStr( screen, 560, 270, "Player 2", FONT_ALIGN_CENTERED );
if ( playerTwoLightFighter ) {
r.x = 560 - lightFighterIcon1->w / 2;
r.y = 340 - lightFighterIcon1->h / 2;
r.w = lightFighterIcon2->w;
r.h = lightFighterIcon2->h;
SDL_BlitSurface( lightFighterIcon2, 0, screen, &r );
} else {
r.x = 560 - heavyFighterIcon1->w / 2;
r.y = 340 - heavyFighterIcon1->h / 2;
r.w = heavyFighterIcon2->w;
r.h = heavyFighterIcon2->h;
SDL_BlitSurface( heavyFighterIcon2, 0, screen, &r );
}
fontHighlighted->drawStr( screen, 560, 400, "Press \"2\"", FONT_ALIGN_CENTERED );
fontHighlighted->drawStr( screen, 560, 430, "To Change", FONT_ALIGN_CENTERED );
}
}
SDL_Flip( screen );
}
void SetDifficulty::handleEvents( GameStates &gameState ) {
SDL_Event event;
while ( SDL_PollEvent(&event) ) {
switch(event.type) {
case SDL_KEYDOWN: {
switch ( event.key.keysym.sym ) {
case SDLK_1: {
playerOneLightFighter = !playerOneLightFighter;
break;
}
case SDLK_2: {
playerTwoLightFighter = !playerTwoLightFighter;
break;
}
case SDLK_F5: {
SDL_WM_ToggleFullScreen( screen );
break;
}
case SDLK_F7: {
if ( playMusicOn ) {
playMusicOn = false;
mixer.stopMusic();
} else {
playMusicOn = true;
mixer.playMusic( MUSIC_INTRO, -1, 1000 );
}
break;
}
case SDLK_UP: {
mixer.playSample( choose, 0 );
activeChoice--;
if ( activeChoice < 0 ) activeChoice = NR_DIFFICULTY_CHOICES - 1;
break;
}
case SDLK_DOWN: {
mixer.playSample( choose, 0 );
activeChoice = (activeChoice + 1) % NR_DIFFICULTY_CHOICES;
break;
}
case SDLK_ESCAPE: {
gameState = GS_INTRO;
break;
}
case SDLK_RETURN: {
mixer.playSample( confirm, 0 );
switch (activeChoice) {
case DIFFICULTY_0: {
difficultyLevel = 0;
gameState = GS_PLAYON;
break;
}
case DIFFICULTY_1: {
difficultyLevel = 1;
gameState = GS_PLAYON;
break;
}
case DIFFICULTY_2: {
difficultyLevel = 2;
gameState = GS_PLAYON;
break;
}
case DIFFICULTY_3: {
difficultyLevel = 3;
gameState = GS_PLAYON;
break;
}
case BACK_TO_MAIN_MENU: {
gameState = GS_INTRO;
break;
}
}
break;
}
default: break;
}
break;
}
case SDL_QUIT: {
gameState = GS_QUIT;
break;
}
default: break;
}
}
}

View File

@@ -0,0 +1,70 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef SET_DIFFICULTY_H
#define SET_DIFFICULTY_H
#include "SDL.h"
#include "game.h"
#include <string>
class Font;
enum DIFFICULTY_CHOICES { DIFFICULTY_0, DIFFICULTY_1, DIFFICULTY_2, DIFFICULTY_3,
BACK_TO_MAIN_MENU };
const std::string SET_DIFFICULTY_CHOICES[] =
{ "Easy Going", "Let's Rock",
"Kick Some Ass", "Argh...",
"Back to Main Menu" };
const int NR_DIFFICULTY_CHOICES = 5;
class SetDifficulty {
private:
SDL_Surface *screen;
SDL_Surface *introSprite;
SDL_Surface *activeChoiceSprite;
SDL_Surface *lightFighterIcon1;
SDL_Surface *lightFighterIcon2;
SDL_Surface *heavyFighterIcon1;
SDL_Surface *heavyFighterIcon2;
Font *font;
Font *fontHighlighted;
int activeChoice;
bool onePlayerGame;
bool playerOneLightFighter;
bool playerTwoLightFighter;
// sounds
int confirm;
int choose;
public:
SetDifficulty( SDL_Surface *scr );
~SetDifficulty();
void run( GameStates &gameState, bool onePlayerGame );
bool getPlayerOneLightFighter();
bool getPlayerTwoLightFighter();
private:
void handleEvents( GameStates &gameState );
void draw();
};
#endif

View File

@@ -0,0 +1,685 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
using namespace std;
#include <cassert>
#include <string>
#include <map>
#include "SDL.h"
#include "options.h"
#include "settings.h"
#include "global.h"
#include "surfaceDB.h"
#include "asstring.h"
#include "font.h"
#include "video.h"
#include "mixer.h"
#include "input.h"
Settings *settings;
Settings::Settings() {
opfile = NULL;
introSprite = surfaceDB.loadSurface( FN_ALIENBLASTER_INTRO );
activeChoiceSprite = surfaceDB.loadSurface( FN_INTRO_SHOW_CHOICE );
bluePlain = surfaceDB.loadSurface( FN_SETTINGS_BLUE, true );
whitePlain = surfaceDB.loadSurface( FN_SETTINGS_WHITE, false );
fontMenu = new Font ( FN_FONT_SETTINGS );
fontMenuHighlighted = new Font ( FN_FONT_SETTINGS_HIGHLIGHTED );
fontNormal = new Font( FN_FONT_SETTINGS_SMALL );
fontKey = new Font ( FN_FONT_SETTINGS_SMALL_BLUE );
fontHighlighted = new Font( FN_FONT_SETTINGS_SMALL_HIGHLIGHTED );
playerEventNames[ PE_UNKNOWN ] = "UNKNOWN";
playerEventNames[ PE_UP ] = "UP";
playerEventNames[ PE_DOWN ] = "DOWN";
playerEventNames[ PE_LEFT ] = "LEFT";
playerEventNames[ PE_RIGHT ] = "RIGHT";
playerEventNames[ PE_FIRE_WEAPONS ] = "FIRE";
playerEventNames[ PE_FIRE_SPECIALS ] = "FIRE-SPECIAL";
playerEventNames[ PE_CHOOSE_WEAPON_SECONDARY ] = "CHOOSE-WEAPON";
playerEventNames[ PE_CHOOSE_WEAPON_SPECIALS ] = "CHOOSE-SPECIALS";
defaultSettings[ string("PLAYER0-") + playerEventNames[ PE_UP ] ] = SDLK_UP;
defaultSettings[ string("PLAYER0-") + playerEventNames[ PE_DOWN ] ] = SDLK_DOWN;
defaultSettings[ string("PLAYER0-") + playerEventNames[ PE_LEFT ] ] = SDLK_LEFT;
defaultSettings[ string("PLAYER0-") + playerEventNames[ PE_RIGHT ] ] = SDLK_RIGHT;
defaultSettings[ string("PLAYER0-") + playerEventNames[ PE_CHOOSE_WEAPON_SECONDARY ] ] = SDLK_RSHIFT;
defaultSettings[ string("PLAYER0-") + playerEventNames[ PE_CHOOSE_WEAPON_SPECIALS ] ] = SDLK_PERIOD;
defaultSettings[ string("PLAYER0-") + playerEventNames[ PE_FIRE_WEAPONS ] ] = SDLK_RCTRL;
defaultSettings[ string("PLAYER0-") + playerEventNames[ PE_FIRE_SPECIALS ] ] = SDLK_MODE;
defaultSettings[ string("PLAYER1-") + playerEventNames[ PE_UP ] ] = SDLK_e;
defaultSettings[ string("PLAYER1-") + playerEventNames[ PE_DOWN ] ] = SDLK_d;
defaultSettings[ string("PLAYER1-") + playerEventNames[ PE_LEFT ] ] = SDLK_s;
defaultSettings[ string("PLAYER1-") + playerEventNames[ PE_RIGHT ] ] = SDLK_f;
defaultSettings[ string("PLAYER1-") + playerEventNames[ PE_CHOOSE_WEAPON_SECONDARY ] ] = SDLK_LSHIFT;
defaultSettings[ string("PLAYER1-") + playerEventNames[ PE_CHOOSE_WEAPON_SPECIALS ] ] = SDLK_y;
defaultSettings[ string("PLAYER1-") + playerEventNames[ PE_FIRE_WEAPONS ] ] = SDLK_LCTRL;
defaultSettings[ string("PLAYER1-") + playerEventNames[ PE_FIRE_SPECIALS ] ] = SDLK_LALT;
setKeyNames();
loadSettings();
}
Settings::~Settings() {
if (fontKey) delete fontKey;
if (fontHighlighted) delete fontHighlighted;
if (fontNormal) delete fontNormal;
if (fontMenu) delete fontMenu;
if (opfile) delete opfile;
}
void Settings::loadSettings() {
bool restoredSettings = false;
if (opfile) {
delete opfile;
}
opfile = new Options( FN_SETTINGS );
playerKeys.clear();
for(int i=0; i < MAX_PLAYER_CNT; ++i) {
PlayerEventKeys pk;
for(int t=1; t < PlayerEventCnt; ++t) {
int key;
string keyname = string("PLAYER") + asString(i) + "-" + playerEventNames[(PlayerEvent)t];
if (!opfile->getInt( keyname , key)) {
key = defaultSettings[ keyname ];
restoredSettings = true;
}
pk[ (PlayerEvent)t ] = (SDLKey)key;
}
playerKeys.push_back(pk);
}
if (restoredSettings) {
saveSettings();
}
}
void Settings::saveSettings() {
for(int i=0; i < MAX_PLAYER_CNT; ++i) {
string name;
for(int t=1; t < PlayerEventCnt; ++t) {
opfile->setInt( (int)playerKeys[i][ (PlayerEvent)t ],
string("PLAYER") + asString(i) + "-" + playerEventNames[(PlayerEvent)t] );
}
}
if (opfile) {
opfile->saveFile( FN_SETTINGS );
}
}
void Settings::draw( SDL_Surface *screen, bool getNewKey ) {
videoserver->clearScreen();
SDL_Rect r;
r.x = screen->w / 2 - introSprite->w / 2;
r.y = 0;
r.w = introSprite->w;
r.h = introSprite->h;
SDL_BlitSurface( introSprite, 0, screen, &r );
showSpecialKeys( screen );
showSettings( screen, getNewKey );
showMenu( screen );
SDL_Flip( screen );
}
void Settings::showSpecialKeys( SDL_Surface *screen ) {
fontNormal->drawStr(screen, screen->w/2, screen->h - 2*fontNormal->getCharHeight() - 10,
"F1: Configure Keys F5: Fullscreen", FONT_ALIGN_CENTERED );
fontNormal->drawStr(screen, screen->w/2, screen->h - fontNormal->getCharHeight() - 5,
"F6: Display Enemy Stats F7: Toggle Music F10: Pause Game",
FONT_ALIGN_CENTERED );
}
void Settings::showSettings( SDL_Surface *screen, bool getNewKey ) {
int playerOfActiveItem = -1;
if ( actChoice <= SC_FIRE_SPEC_1 ) playerOfActiveItem = 0;
else if ( actChoice <= SC_FIRE_SPEC_2 ) playerOfActiveItem = 1;
int activePlayerEvent = actChoice - (8*playerOfActiveItem) + 1;
SDL_Rect r;
SDL_Rect srcDesc;
srcDesc.x = 0;
srcDesc.y = 0;
srcDesc.w = 155;
srcDesc.h = 14;
SDL_Rect srcKey;
srcKey.x = 0;
srcKey.y = 0;
srcKey.w = 100;
srcKey.h = 14;
int i = 150;
fontHighlighted->drawStr( screen, 15, i - fontHighlighted->getCharHeight() - 5, "Player 1" );
fontHighlighted->drawStr( screen, screen->w/2 + 5, i - fontHighlighted->getCharHeight() - 5,
"Player 2" );
std::map< PlayerEvent, SDLKey >::const_iterator pkiter;
for ( pkiter = playerKeys[0].begin(); pkiter != playerKeys[0].end(); ++pkiter ) {
if ( !(playerOfActiveItem == 0 && pkiter->first == activePlayerEvent) ) {
r.x = 15;
r.y = i - 1;
SDL_BlitSurface(bluePlain, &srcDesc, screen, &r );
fontNormal->drawStr( screen, 20, i, playerEventNames[ pkiter->first ] + ":" );
r.x = 175;
r.y = i-1;
SDL_BlitSurface(bluePlain, &srcKey, screen, &r );
fontNormal->drawStr( screen, 270, i, keyName[ pkiter->second ], FONT_ALIGN_RIGHT );
}
if ( !(playerOfActiveItem == 1 && pkiter->first == activePlayerEvent) ) {
r.x = screen->w/2 + 5;
r.y = i - 1;
SDL_BlitSurface(bluePlain, &srcDesc, screen, &r );
fontNormal->drawStr( screen, screen->w/2 + 10, i,
playerEventNames[ pkiter->first ] + ":" );
r.x = screen->w/2 + 165;
r.y = i-1;
SDL_BlitSurface(bluePlain, &srcKey, screen, &r );
fontNormal->drawStr( screen, screen->w/2 + 260, i,
keyName[ playerKeys[1][pkiter->first] ], FONT_ALIGN_RIGHT );
}
if ( playerOfActiveItem == 0 && pkiter->first == activePlayerEvent ) {
r.x = 15;
r.y = i - 1;
SDL_BlitSurface(bluePlain, &srcDesc, screen, &r );
fontNormal->drawStr( screen, 20, i, playerEventNames[ pkiter->first ] + ":" );
r.x = 175;
r.y = i-1;
SDL_BlitSurface(whitePlain, &srcKey, screen, &r );
if (!getNewKey) {
fontHighlighted->drawStr( screen, 270, i, keyName[ pkiter->second ], FONT_ALIGN_RIGHT );
}
}
if ( playerOfActiveItem == 1 && pkiter->first == activePlayerEvent ) {
r.x = screen->w/2 + 5;
r.y = i - 1;
SDL_BlitSurface(bluePlain, &srcDesc, screen, &r );
fontNormal->drawStr( screen, screen->w/2 + 10, i,
playerEventNames[ pkiter->first ] + ":" );
r.x = screen->w/2 + 165;
r.y = i-1;
SDL_BlitSurface(whitePlain, &srcKey, screen, &r );
if (!getNewKey) {
fontHighlighted->drawStr( screen, screen->w/2 + 260, i,
keyName[ playerKeys[1][pkiter->first] ], FONT_ALIGN_RIGHT );
}
}
i = i + fontNormal->getCharHeight() + 5;
}
}
void Settings::showMenu( SDL_Surface *screen ) {
SDL_Rect r;
r.x = 230 - activeChoiceSprite->w - 8;
r.w = activeChoiceSprite->w;
r.h = activeChoiceSprite->h;
if ( actChoice == SC_DEFAULTS ) {
r.y = 328;
SDL_BlitSurface(activeChoiceSprite, 0, screen, &r );
fontMenuHighlighted->drawStr( screen, 230, 330, "Reset Defaults" );
} else fontMenu->drawStr( screen, 230, 330, "Reset Defaults" );
if ( actChoice == SC_CANCEL ) {
r.y = 363;
SDL_BlitSurface(activeChoiceSprite, 0, screen, &r );
fontMenuHighlighted->drawStr( screen, 230, 365, "Cancel" );
} else fontMenu->drawStr( screen, 230, 365, "Cancel" );
if ( actChoice == SC_FINISH ) {
r.y = 398;
SDL_BlitSurface(activeChoiceSprite, 0, screen, &r );
fontMenuHighlighted->drawStr( screen, 230, 400, "Finish" );
} else fontMenu->drawStr( screen, 230, 400, "Finish" );
}
void Settings::settingsDialog( SDL_Surface *screen ) {
bool run = true;
actChoice = SC_FINISH;
wasLeftColumn = true;
draw( screen );
while(run) {
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch(event.type) {
case SDL_KEYDOWN: {
switch(event.key.keysym.sym) {
case SDLK_UP: {
if ( actChoice == SC_DEFAULTS ) {
if ( wasLeftColumn ) actChoice = SC_FIRE_SPEC_1;
else actChoice = SC_FIRE_SPEC_2;
} else if ( actChoice == SC_UP2 || actChoice == SC_UP1 ) {
actChoice = SC_FINISH;
} else {
actChoice = (SettingsChoices)(actChoice - 1);
}
break;
}
case SDLK_DOWN: {
if ( actChoice == SC_FINISH ) {
if ( wasLeftColumn ) actChoice = SC_UP1;
else actChoice = SC_UP2;
} else if ( actChoice == SC_FIRE_SPEC_1 ) {
actChoice = SC_DEFAULTS;
} else {
actChoice = (SettingsChoices)(actChoice + 1);
}
break;
}
case SDLK_RIGHT: {
if (actChoice <= SC_FIRE_SPEC_1) {
actChoice = (SettingsChoices)(actChoice + 8);
wasLeftColumn = false;
}
break;
}
case SDLK_LEFT: {
if ( SC_UP2 <= actChoice && actChoice <= SC_FIRE_SPEC_2 ) {
actChoice = (SettingsChoices)(actChoice - 8);
wasLeftColumn = true;
}
break;
}
case SDLK_TAB: {
if ( SC_UP1 <= actChoice && actChoice <= SC_FIRE_SPEC_1 ) {
actChoice = (SettingsChoices)(actChoice + 8);
wasLeftColumn = false;
} else {
if ( SC_UP2 <= actChoice && actChoice <= SC_FIRE_SPEC_2 ) {
actChoice = (SettingsChoices)(actChoice - 8);
wasLeftColumn = true;
}
}
break;
}
case SDLK_RETURN:
case SDLK_SPACE: {
if ( actChoice == SC_DEFAULTS ) {
loadDefaultSettings();
} else if ( actChoice == SC_CANCEL ) {
run = false;
loadSettings();
} else if ( actChoice == SC_FINISH ) {
run = false;
saveSettings();
} else {
draw( screen, true );
getNewKeyFromUser();
}
break;
}
case SDLK_F5: {
videoserver->toggleFullscreen();
break;
}
case SDLK_F7: {
if ( playMusicOn ) {
playMusicOn = false;
mixer.stopMusic();
} else {
playMusicOn = true;
mixer.playMusic( MUSIC_INTRO, -1, 1000 );
}
break;
}
case SDLK_ESCAPE: {
run = false;
loadDefaultSettings();
break;
}
default: break;
}
}
}
draw( screen );
SDL_Delay( 50 ); // save cpu-power
}
}
}
void Settings::loadDefaultSettings() {
playerKeys.clear();
for(int i=0; i < MAX_PLAYER_CNT; ++i) {
PlayerEventKeys pk;
for(int t=1; t < PlayerEventCnt; ++t) {
int key;
string keyname = string("PLAYER") + asString(i) + "-" + playerEventNames[(PlayerEvent)t];
key = defaultSettings[ keyname ];
pk[ (PlayerEvent)t ] = (SDLKey)key;
}
playerKeys.push_back(pk);
}
}
void Settings::getNewKeyFromUser() {
SDL_Event event;
bool keypressed = false;
while( !keypressed ) {
while (!SDL_PollEvent(&event)) {}
switch(event.type) {
case SDL_KEYDOWN:
case SDL_JOYBUTTONDOWN:
case SDL_JOYAXISMOTION: {
if (input.isPressed(event)) {
int player = (actChoice >= SC_UP2) ? 1 : 0;
playerKeys[player][ (PlayerEvent)(actChoice - (player * 8) + 1) ] =
input.translate(event);
keypressed = true;
}
break;
}
}
}
}
const PlayerKeys Settings::getPlayerKeys(unsigned int player) const {
assert( player < playerKeys.size() );
PlayerKeys pk;
for(int i=SDLK_FIRST; i <= SDLK_LAST; ++i) {
pk[ (SDLKey)i ] = PE_UNKNOWN;
}
std::map< PlayerEvent, SDLKey >::const_iterator pkiter;
for(pkiter = playerKeys[player].begin(); pkiter != playerKeys[player].end(); ++pkiter) {
pk[ pkiter->second ] = pkiter->first;
}
return pk;
}
void Settings::setKeyNames() {
keyName[ (SDLKey)0 ] = "UNKNOWN";
keyName[ (SDLKey)8 ] = "BACKSPACE";
keyName[ (SDLKey)9 ] = "TAB";
keyName[ (SDLKey)12 ] = "CLEAR";
keyName[ (SDLKey)13 ] = "RETURN";
keyName[ (SDLKey)19 ] = "PAUSE";
keyName[ (SDLKey)27 ] = "ESCAPE";
keyName[ (SDLKey)32 ] = "SPACE";
keyName[ (SDLKey)33 ] = "EXCLAIM";
keyName[ (SDLKey)34 ] = "QUOTEDBL";
keyName[ (SDLKey)35 ] = "HASH";
keyName[ (SDLKey)36 ] = "DOLLAR";
keyName[ (SDLKey)38 ] = "AMPERSAND";
keyName[ (SDLKey)39 ] = "QUOTE";
keyName[ (SDLKey)40 ] = "LEFTPAREN";
keyName[ (SDLKey)41 ] = "RIGHTPAREN";
keyName[ (SDLKey)42 ] = "ASTERISK";
keyName[ (SDLKey)43 ] = "PLUS";
keyName[ (SDLKey)44 ] = "COMMA";
keyName[ (SDLKey)45 ] = "MINUS";
keyName[ (SDLKey)46 ] = "PERIOD";
keyName[ (SDLKey)47 ] = "SLASH";
keyName[ (SDLKey)48 ] = "0";
keyName[ (SDLKey)49 ] = "1";
keyName[ (SDLKey)50 ] = "2";
keyName[ (SDLKey)51 ] = "3";
keyName[ (SDLKey)52 ] = "4";
keyName[ (SDLKey)53 ] = "5";
keyName[ (SDLKey)54 ] = "6";
keyName[ (SDLKey)55 ] = "7";
keyName[ (SDLKey)56 ] = "8";
keyName[ (SDLKey)57 ] = "9";
keyName[ (SDLKey)58 ] = "COLON";
keyName[ (SDLKey)59 ] = "SEMICOLON";
keyName[ (SDLKey)60 ] = "LESS";
keyName[ (SDLKey)61 ] = "EQUALS";
keyName[ (SDLKey)62 ] = "GREATER";
keyName[ (SDLKey)63 ] = "QUESTION";
keyName[ (SDLKey)64 ] = "AT";
keyName[ (SDLKey)91 ] = "LEFTBRACKET";
keyName[ (SDLKey)92 ] = "BACKSLASH";
keyName[ (SDLKey)93 ] = "RIGHTBRACKET";
keyName[ (SDLKey)94 ] = "CARET";
keyName[ (SDLKey)95 ] = "UNDERSCORE";
keyName[ (SDLKey)96 ] = "BACKQUOTE";
keyName[ (SDLKey)97 ] = "a";
keyName[ (SDLKey)98 ] = "b";
keyName[ (SDLKey)99 ] = "c";
keyName[ (SDLKey)100 ] = "d";
keyName[ (SDLKey)101 ] = "e";
keyName[ (SDLKey)102 ] = "f";
keyName[ (SDLKey)103 ] = "g";
keyName[ (SDLKey)104 ] = "h";
keyName[ (SDLKey)105 ] = "i";
keyName[ (SDLKey)106 ] = "j";
keyName[ (SDLKey)107 ] = "k";
keyName[ (SDLKey)108 ] = "l";
keyName[ (SDLKey)109 ] = "m";
keyName[ (SDLKey)110 ] = "n";
keyName[ (SDLKey)111 ] = "o";
keyName[ (SDLKey)112 ] = "p";
keyName[ (SDLKey)113 ] = "q";
keyName[ (SDLKey)114 ] = "r";
keyName[ (SDLKey)115 ] = "s";
keyName[ (SDLKey)116 ] = "t";
keyName[ (SDLKey)117 ] = "u";
keyName[ (SDLKey)118 ] = "v";
keyName[ (SDLKey)119 ] = "w";
keyName[ (SDLKey)120 ] = "x";
keyName[ (SDLKey)121 ] = "y";
keyName[ (SDLKey)122 ] = "z";
keyName[ (SDLKey)127 ] = "DELETE";
keyName[ (SDLKey)160 ] = "WORLD_0";
keyName[ (SDLKey)161 ] = "WORLD_1";
keyName[ (SDLKey)162 ] = "WORLD_2";
keyName[ (SDLKey)163 ] = "WORLD_3";
keyName[ (SDLKey)164 ] = "WORLD_4";
keyName[ (SDLKey)165 ] = "WORLD_5";
keyName[ (SDLKey)166 ] = "WORLD_6";
keyName[ (SDLKey)167 ] = "WORLD_7";
keyName[ (SDLKey)168 ] = "WORLD_8";
keyName[ (SDLKey)169 ] = "WORLD_9";
keyName[ (SDLKey)170 ] = "WORLD_10";
keyName[ (SDLKey)171 ] = "WORLD_11";
keyName[ (SDLKey)172 ] = "WORLD_12";
keyName[ (SDLKey)173 ] = "WORLD_13";
keyName[ (SDLKey)174 ] = "WORLD_14";
keyName[ (SDLKey)175 ] = "WORLD_15";
keyName[ (SDLKey)176 ] = "WORLD_16";
keyName[ (SDLKey)177 ] = "WORLD_17";
keyName[ (SDLKey)178 ] = "WORLD_18";
keyName[ (SDLKey)179 ] = "WORLD_19";
keyName[ (SDLKey)180 ] = "WORLD_20";
keyName[ (SDLKey)181 ] = "WORLD_21";
keyName[ (SDLKey)182 ] = "WORLD_22";
keyName[ (SDLKey)183 ] = "WORLD_23";
keyName[ (SDLKey)184 ] = "WORLD_24";
keyName[ (SDLKey)185 ] = "WORLD_25";
keyName[ (SDLKey)186 ] = "WORLD_26";
keyName[ (SDLKey)187 ] = "WORLD_27";
keyName[ (SDLKey)188 ] = "WORLD_28";
keyName[ (SDLKey)189 ] = "WORLD_29";
keyName[ (SDLKey)190 ] = "WORLD_30";
keyName[ (SDLKey)191 ] = "WORLD_31";
keyName[ (SDLKey)192 ] = "WORLD_32";
keyName[ (SDLKey)193 ] = "WORLD_33";
keyName[ (SDLKey)194 ] = "WORLD_34";
keyName[ (SDLKey)195 ] = "WORLD_35";
keyName[ (SDLKey)196 ] = "WORLD_36";
keyName[ (SDLKey)197 ] = "WORLD_37";
keyName[ (SDLKey)198 ] = "WORLD_38";
keyName[ (SDLKey)199 ] = "WORLD_39";
keyName[ (SDLKey)200 ] = "WORLD_40";
keyName[ (SDLKey)201 ] = "WORLD_41";
keyName[ (SDLKey)202 ] = "WORLD_42";
keyName[ (SDLKey)203 ] = "WORLD_43";
keyName[ (SDLKey)204 ] = "WORLD_44";
keyName[ (SDLKey)205 ] = "WORLD_45";
keyName[ (SDLKey)206 ] = "WORLD_46";
keyName[ (SDLKey)207 ] = "WORLD_47";
keyName[ (SDLKey)208 ] = "WORLD_48";
keyName[ (SDLKey)209 ] = "WORLD_49";
keyName[ (SDLKey)210 ] = "WORLD_50";
keyName[ (SDLKey)211 ] = "WORLD_51";
keyName[ (SDLKey)212 ] = "WORLD_52";
keyName[ (SDLKey)213 ] = "WORLD_53";
keyName[ (SDLKey)214 ] = "WORLD_54";
keyName[ (SDLKey)215 ] = "WORLD_55";
keyName[ (SDLKey)216 ] = "WORLD_56";
keyName[ (SDLKey)217 ] = "WORLD_57";
keyName[ (SDLKey)218 ] = "WORLD_58";
keyName[ (SDLKey)219 ] = "WORLD_59";
keyName[ (SDLKey)220 ] = "WORLD_60";
keyName[ (SDLKey)221 ] = "WORLD_61";
keyName[ (SDLKey)222 ] = "WORLD_62";
keyName[ (SDLKey)223 ] = "WORLD_63";
keyName[ (SDLKey)224 ] = "WORLD_64";
keyName[ (SDLKey)225 ] = "WORLD_65";
keyName[ (SDLKey)226 ] = "WORLD_66";
keyName[ (SDLKey)227 ] = "WORLD_67";
keyName[ (SDLKey)228 ] = "WORLD_68";
keyName[ (SDLKey)229 ] = "WORLD_69";
keyName[ (SDLKey)230 ] = "WORLD_70";
keyName[ (SDLKey)231 ] = "WORLD_71";
keyName[ (SDLKey)232 ] = "WORLD_72";
keyName[ (SDLKey)233 ] = "WORLD_73";
keyName[ (SDLKey)234 ] = "WORLD_74";
keyName[ (SDLKey)235 ] = "WORLD_75";
keyName[ (SDLKey)236 ] = "WORLD_76";
keyName[ (SDLKey)237 ] = "WORLD_77";
keyName[ (SDLKey)238 ] = "WORLD_78";
keyName[ (SDLKey)239 ] = "WORLD_79";
keyName[ (SDLKey)240 ] = "WORLD_80";
keyName[ (SDLKey)241 ] = "WORLD_81";
keyName[ (SDLKey)242 ] = "WORLD_82";
keyName[ (SDLKey)243 ] = "WORLD_83";
keyName[ (SDLKey)244 ] = "WORLD_84";
keyName[ (SDLKey)245 ] = "WORLD_85";
keyName[ (SDLKey)246 ] = "WORLD_86";
keyName[ (SDLKey)247 ] = "WORLD_87";
keyName[ (SDLKey)248 ] = "WORLD_88";
keyName[ (SDLKey)249 ] = "WORLD_89";
keyName[ (SDLKey)250 ] = "WORLD_90";
keyName[ (SDLKey)251 ] = "WORLD_91";
keyName[ (SDLKey)252 ] = "WORLD_92";
keyName[ (SDLKey)253 ] = "WORLD_93";
keyName[ (SDLKey)254 ] = "WORLD_94";
keyName[ (SDLKey)255 ] = "WORLD_95";
keyName[ (SDLKey)256 ] = "KP0";
keyName[ (SDLKey)257 ] = "KP1";
keyName[ (SDLKey)258 ] = "KP2";
keyName[ (SDLKey)259 ] = "KP3";
keyName[ (SDLKey)260 ] = "KP4";
keyName[ (SDLKey)261 ] = "KP5";
keyName[ (SDLKey)262 ] = "KP6";
keyName[ (SDLKey)263 ] = "KP7";
keyName[ (SDLKey)264 ] = "KP8";
keyName[ (SDLKey)265 ] = "KP9";
keyName[ (SDLKey)266 ] = "KP_PERIOD";
keyName[ (SDLKey)267 ] = "KP_DIVIDE";
keyName[ (SDLKey)268 ] = "KP_MULTIPLY";
keyName[ (SDLKey)269 ] = "KP_MINUS";
keyName[ (SDLKey)270 ] = "KP_PLUS";
keyName[ (SDLKey)271 ] = "KP_ENTER";
keyName[ (SDLKey)272 ] = "KP_EQUALS";
keyName[ (SDLKey)273 ] = "UP";
keyName[ (SDLKey)274 ] = "DOWN";
keyName[ (SDLKey)275 ] = "RIGHT";
keyName[ (SDLKey)276 ] = "LEFT";
keyName[ (SDLKey)277 ] = "INSERT";
keyName[ (SDLKey)278 ] = "HOME";
keyName[ (SDLKey)279 ] = "END";
keyName[ (SDLKey)280 ] = "PAGEUP";
keyName[ (SDLKey)281 ] = "PAGEDOWN";
keyName[ (SDLKey)282 ] = "F1";
keyName[ (SDLKey)283 ] = "F2";
keyName[ (SDLKey)284 ] = "F3";
keyName[ (SDLKey)285 ] = "F4";
keyName[ (SDLKey)286 ] = "F5";
keyName[ (SDLKey)287 ] = "F6";
keyName[ (SDLKey)288 ] = "F7";
keyName[ (SDLKey)289 ] = "F8";
keyName[ (SDLKey)290 ] = "F9";
keyName[ (SDLKey)291 ] = "F10";
keyName[ (SDLKey)292 ] = "F11";
keyName[ (SDLKey)293 ] = "F12";
keyName[ (SDLKey)294 ] = "F13";
keyName[ (SDLKey)295 ] = "F14";
keyName[ (SDLKey)296 ] = "F15";
keyName[ (SDLKey)300 ] = "NUMLOCK";
keyName[ (SDLKey)301 ] = "CAPSLOCK";
keyName[ (SDLKey)302 ] = "SCROLLOCK";
keyName[ (SDLKey)303 ] = "RSHIFT";
keyName[ (SDLKey)304 ] = "LSHIFT";
keyName[ (SDLKey)305 ] = "RCTRL";
keyName[ (SDLKey)306 ] = "LCTRL";
keyName[ (SDLKey)307 ] = "RALT";
keyName[ (SDLKey)308 ] = "LALT";
keyName[ (SDLKey)309 ] = "RMETA";
keyName[ (SDLKey)310 ] = "LMETA";
keyName[ (SDLKey)311 ] = "LSUPER";
keyName[ (SDLKey)312 ] = "RSUPER";
keyName[ (SDLKey)313 ] = "MODE";
keyName[ (SDLKey)314 ] = "COMPOSE";
keyName[ (SDLKey)315 ] = "HELP";
keyName[ (SDLKey)316 ] = "PRINT";
keyName[ (SDLKey)317 ] = "SYSREQ";
keyName[ (SDLKey)318 ] = "BREAK";
keyName[ (SDLKey)319 ] = "MENU";
keyName[ (SDLKey)320 ] = "POWER";
keyName[ (SDLKey)321 ] = "EURO";
keyName[ (SDLKey)322 ] = "UNDO";
// the following entries are chosen by us... just for the mapping
keyName[ (SDLKey)1024 ] = "GPD1_L";
keyName[ (SDLKey)1025 ] = "GPD1_R";
keyName[ (SDLKey)1026 ] = "GPD1_U";
keyName[ (SDLKey)1027 ] = "GPD1_D";
keyName[ (SDLKey)1028 ] = "GPD2_L";
keyName[ (SDLKey)1029 ] = "GPD2_R";
keyName[ (SDLKey)1030 ] = "GPD2_U";
keyName[ (SDLKey)1031 ] = "GPD2_D";
keyName[ (SDLKey)1032 ] = "GPD3_L";
keyName[ (SDLKey)1033 ] = "GPD3_R";
keyName[ (SDLKey)1034 ] = "GPD3_U";
keyName[ (SDLKey)1035 ] = "GPD3_D";
keyName[ (SDLKey)1036 ] = "GPD4_L";
keyName[ (SDLKey)1037 ] = "GPD4_R";
keyName[ (SDLKey)1038 ] = "GPD4_U";
keyName[ (SDLKey)1039 ] = "GPD4_D";
keyName[ (SDLKey)1040 ] = "GPB_0";
keyName[ (SDLKey)1041 ] = "GPB_1";
keyName[ (SDLKey)1042 ] = "GPB_2";
keyName[ (SDLKey)1043 ] = "GPB_3";
keyName[ (SDLKey)1044 ] = "GPB_4";
keyName[ (SDLKey)1045 ] = "GPB_5";
keyName[ (SDLKey)1046 ] = "GPB_6";
keyName[ (SDLKey)1047 ] = "GPB_7";
keyName[ (SDLKey)1048 ] = "GPB_8";
keyName[ (SDLKey)1049 ] = "GPB_9";
keyName[ (SDLKey)1050 ] = "GPB_10";
keyName[ (SDLKey)1051 ] = "GPB_11";
keyName[ (SDLKey)1052 ] = "GPB_12";
keyName[ (SDLKey)1053 ] = "GPB_13";
keyName[ (SDLKey)1054 ] = "GPB_14";
keyName[ (SDLKey)1055 ] = "GPB_15";
}

View File

@@ -0,0 +1,96 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef _SETTINGS_H_
#define _SETTINGS_H_
#include <string>
#include <map>
#include <vector>
#include "SDL.h"
class Font;
class Options;
enum PlayerEvent { PE_UNKNOWN = 0, PE_UP, PE_DOWN, PE_LEFT, PE_RIGHT,
PE_CHOOSE_WEAPON_SECONDARY, PE_CHOOSE_WEAPON_SPECIALS,
PE_FIRE_WEAPONS, PE_FIRE_SPECIALS };
const int PlayerEventCnt = 9;
enum SettingsChoices { SC_UP1 = 0, SC_DOWN1, SC_LEFT1, SC_RIGHT1,
SC_CHOOSE_WEAP_SEC_1, SC_CHOOSE_WEAP_SPEC_1,
SC_FIRE_WEAP_1, SC_FIRE_SPEC_1,
SC_UP2, SC_DOWN2, SC_LEFT2, SC_RIGHT2,
SC_CHOOSE_WEAP_SEC_2, SC_CHOOSE_WEAP_SPEC_2,
SC_FIRE_WEAP_2, SC_FIRE_SPEC_2,
SC_DEFAULTS, SC_CANCEL, SC_FINISH };
const int NR_SETTINGS_CHOICES = 19;
typedef std::map< PlayerEvent, SDLKey > PlayerEventKeys;
typedef std::map< SDLKey, PlayerEvent > PlayerKeys;
typedef std::map< PlayerEvent, std::string > PlayerEventName;
typedef std::map< std::string, SDLKey > DefaultSettings;
class Settings;
extern Settings *settings;
class Settings {
public:
Settings();
~Settings();
void settingsDialog(SDL_Surface *screen);
const PlayerKeys getPlayerKeys(unsigned int player) const;
private:
SDL_Surface *introSprite;
SDL_Surface *activeChoiceSprite;
SDL_Surface *bluePlain;
SDL_Surface *whitePlain;
SettingsChoices actChoice;
bool wasLeftColumn;
Options *opfile;
Font *fontMenu;
Font *fontMenuHighlighted;
Font *fontNormal;
Font *fontKey;
Font *fontHighlighted;
std::vector< PlayerEventKeys > playerKeys;
std::map< SDLKey, std::string > keyName;
PlayerEventName playerEventNames;
DefaultSettings defaultSettings;
void getNewKeyFromUser();
void loadDefaultSettings();
void loadSettings();
void saveSettings();
void draw( SDL_Surface *screen, bool getNewKey=false );
void showSpecialKeys( SDL_Surface *screen );
void showSettings( SDL_Surface *screen, bool getNewKey );
void showMenu( SDL_Surface *screen );
void changeCurrentSettings(SDL_Surface *screen, int player);
void setKeyNames();
};
#endif

View File

@@ -0,0 +1,62 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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 "shieldGlow.h"
#include "surfaceDB.h"
ShieldGlow::ShieldGlow( ShipTypes shipType ) {
switch ( shipType ) {
case LIGHT_FIGHTER:
{
spriteShieldGlow = surfaceDB.loadSurface( FN_LIGHT_FIGHTER_SHIELD_DAMAGED, true );
break;
}
case HEAVY_FIGHTER:
{
spriteShieldGlow = surfaceDB.loadSurface( FN_HEAVY_FIGHTER_SHIELD_DAMAGED, true );
break;
}
}
nrFrames = spriteShieldGlow->w / spriteShieldGlow->h;
timePerFrame = RACER_SHIELD_DAMAGE_LIFETIME / nrFrames;
frameWidth = spriteShieldGlow->w / nrFrames;
halfFrameWidth = frameWidth / 2;
halfFrameHeight = spriteShieldGlow->h / 2;
}
ShieldGlow::~ShieldGlow() {}
void ShieldGlow::draw( SDL_Surface *screen, Vector2D pos, int time ) {
if ( time < 0 || RACER_SHIELD_DAMAGE_LIFETIME < time ) return;
int actFrame = time / timePerFrame;
SDL_Rect src, dest;
src.x = actFrame*frameWidth;
src.y = 0;
src.w = frameWidth;
src.h = spriteShieldGlow->h;
dest.x = lroundf(pos.getX()) - halfFrameWidth;
dest.y = lroundf(pos.getY()) - halfFrameHeight;
dest.w = frameWidth;
dest.h = spriteShieldGlow->h;
SDL_BlitSurface( spriteShieldGlow, &src, screen, &dest );
}

View File

@@ -0,0 +1,43 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef SHIELD_GLOW_H
#define SHIELD_GLOW_H
#include "SDL.h"
#include "geometry.h"
#include "global.h"
class ShieldGlow {
SDL_Surface *spriteShieldGlow;
int nrFrames;
int frameWidth;
int halfFrameWidth;
int halfFrameHeight;
int timePerFrame;
public:
ShieldGlow( ShipTypes shipType );
~ShieldGlow();
void draw( SDL_Surface *screen, Vector2D drawPos, int time );
};
#endif

View File

@@ -0,0 +1,857 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
using namespace std;
#include <iostream>
#include "shot.h"
#include "surfaceDB.h"
#include "racers.h"
#include "racer.h"
#include "explosions.h"
#include "explosion.h"
#include "enemys.h"
#include "enemy.h"
#include "smokePuffs.h"
#include "boundingBox.h"
Shot::Shot( ShotTypes shotType, int playerNr, Vector2D position, float angle ) {
this->shotType = shotType;
fromWhichPlayer = playerNr;
pos = position;
collidedWithGround = false;
deflectedBySonicFromPlayer1 = false;
deflectedBySonicFromPlayer2 = false;
generatesSmokePuffs = false;
timeToNextSmokePuff = 100;
switch (shotType) {
// primary shots
case SHOT_NORMAL:
{
vel = Vector2D( VEL_SHOT_NORMAL, angle, POLAR);
timeToLive = LIFETIME_SHOT_NORMAL;
sprite = surfaceDB.loadSurface( FN_SHOT_NORMAL );
break;
}
case SHOT_NORMAL_HEAVY:
{
vel = Vector2D( VEL_SHOT_NORMAL_HEAVY, angle, POLAR);
timeToLive = LIFETIME_SHOT_NORMAL_HEAVY;
sprite = surfaceDB.loadSurface( FN_SHOT_NORMAL_HEAVY );
break;
}
case SHOT_DOUBLE:
{
vel = Vector2D(VEL_SHOT_DOUBLE, angle, POLAR);
timeToLive = LIFETIME_SHOT_DOUBLE;
sprite = surfaceDB.loadSurface( FN_SHOT_DOUBLE );
break;
}
case SHOT_DOUBLE_HEAVY:
{
vel = Vector2D(VEL_SHOT_DOUBLE_HEAVY, angle, POLAR);
timeToLive = LIFETIME_SHOT_DOUBLE_HEAVY;
sprite = surfaceDB.loadSurface( FN_SHOT_DOUBLE_HEAVY );
break;
}
case SHOT_TRIPLE:
{
vel = Vector2D(VEL_SHOT_TRIPLE, angle, POLAR);
timeToLive = LIFETIME_SHOT_TRIPLE;
sprite = surfaceDB.loadSurface( FN_SHOT_TRIPLE );
break;
}
// primary shots heavy fighter
case SHOT_HF_NORMAL:
{
vel = Vector2D( VEL_SHOT_HF_NORMAL, angle, POLAR);
timeToLive = LIFETIME_SHOT_HF_NORMAL;
sprite = surfaceDB.loadSurface( FN_SHOT_HF_NORMAL );
break;
}
case SHOT_HF_DOUBLE:
{
vel = Vector2D( VEL_SHOT_HF_DOUBLE, angle, POLAR);
timeToLive = LIFETIME_SHOT_HF_DOUBLE;
sprite = surfaceDB.loadSurface( FN_SHOT_HF_DOUBLE );
break;
}
case SHOT_HF_TRIPLE:
{
vel = Vector2D(VEL_SHOT_HF_TRIPLE, angle, POLAR);
timeToLive = LIFETIME_SHOT_HF_TRIPLE;
sprite = surfaceDB.loadSurface( FN_SHOT_HF_TRIPLE );
break;
}
case SHOT_HF_QUATTRO:
{
vel = Vector2D(VEL_SHOT_HF_QUATTRO, angle, POLAR);
timeToLive = LIFETIME_SHOT_HF_QUATTRO;
sprite = surfaceDB.loadSurface( FN_SHOT_HF_QUATTRO );
break;
}
case SHOT_HF_QUINTO:
{
vel = Vector2D(VEL_SHOT_HF_QUINTO, angle, POLAR);
timeToLive = LIFETIME_SHOT_HF_QUINTO;
sprite = surfaceDB.loadSurface( FN_SHOT_HF_QUINTO );
break;
}
// secondary shots
case SHOT_DUMBFIRE:
{
vel = Vector2D(VEL_SHOT_DUMBFIRE, angle, POLAR);
timeToLive = LIFETIME_SHOT_DUMBFIRE;
sprite = surfaceDB.loadSurface( FN_SHOT_DUMBFIRE );
generatesSmokePuffs = true;
break;
}
case SHOT_DUMBFIRE_DOUBLE:
{
vel = Vector2D(VEL_SHOT_DUMBFIRE_DOUBLE, angle, POLAR);
timeToLive = LIFETIME_SHOT_DUMBFIRE_DOUBLE;
sprite = surfaceDB.loadSurface( FN_SHOT_DUMBFIRE_DOUBLE );
generatesSmokePuffs = true;
break;
}
case SHOT_KICK_ASS_ROCKET:
{
vel = Vector2D(VEL_SHOT_KICK_ASS_ROCKET, angle, POLAR);
timeToLive = LIFETIME_SHOT_KICK_ASS_ROCKET;
sprite = surfaceDB.loadSurface( FN_SHOT_KICK_ASS_ROCKET );
spriteShadow = surfaceDB.loadSurface( FN_SHOT_KICK_ASS_ROCKET_SHADOW, true );
break;
}
case SHOT_HELLFIRE:
{
vel = Vector2D(VEL_SHOT_HELLFIRE / 2.0, angle, POLAR);
timeToLive = LIFETIME_SHOT_HELLFIRE;
sprite = surfaceDB.loadSurface( FN_SHOT_HELLFIRE );
spriteShadow = surfaceDB.loadSurface( FN_SHOT_HELLFIRE_SHADOW, true );
generatesSmokePuffs = true;
break;
}
case SHOT_MACHINE_GUN:
{
vel = Vector2D(VEL_SHOT_MACHINE_GUN, angle, POLAR);
timeToLive = LIFETIME_SHOT_MACHINE_GUN;
sprite = surfaceDB.loadSurface( FN_SHOT_MACHINE_GUN );
break;
}
case SHOT_ENERGY_BEAM:
{
vel = Vector2D(VEL_SHOT_ENERGY_BEAM, angle, POLAR);
timeToLive = LIFETIME_SHOT_ENERY_BEAM;
sprite = surfaceDB.loadSurface( FN_SHOT_ENERGY_BEAM, true );
break;
}
// secondary shots heavy fighter
case SHOT_HF_DUMBFIRE:
{
vel = Vector2D(VEL_SHOT_HF_DUMBFIRE, angle, POLAR);
timeToLive = LIFETIME_SHOT_HF_DUMBFIRE;
sprite = surfaceDB.loadSurface( FN_SHOT_HF_DUMBFIRE );
generatesSmokePuffs = true;
break;
}
case SHOT_HF_DUMBFIRE_DOUBLE:
{
vel = Vector2D(VEL_SHOT_HF_DUMBFIRE_DOUBLE, angle, POLAR);
timeToLive = LIFETIME_SHOT_HF_DUMBFIRE_DOUBLE;
sprite = surfaceDB.loadSurface( FN_SHOT_HF_DUMBFIRE_DOUBLE );
generatesSmokePuffs = true;
break;
}
case SHOT_HF_KICK_ASS_ROCKET:
{
vel = Vector2D(VEL_SHOT_HF_KICK_ASS_ROCKET, angle, POLAR);
timeToLive = LIFETIME_SHOT_HF_KICK_ASS_ROCKET;
sprite = surfaceDB.loadSurface( FN_SHOT_HF_KICK_ASS_ROCKET );
spriteShadow = surfaceDB.loadSurface( FN_SHOT_HF_KICK_ASS_ROCKET_SHADOW, true );
break;
}
case SHOT_HF_LASER:
{
vel = Vector2D(VEL_SHOT_HF_LASER, angle, POLAR);
timeToLive = LIFETIME_SHOT_HF_LASER;
sprite = surfaceDB.loadSurface( FN_SHOT_HF_LASER );
break;
}
// special shots
case SPECIAL_SHOT_HEATSEEKER:
{
vel = Vector2D(VEL_SPECIAL_SHOT_HEATSEEKER, angle, POLAR);
timeToLive = LIFETIME_SPECIAL_SHOT_HEATSEEKER;
sprite = surfaceDB.loadSurface( FN_SPECIAL_SHOT_HEATSEEKER );
generatesSmokePuffs = true;
break;
}
case SPECIAL_SHOT_NUKE:
{
vel = Vector2D( VEL_SPECIAL_SHOT_NUKE, angle, POLAR );
timeToLive = LIFETIME_SPECIAL_SHOT_NUKE;
sprite = surfaceDB.loadSurface( FN_SPECIAL_SHOT_NUKE );
spriteShadow = surfaceDB.loadSurface( FN_SPECIAL_SHOT_NUKE_SHADOW, true );
break;
}
// enemy shots
case ENEMY_SHOT_NORMAL:
{
vel = Vector2D(VEL_ENEMY_SHOT_NORMAL, angle, POLAR);
timeToLive = LIFETIME_ENEMY_SHOT_NORMAL;
sprite = surfaceDB.loadSurface( FN_ENEMY_SHOT_NORMAL );
break;
}
case ENEMY_SHOT_TANK_ROCKET:
{
vel = Vector2D(VEL_ENEMY_SHOT_TANK_ROCKET, angle, POLAR);
timeToLive = LIFETIME_ENEMY_SHOT_TANK_ROCKET;
sprite = surfaceDB.loadSurface( FN_ENEMY_SHOT_TANK_ROCKET );
spriteShadow = surfaceDB.loadSurface( FN_ENEMY_SHOT_TANK_ROCKET_SHADOW, true );
generatesSmokePuffs = true;
break;
}
default:
{
vel = Vector2D(0,0);
timeToLive = 0;
sprite = surfaceDB.loadSurface( FN_SHOT_NORMAL );
break;
}
}
}
void Shot::moveAndCollide( int dT ) {
if ( fromWhichPlayer == 666 ) {
moveAndCollideEnemyShot( dT );
} else {
moveAndCollidePlayerShot( dT );
}
generateSmokePuff( dT );
timeToLive -= dT;
}
void Shot::moveAndCollidePlayerShot( int dT ) {
Vector2D posOld = pos;
// move the shot
movePlayerShot( dT );
if ( !isExpired() && collidePlayerShot( posOld ) ) {
addExplosion();
}
}
void Shot::movePlayerShot( int dT ) {
switch (shotType) {
case SHOT_NORMAL:
case SHOT_NORMAL_HEAVY:
case SHOT_DOUBLE:
case SHOT_DOUBLE_HEAVY:
case SHOT_TRIPLE:
case SHOT_HF_NORMAL:
case SHOT_HF_DOUBLE:
case SHOT_HF_TRIPLE:
case SHOT_HF_QUATTRO:
case SHOT_HF_QUINTO:
case SHOT_DUMBFIRE:
case SHOT_DUMBFIRE_DOUBLE:
case SHOT_KICK_ASS_ROCKET:
case SHOT_MACHINE_GUN:
case SHOT_ENERGY_BEAM:
case SHOT_HF_DUMBFIRE:
case SHOT_HF_DUMBFIRE_DOUBLE:
case SHOT_HF_KICK_ASS_ROCKET:
case SHOT_HF_LASER:
{
pos = pos + vel * dT / 1000.0;
break;
}
case SHOT_HELLFIRE:
{
pos = pos + vel * dT / 1000.0;
if ( timeToLive < LIFETIME_SHOT_HELLFIRE - 100 ) {
vel = Vector2D( 0, -VEL_SHOT_HELLFIRE );
}
break;
}
case SPECIAL_SHOT_HEATSEEKER:
{
pos = pos + vel * dT / 1000.0;
if ( timeToLive >= LIFETIME_SPECIAL_SHOT_HEATSEEKER - 200 ) break;
int idxNearestEnemy = 0;
float distNearest = 10000;
for ( unsigned int i = 0; i < enemys->getNrEnemys(); i++ ) {
// vector from the shotPosition to the enemy
Vector2D v = enemys->getEnemy(i)->getPos() - pos;
if ( getAbsAngleDifference( vel.getDirection(), v.getDirection() ) < 180 ) {
float dist = (enemys->getEnemy(i)->getPos() - pos).getLength();
if ( dist < distNearest ) {
distNearest = dist;
idxNearestEnemy = i;
}
}
}
if ( distNearest != 10000 ) {
float angle =
getAngleDifference( (enemys->getEnemy(idxNearestEnemy)->getPos()-pos).getDirection(),
vel.getDirection() );
if ( fabs(angle) < 80 * dT / 1000.0 ) {
vel.rotate(angle);
} else if ( angle < 0 ) {
vel.rotate( -80 * dT / 1000.0 );
} else {
vel.rotate( 80 * dT / 1000.0 );
}
}
break;
}
case SPECIAL_SHOT_NUKE:
{
pos = pos + vel * dT / 1000.0;
// Nuke is in its place!
if ( (pos - Vector2D( SCREEN_WIDTH / 2.0, SCREEN_HEIGHT / 2.0 )).getLength()
<= (vel * dT / 1000.0).getLength() ) {
nukeIsInPlace = true;
}
break;
}
default:
{
cout << "movePlayerShot: unexpected shotType: " << shotType << endl;
break;
}
}
// clip at the outside of the window
if ( !RectangleGeo( Vector2D( -SHOT_SCREEN_BORDER, -SHOT_SCREEN_BORDER ),
Vector2D( SCREEN_WIDTH + SHOT_SCREEN_BORDER,
SCREEN_HEIGHT + SHOT_SCREEN_BORDER )).isInside(pos) ) {
timeToLive = 0;
}
}
bool Shot::collidePlayerShot( Vector2D posOld ) {
switch (shotType) {
// only against air
case SHOT_ENERGY_BEAM:
{
BoundingBox box( lroundf(posOld.getX()) - sprite->w / 2,
lroundf(pos.getY()) - sprite->w / 2,
sprite->w,
lroundf((posOld-pos).getY()) + sprite->h );
for ( unsigned int i = 0; i < enemys->getNrEnemys(); i++ ) {
if ( ENEMY_FLYING[ enemys->getEnemy(i)->getType() ] &&
enemys->getEnemy(i)->collidesWith( &box ) ) {
enemys->getEnemy(i)->doDamage( shotType, fromWhichPlayer );
timeToLive = 0;
collidedWithGround = !ENEMY_FLYING[ enemys->getEnemy(i)->getType() ];
return true;
}
}
break;
}
//only against air
case SHOT_HF_LASER:
{
for ( unsigned int i = 0; i < enemys->getNrEnemys(); i++ ) {
if ( ENEMY_FLYING[ enemys->getEnemy(i)->getType() ] &&
enemys->getEnemy(i)->collidesWith( posOld, pos ) ) {
enemys->getEnemy(i)->doDamage( shotType, fromWhichPlayer );
timeToLive = 0;
collidedWithGround = false;
return true;
}
}
break;
}
// against air and ground
case SHOT_NORMAL:
case SHOT_NORMAL_HEAVY:
case SHOT_DOUBLE:
case SHOT_DOUBLE_HEAVY:
case SHOT_TRIPLE:
case SHOT_HF_NORMAL:
case SHOT_HF_DOUBLE:
case SHOT_HF_TRIPLE:
case SHOT_HF_QUATTRO:
case SHOT_HF_QUINTO:
{
for ( unsigned int i = 0; i < enemys->getNrEnemys(); i++ ) {
if ( //ENEMY_FLYING[ enemys->getEnemy(i)->getType() ] &&
enemys->getEnemy(i)->collidesWith( posOld, pos ) ) {
enemys->getEnemy(i)->doDamage( shotType, fromWhichPlayer );
timeToLive = 0;
collidedWithGround = !ENEMY_FLYING[ enemys->getEnemy(i)->getType() ];
return true;
}
}
break;
}
// against air and ground
case SHOT_DUMBFIRE:
case SHOT_DUMBFIRE_DOUBLE:
case SHOT_HF_DUMBFIRE:
case SHOT_HF_DUMBFIRE_DOUBLE:
{
for ( unsigned int i = 0; i < enemys->getNrEnemys(); i++ ) {
if ( enemys->getEnemy(i)->collidesWith( Circle(pos, 15) ) ) {
enemys->getEnemy(i)->doDamage( shotType, fromWhichPlayer );
timeToLive = 0;
collidedWithGround = !ENEMY_FLYING[ enemys->getEnemy(i)->getType() ];
return true;
}
}
break;
}
// only against ground
case SHOT_KICK_ASS_ROCKET:
case SHOT_HF_KICK_ASS_ROCKET:
{
for ( unsigned int i = 0; i < enemys->getNrEnemys(); i++ ) {
if ( (!ENEMY_FLYING[ enemys->getEnemy(i)->getType() ]) &&
enemys->getEnemy(i)->collidesWith( Circle(pos, 15) ) ) {
enemys->getEnemy(i)->doDamage( shotType, fromWhichPlayer );
timeToLive = 0;
collidedWithGround = true;
return true;
}
}
break;
}
// only against ground, but has to hit more exactly than kickAssRocket
case SHOT_HELLFIRE:
{
for ( unsigned int i = 0; i < enemys->getNrEnemys(); i++ ) {
if ( (!ENEMY_FLYING[ enemys->getEnemy(i)->getType() ]) &&
enemys->getEnemy(i)->collidesWith( Circle(pos, 5) ) ) {
enemys->getEnemy(i)->doDamage( shotType, fromWhichPlayer );
timeToLive = 0;
collidedWithGround = true;
return true;
}
}
break;
}
// against air and ground
case SHOT_MACHINE_GUN:
{
for ( unsigned int i = 0; i < enemys->getNrEnemys(); i++ ) {
if ( enemys->getEnemy(i)->collidesWith( posOld, pos ) ) {
enemys->getEnemy(i)->doDamage( shotType, fromWhichPlayer );
timeToLive = 0;
collidedWithGround = !ENEMY_FLYING[ enemys->getEnemy(i)->getType() ];
return true;
}
}
break;
}
// against air and ground
case SPECIAL_SHOT_HEATSEEKER:
{
for ( unsigned int i = 0; i < enemys->getNrEnemys(); i++ ) {
if ( enemys->getEnemy(i)->collidesWith( Circle(pos, 5) ) ) {
enemys->getEnemy(i)->doDamage( shotType, fromWhichPlayer );
timeToLive = 0;
collidedWithGround = !ENEMY_FLYING[ enemys->getEnemy(i)->getType() ];
return true;
}
}
break;
}
case SPECIAL_SHOT_NUKE: break;
default:
{
cout << "collidePlayerShot: unexpected shotType: " << shotType << endl;
return false;
}
}
return false;
}
///////////////////////////
void Shot::moveAndCollideEnemyShot( int dT ) {
Vector2D posOld = pos;
moveEnemyShot( dT );
if ( !isExpired() && collideEnemyShot( posOld ) ) {
addExplosion();
}
}
void Shot::moveEnemyShot( int dT ) {
switch (shotType) {
case ENEMY_SHOT_NORMAL: {
// is this shot near the deflector of a racer?
for ( unsigned int i = 0; i < racers->getNrRacers(); i++) {
if ( racers->getRacer(i)->getShipType() == HEAVY_FIGHTER ) {
Vector2D racerToShot = pos - racers->getRacer(i)->getPos();
if ( racerToShot.getLength() < RACER_DEFLECTOR_ACTIVATION_DIST ) {
vel += Vector2D( RACER_DEFLECTOR_POWER * (dT / 1000.0),
racerToShot.getDirection(), POLAR );
}
if ( racers->getRacer(i)->isDeflectorSpecialActive() ) {
if ( racerToShot.getLength() < ITEM_DEFLECTOR_ACTIVATION_DIST ) {
vel += Vector2D( ITEM_DEFLECTOR_POWER * (dT / 1000.0),
racerToShot.getDirection(), POLAR );
}
}
}
}
pos = pos + vel * dT / 1000.0;
break;
}
case ENEMY_SHOT_TANK_ROCKET: {
if ( deflectedBySonicFromPlayer1 ) {
Vector2D racerToShot = pos - racers->getRacer(0)->getPos();
if ( racerToShot.getLength() < RACER_SONIC_ACTIVATION_DIST ) {
vel += Vector2D( RACER_SONIC_POWER * (dT / 1000.0),
racerToShot.getDirection(), POLAR );
deflectedBySonicFromPlayer1 = false;
}
}
if ( deflectedBySonicFromPlayer2 ) {
Vector2D racerToShot = pos - racers->getRacer(1)->getPos();
if ( racerToShot.getLength() < RACER_SONIC_ACTIVATION_DIST ) {
vel += Vector2D( RACER_SONIC_POWER * (dT / 1000.0),
racerToShot.getDirection(), POLAR );
deflectedBySonicFromPlayer2 = false;
}
}
pos = pos + vel * dT / 1000.0;
break;
}
default: {
cout << "moveEnemyShot: unexpected shotType: " << shotType << endl;
break;
}
}
// clip at the outside of the window
if ( !RectangleGeo(Vector2D( -SHOT_SCREEN_BORDER, -SHOT_SCREEN_BORDER ),
Vector2D( SCREEN_WIDTH + SHOT_SCREEN_BORDER,
SCREEN_HEIGHT + SHOT_SCREEN_BORDER )).isInside(pos) ) {
timeToLive = 0;
}
}
bool Shot::collideEnemyShot( Vector2D posOld ) {
switch (shotType) {
case ENEMY_SHOT_NORMAL:
{
for ( unsigned int i = 0; i < racers->getNrRacers(); i++ ) {
if ( racers->getRacer(i)->collidesWith( posOld, pos ) ) {
racers->getRacer(i)->doDamage( shotType );
timeToLive = 0;
collidedWithGround = false;
return true;
}
}
break;
}
case ENEMY_SHOT_TANK_ROCKET:
{
for ( unsigned int i = 0; i < racers->getNrRacers(); i++ ) {
if ( racers->getRacer(i)->collidesWith( Circle(pos, 5) ) ) {
racers->getRacer(i)->doDamage( shotType );
timeToLive = 0;
collidedWithGround = false;
return true;
}
}
break;
}
default:
{
cout << "collideEnemyShot: unexpected shotType: " << shotType << endl;
return false;
}
}
return false;
}
/////////////
void Shot::addExplosion() {
Explosion *explosion;
switch (shotType) {
default:
{
if ( collidedWithGround ) {
explosion = new Explosion( FN_EXPLOSION_NORMAL, pos,
vel / 10.0, EXPLOSION_NORMAL_GROUND );
} else {
if ( shotType == SHOT_HF_LASER ) {
// Laser is too fast...
explosion = new Explosion( FN_EXPLOSION_NORMAL, pos,
vel / 30.0, EXPLOSION_NORMAL_AIR );
} else {
explosion = new Explosion( FN_EXPLOSION_NORMAL, pos,
vel / 10.0, EXPLOSION_NORMAL_AIR );
}
}
break;
}
}
explosions->addExplosion( explosion );
}
////////////////////
void Shot::drawShadow(SDL_Surface *screen) {
switch (shotType) {
case SHOT_KICK_ASS_ROCKET:
case SHOT_HF_KICK_ASS_ROCKET:
case SHOT_HELLFIRE:
case SPECIAL_SHOT_NUKE:
{
SDL_Rect shadowR;
shadowR.x = lroundf(pos.getX()) - spriteShadow->w / 2 - 7;
shadowR.y = lroundf(pos.getY()) - spriteShadow->h / 2 + 7;
shadowR.w = spriteShadow->w;
shadowR.h = spriteShadow->h;
SDL_BlitSurface( spriteShadow, 0, screen, &shadowR );
break;
}
case ENEMY_SHOT_TANK_ROCKET:
{
SDL_Rect destR;
SDL_Rect srcR;
destR.x = lroundf(pos.getX()) - spriteShadow->w / 16 - 10;
destR.y = lroundf(pos.getY()) - spriteShadow->h / 2 + 10;
destR.w = spriteShadow->w / 8;
destR.h = spriteShadow->h;
float angle = vel.getDirection() + 202.5;
int idx = lroundf(angle) % 360;
idx = idx / 45;
srcR.x = idx * spriteShadow->w / 8;
srcR.y = 0;
srcR.w = spriteShadow->w / 8;
srcR.h = spriteShadow->h;
SDL_BlitSurface( spriteShadow, &srcR, screen, &destR );
break;
}
default: break;
}
}
void Shot::drawGroundShot(SDL_Surface *screen) {
switch (shotType) {
case SHOT_KICK_ASS_ROCKET:
case SHOT_HF_KICK_ASS_ROCKET:
case SHOT_HELLFIRE:
{
SDL_Rect destR;
SDL_Rect srcR;
destR.x = lroundf(pos.getX()) - sprite->w / 2;
destR.y = lroundf(pos.getY()) - sprite->h / 2;
destR.w = sprite->w;
destR.h = sprite->h;
srcR.x = 0;
srcR.y = 0;
srcR.w = sprite->w;
srcR.h = sprite->h;
SDL_BlitSurface( sprite, &srcR, screen, &destR );
break;
}
default: break;
}
}
void Shot::drawGroundAirShot(SDL_Surface *screen) {
switch (shotType) {
case SHOT_DUMBFIRE:
case SHOT_DUMBFIRE_DOUBLE:
case SHOT_HF_DUMBFIRE:
case SHOT_HF_DUMBFIRE_DOUBLE:
{
SDL_Rect destR;
SDL_Rect srcR;
destR.x = lroundf(pos.getX()) - sprite->w / 16;
destR.y = lroundf(pos.getY()) - sprite->h / 2;
destR.w = sprite->w / 8;
destR.h = sprite->h;
// TODO: eight directions are outdated for dumbfire, but existent in the image
float angle = vel.getDirection() + 202.5;
int idx = lroundf(angle) % 360;
idx = idx / 45;
srcR.x = idx * 8;
srcR.y = 0;
srcR.w = 8;
srcR.h = 8;
SDL_BlitSurface( sprite, &srcR, screen, &destR );
break;
}
case SHOT_MACHINE_GUN:
case SHOT_HF_LASER:
{
SDL_Rect destR;
destR.x = lroundf(pos.getX()) - sprite->w / 2;
destR.y = lroundf(pos.getY()) - sprite->h / 2;
destR.w = sprite->w;
destR.h = sprite->h;
SDL_BlitSurface( sprite, 0, screen, &destR );
break;
}
case SHOT_ENERGY_BEAM:
{
SDL_Rect destR;
destR.x = lroundf(pos.getX()) - sprite->w / 2;
destR.y = lroundf(pos.getY()) - sprite->h / 2;
destR.w = sprite->w;
destR.h = sprite->h;
SDL_BlitSurface( sprite, 0, screen, &destR );
destR.x = lroundf(pos.getX()) - sprite->w / 2;
destR.y = lroundf(pos.getY()) - sprite->h / 2;
SDL_BlitSurface( sprite, 0, screen, &destR );
break;
}
case SPECIAL_SHOT_HEATSEEKER:
{
SDL_Rect destR;
SDL_Rect srcR;
destR.x = lroundf(pos.getX()) - sprite->w / 16;
destR.y = lroundf(pos.getY()) - sprite->h / 2;
destR.w = sprite->w / 8;
destR.h = sprite->h;
float angle = vel.getDirection() + 202.5;
int idx = lroundf(angle) % 360;
idx = idx / 45;
srcR.x = idx * 8;
srcR.y = 0;
srcR.w = 8;
srcR.h = 8;
SDL_BlitSurface( sprite, &srcR, screen, &destR );
break;
}
case ENEMY_SHOT_TANK_ROCKET:
{
SDL_Rect destR;
SDL_Rect srcR;
destR.x = lroundf(pos.getX()) - sprite->w / 16;
destR.y = lroundf(pos.getY()) - sprite->h / 2;
destR.w = sprite->w / 8;
destR.h = sprite->h;
float angle = vel.getDirection() + 202.5;
int idx = lroundf(angle) % 360;
idx = idx / 45;
srcR.x = idx * sprite->w / 8;
srcR.y = 0;
srcR.w = sprite->w / 8;
srcR.h = sprite->h;
SDL_BlitSurface( sprite, &srcR, screen, &destR );
break;
}
default: break;
}
}
void Shot::drawAirShot(SDL_Surface *screen) {
switch (shotType) {
case SHOT_NORMAL:
case SHOT_NORMAL_HEAVY:
case SHOT_DOUBLE:
case SHOT_DOUBLE_HEAVY:
case SHOT_TRIPLE:
case SHOT_HF_NORMAL:
case SHOT_HF_DOUBLE:
case SHOT_HF_TRIPLE:
case SHOT_HF_QUATTRO:
case SHOT_HF_QUINTO:
case SPECIAL_SHOT_NUKE:
case ENEMY_SHOT_NORMAL:
{
SDL_Rect destR;
destR.x = lroundf(pos.getX()) - sprite->w / 2;
destR.y = lroundf(pos.getY()) - sprite->h / 2;
destR.w = sprite->w;
destR.h = sprite->h;
SDL_BlitSurface( sprite, 0, screen, &destR );
break;
}
default: break;
}
}
ShotTypes Shot::getShotType() {
return shotType;
}
void Shot::generateSmokePuff( int dT) {
if ( ! generatesSmokePuffs ) return;
timeToNextSmokePuff -= dT;
if ( timeToNextSmokePuff < 0 ) {
Vector2D relPos = -vel;
relPos.setLength( sprite->h / 2 );
if ( shotType == SHOT_HELLFIRE ||
shotType == ENEMY_SHOT_TANK_ROCKET ) {
smokePuffs->addSmokePuff( pos + relPos,
vel * SMOKE_PUFF_VELOCITY_FACTOR,
SMOKE_PUFF_MEDIUM );
timeToNextSmokePuff += SMOKE_PUFF_DELAY_TO_NEXT_PUFF[ SMOKE_PUFF_MEDIUM ];
} else {
smokePuffs->addSmokePuff( pos + relPos,
vel * SMOKE_PUFF_VELOCITY_FACTOR,
SMOKE_PUFF_SMALL );
timeToNextSmokePuff += SMOKE_PUFF_DELAY_TO_NEXT_PUFF[ SMOKE_PUFF_SMALL ];
}
}
}

View File

@@ -0,0 +1,82 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef SHOT_H
#define SHOT_H
#include "SDL.h"
#include "geometry.h"
#include <string>
#include "global.h"
class Shot {
// time (ms) the shot may fly around
int timeToLive;
Vector2D pos;
Vector2D vel;
// who fired the shot
int fromWhichPlayer;
ShotTypes shotType;
SDL_Surface *sprite;
SDL_Surface *spriteShadow;
bool collidedWithGround; // defaultValue = false
bool generatesSmokePuffs;
int timeToNextSmokePuff;
public:
Shot( ShotTypes shotType, int playerNr, Vector2D position, float angle );
// for rockets only
bool deflectedBySonicFromPlayer1;
bool deflectedBySonicFromPlayer2;
// checks if the shot hit a racer. if yes it expires, does its damage
// and makes a neat explosion
void moveAndCollide( int dT );
// draws the shot
void drawShadow(SDL_Surface *screen);
void drawGroundShot(SDL_Surface *screen);
void drawAirShot(SDL_Surface *screen);
void drawGroundAirShot(SDL_Surface *screen);
bool isExpired() { return (timeToLive <= 0); }
Vector2D getPos() { return pos; }
ShotTypes getShotType();
private:
void addExplosion();
void moveAndCollidePlayerShot( int dT );
void movePlayerShot( int dT );
bool collidePlayerShot( Vector2D posOld );
void moveAndCollideEnemyShot( int dT );
void moveEnemyShot( int dT );
bool collideEnemyShot( Vector2D posOld );
void generateSmokePuff( int dT );
};
#endif

View File

@@ -0,0 +1,122 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
using namespace std;
#include "shots.h"
#include "shot.h"
Shots::Shots() {}
Shots::~Shots() {
vector<Shot *>::iterator i;
for (i = shots.begin(); i != shots.end(); ++i) {
delete *i;
}
}
void Shots::addShot(Shot *shot) {
if (shot) {
shots.push_back(shot);
}
}
void Shots::moveAndCollide( int dT ) {
vector<Shot *>::iterator i;
for (i = shots.begin(); i != shots.end(); ++i) {
(*i)->moveAndCollide( dT );
}
}
void Shots::deleteAllShots() {
vector<Shot *>::iterator i;
for (i = shots.begin(); i != shots.end(); ++i) {
delete *i;
}
shots.clear();
}
void Shots::expireShots() {
unsigned int i = 0;
while ( i < shots.size() ) {
if ( shots[i]->isExpired() ) {
delete shots[i];
// TODO: Performance-Optimierung, indem der letzte Schuß
// nach vorne kopiert und dann das letzte Element gelöscht wird.
// Dann wird nicht immer der Rest des Vektors kopiert.
shots.erase(shots.begin() + i);
} else {
i++;
}
}
}
void Shots::drawShadows(SDL_Surface *screen) {
vector<Shot *>::iterator i;
for (i = shots.begin(); i != shots.end(); ++i) {
(*i)->drawShadow(screen);
}
}
void Shots::drawGroundShots(SDL_Surface *screen) {
vector<Shot *>::iterator i;
for (i = shots.begin(); i != shots.end(); ++i) {
(*i)->drawGroundShot(screen);
}
}
void Shots::drawAirShots(SDL_Surface *screen) {
vector<Shot *>::iterator i;
for (i = shots.begin(); i != shots.end(); ++i) {
(*i)->drawAirShot(screen);
}
}
void Shots::drawGroundAirShots(SDL_Surface *screen) {
vector<Shot *>::iterator i;
for (i = shots.begin(); i != shots.end(); ++i) {
(*i)->drawGroundAirShot(screen);
}
}
Shot* Shots::getNearestRocket(Vector2D position) {
vector<Shot *>::iterator i;
float distance = 99999.0;
Shot* rocket = NULL;
for (i = shots.begin(); i != shots.end(); ++i) {
if ( (*i)->getShotType() == ENEMY_SHOT_TANK_ROCKET ) {
if (position.distanceTo( (*i)->getPos() ) < distance ) {
distance = position.distanceTo( (*i)->getPos() );
rocket = (*i);
}
}
}
return rocket;
}
bool Shots::existsRocket() {
vector<Shot *>::iterator i;
for (i = shots.begin(); i != shots.end(); ++i) {
if ( (*i)->getShotType() == ENEMY_SHOT_TANK_ROCKET ) {
return true;
}
}
return false;
}

View File

@@ -0,0 +1,57 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef SHOTS_H
#define SHOTS_H
#include <vector>
#include "SDL.h"
#include "geometry.h"
class Shot;
/* manages the shot-objects */
class Shots {
vector<Shot *> shots;
public:
Shots();
~Shots();
void addShot(Shot *shot);
// deletes shots, that timed out or hit
void expireShots();
// deletes all shots (if a nuke is used, this will happen)
void deleteAllShots();
// moves the shots and checks, whether a shot hit a racer or an enemy
void moveAndCollide( int dT );
// draw the shots
void drawShadows(SDL_Surface *screen);
void drawAirShots(SDL_Surface *screen);
void drawGroundShots(SDL_Surface *screen);
void drawGroundAirShots(SDL_Surface *screen);
Shot* getNearestRocket(Vector2D position);
bool existsRocket();
};
#endif

View File

@@ -0,0 +1,71 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
using namespace std;
#include "smokePuff.h"
#include "surfaceDB.h"
#include "global.h"
SmokePuff::SmokePuff( Vector2D position, Vector2D velocity, SmokePuffTypes whichType ) {
smokePuffType = whichType;
pos = position;
vel = velocity;
sprite = surfaceDB.loadSurface( FN_SMOKE_PUFF[ smokePuffType ],
SMOKE_PUFF_ALPHA_BLENDING );
expired = false;
nrAnimStages = sprite->w / sprite->h;
timePerStage = LIFETIME_SMOKE_PUFF[ smokePuffType ] / nrAnimStages;
actAnimStage = 0;
timeLived = 0;
timeNextAnimStage = timePerStage;
}
SmokePuff::~SmokePuff() {}
void SmokePuff::update( int dT ) {
pos += vel * dT / 1000.0;
timeLived += dT;
if ( timeLived > timeNextAnimStage ) {
timeNextAnimStage += timePerStage;
actAnimStage++;
if (actAnimStage == nrAnimStages) expired = true;
}
}
void SmokePuff::drawSmokePuff( SDL_Surface *screen ) {
if (expired) return;
SDL_Rect dest;
dest.x = lroundf(pos.getX()) - sprite->w / (2*nrAnimStages);
dest.y = lroundf(pos.getY()) - sprite->h / 2;
dest.w = sprite->w / nrAnimStages;
dest.h = sprite->h;
SDL_Rect src;
src.x = actAnimStage * sprite->w / nrAnimStages;
src.y = 0;
src.w = sprite->w / nrAnimStages;
src.h = sprite->h;
SDL_BlitSurface( sprite, &src, screen, &dest );
}

View File

@@ -0,0 +1,61 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef SMOKE_PUFF_H
#define SMOKE_PUFF_H
#include "SDL.h"
#include "geometry.h"
#include "global.h"
#include <string>
class SmokePuff {
// a sprite, that contains horizontally all animationframes of the smokePuff.
// it is assumed, that every frame is quadratic.
SDL_Surface *sprite;
// how many frames does this explosion have?
int nrAnimStages;
// which frame is now?
int actAnimStage;
// how long should one frame last (ms)
int timePerStage;
// how long is the current smokePuff already active
int timeLived;
// at what timeLived starts the next frame?
int timeNextAnimStage;
// the explosion can be deleted
bool expired;
Vector2D pos;
Vector2D vel; // the smokepuff moves - yeah
SmokePuffTypes smokePuffType;
public:
SmokePuff( Vector2D position, Vector2D velocity, SmokePuffTypes whichType );
~SmokePuff();
// updates the position and the counters
void update( int dT );
void drawSmokePuff(SDL_Surface *screen);
bool isExpired() { return expired; }
};
#endif

View File

@@ -0,0 +1,69 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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 "smokePuff.h"
#include "smokePuffs.h"
#include "surfaceDB.h"
#include "global.h"
SmokePuffs::SmokePuffs() {}
SmokePuffs::~SmokePuffs() {
vector<SmokePuff *>::iterator i;
for (i = smokePuffs.begin(); i != smokePuffs.end(); ++i) {
delete *i;
}
}
void SmokePuffs::addSmokePuff( SmokePuff *smokePuff ) {
if ( smokePuff ) {
smokePuffs.push_back( smokePuff );
}
}
void SmokePuffs::addSmokePuff( Vector2D pos, Vector2D vel, SmokePuffTypes whichType ) {
SmokePuff *newSmokePuff = new SmokePuff( pos, vel, whichType );
addSmokePuff( newSmokePuff );
}
void SmokePuffs::expireSmokePuffs() {
unsigned int i = 0;
while ( i < smokePuffs.size() ) {
if ( smokePuffs[i]->isExpired() ) {
delete smokePuffs[i];
smokePuffs.erase( smokePuffs.begin() + i );
} else {
i++;
}
}
}
void SmokePuffs::update( int dT ) {
vector<SmokePuff *>::iterator i;
for (i = smokePuffs.begin(); i != smokePuffs.end(); ++i) {
(*i)->update( dT );
}
}
void SmokePuffs::draw(SDL_Surface *screen) {
vector<SmokePuff *>::iterator i;
for (i = smokePuffs.begin(); i != smokePuffs.end(); ++i) {
(*i)->drawSmokePuff( screen );
}
}

View File

@@ -0,0 +1,45 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef SMOKE_PUFFS_H
#define SMOKE_PUFFS_H
#include "SDL.h"
#include "geometry.h"
#include <vector>
class SmokePuff;
class SmokePuffs {
std::vector<SmokePuff *> smokePuffs;
public:
SmokePuffs();
~SmokePuffs();
void addSmokePuff( SmokePuff *smokePuff );
void addSmokePuff( Vector2D pos, Vector2D vel, SmokePuffTypes whichType );
void expireSmokePuffs();
void update( int dT );
void draw(SDL_Surface *screen);
unsigned int getNrSmokePuffs() { return smokePuffs.size(); }
};
#endif

View File

@@ -0,0 +1,69 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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 <iostream>
#include <math.h>
#include "sonic.h"
#include "global.h"
#include "surfaceDB.h"
#include "geometry.h"
#include "video.h"
using namespace std;
Sonic::Sonic() {
sonicBall = surfaceDB.loadSurface( FN_SONIC_EFFECT, true );
timeStage = 0;
active = false;
waveLength = 6.0f;
}
void Sonic::setPos( Vector2D pos1, Vector2D pos2 ) {
this->pos1 = pos1;
this->pos2 = pos2;
active = true;
}
void Sonic::drawAtPos( SDL_Surface *screen, Vector2D pos1, Vector2D pos2 ) {
setPos( pos1, pos2 );
draw( screen );
}
void Sonic::draw( SDL_Surface *screen ) {
if ( !active ) return;
timeStage += 2;
timeStage = (timeStage % (int)(waveLength + 0.5f)) + 1;
SDL_Rect rect;
rect.w = sonicBall->w;
rect.h = sonicBall->h;
Vector2D sonicIncrement = pos2 - pos1;
float dist = sonicIncrement.getLength() - waveLength;
sonicIncrement.setLength((float) timeStage);
Vector2D sonicActual = pos1;
sonicActual += sonicIncrement;
sonicIncrement.setLength(waveLength);
while (dist >= 5) {
sonicActual += sonicIncrement;
dist -= waveLength;
rect.x = (int) sonicActual.getX() - sonicBall->w / 2;
rect.y = (int) sonicActual.getY() - sonicBall->h / 2;
SDL_BlitSurface( sonicBall, 0, screen, &rect );
}
}

View File

@@ -0,0 +1,47 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef _SONIC_H_
#define _SONIC_H_
#include <SDL.h>
#include "geometry.h"
class Sonic {
public:
Sonic();
void setActive( bool newActivation ) { active = newActivation; };
void setWaveLength( float wvLength ) { waveLength = wvLength; };
void setPos( Vector2D pos1, Vector2D pos2 );
void drawAtPos( SDL_Surface *screen, Vector2D pos1, Vector2D pos2 );
void draw( SDL_Surface *screen );
private:
SDL_Surface *sonicBall;
bool active;
Vector2D pos1;
Vector2D pos2;
float waveLength;
Uint32 timeStage;
};
#endif

View File

@@ -0,0 +1,59 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
using namespace std;
#include "soundDB.h"
#include "SDL_mixer.h"
SoundDB::SoundDB() {}
SoundDB::~SoundDB() {
StringSoundMap::iterator pos;
// free all Mix_Chunks
for ( pos = soundDB.begin(); pos != soundDB.end(); ++pos ) {
Mix_FreeChunk( pos->second );
}
}
Mix_Chunk *SoundDB::loadWav( string fn ) {
Mix_Chunk *searchResult = getWav( fn );
if ( searchResult ) {
return searchResult;
}
// TODO: error-handling
Mix_Chunk *newSound = Mix_LoadWAV( fn.c_str() );
soundDB[ fn ] = newSound;
return newSound;
}
Mix_Chunk *SoundDB::getWav( string fn ) {
if ( soundDB.empty() ) {
return 0;
} else {
StringSoundMap::iterator pos = soundDB.find( fn );
if ( pos == soundDB.end() ) {
return 0;
} else {
return pos->second;
}
}
}

View File

@@ -0,0 +1,48 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef SOUND_DB_HH
#define SOUND_DB_HH
#include "SDL.h"
#include "SDL_mixer.h"
#include <map>
#include <string>
#include <functional>
typedef map<string, Mix_Chunk*, greater<string> >StringSoundMap;
// TODO: freeWav mit Reference-Count
class SoundDB {
public:
SoundDB();
~SoundDB();
Mix_Chunk *loadWav( string fn );
private:
StringSoundMap soundDB;
Mix_Chunk *getWav( string fn );
};
#endif //#define SOUND_DB_HH

View File

@@ -0,0 +1,81 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
using namespace std;
#include "surfaceDB.h"
#include <fstream>
#include <iostream>
SurfaceDB surfaceDB;
SurfaceDB::SurfaceDB( Uint8 transparentR,
Uint8 transparentG,
Uint8 transparentB ) {
transR = transparentR;
transG = transparentG;
transB = transparentB;
}
SurfaceDB::~SurfaceDB() {
StringSurfaceMap::iterator pos;
// free all surfaces
for ( pos = surfaceDB.begin(); pos != surfaceDB.end(); ++pos ) {
SDL_FreeSurface( pos->second );
}
}
SDL_Surface *SurfaceDB::loadSurface( string fn, bool alpha ) {
SDL_Surface *searchResult = getSurface( fn );
if ( searchResult ) {
return searchResult;
}
// open the file for reading
ifstream inputFile ( fn.c_str(), ios::in);
if (!inputFile.good()) {
cout << "ERROR: file " << fn << " does not exist!" << endl;
exit(1);
}
SDL_Surface *newSurface = SDL_LoadBMP( fn.c_str() );
SDL_SetColorKey( newSurface, SDL_SRCCOLORKEY,
SDL_MapRGB(newSurface->format, transR, transG, transB) );
if ( alpha ) {
SDL_SetAlpha( newSurface, SDL_SRCALPHA, 128 );
}
surfaceDB[ fn ] = newSurface;
return newSurface;
}
SDL_Surface *SurfaceDB::getSurface( string fn ) {
if ( surfaceDB.empty() ) {
return 0;
} else {
StringSurfaceMap::iterator pos = surfaceDB.find( fn );
if ( pos == surfaceDB.end() ) {
return 0;
} else {
return pos->second;
}
}
}

View File

@@ -0,0 +1,61 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef SURFACE_DB_HH
#define SURFACE_DB_HH
#include "SDL.h"
#include <string>
#include <map>
#include <functional>
typedef std::map<std::string, SDL_Surface *, std::greater<std::string> > StringSurfaceMap;
class SurfaceDB;
extern SurfaceDB surfaceDB;
/* Framework for convenient loading and management of SDL_Surfaces.
Every surface has a transparent color (default violet).
If the requested surface was already loaded it is not loaded again,
instead the old surface is returned.
The clients of the surface may use the surface for blitting, but they must
not change (especially delete) it.
*/
class SurfaceDB {
public:
SurfaceDB( Uint8 transparentR=255,
Uint8 transparentG=0,
Uint8 transparentB=255 );
~SurfaceDB();
SDL_Surface *loadSurface( std::string fn, bool alpha=false );
private:
StringSurfaceMap surfaceDB;
Uint8 transR, transG, transB;
SDL_Surface *getSurface( std::string fn );
};
#endif //#ifndef SURFACE_DB_HH

View File

@@ -0,0 +1,77 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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 "video.h"
#include "SDL.h"
#include <stdlib.h>
#include "global.h"
using namespace std;
Video *videoserver;
Video::Video(){
screen = 0;
}
Video::~Video(){
// kill something
}
SDL_Surface *Video::init(){
// --------------------------------------------------
// SDL initialisation
// -----------------------------------------------------
fullscreen = false;
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) {
printf("Couldn't initialize SDL video subsystem: %s\n", SDL_GetError());
exit(1);
}
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, BIT_DEPTH, SDL_DOUBLEBUF /* | SDL_FULLSCREEN */ );
if (!screen) {
printf("Couldn't set %dx%d, %dbit video mode: %s\n", SCREEN_WIDTH, SCREEN_HEIGHT, BIT_DEPTH, SDL_GetError());
exit(2);
}
SDL_WM_SetCaption("AlienBlaster", "AlienBlaster");
SDL_WM_SetIcon(SDL_LoadBMP( FN_ALIENBLASTER_ICON.c_str() ), NULL);
SDL_ShowCursor(SDL_DISABLE);
return screen;
}
void Video::clearScreen() {
// clear the screen
SDL_Rect r;
r.x = 0;
r.y = 0;
r.w = screen->w;
r.h = screen->h;
SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0, 0, 0) );
}
void Video::toggleFullscreen() {
if ( fullscreen ) {
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, BIT_DEPTH, SDL_DOUBLEBUF );
} else {
screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, BIT_DEPTH, SDL_DOUBLEBUF | SDL_FULLSCREEN );
}
fullscreen = !fullscreen;
}

View File

@@ -0,0 +1,45 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef VIDEO_H
#define VIDEO_H
#include "SDL.h"
class Video;
extern Video *videoserver;
class Video {
private:
SDL_Surface *screen;
public:
Video();
~Video();
SDL_Surface *init();
bool fullscreen;
void clearScreen();
void toggleFullscreen();
};
#endif //#ifndef VIDEO_HH

View File

@@ -0,0 +1,114 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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 "wreck.h"
#include "surfaceDB.h"
#include "global.h"
#include "options.h"
Wreck::Wreck(Vector2D position, WreckTypes wreckType) {
this->wreckType = wreckType;
pos = position;
vel = Vector2D(0, SCROLL_SPEED);
switch (wreckType) {
case WRECK_FIGHTER:
{
string fn = LVL_WRECK_FIGHTER;
levelConf->getStr( LVL_WRECK_FIGHTER, fn);
sprite = surfaceDB.loadSurface( fn );
break;
}
case WRECK_BOMBER:
{
string fn = LVL_WRECK_BOMBER;
levelConf->getStr( LVL_WRECK_BOMBER, fn);
sprite = surfaceDB.loadSurface( fn );
break;
}
case WRECK_TANK:
{
string fn = LVL_WRECK_TANK;
levelConf->getStr( LVL_WRECK_TANK, fn);
sprite = surfaceDB.loadSurface( fn );
break;
}
case WRECK_BOSS_1_BACKGROUND:
{
string fn = LVL_WRECK_BOSS_BACKGROUND;
levelConf->getStr( LVL_WRECK_BOSS_BACKGROUND, fn);
sprite = surfaceDB.loadSurface( fn );
break;
}
case WRECK_BOSS_1_DESTROYED:
{
string fn = LVL_WRECK_BOSS_DESTROYED;
levelConf->getStr( LVL_WRECK_BOSS_DESTROYED, fn);
sprite = surfaceDB.loadSurface( fn );
break;
}
case WRECK_BOSS_2_DESTROYED:
{
sprite = surfaceDB.loadSurface( FN_WRECK_BOSS_2_DESTROYED );
float correlateToBackground = actBackgroundPos - truncf(actBackgroundPos);
pos = Vector2D( position.getX(), truncf(position.getY()) - correlateToBackground );
break;
}
default:
{
string fn = LVL_WRECK_FIGHTER;
levelConf->getStr( LVL_WRECK_FIGHTER, fn);
sprite = surfaceDB.loadSurface( fn );
break;
}
}
}
Wreck::~Wreck() {
}
void Wreck::update( int dT ) {
if ( scrollingOn ) {
pos += vel * dT / 1000.0;
}
}
void Wreck::draw(SDL_Surface *screen) {
SDL_Rect r;
r.x = lroundf(pos.getX()) - sprite->w / 2;
r.y = lroundf(pos.getY()) - sprite->h / 2;
r.w = sprite->w;
r.h = sprite->h;
SDL_BlitSurface( sprite, 0, screen, &r );
}
bool Wreck::isExpired() {
return ( pos.getY() > SCREEN_HEIGHT );
}
void Wreck::deleteWreck() {
pos.setY( SCREEN_HEIGHT + 500 );
}

View File

@@ -0,0 +1,48 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef WRECK_H
#define WRECK_H
#include "SDL.h"
#include "geometry.h"
#include <string>
#include "global.h"
class Wreck {
SDL_Surface *sprite;
Vector2D pos;
Vector2D vel;
WreckTypes wreckType;
public:
Wreck( Vector2D position, WreckTypes wreckType );
~Wreck();
void update( int dT );
void draw(SDL_Surface *screen);
bool isExpired();
void deleteWreck();
Vector2D getPos() { return pos; }
Vector2D getVel() { return vel; }
WreckTypes getType() { return wreckType; }
};
#endif

View File

@@ -0,0 +1,74 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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 "wrecks.h"
#include "wreck.h"
Wrecks::Wrecks() {
}
Wrecks::~Wrecks() {
vector<Wreck *>::iterator i;
for (i = wrecks.begin(); i != wrecks.end(); ++i) {
delete *i;
}
}
void Wrecks::addWreck(Wreck *wreck) {
if (wreck) {
wrecks.push_back(wreck);
}
}
void Wrecks::expireWrecks() {
unsigned int i = 0;
while ( i < wrecks.size() ) {
if ( wrecks[i]->isExpired() ) {
delete wrecks[i];
wrecks.erase(wrecks.begin() + i);
} else {
i++;
}
}
}
void Wrecks::updateWrecks( int dT ) {
vector<Wreck *>::iterator i;
for (i = wrecks.begin(); i != wrecks.end(); ++i) {
(*i)->update( dT );
}
}
void Wrecks::draw(SDL_Surface *screen) {
vector<Wreck *>::iterator i;
for (i = wrecks.begin(); i != wrecks.end(); ++i) {
(*i)->draw(screen);
}
}
void Wrecks::deleteAllWrecks() {
vector<Wreck *>::iterator i;
for (i = wrecks.begin(); i != wrecks.end(); ++i) {
(*i)->deleteWreck();
}
}
Wreck *Wrecks::getWreck(unsigned int idx) {
return wrecks[idx];
}

View File

@@ -0,0 +1,46 @@
/***************************************************************************
alienBlaster
Copyright (C) 2004
Paul Grathwohl, Arne Hormann, Daniel Kuehn, Soenke Schwardt
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, 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.
***************************************************************************/
#ifndef WRECKS_H
#define WRECKS_H
#include "SDL.h"
#include <vector>
class Wreck;
class Wrecks {
std::vector<Wreck *> wrecks;
public:
Wrecks();
~Wrecks();
void addWreck(Wreck *wreck);
void expireWrecks();
void updateWrecks( int dT );
void draw(SDL_Surface *screen);
void deleteAllWrecks();
unsigned int getNrWrecks() { return wrecks.size(); }
Wreck *getWreck(unsigned int idx);
};
#endif

View File

@@ -0,0 +1,41 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := sdl
ifndef SDL_JAVA_PACKAGE_PATH
$(error Please define SDL_JAVA_PACKAGE_PATH to the path of your Java package with dots replaced with underscores, for example "com_example_SanAngeles")
endif
LOCAL_CFLAGS := -I$(LOCAL_PATH)/include -DSDL_JAVA_PACKAGE_PATH=$(SDL_JAVA_PACKAGE_PATH) -DSDL_CURDIR_PATH=\"$(SDL_CURDIR_PATH)\"
SDL_SRCS := \
src/*.c \
src/audio/*.c \
src/cdrom/*.c \
src/cpuinfo/*.c \
src/events/*.c \
src/file/*.c \
src/joystick/*.c \
src/stdlib/*.c \
src/thread/*.c \
src/timer/*.c \
src/video/*.c \
src/audio/dummy/*.c \
src/video/android/*.c \
src/joystick/dummy/*.c \
src/cdrom/dummy/*.c \
src/thread/pthread/*.c \
src/timer/unix/*.c \
src/loadso/dummy/*.c \
LOCAL_CPP_EXTENSION := .cpp
# Note this simple makefile var substitution, you can find even simpler examples in different Android projects
LOCAL_SRC_FILES := $(foreach F, $(SDL_SRCS), $(addprefix $(dir $(F)),$(notdir $(wildcard $(LOCAL_PATH)/$(F)))))
LOCAL_LDLIBS := -lGLESv1_CM -ldl -llog
include $(BUILD_STATIC_LIBRARY)

View File

@@ -0,0 +1,18 @@
Bugs are now managed in the SDL bug tracker, here:
http://bugzilla.libsdl.org/
You may report bugs there, and search to see if a given issue has already
been reported, discussed, and maybe even fixed.
You may also find help at the SDL mailing list. Subscription information:
http://lists.libsdl.org/listinfo.cgi/sdl-libsdl.org
Bug reports are welcome here, but we really appreciate if you use Bugzilla, as
bugs discussed on the mailing list may be forgotten or missed.

View File

@@ -0,0 +1,139 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Building SDL with Borland's C++ compilers</title>
<meta name="author"
content="David Snopek and updated by Dominique Louis.">
</head>
<body>
<xevol @newtonave.net=""> </xevol>
<h1>Building SDL with Borland's C++ compilers. </h1>
<b> by <a href="mailto:xevol@users.sourceforge.net"> David Snopek</a></b>
and updated by <b><a href="mailto:Dominique@SavageSoftware.com.au">Dominique
Louis</a></b> ( Last updated : 30th June 2003 ).<br>
<br>
These instructions cover how to compile SDL and its included test
programs using either Borland <a href="#bcbwin">C++ Builder 5, 6 for Windows</a>,
<a href="#k3">C++ Builder for Linux ( AKA Kylix 3 )</a> or the free <a
href="#bccc">Borland C++ command-line compiler</a>. <br>
<h3> <b> Extract the files </b> </h3>
<p> Unzip the Borland.zip archive into <b>this</b> directory. Do not unzip
it into any other directory because the makefiles ( *.mak ) and project
files ( *.bpr ) use relative paths to refer to the SDL sources. This should
create a directory named "Borland" inside of the top level SDL source directory.
</p>
<h3> <b><a name="bcbwin"></a> Using Borland C++ Builder 5, 6 for Windows </b>
</h3>
<p> Inside of the "Borland" directory there is a "bcb6" directory that contains
a number of Builder project files. Double-click on the "libSDL.bpg" file
icon. Once Builder has started click on the "<u>P</u>rojects" menu on
the menu-bar and go down to "B<u>u</u>ild All Projects" option. <br>
This will proceed to build SDL ( with Borland's calling convention ),
SDLmain, and all the <a href="#tests">test programs</a>. Currently, all
the <a href="#tests">test programs</a> are dynamically linked to Sam Lantinga's
SDL.dll.</p>
<p><b>NOTE :</b> Borland's "lib" format and Microsoft's "lib" format are incompatible.
&nbsp;<br>
If you wish to dynamically link to the SDL library supplied by Sam Lantinga
in each release, I have created the correct *.libs for SDL 1.2.4 and they
exist in the "/lib" directory.<br>
If you would like to create the *.lib files yourself, you will need to
make use of Borland's "implib.exe" utility.<br>
</p>
<p><tt>IMPLIB</tt> works like this: </p>
<pre> IMPLIB (destination lib name) (source dll)<br></pre>
<p> For example,</p>
<pre> IMPLIB SDL.lib SDL.dll<br></pre>
<p>This assumes that SDL.dll was compiled with Visual C++ or similar.<br>
</p>
<p>To learn more about the difference between Borland's and Microsoft's *.lib
format please read the article <a
href="http://www.bcbdev.com/articles/vcdll.htm">here</a>.<br>
</p>
<p> <b><br>
NOTE :</b> The C++ Builder for Windows project format, is not compatible
with the Kylix 3 project format, hence the reason why they are in separate
directories.</p>
<h3> <b><a name="bccc"></a> Using the free Borland C++ command-line compiler
</b> </h3>
<p> The free Borland compiler can be downloaded at no charge from <a
href="http://www.borland.com/bcppbuilder/freecompiler/"> the Borland website
</a>. Make sure that it is installed and properly configured. </p>
<p> Open an MS-DOS Prompt. Change to the "Borland\freebcc" directory under
the SDL source directory. Type "make -f SDL.mak" to build SDL and "make
-f SDLmain.mak". There are also makefiles for all of the <a
href="#tests">test programs</a>, if you wish to build them. All .exes and
DLLs are created in the "test" SDL directory. Ify ou would like to create
the DLL and all the test applications, I have thrown together a basic batchfile
called "makeall.bat" which should create everything in the right order. </p>
<h3> <b> Output files </b> </h3>
No matter which compiler you used, three important files should have
been produced:
<ul>
<li> SDL.dll ( Borland format ) </li>
<li> SDL.lib&nbsp;( Borland format ) </li>
<li> SDLmain.lib&nbsp;( Borland format ) </li>
</ul>
Both of the *.lib files will need to be added to all the projects
that use SDL and SDL.dll must be placed some where the Windows dynamic
linker can find it (either in your project directory or on the system
path, C:\WINDOWS\SYSTEM).
<h3> <b><a name="k3"></a> Using Borland C++ Builder for Linux ( AKA Kylix
3 ) </b> </h3>
<p> Inside of the "Borland" directory there is a "k3" directory that contains
a number of Builder project files. Double-click on the "libSDL.bpg" file
icon. Once Builder has started click on the "<u>P</u>rojects" menu on
the menu-bar and go down to "B<u>u</u>ild All Projects" option. This will
proceed to build all the <a href="#tests">test programs</a>.&nbsp;<br>
Linux users do not need *.lib files as the Shared Object is linked right
into the project ( very neat actually, Windows should do this sort of thing
as it is a lot easier for the developer ). <br>
<b>NOTE :</b>&nbsp;The C++ Builder for Windows project format, is not
compatible with the Kylix 3 project format, hence the reason why they are
in separate directories.</p>
<p> On Mandrake 8.1 the shared objects for SDL are located in the /usr/lib
directory as libSDL_*.so and the Mesa OpenGL shared objects are located
in /usr/X11R6/lib as libGL*.so<br>
<br>
So if your setup is different you may need to change the project file
so that they re-link to the ones on your system.<br>
<br>
On Mandrake 8.1 the headers files are located at /usr/include/SDL/.
So if you you have not installed the development RPMs ( usually named libSDL-devel*
) for SDL ( not included ) you may have to change the include directory
within some of the projects.<br>
</p>
<h3> Known Problems</h3>
The only known problem is that I ( Dominique Louis ), was unable to
create the projects that rebuilt the SDL shared objects under Linux, due
to time constraints and my lack of intimate knowledge of Linux.
<h3><a name="tests"><b> Test programs </b> </a></h3>
Some of the test programs require included media files ( *.wav; *.bmp
etc ). All the test programs are now created in the "test" directory, where
the media files are ( usually ) so they should be ready to go. <br>
<br>
<br>
<br>
</body>
</html>

View File

@@ -0,0 +1,458 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom of use,
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 and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, 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 library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete 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 distribute a copy of this License along with the
Library.
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 Library or any portion
of it, thus forming a work based on the Library, 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) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
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 Library, 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 Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you 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.
If distribution of 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 satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be 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.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library 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.
9. 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 Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
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 with
this License.
11. 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 Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library 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 Library.
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.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library 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.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser 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 Library
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 Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
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
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "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
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. 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 LIBRARY 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
LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS

View File

@@ -0,0 +1,94 @@
Simple DirectMedia Layer CREDITS
Thanks to everyone who made this possible, including:
* Cliff Matthews, for giving me a reason to start this project. :)
-- Executor rocks! *grin*
* Scott Call, for making a home for SDL on the 'Net... Thanks! :)
* The Linux Fund, C Magazine, Educational Technology Resources Inc.,
Gareth Noyce, Jesse Pavel, Keith Kitchin, Jeremy Horvath, Thomas Nicholson,
Hans-Peter Gygax, the Eternal Lands Development Team, Lars Brubaker,
and Phoenix Kokido for financial contributions
* Gaëtan de Menten for writing the PHP and SQL behind the SDL website
* Tim Jones for the new look of the SDL website
* Marco Kraus for setting up SDL merchandise
* Martin Donlon for his work on the SDL Documentation Project
* Ryan Gordon for helping everybody out and keeping the dream alive. :)
* IBM R&D Lab for their PS3 SPE video acceleration code
* Mattias Engdegård, for help with the Solaris port and lots of other help
* Max Watson, Matt Slot, and Kyle for help with the MacOS Classic port
* Stan Shebs, for the initial Mac OS X port
* Eric Wing, Max Horn, and Darrell Walisser for unflagging work on the Mac OS X port
* Patrick Trainor, Jim Boucher, and Mike Gorchak for the QNX Neutrino port
* Carsten Griwodz for the AIX port
* Gabriele Greco, for the Amiga port
* Patrice Mandin, for the Atari port
* Hannu Viitala for the EPOC port
* Marcus Mertama for the S60 port.
* Peter Valchev for nagging me about the OpenBSD port until I got it right. :)
* Kent B Mein, for a place to do the IRIX port
* Ash, for a place to do the OSF/1 Alpha port
* David Sowsy, for help with the BeOS port
* Eugenia Loli, for endless work on porting SDL games to BeOS
* Jon Taylor for the GGI front-end
* Paulus Esterhazy, for the Visual C++ testing and libraries
* Brenda Tantzen, for Metrowerks CodeWarrior on MacOS
* Chris Nentwich, for the Hermes assembly blitters
* Michael Vance and Jim Kutter for the X11 OpenGL support
* Stephane Peter, for the AAlib front-end and multi-threaded timer idea.
* Jon Atkins for SDL_image, SDL_mixer and SDL_net documentation
* Peter Wiklund, for the 1998 winning SDL logo,
and Arto Hamara, Steven Wong, and Kent Mein for other logo entries.
* Arne Claus, for the 2004 winning SDL logo,
and Shandy Brown, Jac, Alex Lyman, Mikkel Gjoel, #Guy, Jonas Hartmann,
Daniel Liljeberg, Ronald Sowa, DocD, Pekka Jaervinen, Patrick Avella,
Erkki Kontilla, Levon Gavalian, Hal Emerich, David Wiktorsson,
S. Schury and F. Hufsky, Ciska de Ruyver, Shredweat, Tyler Montbriand,
Martin Andersson, Merlyn Wysard, Fernando Ibanez, David Miller,
Andre Bommele, lovesby.com, Francisco Camenforte Torres, and David Igreja
for other logo entries.
* Bob Pendleton and David Olofson for being long time contributors to
the SDL mailing list.
* Everybody at Loki Software, Inc. for their great contributions!
And a big hand to everyone else who gave me appreciation, advice,
and suggestions, especially the good folks on the SDL mailing list.
THANKS! :)
-- Sam Lantinga <slouken@libsdl.org>

View File

@@ -0,0 +1,23 @@
To compile and install SDL:
1. Run './configure; make; make install'
If you are compiling for Windows using gcc, read the FAQ at:
http://www.libsdl.org/faq.php?action=listentries&category=4#42
If you are compiling using Visual C++ on Win32, you should read
the file VisualC.html
2. Look at the example programs in ./test, and check out the HTML
documentation in ./docs to see how to use the SDL library.
3. Join the SDL developer mailing list by sending E-mail to
sdl-request@libsdl.org
and put "subscribe" in the subject of the message.
Or alternatively you can use the web interface:
http://www.libsdl.org/mailing-list.php
That's it!
Sam Lantinga <slouken@libsdl.org>

View File

@@ -0,0 +1,111 @@
#GL=1
CC = sh-elf-gcc
AR = sh-elf-ar
ifdef GL
DEFS += -DSDL_VIDEO_OPENGL=1
TARGET = libSDL_gl.a
else
TARGET = libSDL.a
endif
CFLAGS=$(KOS_CFLAGS) $(DEFS) -Iinclude
SRCS = \
src/audio/dc/SDL_dcaudio.c \
src/audio/dc/aica.c \
src/audio/dummy/SDL_dummyaudio.c \
src/audio/SDL_audio.c \
src/audio/SDL_audiocvt.c \
src/audio/SDL_audiodev.c \
src/audio/SDL_mixer.c \
src/audio/SDL_wave.c \
src/cdrom/dc/SDL_syscdrom.c \
src/cdrom/SDL_cdrom.c \
src/events/SDL_active.c \
src/events/SDL_events.c \
src/events/SDL_expose.c \
src/events/SDL_keyboard.c \
src/events/SDL_mouse.c \
src/events/SDL_quit.c \
src/events/SDL_resize.c \
src/file/SDL_rwops.c \
src/joystick/dc/SDL_sysjoystick.c \
src/joystick/SDL_joystick.c \
src/loadso/dummy/SDL_sysloadso.c \
src/SDL.c \
src/SDL_error.c \
src/SDL_fatal.c \
src/stdlib/SDL_getenv.c \
src/stdlib/SDL_iconv.c \
src/stdlib/SDL_malloc.c \
src/stdlib/SDL_qsort.c \
src/stdlib/SDL_stdlib.c \
src/stdlib/SDL_string.c \
src/thread/dc/SDL_syscond.c \
src/thread/dc/SDL_sysmutex.c \
src/thread/dc/SDL_syssem.c \
src/thread/dc/SDL_systhread.c \
src/thread/SDL_thread.c \
src/timer/dc/SDL_systimer.c \
src/timer/SDL_timer.c \
src/video/dc/SDL_dcevents.c \
src/video/dc/SDL_dcvideo.c \
src/video/dummy/SDL_nullevents.c \
src/video/dummy/SDL_nullmouse.c \
src/video/dummy/SDL_nullvideo.c \
src/video/SDL_blit.c \
src/video/SDL_blit_0.c \
src/video/SDL_blit_1.c \
src/video/SDL_blit_A.c \
src/video/SDL_blit_N.c \
src/video/SDL_bmp.c \
src/video/SDL_cursor.c \
src/video/SDL_gamma.c \
src/video/SDL_pixels.c \
src/video/SDL_RLEaccel.c \
src/video/SDL_stretch.c \
src/video/SDL_surface.c \
src/video/SDL_video.c \
src/video/SDL_yuv.c \
src/video/SDL_yuv_sw.c \
OBJS = $(SRCS:.c=.o)
TEST = \
test/checkkeys.c \
test/graywin.c \
test/loopwave.c \
test/testalpha.c \
test/testbitmap.c \
test/testcdrom.c \
test/testerror.c \
test/testgamma.c \
test/testgl.c \
test/testhread.c \
test/testjoystick.c \
test/testkeys.c \
test/testlock.c \
test/testoverlay.c \
test/testpalette.c \
test/testsem.c \
test/testsprite.c \
test/testtimer.c \
test/testtypes.c \
test/testver.c \
test/testvidinfo.c \
test/testwin.c \
test/testwm.c \
test/threadwin.c \
test/torturethread.c \
$(TARGET): copy_config \
$(OBJS)
$(AR) rcs $(TARGET) $(OBJS)
copy_config:
@cp include/SDL_config.h.default include/SDL_config.h
clean:
rm -f include/SDL_config.h $(OBJS)

View File

@@ -0,0 +1,183 @@
# Makefile to build and install the SDL library
top_builddir = .
srcdir = @srcdir@
objects = build
depend = build-deps
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
libdir = @libdir@
includedir = @includedir@
datarootdir = @datarootdir@
datadir = @datadir@
mandir = @mandir@
auxdir = @ac_aux_dir@
distpath = $(srcdir)/..
distdir = SDL-@SDL_VERSION@
distfile = $(distdir).tar.gz
@SET_MAKE@
SHELL = @SHELL@
CC = @CC@
INCLUDE = @INCLUDE@
CFLAGS = @BUILD_CFLAGS@
EXTRA_CFLAGS = @EXTRA_CFLAGS@
LDFLAGS = @BUILD_LDFLAGS@
EXTRA_LDFLAGS = @EXTRA_LDFLAGS@
LIBTOOL = @LIBTOOL@
INSTALL = @INSTALL@
NASM = @NASM@ @NASMFLAGS@
AR = @AR@
RANLIB = @RANLIB@
WINDRES = @WINDRES@
TARGET = libSDL.la
SOURCES = @SOURCES@
OBJECTS = @OBJECTS@
SDLMAIN_TARGET = libSDLmain.a
SDLMAIN_SOURCES = @SDLMAIN_SOURCES@
SDLMAIN_OBJECTS = @SDLMAIN_OBJECTS@
DIST = acinclude autogen.sh Borland.html Borland.zip BUGS build-scripts configure configure.in COPYING CREDITS CWprojects.sea.bin docs docs.html include INSTALL Makefile.dc Makefile.minimal Makefile.in MPWmake.sea.bin README* sdl-config.in sdl.m4 sdl.pc.in SDL.qpg.in SDL.spec SDL.spec.in src test TODO VisualCE.zip VisualC.html VisualC.zip Watcom-OS2.zip Watcom-Win32.zip symbian.zip WhatsNew Xcode.tar.gz
HDRS = SDL.h SDL_active.h SDL_audio.h SDL_byteorder.h SDL_cdrom.h SDL_cpuinfo.h SDL_endian.h SDL_error.h SDL_events.h SDL_getenv.h SDL_joystick.h SDL_keyboard.h SDL_keysym.h SDL_loadso.h SDL_main.h SDL_mouse.h SDL_mutex.h SDL_name.h SDL_opengl.h SDL_platform.h SDL_quit.h SDL_rwops.h SDL_stdinc.h SDL_syswm.h SDL_thread.h SDL_timer.h SDL_types.h SDL_version.h SDL_video.h begin_code.h close_code.h
LT_AGE = @LT_AGE@
LT_CURRENT = @LT_CURRENT@
LT_RELEASE = @LT_RELEASE@
LT_REVISION = @LT_REVISION@
LT_LDFLAGS = -no-undefined -rpath $(DESTDIR)$(libdir) -release $(LT_RELEASE) -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE)
all: $(srcdir)/configure Makefile $(objects) $(objects)/$(TARGET) $(objects)/$(SDLMAIN_TARGET)
$(srcdir)/configure: $(srcdir)/configure.in
@echo "Warning, configure.in is out of date"
#(cd $(srcdir) && sh autogen.sh && sh configure)
@sleep 3
Makefile: $(srcdir)/Makefile.in
$(SHELL) config.status $@
$(objects):
$(SHELL) $(auxdir)/mkinstalldirs $@
.PHONY: all depend install install-bin install-hdrs install-lib install-data install-man uninstall uninstall-bin uninstall-hdrs uninstall-lib uninstall-data uninstall-man clean distclean dist
depend:
@SOURCES="$(SOURCES)" INCLUDE="$(INCLUDE)" output="$(depend)" \
$(SHELL) $(auxdir)/makedep.sh
@for src in $(SDLMAIN_SOURCES); do \
obj=`echo $$src | sed -e 's|.*/||' -e 's|\.[^\.]*$$|.o|'`; \
echo "\$$(objects)/$$obj: $$src" >>$(depend); \
echo " \$$(CC) \$$(CFLAGS) \$$(EXTRA_CFLAGS) -c $$src -o \$$@" >>$(depend); \
done
include $(depend)
$(objects)/$(TARGET): $(OBJECTS)
$(LIBTOOL) --mode=link $(CC) -o $@ $(OBJECTS) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LT_LDFLAGS)
$(objects)/$(SDLMAIN_TARGET): $(SDLMAIN_OBJECTS)
$(AR) cru $@ $(SDLMAIN_OBJECTS)
$(RANLIB) $@
install: all install-bin install-hdrs install-lib install-data install-man
install-bin:
$(SHELL) $(auxdir)/mkinstalldirs $(DESTDIR)$(bindir)
$(INSTALL) -m 755 sdl-config $(DESTDIR)$(bindir)/sdl-config
install-hdrs:
$(SHELL) $(auxdir)/mkinstalldirs $(DESTDIR)$(includedir)/SDL
for file in $(HDRS); do \
$(INSTALL) -m 644 $(srcdir)/include/$$file $(DESTDIR)$(includedir)/SDL/$$file; \
done
$(INSTALL) -m 644 include/SDL_config.h $(DESTDIR)$(includedir)/SDL/SDL_config.h
install-lib: $(objects) $(objects)/$(TARGET) $(objects)/$(SDLMAIN_TARGET)
$(SHELL) $(auxdir)/mkinstalldirs $(DESTDIR)$(libdir)
$(LIBTOOL) --mode=install $(INSTALL) $(objects)/$(TARGET) $(DESTDIR)$(libdir)/$(TARGET)
$(INSTALL) -m 644 $(objects)/$(SDLMAIN_TARGET) $(DESTDIR)$(libdir)/$(SDLMAIN_TARGET)
$(RANLIB) $(DESTDIR)$(libdir)/$(SDLMAIN_TARGET)
install-data:
$(SHELL) $(auxdir)/mkinstalldirs $(DESTDIR)$(datadir)/aclocal
$(INSTALL) -m 644 $(srcdir)/sdl.m4 $(DESTDIR)$(datadir)/aclocal/sdl.m4
$(SHELL) $(auxdir)/mkinstalldirs $(DESTDIR)$(libdir)/pkgconfig
$(INSTALL) -m 644 sdl.pc $(DESTDIR)$(libdir)/pkgconfig
install-man:
$(SHELL) $(auxdir)/mkinstalldirs $(DESTDIR)$(mandir)/man3
for src in $(srcdir)/docs/man3/*.3; do \
file=`echo $$src | sed -e 's|^.*/||'`; \
$(INSTALL) -m 644 $$src $(DESTDIR)$(mandir)/man3/$$file; \
done
uninstall: uninstall-bin uninstall-hdrs uninstall-lib uninstall-data uninstall-man
uninstall-bin:
rm -f $(DESTDIR)$(bindir)/sdl-config
uninstall-hdrs:
for file in $(HDRS); do \
rm -f $(DESTDIR)$(includedir)/SDL/$$file; \
done
rm -f $(DESTDIR)$(includedir)/SDL/SDL_config.h
-rmdir $(DESTDIR)$(includedir)/SDL
uninstall-lib:
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$(TARGET)
rm -f $(DESTDIR)$(libdir)/$(SDLMAIN_TARGET)
uninstall-data:
rm -f $(DESTDIR)$(datadir)/aclocal/sdl.m4
rm -f $(DESTDIR)$(libdir)/pkgconfig/sdl.pc
uninstall-man:
for src in $(srcdir)/docs/man3/*.3; do \
file=`echo $$src | sed -e 's|^.*/||'`; \
rm -f $(DESTDIR)$(mandir)/man3/$$file; \
done
clean:
rm -rf $(objects)
if test -f test/Makefile; then (cd test; $(MAKE) $@); fi
distclean: clean
rm -f Makefile include/SDL_config.h sdl-config
rm -f SDL.qpg
rm -f config.status config.cache config.log libtool $(depend)
rm -rf $(srcdir)/autom4te*
rm -rf $(srcdir)/test/autom4te*
find $(srcdir) \( \
-name '*~' -o \
-name '*.bak' -o \
-name '*.old' -o \
-name '*.rej' -o \
-name '*.orig' -o \
-name '.#*' \) \
-exec rm -f {} \;
cp $(srcdir)/include/SDL_config.h.default $(srcdir)/include/SDL_config.h
if test -f test/Makefile; then (cd test; $(MAKE) $@); fi
dist $(distfile):
$(SHELL) $(auxdir)/mkinstalldirs $(distdir)
tar cf - $(DIST) | (cd $(distdir); tar xf -)
cp $(distdir)/include/SDL_config.h.default $(distdir)/include/SDL_config.h
rm -rf `find $(distdir) -name .svn`
rm -rf $(distdir)/test/autom4te*
find $(distdir) \( \
-name '*~' -o \
-name '*.bak' -o \
-name '*.old' -o \
-name '*.rej' -o \
-name '*.orig' -o \
-name '.#*' \) \
-exec rm -f {} \;
if test -f $(distdir)/test/Makefile; then (cd $(distdir)/test && make distclean); fi
tar cvf - $(distdir) | gzip --best >$(distfile)
rm -rf $(distdir)
rpm: $(distfile)
rpmbuild -ta $?
# Create a SVN snapshot that people can run update on
snapshot:
svn co http://svn.libsdl.org/branches/SDL-1.2
(cd SDL-1.2 && ./autogen.sh && rm -rf autom4te.cache)
cp SDL-1.2/include/SDL_config.h.default SDL-1.2/include/SDL_config.h
tar zcf $(HOME)/SDL-1.2.tar.gz SDL-1.2
rm -f $(HOME)/SDL-1.2.zip
zip -r $(HOME)/SDL-1.2.zip SDL-1.2
rm -rf SDL-1.2

View File

@@ -0,0 +1,42 @@
# Makefile to build the SDL library
INCLUDE = -I./include
CFLAGS = -g -O2 $(INCLUDE)
AR = ar
RANLIB = ranlib
CONFIG_H = include/SDL_config.h
TARGET = libSDL.a
SOURCES = \
src/*.c \
src/audio/*.c \
src/cdrom/*.c \
src/cpuinfo/*.c \
src/events/*.c \
src/file/*.c \
src/joystick/*.c \
src/stdlib/*.c \
src/thread/*.c \
src/timer/*.c \
src/video/*.c \
src/audio/oss/*.c \
src/video/fbcon/*.c \
src/joystick/dummy/*.c \
src/cdrom/dummy/*.c \
src/thread/pthread/*.c \
src/timer/unix/*.c \
src/loadso/dummy/*.c \
OBJECTS = $(shell echo $(SOURCES) | sed -e 's,\.c,\.o,g')
all: $(TARGET)
$(TARGET): $(CONFIG_H) $(OBJECTS)
$(AR) crv $@ $^
$(RANLIB) $@
$(CONFIG_H):
cp $(CONFIG_H).default $(CONFIG_H)
clean:
rm -f $(TARGET) $(OBJECTS)

View File

@@ -0,0 +1,49 @@
Simple DirectMedia Layer
(SDL)
Version 1.2
---
http://www.libsdl.org/
This is the Simple DirectMedia Layer, a general API that provides low
level access to audio, keyboard, mouse, joystick, 3D hardware via OpenGL,
and 2D framebuffer across multiple platforms.
The current version supports Linux, Windows CE/95/98/ME/XP/Vista, BeOS,
MacOS Classic, Mac OS X, FreeBSD, NetBSD, OpenBSD, BSD/OS, Solaris, IRIX,
and QNX. The code contains support for Dreamcast, Atari, AIX, OSF/Tru64,
RISC OS, SymbianOS, Nintendo DS, and OS/2, but these are not officially
supported.
SDL is written in C, but works with C++ natively, and has bindings to
several other languages, including Ada, C#, Eiffel, Erlang, Euphoria,
Guile, Haskell, Java, Lisp, Lua, ML, Objective C, Pascal, Perl, PHP,
Pike, Pliant, Python, Ruby, and Smalltalk.
This library is distributed under GNU LGPL version 2, which can be
found in the file "COPYING". This license allows you to use SDL
freely in commercial programs as long as you link with the dynamic
library.
The best way to learn how to use SDL is to check out the header files in
the "include" subdirectory and the programs in the "test" subdirectory.
The header files and test programs are well commented and always up to date.
More documentation is available in HTML format in "docs/index.html", and
a documentation wiki is available online at:
http://www.libsdl.org/cgi/docwiki.cgi
The test programs in the "test" subdirectory are in the public domain.
Frequently asked questions are answered online:
http://www.libsdl.org/faq.php
If you need help with the library, or just want to discuss SDL related
issues, you can join the developers mailing list:
http://www.libsdl.org/mailing-list.php
Enjoy!
Sam Lantinga (slouken@libsdl.org)

View File

@@ -0,0 +1,13 @@
Please distribute this file with the SDL runtime environment:
The Simple DirectMedia Layer (SDL for short) is a cross-platfrom library
designed to make it easy to write multi-media software, such as games and
emulators.
The Simple DirectMedia Layer library source code is available from:
http://www.libsdl.org/
This library is distributed under the terms of the GNU LGPL license:
http://www.gnu.org/copyleft/lesser.html

View File

@@ -0,0 +1,12 @@
The AmigaOS code has been removed from SDL, since it had been broken for a
long time and had a few bits of fairly invasive code #ifdef'd into the
SDL core.
However, there is an OS4 version of SDL here:
http://www.rcdrummond.net/amiga/index.html
And a MorphOS version here:
http://www.lehtoranta.net/powersdl/
--ryan.

View File

@@ -0,0 +1,13 @@
SDL on BeOS R5
==============
You can build SDL on BeOS like any other GNU style package.
e.g. ./configure && make && make install
By default it is installed in /boot/develop/tools/gnupro/{bin,lib,etc.}
Once you install SDL, you need to copy libSDL.so to /boot/home/config/lib,
so it can be found by the dynamic linker.
Enjoy!
Sam Lantinga (slouken@libsdl.org)

View File

@@ -0,0 +1,4 @@
SDL is no longer hosted in a CVS repository. Please see README.SVN for
information on accessing our Subversion repository.

View File

@@ -0,0 +1,32 @@
SDL for Dreamcast (beta2)
BERO
berobero@users.sourceforge.net
http://www.geocities.co.jp/Playtown/2004/
this work with kos-newlib
http://sourceforge.net/projects/dcquake/
compile
- source environ.sh (from the KOS distribution)
- make -f Makefile.dc
compile with gl support
- install latest libgl from http://sourceforge.net/projects/dcquake/
- uncomment GL=1 in Makefile.dc
- make -f Makefile.dc clean
- make -f Makefile.dc
install
- copy include/*.h and libSDL.a or libSDL_gl.a for your enviroment
changelog:
beta2
- OpenGL support
- Hardware page flip support
beta
- thread, timer don't tested so much.
- not support OpenGL

View File

@@ -0,0 +1,63 @@
==============================================================================
Using the Simple DirectMedia Layer with MacOS 7,8,9 on PPC
==============================================================================
These instructions are for people using the Apple MPW environment:
http://developer.apple.com/tools/mpw-tools/
CodeWarrior projects are available in the CWprojects directory.
==============================================================================
I. Building the Simple DirectMedia Layer libraries:
(This step isn't necessary if you have the SDL binary distribution)
First, unpack the MPWmake.sea.hqx archive and move SDL.make into the
SDL directory.
Start MPW
Set the current directory within MPW to the SDL toplevel directory.
Build "SDL" (Type Command-B and enter "SDL" in the dialog)
If everything compiles successfully, you now have the PPC libraries
"SDL" and "SDLmain.o" in the 'lib' subdirectory.
==============================================================================
II. Building the Simple DirectMedia Layer test programs:
First, unpack the MPWmake.sea.hqx archive, move the new rsrc directory to
the main SDL directory, and move the makefiles in the new test subdirectory
to the SDL 'test' subdirectory.
Start MPW
Set the current directory within MPW to the SDL 'test' subdirectory.
Build the programs that have an associated MPW makefile (file ending
with .make), including "testwin", "testalpha", and "graywin".
Copy the SDL library file into the test directory, and run!
==============================================================================
III. Building the Simple DirectMedia Layer demo programs:
Copy one of the test program Makefiles to the demo directory
and modify it to match the sources in the demo.
==============================================================================
IV. Enjoy! :)
If you have a project you'd like me to know about, or want to ask questions,
go ahead and join the SDL developer's mailing list by sending e-mail to:
sdl-request@libsdl.org
and put "subscribe" into the subject of the message. Or alternatively you
can use the web interface:
http://www.libsdl.org/mailman/listinfo/sdl
==============================================================================

View File

@@ -0,0 +1,186 @@
==============================================================================
Using the Simple DirectMedia Layer with Mac OS X
==============================================================================
These instructions are for people using Apple's Mac OS X (pronounced
"ten").
From the developer's point of view, OS X is a sort of hybrid Mac and
Unix system, and you have the option of using either traditional
command line tools or Apple's IDE Xcode.
To build SDL using the command line, use the standard configure and make
process:
./configure
make
sudo make install
You can also build SDL as a Universal library (a single binary for both
PowerPC and Intel architectures), on Mac OS X 10.4 and newer, by using
the fatbuild.sh script in build-scripts:
sh build-scripts/fatbuild.sh
sudo build-scripts/fatbuild.sh install
This script builds SDL with 10.2 ABI compatibility on PowerPC and 10.4
ABI compatibility on Intel architectures. For best compatibility you
should compile your application the same way. A script which wraps
gcc to make this easy is provided in test/gcc-fat.sh
To use the library once it's built, you essential have two possibilities:
use the traditional autoconf/automake/make method, or use Xcode.
==============================================================================
Using the Simple DirectMedia Layer with a traditional Makefile
==============================================================================
An existing autoconf/automake build system for your SDL app has good chances
to work almost unchanged on OS X. However, to produce a "real" Mac OS X binary
that you can distribute to users, you need to put the generated binary into a
so called "bundle", which basically is a fancy folder with a name like
"MyCoolGame.app".
To get this build automatically, add something like the following rule to
your Makefile.am:
bundle_contents = APP_NAME.app/Contents
APP_NAME_bundle: EXE_NAME
mkdir -p $(bundle_contents)/MacOS
mkdir -p $(bundle_contents)/Resources
echo "APPL????" > $(bundle_contents)/PkgInfo
$(INSTALL_PROGRAM) $< $(bundle_contents)/MacOS/
You should replace EXE_NAME with the name of the executable. APP_NAME is what
will be visible to the user in the Finder. Usually it will be the same
as EXE_NAME but capitalized. E.g. if EXE_NAME is "testgame" then APP_NAME
usually is "TestGame". You might also want to use @PACKAGE@ to use the package
name as specified in your configure.in file.
If your project builds more than one application, you will have to do a bit
more. For each of your target applications, you need a seperate rule.
If you want the created bundles to be installed, you may want to add this
rule to your Makefile.am:
install-exec-hook: APP_NAME_bundle
rm -rf $(DESTDIR)$(prefix)/Applications/APP_NAME.app
mkdir -p $(DESTDIR)$(prefix)/Applications/
cp -r $< /$(DESTDIR)$(prefix)Applications/
This rule takes the Bundle created by the rule from step 3 and installs them
into $(DESTDIR)$(prefix)/Applications/.
Again, if you want to install multiple applications, you will have to augment
the make rule accordingly.
But beware! That is only part of the story! With the above, you end up with
a bare bone .app bundle, which is double clickable from the Finder. But
there are some more things you should do before shipping yor product...
1) The bundle right now probably is dynamically linked against SDL. That
means that when you copy it to another computer, *it will not run*,
unless you also install SDL on that other computer. A good solution
for this dilemma is to static link against SDL. On OS X, you can
achieve that by linkinag against the libraries listed by
sdl-config --static-libs
instead of those listed by
sdl-config --libs
Depending on how exactly SDL is integrated into your build systems, the
way to achieve that varies, so I won't describe it here in detail
2) Add an 'Info.plist' to your application. That is a special XML file which
contains some meta-information about your application (like some copyright
information, the version of your app, the name of an optional icon file,
and other things). Part of that information is displayed by the Finder
when you click on the .app, or if you look at the "Get Info" window.
More information about Info.plist files can be found on Apple's homepage.
As a final remark, let me add that I use some of the techniques (and some
variations of them) in Exult and ScummVM; both are available in source on
the net, so feel free to take a peek at them for inspiration!
==============================================================================
Using the Simple DirectMedia Layer with Xcode
==============================================================================
These instructions are for using Apple's Xcode IDE to build SDL applications.
- First steps
The first thing to do is to unpack the Xcode.tar.gz archive in the
top level SDL directory (where the Xcode.tar.gz archive resides).
Because Stuffit Expander will unpack the archive into a subdirectory,
you should unpack the archive manually from the command line:
cd [path_to_SDL_source]
tar zxf Xcode.tar.gz
This will create a new folder called Xcode, which you can browse
normally from the Finder.
- Building the Framework
The SDL Library is packaged as a framework bundle, an organized
relocatable folder heirarchy of executible code, interface headers,
and additional resources. For practical purposes, you can think of a
framework as a more user and system-friendly shared library, whose library
file behaves more or less like a standard UNIX shared library.
To build the framework, simply open the framework project and build it.
By default, the framework bundle "SDL.framework" is installed in
/Library/Frameworks. Therefore, the testers and project stationary expect
it to be located there. However, it will function the same in any of the
following locations:
~/Library/Frameworks
/Local/Library/Frameworks
/System/Library/Frameworks
- Build Options
There are two "Build Styles" (See the "Targets" tab) for SDL.
"Deployment" should be used if you aren't tweaking the SDL library.
"Development" should be used to debug SDL apps or the library itself.
- Building the Testers
Open the SDLTest project and build away!
- Using the Project Stationary
Copy the stationary to the indicated folders to access it from
the "New Project" and "Add target" menus. What could be easier?
- Setting up a new project by hand
Some of you won't want to use the Stationary so I'll give some tips:
* Create a new "Cocoa Application"
* Add src/main/macosx/SDLMain.m , .h and .nib to your project
* Remove "main.c" from your project
* Remove "MainMenu.nib" from your project
* Add "$(HOME)/Library/Frameworks/SDL.framework/Headers" to include path
* Add "$(HOME)/Library/Frameworks" to the frameworks search path
* Add "-framework SDL -framework Foundation -framework AppKit" to "OTHER_LDFLAGS"
* Set the "Main Nib File" under "Application Settings" to "SDLMain.nib"
* Add your files
* Clean and build
- Building from command line
Use pbxbuild in the same directory as your .pbproj file
- Running your app
You can send command line args to your app by either invoking it from
the command line (in *.app/Contents/MacOS) or by entering them in the
"Executibles" panel of the target settings.
- Implementation Notes
Some things that may be of interest about how it all works...
* Working directory
As defined in the SDL_main.m file, the working directory of your SDL app
is by default set to its parent. You may wish to change this to better
suit your needs.
* You have a Cocoa App!
Your SDL app is essentially a Cocoa application. When your app
starts up and the libraries finish loading, a Cocoa procedure is called,
which sets up the working directory and calls your main() method.
You are free to modify your Cocoa app with generally no consequence
to SDL. You cannot, however, easily change the SDL window itself.
Functionality may be added in the future to help this.
Known bugs are listed in the file "BUGS"

Some files were not shown because too many files have changed in this diff Show More