author | andyq <andyq> | 2003-01-21 20:37:00 (UTC) |
---|---|---|
committer | andyq <andyq> | 2003-01-21 20:37:00 (UTC) |
commit | 0a6563fcc2f49857c581d9def24407a3a4ef526c (patch) (side-by-side diff) | |
tree | f1b82a4bd7582ef2cb722cffb87eecff1e1f96e6 | |
parent | 50b5915b48fc5cbacf23e4d2b75d7a266f141a4a (diff) | |
download | opie-0a6563fcc2f49857c581d9def24407a3a4ef526c.zip opie-0a6563fcc2f49857c581d9def24407a3a4ef526c.tar.gz opie-0a6563fcc2f49857c581d9def24407a3a4ef526c.tar.bz2 |
Clean up of code - fixed memory leaks (most of them) and added new custom config menu
25 files changed, 791 insertions, 409 deletions
diff --git a/noncore/games/sfcave-sdl/animatedimage.cpp b/noncore/games/sfcave-sdl/animatedimage.cpp index d9d6ff6..441c647 100644 --- a/noncore/games/sfcave-sdl/animatedimage.cpp +++ b/noncore/games/sfcave-sdl/animatedimage.cpp @@ -1,68 +1,68 @@ #include "SDL.h" #include "SDL_image.h" #include "constants.h" #include "animatedimage.h" -AnimatedImage :: AnimatedImage( QString file, int nFrames ) +AnimatedImage :: AnimatedImage( string file, int nFrames ) { nrFrames = nFrames; currentFrame = 0; // Load image image = IMG_Load( (const char *)file.c_str() ); if ( !image ) { nrFrames = 0; image = 0; return; } SDL_SetColorKey(image, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB( image->format, 0, 0, 0 ) ); -// image = SDL_DisplayFormat( tmp ); - -// SDL_FreeSurface( tmp ); frameWidth = image->w/nrFrames; frameHeight = image->h; } AnimatedImage :: ~AnimatedImage() { if ( image != 0 ) SDL_FreeSurface( image ); } bool AnimatedImage :: nextFrame() { bool rc = true; currentFrame ++; if ( currentFrame >= nrFrames ) { currentFrame --; rc = false; } return rc; } void AnimatedImage :: draw( SDL_Surface *screen, int x, int y ) { + if ( !image ) + return; + SDL_Rect dst; dst.x = currentFrame * frameWidth; dst.y = 0; dst.w = frameWidth; dst.h = frameHeight; SDL_Rect dst2; dst2.x = x - (frameWidth/2); dst2.y = y - (frameHeight/2);; SDL_BlitSurface( image, &dst, screen, &dst2 ); } bool AnimatedImage :: AtEnd() { if ( currentFrame +1 >= nrFrames || image == 0 ) return true; return false; } diff --git a/noncore/games/sfcave-sdl/animatedimage.h b/noncore/games/sfcave-sdl/animatedimage.h index 1b38e6d..3c03f52 100644 --- a/noncore/games/sfcave-sdl/animatedimage.h +++ b/noncore/games/sfcave-sdl/animatedimage.h @@ -1,25 +1,25 @@ #ifndef __ANIMATED_IMAGE_H #define __ANIMATED_IMAGE_H #include "SDL.h" class AnimatedImage { public: - AnimatedImage( QString file, int nFrames ); + AnimatedImage( string file, int nFrames ); ~AnimatedImage(); bool nextFrame(); void draw( SDL_Surface *screen, int x, int y ); bool AtEnd(); void reset() { currentFrame = 0; } private: SDL_Surface *image; int nrFrames; int currentFrame; int frameWidth; int frameHeight; }; #endif diff --git a/noncore/games/sfcave-sdl/bfont.cpp b/noncore/games/sfcave-sdl/bfont.cpp index 0f29104..7dec8f5 100644 --- a/noncore/games/sfcave-sdl/bfont.cpp +++ b/noncore/games/sfcave-sdl/bfont.cpp @@ -1,230 +1,225 @@ /***********************************************************/ /* */ /* BFONT.c v. 1.0.2 - Billi Font Library by Diego Billi */ /* BFONT++ C++ port by Gianluigi Davassi */ /***********************************************************/ #include "iostream" using namespace std; #include "string.h" #include "stdlib.h" #include "stdarg.h" #include "SDL_image.h" #include "bfont.h" void BFont::InitFont() { int x = 0, i = '!'; Uint32 sentry = GetPixel(0,0); if (SDL_MUSTLOCK(Surface)) SDL_LockSurface(Surface); while ( x < (Surface->w-1)) { if(GetPixel(x,0) != sentry) { Chars[i].x = x; Chars[i].y = 1; Chars[i].h = Surface->h; for (; GetPixel(x, 0) != sentry && x < (Surface->w); ++x) ; Chars[i].w = (x - Chars[i].x); i++; } else { x++; } } Chars[' '].x = 0; Chars[' '].y = 0; Chars[' '].h = Surface->h; Chars[' '].w = Chars['!'].w; if (SDL_MUSTLOCK(Surface)) SDL_UnlockSurface(Surface); h = Surface->h; SDL_SetColorKey(Surface, SDL_SRCCOLORKEY, GetPixel(0, Surface->h-1)); } /* Load the font and stores it in the BFont_Info structure */ void BFont::LoadFont (const char *filename) { SDL_Surface *surface(NULL); int x; // tutta roba inutile in C++.... :-) /* BFont_Info *Font=NULL; Font = (BFont_Info *) malloc(sizeof(BFont_Info));*/ if ((filename != NULL ) && (this != NULL)) { surface = IMG_Load( filename ); if (surface != NULL) { Surface = surface; for (x=0; x<256; x++) { Chars[x].x = 0; Chars[x].y = 0; Chars[x].h = 0; Chars[x].w = 0; } InitFont(); // Init the font } } - else - { - cerr << "Error! The font has not been loaded!" << endl; - } } BFont * BFont :: SetFontColor(Uint8 r, Uint8 g, Uint8 b) { int x,y; BFont *newfont; SDL_Surface *surface = NULL; Uint32 pixel; Uint8 old_r, old_g, old_b; Uint8 new_r, new_g, new_b; Uint32 color_key; newfont = new BFont(NULL); if (newfont != NULL) { newfont->h = h; for (x=0; x<256; x++) { newfont->Chars[x].x = Chars[x].x; newfont->Chars[x].y = Chars[x].y; newfont->Chars[x].h = Chars[x].h; newfont->Chars[x].w = Chars[x].w; } surface = SDL_CreateRGBSurface(SDL_SWSURFACE, Surface->w, Surface->h, 32, 0x000000ff,0x0000ff00, 0x00ff0000, 0xff000000); if (surface != NULL) { if (SDL_MUSTLOCK(surface)) SDL_LockSurface(surface); if (SDL_MUSTLOCK(Surface)) SDL_LockSurface(Surface); color_key = xGetPixel(Surface, 0, Surface->h-1); - printf("looking...\n"); for( x=0; x < Surface->w; x++) { for( y=0; y < Surface->h; y++) { old_r = old_g = old_b = 0; pixel = xGetPixel(Surface,x,y); if (pixel != color_key) { SDL_GetRGB(pixel, Surface->format, &old_r,&old_g,&old_b); new_r = (Uint8) ((old_r * r) / 255); new_g = (Uint8) ((old_g * g) / 255); new_b = (Uint8) ((old_b * b) / 255); pixel = SDL_MapRGB(surface->format,new_r,new_g,new_b); } PutPixel(surface,x,y,pixel); } } - printf("unlooking...\n"); + if (SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface); if (SDL_MUSTLOCK(Surface)) SDL_UnlockSurface(Surface); SDL_SetColorKey(surface, SDL_SRCCOLORKEY, color_key); } newfont->Surface = surface; } return newfont; } /* Puts a single char on the surface with the specified font */ int BFont::PutChar(SDL_Surface *screen, int x, int y, char c) { int r=0; SDL_Rect dest; dest.w = CharWidth(' '); dest.h = FontHeight(); dest.x = x; dest.y = y; if (c != ' ') SDL_BlitSurface( Surface, &Chars[c], screen, &dest); r = dest.w; return r; } void BFont::PutString(SDL_Surface *screen, int x, int y, const char *text) { int i(0); while (text[i]!='\0') { x += PutChar(screen,x,y,text[i]); i++; } } int BFont::TextWidth(const char *text) { int i(0),x(0); while (text[i]!='\0') { x += CharWidth(text[i]); i++; } return x; } /* counts the spaces of the strings */ int BFont::count (const char *text) { char *p(NULL); int pos(-1),i(0); /* Calculate the space occupied by the text without spaces */ while ((p=strchr(&text[pos+1],' ')) != NULL) { i++; pos = p - text; } return i; } void BFont::JustifiedPutString( SDL_Surface *screen, int y, const char *text) { int spaces(0),gap,single_gap,dif; char *strtmp,*p; int pos(-1),xpos(0); if (strchr(text,' ') == NULL) { PutString(screen, 0, y, text); } else { gap = (screen->w-1) - TextWidth(text); if (gap <= 0) { PutString(screen, 0,y,text); } else { spaces = count(text); dif = gap % spaces; single_gap = (gap - dif) / spaces; xpos=0; pos = -1; while ( spaces > 0 ) { p = strstr(&text[pos+1]," "); strtmp = NULL; diff --git a/noncore/games/sfcave-sdl/constants.h b/noncore/games/sfcave-sdl/constants.h index 8fadae4..f10764e 100644 --- a/noncore/games/sfcave-sdl/constants.h +++ b/noncore/games/sfcave-sdl/constants.h @@ -1,67 +1,84 @@ #ifndef __CONSTANTS_H #define __CONSTANTS_H #include <string> using namespace std; -#define QString string #ifdef QWS #define IMAGES_PATH "/opt/QtPalmtop/pics/sfcave/data/" #define SOUND_PATH "/opt/QtPalmtop/sounds/sfcave/" #else #define IMAGES_PATH "./images/" #define SOUND_PATH "./sounds/" #endif // Width and height of app #define WIDTH 240 #define HEIGHT 320 //Number of map segments #define MAPSIZE 51 // Maximum number of blocks visible on screen at any one time #define BLOCKSIZE 6 // length of players trail #define TRAILSIZE 60 // Game States #define STATE_QUIT -1 #define STATE_PLAYING 0 #define STATE_CRASHING 1 #define STATE_CRASHED 2 #define STATE_NEWGAME 3 #define STATE_MENU 4 #define STATE_REPLAY 5 #define STATE_HELP 6 // Menu Options #define MENU_STARTGAME 1 #define MENU_REPLAYS 2 #define MENU_OPTIONS 3 #define MENU_HELP 4 #define MENU_QUIT 5 #define MENU_PLAY_REPLAY 6 #define MENU_LOAD_REPLAY 7 #define MENU_SAVE_REPLAY 8 #define MENU_BACK 9 #define MENU_GAME_TYPE 10 #define MENU_DIFFICULTY 11 #define MENU_CLEAR_SCORES 12 #define MENU_GAME_SFCAVE 13 #define MENU_GAME_GATES 14 #define MENU_GAME_FLY 15 #define MENU_DIFFICULTY_EASY 16 #define MENU_DIFFICULTY_NORMAL 17 #define MENU_DIFFICULTY_HARD 18 -#define MENU_SOUNDS 19 -#define MENU_SOUND_ON 20 -#define MENU_SOUND_OFF 21 -#define MENU_MUSIC_ON 22 -#define MENU_MUSIC_OFF 23 +#define MENU_DIFFICULTY_HARD 18 +#define MENU_DIFFICULTY_CUSTOM 19 +#define MENU_SOUNDS 20 +#define MENU_SOUND_ON 21 +#define MENU_SOUND_OFF 22 +#define MENU_MUSIC_ON 23 +#define MENU_MUSIC_OFF 24 +#define MENU_CUSTOM_THRUST 25 +#define MENU_CUSTOM_GRAVITY 26 +#define MENU_CUSTOM_MAXSPEEDUP 27 +#define MENU_CUSTOM_MAXSPEEDDOWN 28 +#define MENU_CUSTOM_INCREASE 29 +#define MENU_CUSTOM_DECREASE 30 +#define MENU_CUSTOM_SAVE 31 +#define MENU_CUSTOM_CANCEL 32 // Sounds #define SND_EXPLOSION 0 #define SND_THRUST 1 +#define INGAME_MUSIC SOUND_PATH "ingame.mod" + +// Constants for player values +#define PLAYER_THRUST 0 +#define PLAYER_GRAVITY 1 +#define PLAYER_MAX_SPEED_UP 2 +#define PLAYER_MAX_SPEED_DOWN 3 + #endif diff --git a/noncore/games/sfcave-sdl/fly_game.cpp b/noncore/games/sfcave-sdl/fly_game.cpp index f5ab401..7605c3f 100644 --- a/noncore/games/sfcave-sdl/fly_game.cpp +++ b/noncore/games/sfcave-sdl/fly_game.cpp @@ -1,103 +1,112 @@ #include "SDL_gfxPrimitives.h" #include "constants.h" #include "fly_game.h" #include "random.h" FlyGame :: FlyGame( SFCave *p, int w, int h, int diff ) : Game( p, w, h, diff ) { gameName = "Fly"; difficulty = MENU_DIFFICULTY_EASY; terrain = new FlyTerrain( w, h ); player = new Player( w, h ); highScore = 0; } FlyGame :: ~FlyGame() { + // terrain and player get deleted by parent class } void FlyGame :: init() { Game :: init(); switch( difficulty ) { case MENU_DIFFICULTY_EASY: player->setMovementInfo( 0.3, 0.2, 1.5, 1.5 ); break; case MENU_DIFFICULTY_NORMAL: player->setMovementInfo( 0.35, 0.4, 2.5, 3 ); break; case MENU_DIFFICULTY_HARD: player->setMovementInfo( 0.4, 0.6, 4, 5 ); break; + case MENU_DIFFICULTY_CUSTOM: + { + double thrust = parent->loadDoubleSetting( "Fly_custom_player_thrust", 0.3 ); + double gravity = parent->loadDoubleSetting( "Fly_custom_player_gravity", 0.2 ); + double maxUp = parent->loadDoubleSetting( "Fly_custom_player_maxupspeed", 1.5 ); + double maxDown = parent->loadDoubleSetting( "Fly_custom_player_maxdownspeed", 1.5 ); + player->setMovementInfo( thrust, gravity, maxUp, maxDown ); + break; + } } startScoring = false; } void FlyGame :: update( int state ) { Game::update( state ); if ( state == STATE_PLAYING ) { if ( nrFrames % 3 == 0 ) { int diff = terrain->getMapBottom( 10 ) - player->getY(); int tmpScore = ((FlyTerrain *)terrain)->getScore( 1, diff ); -// printf( "diff - %d score - %d\n", diff, tmpScore ); + if ( !startScoring ) { if ( tmpScore > 0 ) startScoring = true; } if ( startScoring ) { // Update score // get distance between landscape and ship // the closer the difference is to 0 means more points score += tmpScore; } } if ( checkCollisions() ) { -// printf( "Crashed!\n" ); parent->changeState( STATE_CRASHING ); return; } // Game logic goes here terrain->moveTerrain( 5 ); player->move( press ); } } void FlyGame :: draw( SDL_Surface *screen ) { Game::preDraw( screen ); // Screen drawing goes here terrain->drawTerrain( screen ); player->draw( screen ); Game::draw( screen ); } bool FlyGame :: checkCollisions() { bool ret = false; // Check collision with landscape return terrain->checkCollision( player->getX(), player->getY(), player->getHeight() ); } diff --git a/noncore/games/sfcave-sdl/font.cpp b/noncore/games/sfcave-sdl/font.cpp index 2976d48..1988252 100644 --- a/noncore/games/sfcave-sdl/font.cpp +++ b/noncore/games/sfcave-sdl/font.cpp @@ -1,72 +1,84 @@ #include "font.h" #include "constants.h" BFont *FontHandler :: menuSelFont; BFont *FontHandler :: menuUnSelFont; BFont *FontHandler :: whiteFont; BFont *FontHandler :: colouredFont; BFont *FontHandler :: helpFont; -void FontHandler :: init() +bool FontHandler :: init() { // Load font images // Convert to fonts menuSelFont = new BFont( IMAGES_PATH "sel_menu_font.bmp" ); menuUnSelFont = new BFont( IMAGES_PATH "unsel_menu_font.bmp" ); whiteFont = new BFont( IMAGES_PATH "score_font.bmp" ); helpFont = new BFont( IMAGES_PATH "help_font.bmp" ); colouredFont = 0; + + // Check if we are installed correctly (we need fonts to function) + if ( menuSelFont == 0 || menuUnSelFont == 0 || whiteFont == 0 || helpFont == 0 ) + { + printf( "One or more fonts are not installed correctly\n" ); + return false; + } + + return true; } void FontHandler :: cleanUp() { - delete menuSelFont; - delete menuUnSelFont; - delete whiteFont; - delete helpFont; - + if ( menuSelFont ) + delete menuSelFont; + if ( menuUnSelFont ) + delete menuUnSelFont; + if ( whiteFont ) + delete whiteFont; + if ( helpFont ) + delete helpFont; if ( colouredFont ) delete colouredFont; } int FontHandler :: TextWidth( int font, const char *text ) { return getFont( font )->TextWidth( text ); } int FontHandler :: FontHeight( int font ) { return getFont( font )->FontHeight(); } void FontHandler :: draw( SDL_Surface *screen, int font, const char *text, int x, int y ) { if ( x == -1 ) getFont( font )->CenteredPutString( screen, y, text ); else getFont( font )->PutString( screen, x, y, text ); } void FontHandler :: changeColor( int font, int r, int g, int b ) { if ( colouredFont ) delete colouredFont; colouredFont = getFont( font )->SetFontColor( r, g, b ); } BFont *FontHandler :: getFont( int font ) { if ( font == FONT_MENU_HIGHLIGHTED ) return menuSelFont; else if ( font == FONT_MENU_UNHIGHLIGHTED ) return menuUnSelFont; else if ( font == FONT_COLOURED_TEXT ) return colouredFont; else if ( font == FONT_HELP_FONT ) return helpFont; else return whiteFont; } diff --git a/noncore/games/sfcave-sdl/font.h b/noncore/games/sfcave-sdl/font.h index e5bb707..5f0674a 100644 --- a/noncore/games/sfcave-sdl/font.h +++ b/noncore/games/sfcave-sdl/font.h @@ -1,33 +1,33 @@ #ifndef __FONT_H #define __FONT_H #include "SDL.h" #include "bfont.h" #define FONT_MENU_HIGHLIGHTED 1 #define FONT_MENU_UNHIGHLIGHTED 2 #define FONT_WHITE_TEXT 3 #define FONT_COLOURED_TEXT 4 #define FONT_HELP_FONT 5 class FontHandler { public: - static void init(); + static bool init(); static void cleanUp(); static int TextWidth( int font, const char *text ); static int FontHeight( int font ); static void draw( SDL_Surface *screen, int font, const char *text, int x, int y ); static void changeColor( int font, int r, int g, int b ); static BFont *getFont( int font ); private: static BFont *menuSelFont; static BFont *menuUnSelFont; static BFont *whiteFont; static BFont *colouredFont; static BFont *helpFont; }; #endif diff --git a/noncore/games/sfcave-sdl/game.cpp b/noncore/games/sfcave-sdl/game.cpp index a644696..e41e510 100644 --- a/noncore/games/sfcave-sdl/game.cpp +++ b/noncore/games/sfcave-sdl/game.cpp @@ -1,332 +1,328 @@ #include <stdio.h> #include <time.h> #include <SDL.h> #include <SDL_image.h> #include "font.h" #include "constants.h" #include "game.h" #include "player.h" #include "random.h" #include "sound.h" #include "stringtokenizer.h" #include "sfcave_game.h" #include "gates_game.h" #include "fly_game.h" #include "starfield.h" Game :: Game( SFCave *p, int w, int h, int diff ) { parent = p; sHeight = h; sWidth = w; difficulty = diff; replayIt = 0; replay = false; terrain = 0; player = 0; thrustChannel = -1; } Game :: ~Game() { if ( terrain ) delete terrain; if ( player ) delete player; replayList.clear(); } void Game :: init() { if ( replay ) { setSeed( currentSeed ); replayIt = replayList.begin(); } else { setSeed( -1 ); replayList.clear(); } - + score = 0; nrFrames = 0; press = false; // Load highscore string key = getGameName() + "_" + getGameDifficultyText() + "_highscore"; highScore = atoi( parent->loadSetting( key, "0" ).c_str() ); terrain->initTerrain(); player->init(); } void Game :: handleKeys( SDL_KeyboardEvent &key ) { if ( !replay && key.keysym.sym == SDLK_SPACE ) { if ( key.type == SDL_KEYDOWN ) { if ( !press ) replayList.push_back( nrFrames ); press = true; - -// if ( thrustChannel == -1 && parent->getState() == STATE_PLAYING ) -// thrustChannel = SoundHandler :: playSound( SND_THRUST, -1, -1, false ); } else { if ( press ) replayList.push_back( nrFrames ); press = false; - if ( thrustChannel != -1 ) - { -// SoundHandler :: stopSound( thrustChannel, true, 300 ); -// thrustChannel = -1; - } } } } -QString Game :: getGameDifficultyText() +string Game :: getGameDifficultyText() { - QString ret; + string ret; if ( difficulty == MENU_DIFFICULTY_EASY ) ret = "Easy"; else if ( difficulty == MENU_DIFFICULTY_NORMAL ) ret = "Medium"; else if ( difficulty == MENU_DIFFICULTY_HARD ) ret = "Hard"; + else if ( difficulty == MENU_DIFFICULTY_CUSTOM ) + ret = "Custom"; return ret; } void Game :: setDifficulty( string diff ) { if ( diff == "Easy" ) difficulty = MENU_DIFFICULTY_EASY; else if ( diff == "Medium" ) difficulty = MENU_DIFFICULTY_NORMAL; else if ( diff == "Hard" ) difficulty = MENU_DIFFICULTY_HARD; + else if ( diff == "Custom" ) + difficulty = MENU_DIFFICULTY_CUSTOM; + + init(); +} + +void Game :: setDifficulty( int diff ) +{ + difficulty = diff; + init(); } void Game :: update( int state ) { nrFrames ++; if ( score > highScore ) highScore = score; if ( state == STATE_PLAYING ) { - if ( replay ) + if ( replay ) { while( replayIt != replayList.end() && (*replayIt) == nrFrames-1 ) { press = !press; replayIt ++; } } if ( press && thrustChannel == -1 ) thrustChannel = SoundHandler :: playSound( SND_THRUST, -1, -1, false ); if ( !press &&thrustChannel != -1 ) { SoundHandler :: stopSound( thrustChannel, true, 300 ); thrustChannel = -1; } } if ( state == STATE_CRASHING || state == STATE_CRASHED ) { // fade out any trail marks remainin if ( player->updateCrashing() ) parent->changeState( STATE_CRASHED ); } } void Game :: preDraw( SDL_Surface *screen ) { } void Game :: draw( SDL_Surface *screen ) { char tmp[100]; - QString scoreText; + string scoreText; sprintf( tmp, "Score: %06ld High Score: %06ld", score, highScore ); -// printf( "%s\n", (const char *)scoreText ); FontHandler::draw( screen, FONT_WHITE_TEXT, tmp, 3, 10 ); if ( parent->getState() == STATE_CRASHED ) { - QString crashText; + string crashText; crashText = "Game Over"; int x = (240 - FontHandler::TextWidth( FONT_WHITE_TEXT, (const char *)crashText.c_str() )) / 2; FontHandler::draw( screen, FONT_WHITE_TEXT, (const char *)crashText.c_str(), x, 150 ); int fontHeight = FontHandler::FontHeight( FONT_WHITE_TEXT ); crashText = "Press Middle Button to play again"; x = (240 - FontHandler::TextWidth( FONT_WHITE_TEXT, (const char *)crashText.c_str() )) / 2; FontHandler::draw( screen, FONT_WHITE_TEXT, (const char *)crashText.c_str(), x, 150 + fontHeight ); crashText = "or OK for menu"; x = (240 - FontHandler::TextWidth( FONT_WHITE_TEXT, (const char *)crashText.c_str() )) / 2; FontHandler::draw( screen, FONT_WHITE_TEXT, (const char *)crashText.c_str(), x, 150 + 2*fontHeight ); } if ( parent->showFPS() ) { sprintf( tmp, "FPS : %d", parent->getFPS() ); FontHandler::draw( screen, FONT_WHITE_TEXT, tmp, 20, 300 ); } } void Game :: stateChanged( int from, int to ) { if ( from != STATE_CRASHING && to == STATE_CRASHING ) { // play explosion sound SoundHandler :: stopSound( -1, false ); SoundHandler :: playSound( SND_EXPLOSION ); // Check and save highscore printf( "Got Highscore = %d\n", gotHighScore() ); if ( gotHighScore() ) { string key = getGameName() + "_" + getGameDifficultyText() + "_highscore"; parent->saveSetting( key, getHighScore() ); } } } void Game :: setSeed( int seed ) { if ( seed == -1 ) currentSeed = ((unsigned long) time((time_t *) NULL)); else currentSeed = seed; PutSeed( currentSeed ); } -void Game :: saveReplay( QString file ) +void Game :: saveReplay( string file ) { FILE *out; out = fopen( file.c_str(), "w" ); if ( !out ) { printf( "Couldn't write to /home/root/%s\n", file.c_str() ); parent->setMenuStatusText( "Couldn't save replay file" ); return; } // Build up string of values // Format is:: <landscape seed> <game type> <difficulty> <framenr> <framenr>....... - QString val; + string val; char tmp[20]; sprintf( tmp, "%d %d ", currentSeed, difficulty ); val = tmp; list<int>::iterator it = replayList.begin(); while( it != replayList.end() ) { sprintf( tmp, "%d ", *it ); val += tmp; it++; } val += "\n"; - QString line; + string line; sprintf( tmp, "%d\n", val.length() ); line = tmp; fwrite( line.c_str(), 1, line.length(), out ); fwrite( val.c_str(), 1, val.length(), out ); fclose( out ); - - printf( "Replay saved to %s\n", (const char *)file.c_str() ); - } -void Game :: loadReplay( QString file ) +void Game :: loadReplay( string file ) { FILE *in = fopen( (const char *)file.c_str(), "r" ); if ( in == 0 ) { printf( "Couldn't load replay file %s!\n", (const char *)file.c_str() ); parent->setMenuStatusText( "Couldn't load replay file" ); return; } // Read next line - contains the size of the options char line[10+1]; fgets( line, 10, in ); int length = -1; sscanf( line, "%d", &length ); char *data = new char[length+1]; fread( data, 1, length, in ); -// printf( "data - %s", data ); - QString sep = " "; + string sep = " "; StringTokenizer st( data, sep ); // print it out vector<string>::iterator it = st.begin(); currentSeed = atoi( (*it).c_str() ); ++it; difficulty = atoi( (*it).c_str() ); ++it; replayList.clear(); for ( ; it != st.end(); ++it ) { int v = atoi( (*it).c_str() ); replayList.push_back( v ); } delete data; fclose( in ); - - printf( "Replay loaded from %s\n", (const char *)file.c_str() ); - } Game *Game :: createGame( SFCave *p, int w, int h, string game, string difficulty ) { Game *g; if ( game == "SFCave" ) g = new SFCaveGame( p, w, h, 0 ); else if ( game == "Gates" ) g = new GatesGame( p, w, h, 0 ); else if ( game == "Fly" ) g = new FlyGame( p, w, h, 0 ); if ( g ) g->setDifficulty( difficulty ); return g; } diff --git a/noncore/games/sfcave-sdl/game.h b/noncore/games/sfcave-sdl/game.h index 56fa6a1..087f848 100644 --- a/noncore/games/sfcave-sdl/game.h +++ b/noncore/games/sfcave-sdl/game.h @@ -1,82 +1,81 @@ #ifndef __GAME_H #define __GAME_H #include <list> using namespace std; #include "sfcave.h" class Terrain; class Player; class Game { public: Game( SFCave *p, int w, int h, int diff ); virtual ~Game(); virtual void init( ); virtual void update( int state ); virtual void preDraw( SDL_Surface * ); virtual void draw( SDL_Surface * ); virtual void stateChanged( int from, int to ); void setReplay( bool val ) { replay = val; } void handleKeys( SDL_KeyboardEvent &key ); - QString getGameName() { return gameName; } + string getGameName() { return gameName; } int getDifficulty() { return difficulty; } - QString getGameDifficultyText(); - void setDifficulty( int diff ) { difficulty = diff; } + string getGameDifficultyText(); + void setDifficulty( int diff ); void setDifficulty( string diff ); long getScore() { return score; } long getHighScore() { return highScore; } void increaseScore( long val ) { score += val; } void clearScore() { score = 0; } bool gotHighScore() { return (score >= highScore); } bool isReplayAvailable() { return replayList.size() > 0; } Terrain *getTerrain() { return terrain; } + Player *getPlayer() { return player; } void setSeed( int seed ); - void loadReplay( QString file ); - void saveReplay( QString file ); + void loadReplay( string file ); + void saveReplay( string file ); static Game *createGame( SFCave *p, int w, int h, string game, string difficulty ); protected: - QString gameName; + string gameName; int thrustChannel; int difficulty; SFCave *parent; Terrain *terrain; Player *player; int nrFrames; bool press; int sHeight; int sWidth; long score; long highScore; // Stuff for the replays int currentSeed; -// QListIterator<int> *replayIt; list<int> replayList; list<int>::iterator replayIt; -// QList<int> replayList; bool replay; - QString replayFile; + string replayFile; private: }; #endif diff --git a/noncore/games/sfcave-sdl/gates_game.cpp b/noncore/games/sfcave-sdl/gates_game.cpp index 1a9bc89..762801d 100644 --- a/noncore/games/sfcave-sdl/gates_game.cpp +++ b/noncore/games/sfcave-sdl/gates_game.cpp @@ -1,176 +1,189 @@ #include "SDL_gfxPrimitives.h" #include "constants.h" #include "gates_game.h" #include "random.h" GatesGame :: GatesGame( SFCave *p, int w, int h, int diff ) : Game( p, w, h, diff ) { gameName = "Gates"; difficulty = MENU_DIFFICULTY_EASY; blockUpdateRate = 200; terrain = new Terrain( w, h ); player = new Player( w, h ); highScore = 0; } GatesGame :: ~GatesGame() { + // terrain and player get deleted by parent class } void GatesGame :: init() { Game :: init(); blockHeight = 80; blockWidth = 20; lastGateBottomY = 0; gateDistance = 75; nextGate = nextInt( 50 ) + gateDistance; gapHeight = 75; switch( difficulty ) { case MENU_DIFFICULTY_EASY: gapHeight = 75; player->setMovementInfo( 0.4, 0.6, 4, 5 ); break; case MENU_DIFFICULTY_NORMAL: gapHeight = 50; player->setMovementInfo( 0.4, 0.6, 4, 5 ); break; case MENU_DIFFICULTY_HARD: gapHeight = 25; player->setMovementInfo( 0.6, 0.8, 6, 7 ); break; + case MENU_DIFFICULTY_CUSTOM: + { + // Read custom difficulty settings for this game + gapHeight = parent->loadIntSetting( "Gates_custom_gapHeight", 75 ); + + double thrust = parent->loadDoubleSetting( "Gates_custom_player_thrust", 0.4 ); + double gravity = parent->loadDoubleSetting( "Gates_custom_player_gravity", 0.6 ); + double maxUp = parent->loadDoubleSetting( "Gates_custom_player_maxupspeed", 4.0 ); + double maxDown = parent->loadDoubleSetting( "Gates_custom_player_maxdownspeed", 5.0 ); + player->setMovementInfo( thrust, gravity, maxUp, maxDown ); + + break; + } } for ( int i = 0 ; i < BLOCKSIZE ; ++i ) blocks[i].y( -1 ); } void GatesGame :: update( int state ) { Game::update( state ); // Game logic goes here if ( state == STATE_PLAYING ) { if ( nrFrames % 3 == 0 ) score ++; if ( nrFrames % 500 == 0 ) { if ( gapHeight > 75 ) gapHeight -= 5; } // Slightly random gap distance if ( nrFrames >= nextGate ) { nextGate = nrFrames + nextInt( 50 ) + gateDistance; addGate(); } if ( checkCollisions() ) { -// printf( "Crashed!\n" ); parent->changeState( STATE_CRASHING ); return; } terrain->moveTerrain( 5 ); moveBlocks( 5 ); player->move( press ); } } void GatesGame :: draw( SDL_Surface *screen ) { Game::preDraw( screen ); if ( parent->getState() == STATE_PLAYING ) { // Screen drawing goes here terrain->drawTerrain( screen ); player->draw( screen ); drawBlocks( screen ); } else { // Screen drawing goes here terrain->drawTerrain( screen ); drawBlocks( screen ); player->draw( screen ); } Game::draw( screen ); } void GatesGame :: addGate() { printf( "gapHeight = %d\n", gapHeight ); for ( int i = 0 ; i < BLOCKSIZE ; ++i ) { if ( blocks[i].y() == -1 ) { int x1 = sWidth; int y1 = terrain->getMapTop(50); int b1Height = nextInt(terrain->getMapBottom( 50 ) - terrain->getMapTop(50) - gapHeight); // See if height between last gate and this one is too big if ( b1Height - 100 > lastGateBottomY ) b1Height -= 25; else if ( b1Height + 100 < lastGateBottomY ) b1Height += 25; lastGateBottomY = b1Height; int x2 = sWidth; int y2 = y1 + b1Height + gapHeight; int b2Height = terrain->getMapBottom( 50 ) - y2; blocks[i].setRect( x1, y1, blockWidth, b1Height ); blocks[i+1].setRect( x2, y2, blockWidth, b2Height ); break; } } } void GatesGame :: moveBlocks( int amountToMove ) { for ( int i = 0 ; i < BLOCKSIZE ; ++i ) { if ( blocks[i].y() != -1 ) { blocks[i].moveBy( -amountToMove, 0 ); if ( blocks[i].x() + blocks[i].y() < 0 ) blocks[i].y( -1 ); } } } void GatesGame :: drawBlocks( SDL_Surface *screen ) { for ( int i = 0 ; i < BLOCKSIZE ; ++i ) { if ( blocks[i].y() != -1 ) { SDL_Rect r = blocks[i].getRect(); SDL_FillRect( screen, &r, SDL_MapRGB( screen->format, 100, 100, 255 ) ); } } } bool GatesGame :: checkCollisions() { diff --git a/noncore/games/sfcave-sdl/help.cpp b/noncore/games/sfcave-sdl/help.cpp index 91c62da..f1728f6 100644 --- a/noncore/games/sfcave-sdl/help.cpp +++ b/noncore/games/sfcave-sdl/help.cpp @@ -1,180 +1,179 @@ #include "SDL.h"
#include "constants.h"
#include "font.h"
#include "help.h"
#include "sfcave.h"
#include "starfield.h"
Help :: Help( SFCave *p )
{
parent = p;
stars = new StarField( false, 200 );
loadText();
init();
}
Help :: ~Help()
{
delete stars;
}
void Help :: handleKeys( SDL_KeyboardEvent &key )
{
if ( key.type == SDL_KEYDOWN )
{
if ( key.keysym.sym == SDLK_SPACE )
parent->changeState( STATE_MENU );
else if ( key.keysym.sym == SDLK_DOWN )
textSpeed = 5;
else if ( key.keysym.sym == SDLK_UP )
{
if ( textSpeed > 0 )
textSpeed = 0;
else textSpeed = 1;
}
-
+
}
else if ( key.type == SDL_KEYUP )
{
if ( key.keysym.sym == SDLK_DOWN )
textSpeed = 1;
}
}
void Help :: init()
{
startPos = 320;
currLine = 0;
textSpeed = 1;
-
+
// Create our coloured font
FontHandler :: changeColor( FONT_HELP_FONT, 0, 0, 255 );
}
void Help :: draw( SDL_Surface *screen )
{
stars->draw( screen );
-
list<string>::iterator it = textList.begin();
// Move to start of text
for ( int i = 0 ; i < currLine && it != textList.end() ; ++i )
it++;
int pos = startPos;
while ( pos < 320 && it != textList.end() )
{
// get next line
string text = *it;
// draw text
FontHandler::draw( screen, FONT_COLOURED_TEXT, text.c_str(), -1, pos );
pos += FontHandler::FontHeight( FONT_COLOURED_TEXT );
it ++;
}
-
+
}
void Help :: update()
{
stars->move();
-
+
startPos -= textSpeed;
if ( startPos <= -FontHandler::FontHeight( FONT_COLOURED_TEXT ) )
{
startPos = 0;
currLine ++;
if ( currLine > textList.size() )
{
startPos = 320;
currLine = 0;
}
}
}
void Help :: loadText()
{
textList.push_back( "SFCave" );
textList.push_back( "Written By AndyQ" );
textList.push_back( "" );
textList.push_back( "Instructions" );
textList.push_back( "To return to the menu" );
textList.push_back( "press the space or " );
textList.push_back( "middle button." );
textList.push_back( "" );
textList.push_back( "To speed up the text" );
textList.push_back( "hold the down button" );
textList.push_back( "(releasing will return" );
textList.push_back( "to normal speed)" );
textList.push_back( "" );
textList.push_back( "" );
textList.push_back( "SFCave is a flying game" );
textList.push_back( "writtin originally for the" );
textList.push_back( "Sharp Zaurus." );
textList.push_back( "" );
textList.push_back( "The aim is to stay alive" );
textList.push_back( "for as long as possible," );
textList.push_back( "and get the highest score" );
textList.push_back( "you can." );
textList.push_back( "" );
textList.push_back( "There are currently three" );
textList.push_back( "game types - SFCave," );
textList.push_back( "Gates, and Fly." );
textList.push_back( "" );
textList.push_back( "SFCave is a remake of" );
textList.push_back( "the classic SFCave game." );
textList.push_back( "Fly through the cavern" );
textList.push_back( "avoiding all the blocks" );
textList.push_back( "that just happen to be" );
textList.push_back( "hanging in mid-air" );
textList.push_back( "" );
textList.push_back( "Gates is similar to" );
textList.push_back( "SFCave but instead of" );
textList.push_back( "avoiding blocks you must" );
textList.push_back( "fly through gates without" );
textList.push_back( "crashing." );
textList.push_back( "" );
textList.push_back( "Fly is a different kettle of" );
textList.push_back( "fish altogether. Instead," );
textList.push_back( "you are flying in the " );
textList.push_back( "open air above a" );
textList.push_back( "scrolling landscape and" );
textList.push_back( "the aim is to fly as close" );
textList.push_back( "to the land as possible." );
textList.push_back( "The closer to the land" );
textList.push_back( "you fly the more points" );
textList.push_back( "you score. But beware," );
textList.push_back( "fly too high above the" );
textList.push_back( "land and points get" );
textList.push_back( "deducted." );
textList.push_back( "" );
textList.push_back( "How to play" );
textList.push_back( "Press the space or middle" );
textList.push_back( "button (Zaurus only) to " );
textList.push_back( "apply thrust (makes you" );
textList.push_back( "go up) and release it" );
textList.push_back( "to go down." );
textList.push_back( "" );
textList.push_back( "Have fun" );
textList.push_back( "AndyQ" );
}
// Test
#ifdef DEBUG_HELP
SDL_Surface *screen;
Help *help;
void go()
{
FontHandler :: init();
/* Initialize SDL */
if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
{
fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
exit(1);
diff --git a/noncore/games/sfcave-sdl/menu.cpp b/noncore/games/sfcave-sdl/menu.cpp index 0a7366f..a4a4216 100644 --- a/noncore/games/sfcave-sdl/menu.cpp +++ b/noncore/games/sfcave-sdl/menu.cpp @@ -1,337 +1,360 @@ #include <SDL_image.h> #include "SDL_rotozoom.h" #include "constants.h" #include "sfcave.h" #include "game.h" #include "menu.h" #include "font.h" #include "starfield.h" -MenuOption :: MenuOption( QString text, int id ) +MenuOption :: MenuOption( string text, int id ) { menuText = text; menuId = id; nextMenu = 0; highlighted = false; } MenuOption :: ~MenuOption() { } int MenuOption :: draw( SDL_Surface *screen, int y ) { if ( highlighted ) { int x = (240 - FontHandler::TextWidth( FONT_MENU_HIGHLIGHTED, (const char *)menuText.c_str() ))/2; FontHandler::draw( screen, FONT_MENU_HIGHLIGHTED, (const char *)menuText.c_str(), x, y ); return FontHandler::FontHeight( FONT_MENU_HIGHLIGHTED ); } else { int x = (240 - FontHandler::TextWidth( FONT_MENU_UNHIGHLIGHTED, (const char *)menuText.c_str() ))/2; FontHandler::draw( screen, FONT_MENU_UNHIGHLIGHTED, (const char *)menuText.c_str(), x, y ); return FontHandler::FontHeight( FONT_MENU_UNHIGHLIGHTED ); } } void MenuOption :: setNextMenu( Menu *item, bool down ) { nextMenu = item; downMenuTree = down; } //----------------- Menu Class ------------- SDL_Surface * Menu :: sfcaveTextImage; Menu *Menu :: mainMenu; Menu *Menu :: currentMenu; // This is the Master Menu constructor Menu :: Menu( SFCave *p ) { parent = p; parentMenu = 0; statusText = ""; // listItems.setAutoDelete( TRUE ); SDL_Surface *tmp = IMG_Load( IMAGES_PATH "sfcave_text.bmp" ); sfcaveTextImage = SDL_CreateRGBSurface(SDL_SWSURFACE, tmp->w, tmp->h, 32, 0x000000ff,0x0000ff00, 0x00ff0000, 0xff000000); SDL_BlitSurface(tmp, NULL, sfcaveTextImage, NULL); SDL_FreeSurface(tmp); // Create menu structure // Top level menu has 5 items - Start Game, Replays, Options, Help, and Quit // Replays, Option menu items hav submenus MenuOption *replayMenu = 0; MenuOption *optionsMenu = 0; MenuOption *item = 0; addMenuOption( "Start Game", MENU_STARTGAME ); replayMenu = addMenuOption( "Replays", MENU_REPLAYS ); optionsMenu = addMenuOption( "Options", MENU_OPTIONS ); addMenuOption( "Help", MENU_HELP ); addMenuOption( "Quit", MENU_QUIT ); // Now deal with the Replays Menu Menu *replay = new Menu( this ); replay->addMenuOption( "Play Replay", MENU_PLAY_REPLAY ); replay->addMenuOption( "Load Replay", MENU_LOAD_REPLAY ); replay->addMenuOption( "Save Replay", MENU_SAVE_REPLAY ); item = replay->addMenuOption( "Back", MENU_BACK ); item->setNextMenu( this, false ); replayMenu->setNextMenu( replay ); // Now deal with the Options Menu currentMenu->currentMenuOption->setHighlighted( false ); listItems.front()->highlight( true ); Menu *options = new Menu( this ); MenuOption *typeMenu = 0; MenuOption *difficultyMenu = 0; MenuOption *soundsMenu = 0; typeMenu = options->addMenuOption( "Game Type", MENU_GAME_TYPE ); difficultyMenu = options->addMenuOption( "Difficulty", MENU_DIFFICULTY ); soundsMenu = options->addMenuOption( "Sound", MENU_SOUNDS ); options->addMenuOption( "Clear Scores", MENU_CLEAR_SCORES ); item = options->addMenuOption( "Back", MENU_BACK ); item->setNextMenu( this, false ); optionsMenu->setNextMenu( options ); // Game Type menu Menu *gameType = new Menu( options ); item = gameType->addMenuOption( "SFCave", MENU_GAME_SFCAVE ); item->setNextMenu( options ); item = gameType->addMenuOption( "Gates", MENU_GAME_GATES ); item->setNextMenu( options ); item = gameType->addMenuOption( "Fly", MENU_GAME_FLY ); item->setNextMenu( options ); item = gameType->addMenuOption( "Back", MENU_BACK ); item->setNextMenu( options ); typeMenu->setNextMenu( gameType ); // Game Difficulty menu + MenuOption *customMenu = 0; Menu *gameDifficulty = new Menu( options ); item = gameDifficulty->addMenuOption( "Easy", MENU_DIFFICULTY_EASY ); item->setNextMenu( options, false ); item = gameDifficulty->addMenuOption( "Normal", MENU_DIFFICULTY_NORMAL ); item->setNextMenu( options, false ); item = gameDifficulty->addMenuOption( "Hard", MENU_DIFFICULTY_HARD ); item->setNextMenu( options, false ); + customMenu = gameDifficulty->addMenuOption( "Custom", MENU_DIFFICULTY_CUSTOM ); item = gameDifficulty->addMenuOption( "Back", MENU_BACK ); item->setNextMenu( options, false ); difficultyMenu->setNextMenu( gameDifficulty ); // Sounds Menu Menu *sounds = new Menu( options ); sounds->addMenuOption( "Sound On", MENU_SOUND_ON ); sounds->addMenuOption( "Sound Off", MENU_SOUND_OFF ); sounds->addMenuOption( "Music On", MENU_MUSIC_ON ); sounds->addMenuOption( "Music Off", MENU_MUSIC_OFF ); item = sounds->addMenuOption( "Back", MENU_BACK ); item->setNextMenu( options, false ); soundsMenu->setNextMenu( sounds ); + + // Custom Menu + Menu *custom = new Menu( gameDifficulty ); + Menu *updown = new Menu( custom ); + item = custom->addMenuOption( "Thrust", MENU_CUSTOM_THRUST ); + item->setNextMenu( updown ); + item = custom->addMenuOption( "Gravity", MENU_CUSTOM_GRAVITY ); + item->setNextMenu( updown ); + item = custom->addMenuOption( "Max Speed Up", MENU_CUSTOM_MAXSPEEDUP ); + item->setNextMenu( updown ); + item = custom->addMenuOption( "Max Speed Down", MENU_CUSTOM_MAXSPEEDDOWN ); + item->setNextMenu( updown ); + item = custom->addMenuOption( "Back", MENU_BACK ); + item->setNextMenu( gameDifficulty, false ); + customMenu->setNextMenu( custom ); + + // Up down menu + item = updown->addMenuOption( "Increase", MENU_CUSTOM_INCREASE ); + item = updown->addMenuOption( "Decrease", MENU_CUSTOM_DECREASE ); + item = updown->addMenuOption( "Save", MENU_CUSTOM_SAVE ); + item->setNextMenu( custom, false ); + item = updown->addMenuOption( "Cancel", MENU_CUSTOM_CANCEL ); + item->setNextMenu( custom, false ); // Set static variables for menu selection up mainMenu = this; currentMenuOption = 0; resetToTopMenu(); angle = 0; stars = new StarField; } // This is a private constructor used for creating sub menus - only called by the Master Menu Menu :: Menu( Menu *p ) { parentMenu = p; // listItems.setAutoDelete( TRUE ); currentMenuOption = 0; } Menu :: ~Menu() { if ( this == mainMenu ) { SDL_FreeSurface( sfcaveTextImage ); delete stars; } } void Menu :: draw( SDL_Surface *screen ) { // draw stafield stars->draw( screen ); stars->move( ); // Draw the spinning SFCave logo SDL_Surface *rotozoom_pic; SDL_Rect dest; angle += 2; if ( angle > 359 ) angle = 0; if ((rotozoom_pic=rotozoomSurface (sfcaveTextImage, angle*1, 1, SMOOTHING_ON))!=NULL) { dest.x = (screen->w - rotozoom_pic->w)/2; dest.y = 10; dest.w = rotozoom_pic->w; dest.h = rotozoom_pic->h; SDL_BlitSurface( rotozoom_pic, NULL, screen, &dest ); SDL_FreeSurface(rotozoom_pic); } // Draw what game is selected char text[100]; sprintf( text, "Current Game: %s", (const char *)parent->getCurrentGame()->getGameName().c_str() ); // Menu::scoreFont.PutString( screen, (240 - Menu::scoreFont.TextWidth( (const char *)text ))/2, 120, (const char *)text ); FontHandler::draw( screen, FONT_WHITE_TEXT, (const char *)text, (240 - FontHandler::TextWidth( FONT_WHITE_TEXT,(const char *)text ))/2, 120 ); sprintf( text, "Difficulty: %s", (const char *)parent->getCurrentGame()->getGameDifficultyText().c_str() ); // Menu::scoreFont.PutString( screen, (240 - Menu::scoreFont.TextWidth( (const char *)text ))/2, 120 + Menu::scoreFont.FontHeight()+2, (const char *)text ); FontHandler::draw( screen, FONT_WHITE_TEXT, (const char *)text, (240 - FontHandler::TextWidth( FONT_WHITE_TEXT,(const char *)text ))/2, 120 + FontHandler::FontHeight( FONT_WHITE_TEXT ) ); if ( statusText != "" ) FontHandler::draw( screen, FONT_WHITE_TEXT, (const char *)statusText.c_str(), (240 - FontHandler::TextWidth( FONT_WHITE_TEXT,(const char *)statusText.c_str() ))/2, 120 + (2*FontHandler::FontHeight( FONT_WHITE_TEXT ))+6 ); // Menu::scoreFont.PutString( screen, (240 - Menu::scoreFont.TextWidth( (const char *)statusText ))/2, 120 + (Menu::scoreFont.FontHeight()*2)+6, (const char *)statusText ); // Loop round each menu option and draw it int y = 155; list<MenuOption *>::iterator it; for ( it = currentMenu->listItems.begin(); it != currentMenu->listItems.end() ; ++it ) { y += (*it)->draw( screen, y ) + 2; } } int Menu :: handleKeys( SDL_KeyboardEvent &key ) { if ( key.type != SDL_KEYDOWN ) return -1; - statusText = ""; switch( key.keysym.sym ) { case SDLK_DOWN: { // Move to next menu item currentMenu->currentMenuOption->highlight( false ); list<MenuOption *>::iterator it; for ( it = currentMenu->listItems.begin(); it != currentMenu->listItems.end() ; ++it ) { if ( (*it) == currentMenu->currentMenuOption ) { it++; break; } } if ( it == currentMenu->listItems.end() ) it = currentMenu->listItems.begin(); currentMenu->currentMenuOption = *it; currentMenu->currentMenuOption->highlight( true ); break; } case SDLK_UP: { // Move to previous menu item currentMenu->currentMenuOption->highlight( false ); list<MenuOption *>::iterator it; bool reachedBeginning = false; for ( it = (currentMenu->listItems).end()--; ; --it ) { if ( (*it) == currentMenu->currentMenuOption ) { if ( it == currentMenu->listItems.begin( ) ) { reachedBeginning = true; break; } else it--; break; } } if ( reachedBeginning ) currentMenu->currentMenuOption = currentMenu->listItems.back(); else currentMenu->currentMenuOption = *it; currentMenu->currentMenuOption->highlight( true ); break; } case SDLK_LEFT: if ( currentMenu->parentMenu != 0 ) { + statusText = ""; currentMenu = currentMenu->parentMenu; - printf( "HERE\n" ); return -1; } break; case SDLK_RETURN: case SDLK_SPACE: { + statusText = ""; // select menu item int id = currentMenu->currentMenuOption->getMenuId(); -// // if the current item has a child menu then move to that menu + + // if the current item has a child menu then move to that menu Menu *next = currentMenu->currentMenuOption->getNextMenu(); if ( next != 0 ) { bool down = currentMenu->currentMenuOption->isDownMenuTree(); currentMenu = next; if ( down ) initCurrentMenu(); -// return -1; - } -// else - { - return id; } + return id; + break; } default: break; } return -1; } -MenuOption *Menu :: addMenuOption( QString text, int id ) +MenuOption *Menu :: addMenuOption( string text, int id ) { MenuOption *item = new MenuOption( text, id ); listItems.push_back( item ); return item; } void Menu :: resetToTopMenu() { currentMenu = mainMenu; initCurrentMenu(); } void Menu :: initCurrentMenu() { if ( currentMenu->currentMenuOption != 0 ) currentMenu->currentMenuOption->highlight( false ); currentMenu->currentMenuOption = currentMenu->listItems.front(); currentMenu->currentMenuOption->highlight( true ); } diff --git a/noncore/games/sfcave-sdl/menu.h b/noncore/games/sfcave-sdl/menu.h index 08f7528..6a5ef40 100644 --- a/noncore/games/sfcave-sdl/menu.h +++ b/noncore/games/sfcave-sdl/menu.h @@ -1,71 +1,71 @@ #ifndef __MENU_H #define __MENU_H #include <list> using namespace std; #include <SDL.h> class SFCave; class StarField; class Menu; class MenuOption { public: - MenuOption( QString text, int id ); + MenuOption( string text, int id ); ~MenuOption(); void highlight( bool val ) { highlighted = val; } int draw( SDL_Surface *screen, int y ); void setNextMenu( Menu *item, bool down = true ); Menu *getNextMenu() { return nextMenu; } int getMenuId() { return menuId; } bool isDownMenuTree() { return downMenuTree; } private: int menuId; - QString menuText; + string menuText; bool highlighted; bool downMenuTree; Menu *nextMenu; }; class Menu { public: Menu( SFCave *p ); ~Menu(); void draw( SDL_Surface *screen ); int handleKeys( SDL_KeyboardEvent & ); - MenuOption *addMenuOption( QString text, int id ); + MenuOption *addMenuOption( string text, int id ); void resetToTopMenu(); void initCurrentMenu(); - void setStatusText( QString text ) { statusText = text; } + void setStatusText( string text ) { statusText = text; } protected: private: static SDL_Surface * sfcaveTextImage; int angle; static Menu *mainMenu; static Menu *currentMenu; Menu *parentMenu; StarField *stars; - QString statusText; + string statusText; SFCave *parent; list<MenuOption *> listItems; MenuOption *currentMenuOption; Menu( Menu* p ); }; #endif diff --git a/noncore/games/sfcave-sdl/player.cpp b/noncore/games/sfcave-sdl/player.cpp index 830ee78..2d52ae2 100644 --- a/noncore/games/sfcave-sdl/player.cpp +++ b/noncore/games/sfcave-sdl/player.cpp @@ -1,162 +1,284 @@ #include <SDL.h> #include "SDL_gfxPrimitives.h" #include "constants.h" #include "player.h" #include "random.h" #include "animatedimage.h" Player :: Player( int w, int h ) { sWidth = w; sHeight = h; - thrustUp = 0.4; - thrustDown = 0.6; + thrust = 0.4; + gravity = 0.6; maxUpSpeed = 4.0; maxDownSpeed = 5.0; explosion = new AnimatedImage( IMAGES_PATH "explosion.bmp", 15 ); init(); } Player :: ~Player() { if ( explosion ) delete explosion; } void Player :: init() { // Set player position pos.x( 50 ); pos.y( sWidth/2 ); pos.h( 2 ); pos.w( 4 ); thrust = 0; crashing = false; crashLineLength = 0; crashed = false; explosion->reset(); allFaded = false; expNextFrame = false; // Reset Trail for ( int i = 0 ; i < TRAILSIZE ; ++i ) { trail[i].x( -1 ); trail[i].y( 0 ); trail[i].w( 2 ); trail[i].h( 2 ); } } void Player :: draw( SDL_Surface *screen ) { if ( !crashing ) { // Draw Player // ellipseRGBA( screen, pos.x(), pos.y(), pos.x()+ pos.width(), pos.y()+pos.height(), 0, 255, 255, 255 ); filledEllipseRGBA( screen, pos.x() + pos.w(), pos.y(), pos.w(), pos.h(), 0, 255, 255, 255 ); // Draw Trail drawTrails( screen ); } else { drawTrails( screen ); if ( !crashed ) explosion->draw( screen, pos.x(), pos.y() ); } } void Player :: drawTrails( SDL_Surface *screen ) { if ( allFaded && crashing ) return; for ( int i = 0 ; i < TRAILSIZE ; ++i ) { if ( trail[i].x() >= 0 ) { -// int r = (int) ((255.0/pos.x()) * (trail[i].x)); -// int g = (int) ((150.0/pos.x()) * (trail[i].x)); int c = (int)((150.0/50) * (50.0 - (pos.x() - trail[i].x() ) )); -// SDL_FillRect( screen, &trail[i], SDL_MapRGBA( screen->format, r, g, 0, 0 ) ); //(int)(1.5*c), 0, 255 ) ); boxRGBA( screen, trail[i].x(), trail[i].y(), trail[i].x() + 2, trail[i].y() + 2, 255, (int)(1.5*c), 0, c ); } } } void Player :: move( bool up ) { // Find enpty trail and move others moveTrails(); if ( up ) - thrust -= thrustUp; + currentThrust -= thrust; else - thrust += thrustDown; + currentThrust += gravity; - if ( thrust > maxDownSpeed ) - thrust = maxDownSpeed; - else if ( thrust < -maxUpSpeed ) - thrust = -maxUpSpeed; + if ( currentThrust > maxDownSpeed ) + currentThrust = maxDownSpeed; + else if ( currentThrust < -maxUpSpeed ) + currentThrust = -maxUpSpeed; - pos.moveBy( 0, (int)(thrust) ); + pos.moveBy( 0, (int)(currentThrust) ); } void Player :: moveTrails() { bool done = false; bool stillVisible = false; // Dont do anything here if all faded when were crashing if ( allFaded && crashing ) return; for ( int i = 0 ; i < TRAILSIZE ; ++i ) { if ( trail[i].x() < 0 ) { stillVisible = true; if ( !crashing && !done ) { trail[i].x( pos.x() - 5 ); trail[i].y( pos.y() ); done = true; } } else trail[i].x( trail[i].x() - 1 ); } if ( !stillVisible ) allFaded = true; } bool Player :: updateCrashing() { crashing = true; moveTrails(); if ( expNextFrame ) { expNextFrame = false; crashed = !explosion->nextFrame(); } else expNextFrame = true; return crashed; } -void Player :: setMovementInfo( double up, double down, double maxUp, double maxDown ) +void Player :: setMovementInfo( double up, double grav, double maxUp, double maxDown ) { - thrustUp = up; - thrustDown = down; + thrust = up; + gravity = grav; maxUpSpeed = maxUp; maxDownSpeed = maxDown; } + +void Player :: incValue( int valueType ) +{ + switch( valueType ) + { + case PLAYER_THRUST: + thrust += 0.1; + break; + case PLAYER_GRAVITY: + gravity += 0.1; + break; + case PLAYER_MAX_SPEED_UP: + maxUpSpeed += 0.1; + break; + case PLAYER_MAX_SPEED_DOWN: + maxDownSpeed += 0.1; + break; + } +} + +void Player :: decValue( int valueType ) +{ + switch( valueType ) + { + case PLAYER_THRUST: + thrust -= 0.1; + break; + case PLAYER_GRAVITY: + gravity -= 0.1; + break; + case PLAYER_MAX_SPEED_UP: + maxUpSpeed -= 0.1; + break; + case PLAYER_MAX_SPEED_DOWN: + maxDownSpeed -= 0.1; + break; + } +} + +void Player :: setValue( int valueType, double val ) +{ + switch( valueType ) + { + case PLAYER_THRUST: + thrust = val; + break; + case PLAYER_GRAVITY: + gravity = val; + break; + case PLAYER_MAX_SPEED_UP: + maxUpSpeed = val; + break; + case PLAYER_MAX_SPEED_DOWN: + maxDownSpeed = val; + break; + } +} + +double Player :: getValue( int valueType ) +{ + double val; + switch( valueType ) + { + case PLAYER_THRUST: + val = thrust; + break; + case PLAYER_GRAVITY: + val = gravity; + break; + case PLAYER_MAX_SPEED_UP: + val = maxUpSpeed; + break; + case PLAYER_MAX_SPEED_DOWN: + val = maxDownSpeed; + break; + } + + return val; +} + +string Player :: getValueTypeString( int valueType ) +{ + string val; + switch( valueType ) + { + case PLAYER_THRUST: + val = "thrust"; + break; + case PLAYER_GRAVITY: + val = "gravity"; + break; + case PLAYER_MAX_SPEED_UP: + val = "maxupspeed"; + break; + case PLAYER_MAX_SPEED_DOWN: + val = "maxdownspeed"; + break; + } + + return val; +} + +string Player :: getValueString( int valueType ) +{ + char val[50]; + switch( valueType ) + { + case PLAYER_THRUST: + sprintf( val, "Thrust - %lf", thrust ); + break; + case PLAYER_GRAVITY: + sprintf( val, "Gravity - %lf", gravity ); + break; + case PLAYER_MAX_SPEED_UP: + sprintf( val, "Max Speed Up - %lf", maxUpSpeed ); + break; + case PLAYER_MAX_SPEED_DOWN: + sprintf( val, "Max Speed Down - %lf", maxDownSpeed ); + break; + } + + string ret = val; + return ret; +} + diff --git a/noncore/games/sfcave-sdl/player.h b/noncore/games/sfcave-sdl/player.h index e4c904a..595c25b 100644 --- a/noncore/games/sfcave-sdl/player.h +++ b/noncore/games/sfcave-sdl/player.h @@ -1,50 +1,56 @@ #ifndef __PLAYER_H #define __PLAYER_H #include "rect.h" class SDL_Surface; class AnimatedImage; class Player { public: Player( int w, int h ); ~Player(); void init(); void draw( SDL_Surface *screen ); void drawTrails( SDL_Surface *screen ); void move( bool up ); void moveTrails(); Rect getPos() { return pos; } int getX() { return pos.x(); } int getY() { return pos.y(); } int getHeight() { return pos.h(); } bool updateCrashing(); - void setMovementInfo( double up, double down, double maxUp, double maxDown ); + void setMovementInfo( double up, double grav, double maxUp, double maxDown ); + void incValue( int valType ); + void decValue( int valType ); + double getValue( int valueType ); + string getValueString( int valueType ); + string getValueTypeString( int valueType ); + void setValue( int valueType, double val ); private: AnimatedImage *explosion; int sWidth; int sHeight; bool expNextFrame; bool allFaded; bool crashing; bool crashed; int crashLineLength; Rect pos; - double thrust; + double currentThrust; - double thrustUp; - double thrustDown; + double thrust; + double gravity; double maxUpSpeed; double maxDownSpeed; Rect trail[TRAILSIZE]; }; #endif diff --git a/noncore/games/sfcave-sdl/settings.cpp b/noncore/games/sfcave-sdl/settings.cpp index 914c4ec..20cce4f 100644 --- a/noncore/games/sfcave-sdl/settings.cpp +++ b/noncore/games/sfcave-sdl/settings.cpp @@ -1,273 +1,271 @@ #include <stdio.h> #include <stdlib.h> #include <sys/stat.h> #include <vector> #include "settings.h" +// Defined in util.h +string getHomeDir(); #define DEFAULT_DIR "." #define DEFAULT_FILE "Settings.cfg" #define MAX_LINE_SIZE 2048 Settings::Settings( char * env_file, char * env_dir ) { // Store the correct environment directory if (env_dir == NULL) { - char * homeDir = getenv( "HOME" );; - - if ( homeDir ) - { - envFile.append(homeDir); - envFile.append("/"); - } - else - printf( "Environment var HOME not set!\n" ); + envFile = getHomeDir(); + envFile.append("/"); envFile.append(DEFAULT_DIR); } else envFile.append(env_dir); envFile.append("/"); // Store the correct environment file if (env_file == NULL) envFile.append(DEFAULT_FILE); else envFile.append(env_file); } Settings::Settings() { - char * homeDir = getenv("HOME"); - - if ( homeDir) - { - envFile.append(homeDir); - envFile.append("/"); - } - else - printf( "Environment var HOME not set!\n" ); + envFile = getHomeDir(); + envFile.append("/"); envFile.append(DEFAULT_DIR); envFile.append("/"); envFile.append(DEFAULT_FILE); } Settings::~Settings() { } bool Settings::readSetting(const string key_str,int& result) { string Buffer; if (readSetting(key_str,Buffer)) { result = atoi(Buffer.c_str()); return true; } else return false; } bool Settings::readSetting(const string key_str,unsigned int& result) { string Buffer; if (readSetting(key_str,Buffer)) { result = atoi(Buffer.c_str()); return true; } else return false; } bool Settings::readSetting(const string key_str,long int& result) { string Buffer; if (readSetting(key_str,Buffer)) { result = atol(Buffer.c_str()); return true; } else return false; } bool Settings::readSetting(const string key_str,unsigned long& result) { string Buffer; if (readSetting(key_str,Buffer)) { result = atol(Buffer.c_str()); return true; } else return false; } +bool Settings::readSetting(const string key_str,double& result) +{ + string Buffer; + if (readSetting(key_str,Buffer)) + { + result = atof( Buffer.c_str() ); + return true; + } + else + return false; +} + bool Settings::readSetting(const string key_str,bool& result) { string Buffer; if (readSetting(key_str,Buffer)) { result = (Buffer == "true"); return true; } else return false; } bool Settings::readSetting(const string key_str,string& results) { // This function will read a string from the env file that corresponds to the // key key_str passed in. FILE * fd = 0; char buf[MAX_LINE_SIZE]; bool ret_flag = false; char* key; char* value; // open file fd = fopen(envFile.c_str(), "r"); if (fd) { while (fgets(buf, MAX_LINE_SIZE-1, fd)) { key = strtok(buf, "\t"); value = strtok(NULL, "\n"); // find key in file if (!strcasecmp(key,key_str.c_str())) { results = value; ret_flag = true; } } fclose(fd); } return(ret_flag); } void Settings::writeSetting(const string key_str,const bool value) { value ? writeSetting(key_str,string("true")) :writeSetting(key_str,string("false")); } +void Settings::writeSetting(const string key_str,const double value) +{ + char Buffer[30]; + + sprintf(Buffer,"%lf",value); + writeSetting(key_str,string(Buffer)); +} + void Settings::writeSetting(const string key_str,const int value) { char Buffer[30]; sprintf(Buffer,"%i",value); writeSetting(key_str,string(Buffer)); } void Settings::writeSetting(const string key_str,const unsigned int value) { char Buffer[30]; sprintf(Buffer,"%i",value); writeSetting(key_str,string(Buffer)); } void Settings::writeSetting(const string key_str,const long int value) { char Buffer[30]; sprintf(Buffer,"%li",value); writeSetting(key_str,string(Buffer)); } void Settings::writeSetting(const string key_str,const unsigned long value) { char Buffer[30]; sprintf(Buffer,"%lu",value); writeSetting(key_str,string(Buffer)); } void Settings::writeSetting(const string key_str,const string value) { // This function will write a value for the key key_str. If the key_str // already exists then it will be overwritten. - - std::vector<string> FileEntries; FILE *fd=NULL,*ftemp=NULL; - char * dir_str; - char * dir_ptr; char buf[MAX_LINE_SIZE]; - char tempname[12]; - dir_str = strdup(envFile.c_str()); - printf( "dir = %s, file - %s\n", dir_str, envFile.c_str() ); - if (dir_str) + string tmp = getHomeDir() + "/tmpsfcave.dat"; + + // if file exists we need to save contents + fd = fopen( envFile.c_str(), "r" ); + ftemp = fopen( tmp.c_str(), "w" ); + if ( fd != NULL && ftemp != NULL ) { - // remove file from the directory string - dir_ptr = strrchr(dir_str, (int)'/'); - if (dir_ptr) + while (fgets(buf, MAX_LINE_SIZE-1, fd)) { - *dir_ptr = 0; - - // make the directory path if it does not exist -// mkdir(dir_str, 777 ); + if ( strncmp( buf, key_str.c_str(), key_str.size() ) != 0 ) + fprintf( ftemp, "%s", buf ); + } + fclose(fd); + } - // if file exists we need to save contents - if ((fd = fopen(envFile.c_str(), "r")) != NULL) - { - while (fgets(buf, MAX_LINE_SIZE-1, fd)) - FileEntries.push_back(string(buf)); - fclose(fd); - } + if ( ftemp != NULL ) + { + fprintf(ftemp, "%s\t%s\n", key_str.c_str(),value.c_str()); + fclose( ftemp ); - char *home = getenv( "HOME" ); - string tmp; - if ( home ) - tmp = home + string( "/" ) + "tmpsfcave.dat"; - else - tmp = "./tmpsfcave.dat"; + remove(envFile.c_str()); + rename( tmp.c_str(), envFile.c_str() ); + } +/* + string tmp = getHomeDir() + "/tmpsfcave.dat"; strcpy(tempname,tmp.c_str() ); printf( "tmp - %s\n", tempname ); if ((ftemp = fopen(tempname,"w")) != NULL) { char *key1,*key2; char buff1[80],buff2[80]; strncpy(buff1,key_str.c_str(),80); key1 = strtok(buff1,"\t"); for (std::vector<string>::iterator iter = FileEntries.begin(); iter < FileEntries.end(); iter++) { strncpy(buff2,(*iter).c_str(),80); key2 = strtok(buff2,"\t"); // IF not the key string then write out to file if (strcmp(key1,key2) != 0) { fprintf(ftemp,"%s",iter->c_str()); fflush(ftemp); } } fprintf(ftemp, "%s\t%s\n", key_str.c_str(),value.c_str()); fflush(ftemp); fclose(ftemp); - - remove(envFile.c_str()); - - rename( tempname, envFile.c_str() ); } else printf( "Can't open file %s\n", envFile.c_str() ); } delete dir_str; } +*/ } void Settings::deleteFile(void) { remove(envFile.c_str()); } diff --git a/noncore/games/sfcave-sdl/settings.h b/noncore/games/sfcave-sdl/settings.h index 5e828ed..a3af999 100644 --- a/noncore/games/sfcave-sdl/settings.h +++ b/noncore/games/sfcave-sdl/settings.h @@ -1,52 +1,54 @@ #ifndef __SETTINGS_H #define __SETTINGS_H // This class will create a .<name> directory in the users home directory or // a directory for the users choice. It will then manage a set of key values // that the programmer can search for. This allows programmers to save a users // settings and then retrieve then at a latter time. It currently supports // upto 1024 different settings. // Two constructors are provided. They will dertermine what directory to look // for the settings file and what the name of the file is. If the directory is // not specified then a default directory of .<DEFAULT_DIR> will be created in // the users home directory. A file will be created in this directory. The name // will be the one specified by the caller. If none is specified then // DEFAULT_FILE will be created. // To retrieve and store strings into the file readSetting and writeSetting // should be called. #include <string> using namespace std; class Settings { public: Settings( char * env_file = 0, char * env_dir = 0 ); Settings(); ~Settings(); bool readSetting(const string key_str,string& results); bool readSetting(const string key_str,int& result); bool readSetting(const string key_str,unsigned int& result); bool readSetting(const string key_str,long int& result); bool readSetting(const string key_str,unsigned long& result); + bool readSetting(const string key_str,double & result); bool readSetting(const string key_str,bool& result); void writeSetting(const string key_str,const string value); void writeSetting(const string key_str,const int value); void writeSetting(const string key_str,const unsigned int result); void writeSetting(const string key_str,const long int result); void writeSetting(const string key_str,const unsigned long result); + void writeSetting(const string key_str,const double value); void writeSetting(const string key_str,const bool value); void deleteFile(void); - + private: string envFile; }; #endif diff --git a/noncore/games/sfcave-sdl/sfcave.cpp b/noncore/games/sfcave-sdl/sfcave.cpp index 8d376a1..dbd788c 100644 --- a/noncore/games/sfcave-sdl/sfcave.cpp +++ b/noncore/games/sfcave-sdl/sfcave.cpp @@ -1,546 +1,633 @@ #include <stdio.h> #include <stdlib.h> #include <time.h> #include <sys/timeb.h> #include "SDL.h" #include "SDL_gfxPrimitives.h" #include "constants.h" #include "sound.h" #include "menu.h" #include "help.h" #include "game.h" #include "terrain.h" #include "random.h" #include "sfcave.h" #include "font.h" #include "settings.h" #include "util.h" #include "sfcave_game.h" #include "gates_game.h" #include "fly_game.h" void start( int argc, char *argv[] ) { - FontHandler::init(); - SFCave app( argc, argv ); - FontHandler::cleanUp(); + SFCave *app = new SFCave( argc, argv ); + app->mainEventLoop(); + delete app; } #ifdef __cplusplus extern "C" #endif int main(int argc, char *argv[]) { start( argc, argv ); return 0; } SFCave :: SFCave( int argc, char *argv[] ) { + setupOK = false; + + // Load settings string diff = loadSetting( "GameDifficulty", "Easy" ); string game = loadSetting( "GameType", "SFCave" ); musicPath = loadSetting( "MusicPath", SOUND_PATH ); - printf( "musicPath %s\n", musicPath.c_str() ); musicType = loadSetting( "MusicType", "mod,ogg" ); + bool soundOn = loadBoolSetting( "SoundOn", true ); + bool musicOn = loadBoolSetting( "MusicOn", true ); if ( musicPath[musicPath.size()-1] != '/' ) musicPath += "/"; + printf( "musicPath %s\n", musicPath.c_str() ); // Init main SDL Library initSDL( argc, argv ); + // Init font handler + if ( !FontHandler::init() ) + { + printf( "Unable to initialise fonts!\n" ); + return; + } + // Init SoundHandler if ( !SoundHandler :: init() ) printf("Unable to open audio!\n"); + SoundHandler :: setSoundsOn( soundOn ); + SoundHandler :: setMusicOn( musicOn ); + currentGame = Game::createGame( this, WIDTH, HEIGHT, game, diff ); if ( !currentGame ) currentGame = new SFCaveGame( this, WIDTH, HEIGHT, 0 ); currentGame->setSeed(-1); + + // Create menu menu = new Menu( this ); - + + // Create help screen help = new Help( this ); maxFPS = 50; showFps = false; - mainEventLoop(); - - SoundHandler :: cleanUp(); - SDL_Quit(); + + setupOK = true; } SFCave :: ~SFCave() { if ( currentGame ) delete currentGame; if ( menu ) delete menu; - SDL_FreeSurface( screen ); -} - + if ( help ) + delete help; -void SFCave :: drawGameScreen( ) -{ - //ClearScreen(screen, "Titletext"); + SDL_FreeSurface( screen ); + FontHandler::cleanUp(); + SoundHandler :: cleanUp(); + SDL_Quit(); } + void SFCave :: initSDL( int argc, char *argv[] ) { const SDL_VideoInfo *info; Uint8 video_bpp; Uint32 videoflags; - - - /* Initialize SDL */ + // Initialize SDL if ( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0 ) { fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); exit(1); } - atexit(SDL_Quit); - /* Alpha blending doesn't work well at 8-bit color */ video_bpp = 16; - if ( !SDL_VideoModeOK(WIDTH, HEIGHT, 16, SDL_DOUBLEBUF) ) + if ( !SDL_VideoModeOK(WIDTH, HEIGHT, video_bpp, SDL_DOUBLEBUF) ) printf( "No double buffering\n" ); - videoflags = SDL_HWSURFACE | SDL_SRCALPHA;//|| SDL_DOUBLEBUF;// | SDL_SRCALPHA | SDL_RESIZABLE; - while ( argc > 1 ) { + videoflags = SDL_HWSURFACE | SDL_SRCALPHA; + while ( argc > 1 ) + { --argc; - if ( strcmp(argv[argc-1], "-bpp") == 0 ) { + if ( strcmp(argv[argc-1], "-bpp") == 0 ) + { video_bpp = atoi(argv[argc]); --argc; - } else - if ( strcmp(argv[argc], "-hw") == 0 ) { + } + else if ( strcmp(argv[argc], "-hw") == 0 ) + { videoflags |= SDL_HWSURFACE; - } else - if ( strcmp(argv[argc], "-warp") == 0 ) { + } + else if ( strcmp(argv[argc], "-warp") == 0 ) + { videoflags |= SDL_HWPALETTE; - } else - if ( strcmp(argv[argc], "-fullscreen") == 0 ) { + } + else if ( strcmp(argv[argc], "-fullscreen") == 0 ) + { videoflags |= SDL_FULLSCREEN; - } else { + } + else if ( strcmp(argv[argc], "-h") == 0 ) + { fprintf(stderr, "Usage: %s [-bpp N] [-warp] [-hw] [-fullscreen]\n", argv[0]); exit(1); } } - /* Set 240x320 video mode */ - if ( (screen=SDL_SetVideoMode(WIDTH,HEIGHT,video_bpp,videoflags)) == NULL ) { - fprintf(stderr, "Couldn't set %ix%i video mode: %s\n",WIDTH,HEIGHT,SDL_GetError()); + // Set 240x320 video mode + if ( (screen = SDL_SetVideoMode( WIDTH,HEIGHT,video_bpp,videoflags )) == NULL ) + { + printf( "Couldn't set %ix%i video mode: %s\n",WIDTH,HEIGHT,SDL_GetError() ); exit(2); } - /* Use alpha blending */ - SDL_SetAlpha(screen, SDL_RLEACCEL, 0); + // Use alpha blending + //SDL_SetAlpha(screen, SDL_RLEACCEL, 0); - /* Set title for window */ + // Set title for window SDL_WM_SetCaption("SFCave","SFCave"); } void SFCave :: mainEventLoop() { - SDL_Event event; - int done; - - /* Wait for a keystroke */ - done = 0; + if ( !setupOK ) + return; + + // Wait for a keystroke + finish = false; state = 0; state = STATE_CRASHED; changeState( STATE_MENU ); - int FPS = 0; - bool limitFPS = true; + FPS = 0; actualFPS = 0; - long time1 = 0; - long start; - long end; -// long nrTimes = 0; - struct timeb tp; - while ( !done ) + time1 = 0; + + limitFPS = true; + while ( !finish ) { // calc FPS - ftime( &tp ); - start =(tp.time%10000)*10000 + tp.millitm; -// printf( "start = %ld, time1 - %d, st-tm - %d, tp.time - %ld\n", start, time1, start-time1, (tp.time%1000)*1000 ); - if ( start - time1 >= 1000 ) - { - actualFPS = FPS; -// printf( "%d FPS = %d\n", nrTimes++, actualFPS ); - FPS = 0; - time1 = start; - } - else - FPS ++; + calcFPS(); SDL_FillRect( screen, 0, 0 ); - switch( state ) - { - case STATE_MENU: - SDL_FillRect( screen, 0, 0 ); - menu->draw( screen ); - break; - case STATE_HELP: - SDL_FillRect( screen, 0, 0 ); - help->update(); - help->draw( screen ); - break; - case STATE_NEWGAME: - printf( "STATE_NEWGAME\n" ); - currentGame->setReplay( false ); - currentGame->init(); - changeState( STATE_PLAYING ); - break; - case STATE_REPLAY: - printf( "STATE_NEWGAME\n" ); - currentGame->setReplay( true ); - currentGame->init(); - changeState( STATE_PLAYING ); - break; + handleGameState( ); - case STATE_PLAYING: - case STATE_CRASHING: - currentGame->update( state ); - currentGame->draw( screen ); - break; - - case STATE_CRASHED: - currentGame->update( state ); - currentGame->draw( screen ); - - // Display Game Over message - break; - - case STATE_QUIT: - done = 1; - break; - } - - /* Show */ -// if ( state != STATE_CRASHED ) - SDL_Flip( screen ); -// SDL_UpdateRect(screen, 0, 0, 0, 0); + SDL_Flip( screen ); if ( limitFPS ) - { - /* Slow down polling - limit to x FPS*/ - ftime( &tp ); - end = abs((tp.time%10000)*10000 + tp.millitm); - if ( end-start < (1000/maxFPS) ) - { -// printf( "end - %ld, timetaken for frame = %ld, sleeping for %ld %d\n", end, end-start, (1000/maxFPS)-(end-start), actualFPS ); - if ( (1000/maxFPS)-(end-start) > 500 ) - { - // Should never happen but in case it does sleep for 5 seconds - printf( "WARNING WILL ROBINSON! delay = %ld - start %ld, end %ld\n", (1000/maxFPS)-(end-start), start, end ); - SDL_Delay( 5 ); - } - else - SDL_Delay((1000/maxFPS)-(end-start) ); - } - } + FPSDelay(); else SDL_Delay( 5 ); - /* Check for events */ - while ( SDL_PollEvent(&event) ) + handleEvents(); + } +} + + +void SFCave :: handleGameState() +{ + switch( state ) + { + case STATE_MENU: + SDL_FillRect( screen, 0, 0 ); + menu->draw( screen ); + break; + case STATE_HELP: + SDL_FillRect( screen, 0, 0 ); + help->update(); + help->draw( screen ); + break; + case STATE_NEWGAME: + currentGame->setReplay( false ); + currentGame->init(); + changeState( STATE_PLAYING ); + break; + + case STATE_REPLAY: + currentGame->setReplay( true ); + currentGame->init(); + changeState( STATE_PLAYING ); + break; + + case STATE_PLAYING: + case STATE_CRASHING: + case STATE_CRASHED: + currentGame->update( state ); + currentGame->draw( screen ); + break; + + case STATE_QUIT: + finish = true; + break; + } +} + +void SFCave :: handleEvents() +{ + SDL_Event event; + + // Check for events + while ( SDL_PollEvent(&event) ) + { + switch (event.type) { - switch (event.type) + case SDL_KEYDOWN: + case SDL_KEYUP: { - case SDL_KEYDOWN: - case SDL_KEYUP: - // Escape keypress quits the app - if ( event.key.keysym.sym != SDLK_ESCAPE ) + // Escape keypress quits the app + if ( event.key.keysym.sym == SDLK_ESCAPE ) + { + finish = true; + break; + } + + if ( state == STATE_MENU ) + { + int rc = menu->handleKeys( event.key ); + if ( rc != -1 ) + handleMenuSelect( rc ); + } + else if ( state == STATE_HELP ) + { + help->handleKeys( event.key ); + } + else if ( state == STATE_CRASHED ) + { + if ( event.type == SDL_KEYDOWN ) { -// printf( "Key Pressed was %d %s\n", event.key.keysym.sym, SDL_GetKeyName( event.key.keysym.sym ) ); - - if ( state == STATE_MENU ) + if ( event.key.keysym.sym == SDLK_UP || + event.key.keysym.sym == SDLK_DOWN || + event.key.keysym.sym == SDLK_SPACE ) + changeState( STATE_NEWGAME ); + else if ( event.key.keysym.sym == SDLK_RETURN || event.key.keysym.sym == 0 ) { - int rc = menu->handleKeys( event.key ); - if ( rc != -1 ) - handleMenuSelect( rc ); + changeState( STATE_MENU ); + menu->resetToTopMenu(); } - else if ( state == STATE_HELP ) + else if ( event.key.keysym.sym == SDLK_r ) { - help->handleKeys( event.key ); + changeState( STATE_REPLAY ); } - else if ( state == STATE_CRASHED ) + else if ( event.key.keysym.sym == SDLK_s ) { - if ( event.type == SDL_KEYDOWN ) - { - if ( event.key.keysym.sym == SDLK_UP || - event.key.keysym.sym == SDLK_DOWN || - event.key.keysym.sym == SDLK_SPACE ) - changeState( STATE_NEWGAME ); - else if ( event.key.keysym.sym == SDLK_RETURN || event.key.keysym.sym == 0 ) - { - changeState( STATE_MENU ); - menu->resetToTopMenu(); - } - else if ( event.key.keysym.sym == SDLK_r ) - { - changeState( STATE_REPLAY ); - } - else if ( event.key.keysym.sym == SDLK_s ) - { - SoundHandler :: playSound( SND_EXPLOSION ); - } - } + SoundHandler :: playSound( SND_EXPLOSION ); } - else - { - switch ( event.key.keysym.sym ) - { - case SDLK_f: - printf( "showFPS - %d\n", showFps ); - if ( event.type == SDL_KEYDOWN ) - showFps = !showFps; - break; - case SDLK_l: - if ( event.type == SDL_KEYDOWN ) - limitFPS = !limitFPS; - break; - - case SDLK_p: - if ( event.type == SDL_KEYDOWN ) - { - maxFPS ++; - printf( "maxFPS - %d\n", maxFPS ); - } - break; - - case SDLK_o: - if ( event.type == SDL_KEYDOWN ) - { - maxFPS --; - printf( "maxFPS - %d\n", maxFPS ); - } - break; - - case SDLK_n: - currentGame->getTerrain()->offset++; - break; - - default: - currentGame->handleKeys( event.key ); - break; - } - } - - break; } + } + else + { + switch ( event.key.keysym.sym ) + { + case SDLK_f: + if ( event.type == SDL_KEYDOWN ) + showFps = !showFps; + break; + case SDLK_l: + if ( event.type == SDL_KEYDOWN ) + limitFPS = !limitFPS; + break; + default: + currentGame->handleKeys( event.key ); + break; + } + } - case SDL_QUIT: - done = 1; - break; - default: - break; + break; } + + case SDL_QUIT: + finish = true; + break; + default: + break; } } } void SFCave :: changeState( int s ) { if ( state != s ) currentGame->stateChanged( state, s ); if ( state == STATE_MENU && s == STATE_HELP ) help->init(); if ( state == STATE_CRASHED && s == STATE_MENU ) { SoundHandler :: stopMusic( true ); string musicFile = chooseRandomFile( musicPath, musicType ); - printf("playing music %s\n", musicFile.c_str() ); SoundHandler :: setMusicVolume( 128 ); SoundHandler :: playMusic( musicFile ); } else if ( state == STATE_MENU && (s == STATE_NEWGAME || s == STATE_REPLAY) ) { SoundHandler :: stopMusic( ); // Start the in game music - string musicFile = SOUND_PATH "ingame.mod"; + string musicFile = INGAME_MUSIC; SoundHandler :: playMusic( musicFile ); SoundHandler :: setMusicVolume( 25 ); } state = s; } void SFCave :: handleMenuSelect( int menuId ) { switch( menuId ) { case MENU_STARTGAME: changeState( STATE_NEWGAME ); break; case MENU_HELP: changeState( STATE_HELP ); break; case MENU_QUIT: changeState( STATE_QUIT ); break; case MENU_PLAY_REPLAY: if ( currentGame->isReplayAvailable() ) changeState( STATE_REPLAY ); else setMenuStatusText( "No replay available yet" ); break; case MENU_LOAD_REPLAY: { -#ifdef QWS - QString replayFile = getenv( "HOME" ); -#else - QString replayFile = "."; -#endif - replayFile += string( "/" ) + currentGame->getGameName() + ".replay"; + string replayFile = getHomeDir() + "/" + currentGame->getGameName() + ".replay"; currentGame->loadReplay( replayFile ); break; } case MENU_SAVE_REPLAY: { if ( currentGame->isReplayAvailable() ) { -#ifdef QWS - QString replayFile = getenv( "HOME" ); -#else - QString replayFile = "."; -#endif - replayFile += string( "/" ) + currentGame->getGameName() + ".replay"; + string replayFile = getHomeDir() + "/" + currentGame->getGameName() + ".replay"; currentGame->saveReplay( replayFile ); } else setMenuStatusText( "No replay available yet" ); break; } case MENU_CLEAR_SCORES: break; case MENU_GAME_SFCAVE: if ( currentGame->getGameName() != "SFCave" ) { int diff = currentGame->getDifficulty(); delete currentGame; currentGame = new SFCaveGame( this, WIDTH, HEIGHT, 0 ); currentGame->setDifficulty( diff ); saveSetting( "GameType", "SFCave" ); } break; case MENU_GAME_GATES: if ( currentGame->getGameName() != "Gates" ) { int diff = currentGame->getDifficulty(); delete currentGame; currentGame = new GatesGame( this, WIDTH, HEIGHT, 0 ); currentGame->setDifficulty( diff ); saveSetting( "GameType", "Gates" ); } break; break; case MENU_GAME_FLY: if ( currentGame->getGameName() != "Fly" ) { int diff = currentGame->getDifficulty(); delete currentGame; currentGame = new FlyGame( this, WIDTH, HEIGHT, 0 ); currentGame->setDifficulty( diff ); saveSetting( "GameType", "Fly" ); } break; case MENU_DIFFICULTY_EASY: currentGame->setDifficulty( MENU_DIFFICULTY_EASY ); saveSetting( "GameDifficulty", "Easy" ); break; case MENU_DIFFICULTY_NORMAL: currentGame->setDifficulty( MENU_DIFFICULTY_NORMAL ); saveSetting( "GameDifficulty", "Medium" ); break; case MENU_DIFFICULTY_HARD: currentGame->setDifficulty( MENU_DIFFICULTY_HARD ); saveSetting( "GameDifficulty", "Hard" ); break; + case MENU_DIFFICULTY_CUSTOM: + currentGame->setDifficulty( MENU_DIFFICULTY_CUSTOM ); + saveSetting( "GameDifficulty", "Custom" ); + break; + case MENU_SOUND_ON: SoundHandler :: setSoundsOn( true ); + saveSetting( "SoundOn", "true" ); break; case MENU_SOUND_OFF: SoundHandler :: setSoundsOn( false ); + saveSetting( "SoundOn", "false" ); break; case MENU_MUSIC_ON: SoundHandler :: setMusicOn( true ); + saveSetting( "MusicOn", "true" ); break; case MENU_MUSIC_OFF: SoundHandler :: setMusicOn( false ); + saveSetting( "MusicOn", "false" ); break; + case MENU_CUSTOM_THRUST: + customPlayerMenuVal = PLAYER_THRUST; + origValue = currentGame->getPlayer()->getValue( customPlayerMenuVal ); + setMenuStatusText( currentGame->getPlayer()->getValueString( customPlayerMenuVal ) ); + break; + case MENU_CUSTOM_GRAVITY: + customPlayerMenuVal = PLAYER_GRAVITY; + origValue = currentGame->getPlayer()->getValue( customPlayerMenuVal ); + setMenuStatusText( currentGame->getPlayer()->getValueString( customPlayerMenuVal ) ); + break; + case MENU_CUSTOM_MAXSPEEDUP: + customPlayerMenuVal = PLAYER_MAX_SPEED_UP; + origValue = currentGame->getPlayer()->getValue( customPlayerMenuVal ); + setMenuStatusText( currentGame->getPlayer()->getValueString( customPlayerMenuVal ) ); + break; + case MENU_CUSTOM_MAXSPEEDDOWN: + customPlayerMenuVal = PLAYER_MAX_SPEED_DOWN; + origValue = currentGame->getPlayer()->getValue( customPlayerMenuVal ); + setMenuStatusText( currentGame->getPlayer()->getValueString( customPlayerMenuVal ) ); + break; + case MENU_CUSTOM_INCREASE: + currentGame->getPlayer()->incValue( customPlayerMenuVal ); + setMenuStatusText( currentGame->getPlayer()->getValueString( customPlayerMenuVal ) ); + break; + case MENU_CUSTOM_DECREASE: + currentGame->getPlayer()->decValue( customPlayerMenuVal ); + setMenuStatusText( currentGame->getPlayer()->getValueString( customPlayerMenuVal ) ); + break; + case MENU_CUSTOM_SAVE: + { + // save settings + string key = currentGame->getGameName() + "_custom_player_" + currentGame->getPlayer()->getValueTypeString( customPlayerMenuVal ); + saveSetting( key, currentGame->getPlayer()->getValue( customPlayerMenuVal ) ); + + break; + } + case MENU_CUSTOM_CANCEL: + currentGame->getPlayer()->setValue( customPlayerMenuVal, origValue ); + break; + default: break; } } void SFCave :: setMenuStatusText( string statusText ) { menu->setStatusText( statusText ); } void SFCave :: saveSetting( string key, string val ) { Settings cfg( "sfcave-sdl" ); cfg.writeSetting( key, val ); } void SFCave :: saveSetting( string key, int val ) { Settings cfg( "sfcave-sdl" ); cfg.writeSetting( key, val ); } +void SFCave :: saveSetting( string key, long val ) +{ + Settings cfg( "sfcave-sdl" ); + cfg.writeSetting( key, val ); +} + +void SFCave :: saveSetting( string key, double val ) +{ + Settings cfg( "sfcave-sdl" ); + cfg.writeSetting( key, val ); +} + string SFCave :: loadSetting( string key, string defaultVal ) { string val; Settings cfg( "sfcave-sdl" ); cfg.readSetting( key, val ); if ( val == "" ) val = defaultVal; return val; } + +bool SFCave :: loadBoolSetting( string key, bool defaultVal ) +{ + bool val = defaultVal; + Settings cfg( "sfcave-sdl" ); + cfg.readSetting( key, val ); + + return val; +} + +int SFCave :: loadIntSetting( string key, int defaultVal ) +{ + int val = defaultVal; + Settings cfg( "sfcave-sdl" ); + cfg.readSetting( key, val ); + + return val; +} + +double SFCave :: loadDoubleSetting( string key, double defaultVal ) +{ + double val = defaultVal; + Settings cfg( "sfcave-sdl" ); + cfg.readSetting( key, val ); + + return val; +} + + +void SFCave :: calcFPS() +{ + struct timeb tp; + ftime( &tp ); + start =(tp.time%10000)*10000 + tp.millitm; + if ( start - time1 >= 1000 ) + { + actualFPS = FPS; + FPS = 0; + time1 = start; + } + else + FPS ++; +} + +void SFCave :: FPSDelay() +{ + struct timeb tp; + // Slow down polling - limit to x FPS + ftime( &tp ); + end = abs((tp.time%10000)*10000 + tp.millitm); + if ( end-start < (1000/maxFPS) ) + { + if ( (1000/maxFPS)-(end-start) > 500 ) + { + // Should never happen but in case it does sleep for 5 seconds + printf( "WARNING WILL ROBINSON! delay = %ld - start %ld, end %ld\n", (1000/maxFPS)-(end-start), start, end ); + SDL_Delay( 5 ); + } + else + SDL_Delay((1000/maxFPS)-(end-start) ); + } +} diff --git a/noncore/games/sfcave-sdl/sfcave.h b/noncore/games/sfcave-sdl/sfcave.h index 96c2334..c707919 100644 --- a/noncore/games/sfcave-sdl/sfcave.h +++ b/noncore/games/sfcave-sdl/sfcave.h @@ -1,50 +1,72 @@ #ifndef __SFCAVE_H #define __SFCAVE_H #include "SDL.h" #include "terrain.h" class Game; class Menu; class Help; class SFCave { public: SFCave( int argc, char *argv[] ); ~SFCave(); - void drawGameScreen(); void initSDL( int argc, char *argv[] ); void mainEventLoop(); void setCrashed( bool val ); void changeState( int s ); int getState() { return state; } Game *getCurrentGame() { return currentGame; } int getFPS() { return actualFPS; } bool showFPS() { return showFps; } void setMenuStatusText( string statusText ); void saveSetting( string key, string val ); void saveSetting( string key, int val ); + void saveSetting( string key, long val ); + void saveSetting( string key, double val ); string loadSetting( string key, string defaultVal = "" ); + bool loadBoolSetting( string key, bool defaultVal); + int loadIntSetting( string key, int defaultVal ); + double loadDoubleSetting( string key, double defaultVal ); + private: SDL_Surface *screen; + bool setupOK; Game *currentGame; Menu *menu; Help *help; int state; - int maxFPS; - int actualFPS; bool showFps; string musicPath; string musicType; + bool finish; + + bool limitFPS; + int maxFPS; + int actualFPS; + int FPS; + long time1; + long start; + long end; + + // This is used when the user is setting the custom + // values in the menu + int customPlayerMenuVal; + double origValue; void handleMenuSelect( int menuId ); + void handleGameState(); + void handleEvents(); + void calcFPS(); + void FPSDelay(); }; #endif diff --git a/noncore/games/sfcave-sdl/sfcave_game.cpp b/noncore/games/sfcave-sdl/sfcave_game.cpp index 72c5ce3..1b00e14 100644 --- a/noncore/games/sfcave-sdl/sfcave_game.cpp +++ b/noncore/games/sfcave-sdl/sfcave_game.cpp @@ -1,167 +1,179 @@ #include "SDL_gfxPrimitives.h" #include "constants.h" #include "sfcave_game.h" #include "random.h" SFCaveGame :: SFCaveGame( SFCave *p, int w, int h, int diff ) : Game( p, w, h, diff ) { gameName = "SFCave"; difficulty = MENU_DIFFICULTY_EASY; blockUpdateRate = 200; terrain = new Terrain( w, h ); player = new Player( w, h ); highScore = 0; } SFCaveGame :: ~SFCaveGame() { } void SFCaveGame :: init() { Game :: init(); blockDistance = 50; blockHeight = 80; blockWidth = 20; switch( difficulty ) { case MENU_DIFFICULTY_EASY: blockDistance = 50; break; case MENU_DIFFICULTY_NORMAL: blockDistance = 40; break; case MENU_DIFFICULTY_HARD: blockDistance = 30; break; + case MENU_DIFFICULTY_CUSTOM: + { + // Read custom difficulty settings for this game + blockDistance = parent->loadIntSetting( "SFCave_custom_blockdistance", 50 ); + + double thrust = parent->loadDoubleSetting( "SFCave_custom_player_thrust", 0.4 ); + double gravity = parent->loadDoubleSetting( "SFCave_custom_player_gravity", 0.6 ); + double maxUp = parent->loadDoubleSetting( "SFCave_custom_player_maxupspeed", 4.0 ); + double maxDown = parent->loadDoubleSetting( "SFCave_custom_player_maxdownspeed", 5.0 ); + player->setMovementInfo( thrust, gravity, maxUp, maxDown ); + + break; + } } for ( int i = 0 ; i < BLOCKSIZE ; ++i ) blocks[i].y( -1 ); } void SFCaveGame :: update( int state ) { Game::update( state ); if ( state == STATE_PLAYING ) { if ( nrFrames % 3 == 0 ) score ++; if ( nrFrames % 200 == 0 ) { if ( terrain->getMaxHeight() < sHeight - 100 ) { terrain->increaseMaxHeight( 10 ); // Reduce block height if ( terrain->getMaxHeight() > sHeight - 150 ) blockHeight -= 5; } } if ( checkCollisions() ) { -// printf( "Crashed!\n" ); parent->changeState( STATE_CRASHING ); return; } if ( nrFrames % blockDistance == 0 ) addBlock(); // Game logic goes here terrain->moveTerrain( 5 ); moveBlocks( 5 ); player->move( press ); } } void SFCaveGame :: draw( SDL_Surface *screen ) { Game::preDraw( screen ); if ( parent->getState() == STATE_PLAYING ) { // Screen drawing goes here terrain->drawTerrain( screen ); player->draw( screen ); drawBlocks( screen ); } else { // Screen drawing goes here terrain->drawTerrain( screen ); drawBlocks( screen ); player->draw( screen ); } Game::draw( screen ); } void SFCaveGame :: addBlock() { for ( int i = 0 ; i < BLOCKSIZE ; ++i ) { if ( blocks[i].y() == -1 ) { int x = sWidth; int y = terrain->getMapTop( MAPSIZE-1 ) + (int)(nextInt(terrain->getMapBottom( MAPSIZE-1 ) - terrain->getMapTop( MAPSIZE-1 ) - blockHeight)); blocks[i].setRect( x, y, blockWidth, blockHeight ); break; } } } void SFCaveGame :: moveBlocks( int amountToMove ) { for ( int i = 0 ; i < BLOCKSIZE ; ++i ) { if ( blocks[i].y() != -1 ) { blocks[i].moveBy( -amountToMove, 0 ); if ( blocks[i].x() + blocks[i].y() < 0 ) blocks[i].y( -1 ); } } } void SFCaveGame :: drawBlocks( SDL_Surface *screen ) { for ( int i = 0 ; i < BLOCKSIZE ; ++i ) { if ( blocks[i].y() != -1 ) { SDL_Rect r = blocks[i].getRect(); SDL_FillRect( screen, &r, SDL_MapRGB( screen->format, 100, 100, 255 ) ); } } } bool SFCaveGame :: checkCollisions() { // Check collisions with blocks for ( int i = 0 ; i < BLOCKSIZE ; ++i ) { if ( blocks[i].y() != -1 ) { if ( blocks[i].intersects( player->getPos() ) ) return true; } } // Check collision with landscape return terrain->checkCollision( player->getX(), player->getY(), player->getHeight() ); } diff --git a/noncore/games/sfcave-sdl/sound.cpp b/noncore/games/sfcave-sdl/sound.cpp index 5fda859..855f2e6 100644 --- a/noncore/games/sfcave-sdl/sound.cpp +++ b/noncore/games/sfcave-sdl/sound.cpp @@ -1,154 +1,157 @@ #include "constants.h"
#include "sound.h"
Mix_Chunk *SoundHandler :: sounds[NR_SOUNDS];
Mix_Music *SoundHandler :: music;
int SoundHandler :: soundChannels[NR_SOUNDS];
bool SoundHandler :: soundOn;
bool SoundHandler :: musicOn;
bool SoundHandler :: init( )
{
// We're going to be requesting certain things from our audio
// device, so we set them up beforehand
int audio_rate = 22050;
Uint16 audio_format = AUDIO_S16; //AUDIO_S16; /* 16-bit stereo */
int audio_channels = 2;
int audio_buffers = 1024;//4096;
// This is where we open up our audio device. Mix_OpenAudio takes
// as its parameters the audio format we'd /like/ to have.
if(Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers))
{
printf("Unable to open audio!\n");
return false;
}
// We're going to pre-load the sound effects that we need right here
sounds[SND_EXPLOSION] = Mix_LoadWAV( SOUND_PATH "explosion.wav");
sounds[SND_THRUST] = Mix_LoadWAV( SOUND_PATH "thrust.wav");
music = 0;
soundOn = true;
+ musicOn = true;
return true;
}
void SoundHandler :: cleanUp()
{
// Free audio sounds
- Mix_FreeChunk( sounds[SND_EXPLOSION] );
- Mix_FreeChunk( sounds[SND_THRUST] );
+ if ( sounds[SND_EXPLOSION] )
+ Mix_FreeChunk( sounds[SND_EXPLOSION] );
+ if ( sounds[SND_THRUST] )
+ Mix_FreeChunk( sounds[SND_THRUST] );
if ( music )
Mix_FreeMusic( music );
Mix_CloseAudio();
}
int SoundHandler :: playSound( int soundNr, int channel, int nrLoops, int playBeforeFinished )
{
if ( !soundOn )
return -1;
- if ( soundNr >= NR_SOUNDS )
+ if ( soundNr >= NR_SOUNDS || !sounds[soundNr] )
return -1;
Mix_Chunk *chunk = sounds[soundNr];
if( channel == -1 || !Mix_Playing( channel ) )
channel = Mix_PlayChannel(-1, sounds[soundNr], nrLoops);
Mix_Volume( channel, MIX_MAX_VOLUME );
return channel;
}
void SoundHandler :: stopSound( int channel, bool fadeOut, int nrMilliSecs )
{
if ( !soundOn )
return;
if ( !fadeOut )
Mix_HaltChannel( channel );
else
{
Mix_FadeOutChannel( channel, nrMilliSecs );
}
}
void SoundHandler :: playMusic( string musicFile )
{
if ( !soundOn )
return;
// If music already exists - stop it playing if necessary and free it up
if ( music )
{
stopMusic();
Mix_FreeMusic( music );
}
// Load music
music = Mix_LoadMUS( musicFile.c_str() );
if(!music)
{
printf("Mix_LoadMUS(%s): %s\n", musicFile.c_str(), Mix_GetError());
// this might be a critical error...
}
playMusic();
}
void SoundHandler :: playMusic( bool fade )
{
- if ( !soundOn )
+ if ( !musicOn )
return;
if ( music )
{
Mix_VolumeMusic( MIX_MAX_VOLUME );
Mix_RewindMusic();
-
+
if ( fade )
Mix_FadeInMusic( music, -1, 1000 );
else
Mix_PlayMusic( music, -1 );
}
}
void SoundHandler :: stopMusic( bool fadeOut )
{
if ( !music || !Mix_PlayingMusic() )
return;
if ( fadeOut && Mix_FadingMusic() == MIX_NO_FADING )
{
Mix_FadeOutMusic( 1000 );
}
else
{
Mix_HaltMusic();
}
}
void SoundHandler :: setMusicVolume( int vol )
{
Mix_VolumeMusic( vol );
}
void SoundHandler :: setSoundsOn( bool val )
{
soundOn = val;
}
void SoundHandler :: setMusicOn( bool val )
{
musicOn = val;
-
+
if ( !musicOn )
stopMusic();
else
playMusic( true );
}
diff --git a/noncore/games/sfcave-sdl/starfield.cpp b/noncore/games/sfcave-sdl/starfield.cpp index c1f2d73..82edfc1 100644 --- a/noncore/games/sfcave-sdl/starfield.cpp +++ b/noncore/games/sfcave-sdl/starfield.cpp @@ -68,156 +68,228 @@ StarField :: ~StarField() if ( y )
delete []y;
if ( z )
delete []z;
}
void StarField :: init()
{
if ( !sideways )
{
for ( int i = 0 ; i < nrStars ; ++i )
{
newStar( i );
z[i] = (int)(Random() * (double)(maxZ - minZ)) + minZ ;
}
}
else
{
int brightness;
//Initialise each star
for(int i = 0; i < nrStars ; i++)
{
//Inialise velocities
vel_x[i] = -(int)floor( (Random() * top_star_speed)+1 );
vel_y[i] = VERTICAL_VELOCITY;
//Initialise positions randomly
pos_x[i] = (int)floor((Random() * 240));
pos_y[i] = (int)floor((Random() * 320));
//The Faster it goes, the Dimmer it is
if (vel_x[i] != 0)
{
brightness = (int)(255 / fabs(vel_x[i]) );
if (brightness < min_brightness)
brightness = min_brightness;
}
else
brightness = 255;
star_color[i] = brightness;
}
}
}
void StarField :: newStar( int starNr )
{
if ( !sideways )
{
x[starNr] = (int)(Random() * (double)maxX) + 1;
y[starNr] = (int)(Random() * (double)maxY) + 1;
z[starNr] = maxZ;
int i = (int)(Random() * 4.0);
if(i < 2)
x[starNr] = -x[starNr];
if(i == 0 || i == 2)
y[starNr] = -y[starNr];
}
}
void StarField :: move( )
{
if ( !sideways )
{
int amountToMove = 16;
for(int i = 0; i < nrStars; i++)
{
// Rotate star
z[i] = z[i] - amountToMove;
if(z[i] < minZ)
newStar(i);
}
}
else
{
for(int i = 0; i < nrStars ; i++)
{
//Check speed limits x
if (vel_x[i] > top_star_speed)
vel_x[i] = top_star_speed;
else if (vel_x[i] < -top_star_speed)
vel_x[i] = -top_star_speed;
//Check speed limits y
if (vel_y[i] > top_star_speed)
vel_y[i] = top_star_speed;
else if (vel_y[i] < -top_star_speed)
vel_y[i] = -top_star_speed;
//Move Star
pos_x[i] += vel_x[i];
pos_y[i] += vel_y[i];
-
+
if (pos_x[i] < 0)
pos_x[i] = pos_x[i] + 240;
if (pos_x[i] > 240)
pos_x[i] = pos_x[i] - 240;
if (pos_y[i] < 0)
pos_y[i] = pos_y[i] + 320;
if (pos_y[i] > 320)
pos_y[i] = pos_y[i] - 320;
}
}
}
void StarField :: draw( SDL_Surface *screen, int w, int h )
{
if ( !sideways )
{
int scrW = w / 2;
int scrH = h / 2;
for(int i = 0; i < nrStars; i++)
{
int sx = (x[i] * 256) / z[i] + scrW;
int sy = (y[i] * 256) / z[i] + scrH;
if(sx < 0 || sx > w || sy < 0 || sy > h)
{
newStar(i);
}
else
{
int size = (z[i] * 3) / maxZ;
SDL_Rect r;
r.x = sx;
r.y = sy;
r.w = 3 - size;
r.h = 3 - size;
SDL_FillRect( screen, &r, SDL_MapRGB( screen->format, 255, 255, 255 ) );
}
}
}
else
{
SDL_LockSurface( screen );
for(int i = 0; i < nrStars ; i++)
{
Uint32 c = getpixel( screen, pos_x[i], pos_y[i] );
if ( c == 0 )
lineRGBA( screen, pos_x[i], pos_y[i], pos_x [i]+ vel_x[i], pos_y[i] + vel_y[i], star_color[i], star_color[i], star_color[i], 255 );
//*** NOTE : if the velocity of the stars never changes then the values such as 'pos_x[i] + vel_x[i]' could be precalculated for each star ***
}
SDL_UnlockSurface( screen );
}
}
+
+
+
+// Test
+#ifdef DEBUG_STARS
+SDL_Surface *screen;
+StarField *stars;
+
+void go()
+{
+ /* Initialize SDL */
+ if ( SDL_Init(SDL_INIT_VIDEO) < 0 )
+ {
+ fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
+ exit(1);
+ }
+ atexit(SDL_Quit);
+
+ int videoflags = SDL_SWSURFACE ;
+
+ if ( (screen=SDL_SetVideoMode(240, 320,32,videoflags)) == NULL )
+ {
+ fprintf(stderr, "Couldn't set %ix%i video mode: %s\n",240,320,SDL_GetError());
+ exit(2);
+ }
+
+ stars = new StarField( false, 200 );
+
+ bool done = false;
+ while ( !done )
+ {
+ SDL_FillRect( screen, 0, 0 );
+ stars->draw( screen );
+ stars->move( );
+
+ SDL_Flip( screen );
+
+ SDL_Delay( 10 );
+
+ SDL_Event event;
+ while ( SDL_PollEvent(&event) )
+ {
+ switch (event.type)
+ {
+ case SDL_KEYDOWN:
+ // Escape keypress quits the app
+ if ( event.key.keysym.sym != SDLK_ESCAPE )
+ {
+ break;
+ }
+ case SDL_QUIT:
+ done = 1;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+
+
+
+#ifdef __cplusplus
+extern "C"
+#endif
+int main( int argc, char *argv[] )
+{
+ go();
+}
+
+#endif
diff --git a/noncore/games/sfcave-sdl/terrain.cpp b/noncore/games/sfcave-sdl/terrain.cpp index c001a56..b243f45 100644 --- a/noncore/games/sfcave-sdl/terrain.cpp +++ b/noncore/games/sfcave-sdl/terrain.cpp @@ -1,313 +1,297 @@ #include "SDL.h" #include "SDL_rotozoom.h" #include "SDL_gfxPrimitives.h" #include "constants.h" #include "terrain.h" #include "random.h" #include "util.h" #include "starfield.h" Terrain :: Terrain( int w, int h, bool drawTop, bool drawBottom ) { sWidth = w; sHeight = h; speed = 1; segSize = sWidth/(MAPSIZE-2)+1; this->drawTop = drawTop; this->drawBottom = drawBottom; stars = new StarField( true ); SDL_Surface *tmp = SDL_CreateRGBSurface(SDL_SWSURFACE, sWidth + 20, sHeight, 32, 0x000000ff,0x0000ff00, 0x00ff0000, 0xff000000); terrainSurface = SDL_DisplayFormat( tmp ); SDL_FreeSurface( tmp ); initTerrain(); } Terrain :: ~Terrain() { SDL_FreeSurface( terrainSurface ); delete stars; } void Terrain :: initTerrain() { dir = 1; offset = 0; maxHeight = 50; mapTop[0] = (int)(nextInt(50)) + 5; mapBottom[0] = sHeight - (maxHeight - mapTop[0]); for ( int i = 1 ; i < MAPSIZE ; ++i ) setPoint( i ); SDL_FillRect( terrainSurface, 0, 0 ); + // Draw Terrain into surface Sint16 px[5]; Sint16 py[5]; for ( int i = 0 ; i < MAPSIZE ; ++i ) { int left = (i*segSize); int right = ((i+1)*segSize); px[0] = left; py[0] = mapTop[i]; px[1] = right; py[1] = mapTop[i+1]; px[2] = right; py[2] = 0; px[3] = left; py[3] = 0; if ( drawTop ) { // Only display top landscape if not running FLY_GAME filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 ); } if ( drawBottom ) { py[0] = mapBottom[i]; py[1] = mapBottom[i+1]; py[2] = sHeight; py[3] = sHeight; filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 ); } } } void Terrain :: moveTerrain( int amountToMove ) { stars->move(); offset += amountToMove; speed = offset/segSize; -// printf( "offset - %d, speed - %d\n", offset, speed ); if ( offset >= segSize ) { for ( int i = 0 ; i < (MAPSIZE)-speed ; ++i ) { mapTop[i] = mapTop[i+speed]; mapBottom[i] = mapBottom[i+speed]; } for ( int i = (MAPSIZE)-speed ; i < MAPSIZE ; ++i ) { setPoint( i ); } SDL_Rect dst; dst.x = offset; dst.y = 0; dst.w = sWidth; dst.h = sHeight; SDL_Rect dst2; dst2.x = 0; dst2.y = 0; SDL_BlitSurface(terrainSurface, &dst, terrainSurface, &dst2 ); dst.x = sWidth-5; dst.y = 0; dst.w = offset; dst.h = sHeight; SDL_FillRect( terrainSurface, &dst, 0 ); for ( int i = (MAPSIZE-1) - speed -1; i < MAPSIZE-1 ; ++i ) { Sint16 px[4]; Sint16 py[5]; int left = ((i-1)*segSize); int right = ((i)*segSize); // printf( "left = %d, right = %d\n", left, right ); px[0] = left; py[0] = mapTop[i]; px[1] = right; py[1] = mapTop[i+1]; px[2] = right; py[2] = 0; px[3] = left; py[3] = 0; if ( drawTop ) { // Only display top landscape if not running FLY_GAME filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 ); } if ( drawBottom ) { py[0] = mapBottom[i]; py[1] = mapBottom[i+1]; py[2] = sHeight; py[3] = sHeight; filledPolygonRGBA( terrainSurface, px, py, 4, 0, 190, 0, 255 ); } } offset -= speed*segSize; } } void Terrain :: setPoint( int point ) { if ( nextInt( 100 ) >= 80 ) dir *= -1; mapTop[point] = mapTop[point-1] + (dir * nextInt( 5 )); if ( mapTop[point] < 0 ) { mapTop[point] = 0; dir *= -1; } else if ( mapTop[point] >= maxHeight ) { mapTop[point] = maxHeight; dir *= -1; } mapBottom[point] = sHeight - (maxHeight - mapTop[point]); } void Terrain :: increaseMaxHeight( int amount ) { maxHeight += amount; } void Terrain :: drawTerrain( SDL_Surface *screen ) { // Blit terrain surface onto screen SDL_Rect dst; dst.x = offset; dst.y = 0; dst.w = sWidth; dst.h = sHeight; -// dst.h = maxHeight; SDL_Rect dst2; dst2.x = 0; dst2.y = 0; SDL_BlitSurface(terrainSurface, &dst, screen, &dst2 ); stars->draw( screen ); - -// dst.y = sHeight - maxHeight; -// dst2.y = sHeight - maxHeight; -// SDL_BlitSurface(terrainSurface, &dst, screen, &dst2 ); - -/* - for ( int i = 0 ; i < MAPSIZE ; ++i ) - { - int x1 = (i*segSize) - (offset*speed); - int x2 = ((i+1)*segSize)-(offset*speed); - if ( x2 >= sWidth ) - x2 = sWidth-1; - aalineRGBA( screen, x1, mapTop[i], x2, mapTop[i+1], 0, 220, 0, 255 ); - aalineRGBA( screen, x1, mapBottom[i], x2, mapBottom[i+1], 0, 220, 0, 255 ); - } -*/ } bool Terrain :: checkCollision( int x, int y, int h ) { if ( y < 0 || y > sHeight ) return true; + // First get segment that matches x SDL_LockSurface( terrainSurface ); Uint32 c = getpixel( terrainSurface, x, y ); SDL_UnlockSurface( terrainSurface ); if ( c == 0 ) return false; else return true; } // Test #ifdef DEBUG_TERRAIN SDL_Surface *screen; Terrain *terrain; void go() { - /* Initialize SDL */ + // Initialize SDL if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); exit(1); } atexit(SDL_Quit); int videoflags = SDL_SWSURFACE ; if ( (screen=SDL_SetVideoMode(280, 320,32,videoflags)) == NULL ) { fprintf(stderr, "Couldn't set %ix%i video mode: %s\n",WIDTH,HEIGHT,SDL_GetError()); exit(2); } terrain = new Terrain( 240, 320 ); bool done = false; while ( !done ) { SDL_FillRect( screen, 0, 0 ); terrain->drawTerrain( screen ); terrain->moveTerrain( 5 ); SDL_Flip( screen ); SDL_Delay( 5 ); SDL_Event event; while ( SDL_PollEvent(&event) ) { switch (event.type) { case SDL_KEYDOWN: // Escape keypress quits the app if ( event.key.keysym.sym != SDLK_ESCAPE ) { terrain->moveTerrain( 5 ); break; } case SDL_QUIT: done = 1; break; default: break; } } } } #ifdef __cplusplus extern "C" #endif int main( int argc, char *argv[] ) { go(); } #endif diff --git a/noncore/games/sfcave-sdl/util.cpp b/noncore/games/sfcave-sdl/util.cpp index 86738ad..f73e256 100644 --- a/noncore/games/sfcave-sdl/util.cpp +++ b/noncore/games/sfcave-sdl/util.cpp @@ -1,64 +1,75 @@ #include "SDL.h"
#include <dirent.h>
#include <vector>
using namespace std;
#include "util.h"
#include "random.h"
Uint32 getpixel(SDL_Surface *surface, int x, int y)
{
int bpp = surface->format->BytesPerPixel;
/* Here p is the address to the pixel we want to retrieve */
Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
switch(bpp) {
case 1:
return *p;
case 2:
return *(Uint16 *)p;
case 3:
if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
return p[0] << 16 | p[1] << 8 | p[2];
else
return p[0] | p[1] << 8 | p[2] << 16;
case 4:
return *(Uint32 *)p;
default:
return 0; /* shouldn't happen, but avoids warnings */
}
}
-const char *chooseRandomFile( string path, string fileType )
+string chooseRandomFile( string path, string fileType )
{
vector<string> files;
DIR *d = opendir( path.c_str() );
if ( !d )
return "";
struct dirent *item = readdir( d );
while ( item )
{
string file = string( path ) + item->d_name;
// Rip extension from file
int pos = file.find( ".", 1 ) + 1;
string tmp = file.substr( pos );
- printf( "pos = %d, tmp =%s\n", pos, tmp.c_str() );
if ( tmp.size() > 0 && fileType.find( tmp ) != -1 )
{
- printf( "Matching <%s> - %s with <%s>\n", file.substr( pos ).c_str(), file.c_str(), fileType.c_str() );
files.push_back( file );
}
item = readdir( d );
}
closedir( d );
- return files[nextInt( files.size() )].c_str();
+ return files[nextInt( files.size() )];
+}
+
+
+string getHomeDir()
+{
+ string home;
+#ifdef QWS
+ home = getenv( "HOME" );
+#else
+ home = ".";
+#endif
+
+ return home;
}
diff --git a/noncore/games/sfcave-sdl/util.h b/noncore/games/sfcave-sdl/util.h index fe3e9c0..e3aa31a 100644 --- a/noncore/games/sfcave-sdl/util.h +++ b/noncore/games/sfcave-sdl/util.h @@ -1,10 +1,10 @@ #ifndef __UTIL_H
#define __UTIL_H
#include <string>
using namespace std;
Uint32 getpixel(SDL_Surface *surface, int x, int y);
-const char *chooseRandomFile( string path, string fileType );
-
+string chooseRandomFile( string path, string fileType );
+string getHomeDir();
#endif
|