├── INSTALL ├── Makefile ├── readme.txt ├── screenshot.png ├── src ├── sge │ ├── sge.h │ ├── sge_blib.h │ ├── sge_misc.h │ ├── sge_shape.h │ ├── sge_blib.cpp │ ├── sge_bm_text.h │ ├── sge_misc.cpp │ ├── sge_shape.cpp │ ├── sge_surface.h │ ├── sge_textpp.h │ ├── sge_tt_text.h │ ├── sge_bm_text.cpp │ ├── sge_collision.h │ ├── sge_internal.h │ ├── sge_primitives.h │ ├── sge_rotation.cpp │ ├── sge_rotation.h │ ├── sge_surface.cpp │ ├── sge_textpp.cpp │ ├── sge_tt_text.cpp │ ├── sge_collision.cpp │ ├── sge_primitives.cpp │ └── sge_config.h ├── auxiliar.cpp ├── menu_state.cpp ├── CRoadFighter.cpp ├── debug.h ├── filehandling.h ├── CEnemyNormalCarObject.cpp ├── debug.cpp ├── sound.h ├── CExplosionObject.cpp ├── CEnemyRacerCarObject.cpp ├── CEnemySlidderCarObject.cpp ├── filehandling.cpp ├── CTile.h ├── konami_state.cpp ├── CSemaphoreObject.cpp ├── CFuelObject.cpp ├── configuration.cpp ├── presentation_state.cpp ├── CCarObject.cpp ├── auxiliar.h ├── quick_tables.cpp ├── gameover_state.cpp ├── CObject.cpp ├── CEnemyTruckObject.cpp ├── CRoadFighter.h ├── CEnemyCarObject.cpp ├── CEnemyFastCarObject.cpp ├── playing_state.cpp ├── CGame.h ├── CObject.h ├── CTile.cpp ├── main.cpp ├── loadmg2.cpp ├── interlevel_state.cpp ├── sound.cpp ├── List.h ├── CPlayerCarObject.cpp └── CGame.cpp ├── sound ├── start.ogg ├── truck.ogg ├── water.wav ├── car_brake.ogg ├── car_crash.ogg ├── car_pass.ogg ├── car_start.ogg ├── collision.wav ├── fuelempty.ogg ├── gameover.ogg ├── logo_in.ogg ├── logo_out.ogg ├── menu_move.wav ├── redlight.ogg ├── takefuel.ogg ├── car_running.ogg ├── car_running.wav ├── game_theme.ogg ├── game_theme2.ogg ├── greenlight.ogg ├── menu_select.ogg ├── menu_theme.ogg └── levelcomplete.ogg ├── fonts ├── comicbd.ttf └── tanglewo.ttf ├── graphics ├── arrow.bmp ├── car1.bmp ├── car2.bmp ├── empty.bmp ├── fuel.bmp ├── goal.bmp ├── level1.bmp ├── level2.bmp ├── level3.bmp ├── level4.bmp ├── level5.bmp ├── level6.bmp ├── pause.bmp ├── road.bmp ├── stage1.jpg ├── stage2.jpg ├── stage3.jpg ├── stage4.jpg ├── stage5.jpg ├── stage6.jpg ├── title.jpg ├── gamemap.bmp ├── gameover.jpg ├── konami1.jpg ├── konami2.jpg ├── minicar1.bmp ├── minicar2.bmp ├── checkpoint.bmp ├── disclaimer.jpg ├── enemycars.bmp ├── explosion.bmp ├── fuel_scores.bmp ├── obstacles.bmp ├── s_board11p.bmp ├── s_board12p.bmp ├── s_board21p.bmp ├── s_board22p.bmp ├── scoreboard.bmp ├── semaphore.bmp ├── retroremakes.bmp └── scoreboard_left.bmp ├── .gitignore ├── .gitattributes ├── .travis.yml └── README.md /INSTALL: -------------------------------------------------------------------------------- 1 | build/linux/INSTALL -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | build/linux/Makefile -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/readme.txt -------------------------------------------------------------------------------- /screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/screenshot.png -------------------------------------------------------------------------------- /src/sge/sge.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge.h -------------------------------------------------------------------------------- /sound/start.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/start.ogg -------------------------------------------------------------------------------- /sound/truck.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/truck.ogg -------------------------------------------------------------------------------- /sound/water.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/water.wav -------------------------------------------------------------------------------- /src/auxiliar.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/auxiliar.cpp -------------------------------------------------------------------------------- /fonts/comicbd.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/fonts/comicbd.ttf -------------------------------------------------------------------------------- /fonts/tanglewo.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/fonts/tanglewo.ttf -------------------------------------------------------------------------------- /graphics/arrow.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/arrow.bmp -------------------------------------------------------------------------------- /graphics/car1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/car1.bmp -------------------------------------------------------------------------------- /graphics/car2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/car2.bmp -------------------------------------------------------------------------------- /graphics/empty.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/empty.bmp -------------------------------------------------------------------------------- /graphics/fuel.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/fuel.bmp -------------------------------------------------------------------------------- /graphics/goal.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/goal.bmp -------------------------------------------------------------------------------- /graphics/level1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/level1.bmp -------------------------------------------------------------------------------- /graphics/level2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/level2.bmp -------------------------------------------------------------------------------- /graphics/level3.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/level3.bmp -------------------------------------------------------------------------------- /graphics/level4.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/level4.bmp -------------------------------------------------------------------------------- /graphics/level5.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/level5.bmp -------------------------------------------------------------------------------- /graphics/level6.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/level6.bmp -------------------------------------------------------------------------------- /graphics/pause.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/pause.bmp -------------------------------------------------------------------------------- /graphics/road.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/road.bmp -------------------------------------------------------------------------------- /graphics/stage1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/stage1.jpg -------------------------------------------------------------------------------- /graphics/stage2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/stage2.jpg -------------------------------------------------------------------------------- /graphics/stage3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/stage3.jpg -------------------------------------------------------------------------------- /graphics/stage4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/stage4.jpg -------------------------------------------------------------------------------- /graphics/stage5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/stage5.jpg -------------------------------------------------------------------------------- /graphics/stage6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/stage6.jpg -------------------------------------------------------------------------------- /graphics/title.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/title.jpg -------------------------------------------------------------------------------- /sound/car_brake.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/car_brake.ogg -------------------------------------------------------------------------------- /sound/car_crash.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/car_crash.ogg -------------------------------------------------------------------------------- /sound/car_pass.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/car_pass.ogg -------------------------------------------------------------------------------- /sound/car_start.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/car_start.ogg -------------------------------------------------------------------------------- /sound/collision.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/collision.wav -------------------------------------------------------------------------------- /sound/fuelempty.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/fuelempty.ogg -------------------------------------------------------------------------------- /sound/gameover.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/gameover.ogg -------------------------------------------------------------------------------- /sound/logo_in.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/logo_in.ogg -------------------------------------------------------------------------------- /sound/logo_out.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/logo_out.ogg -------------------------------------------------------------------------------- /sound/menu_move.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/menu_move.wav -------------------------------------------------------------------------------- /sound/redlight.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/redlight.ogg -------------------------------------------------------------------------------- /sound/takefuel.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/takefuel.ogg -------------------------------------------------------------------------------- /src/menu_state.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/menu_state.cpp -------------------------------------------------------------------------------- /src/sge/sge_blib.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_blib.h -------------------------------------------------------------------------------- /src/sge/sge_misc.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_misc.h -------------------------------------------------------------------------------- /src/sge/sge_shape.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_shape.h -------------------------------------------------------------------------------- /graphics/gamemap.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/gamemap.bmp -------------------------------------------------------------------------------- /graphics/gameover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/gameover.jpg -------------------------------------------------------------------------------- /graphics/konami1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/konami1.jpg -------------------------------------------------------------------------------- /graphics/konami2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/konami2.jpg -------------------------------------------------------------------------------- /graphics/minicar1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/minicar1.bmp -------------------------------------------------------------------------------- /graphics/minicar2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/minicar2.bmp -------------------------------------------------------------------------------- /sound/car_running.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/car_running.ogg -------------------------------------------------------------------------------- /sound/car_running.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/car_running.wav -------------------------------------------------------------------------------- /sound/game_theme.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/game_theme.ogg -------------------------------------------------------------------------------- /sound/game_theme2.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/game_theme2.ogg -------------------------------------------------------------------------------- /sound/greenlight.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/greenlight.ogg -------------------------------------------------------------------------------- /sound/menu_select.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/menu_select.ogg -------------------------------------------------------------------------------- /sound/menu_theme.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/menu_theme.ogg -------------------------------------------------------------------------------- /src/CRoadFighter.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/CRoadFighter.cpp -------------------------------------------------------------------------------- /src/sge/sge_blib.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_blib.cpp -------------------------------------------------------------------------------- /src/sge/sge_bm_text.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_bm_text.h -------------------------------------------------------------------------------- /src/sge/sge_misc.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_misc.cpp -------------------------------------------------------------------------------- /src/sge/sge_shape.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_shape.cpp -------------------------------------------------------------------------------- /src/sge/sge_surface.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_surface.h -------------------------------------------------------------------------------- /src/sge/sge_textpp.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_textpp.h -------------------------------------------------------------------------------- /src/sge/sge_tt_text.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_tt_text.h -------------------------------------------------------------------------------- /graphics/checkpoint.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/checkpoint.bmp -------------------------------------------------------------------------------- /graphics/disclaimer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/disclaimer.jpg -------------------------------------------------------------------------------- /graphics/enemycars.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/enemycars.bmp -------------------------------------------------------------------------------- /graphics/explosion.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/explosion.bmp -------------------------------------------------------------------------------- /graphics/fuel_scores.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/fuel_scores.bmp -------------------------------------------------------------------------------- /graphics/obstacles.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/obstacles.bmp -------------------------------------------------------------------------------- /graphics/s_board11p.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/s_board11p.bmp -------------------------------------------------------------------------------- /graphics/s_board12p.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/s_board12p.bmp -------------------------------------------------------------------------------- /graphics/s_board21p.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/s_board21p.bmp -------------------------------------------------------------------------------- /graphics/s_board22p.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/s_board22p.bmp -------------------------------------------------------------------------------- /graphics/scoreboard.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/scoreboard.bmp -------------------------------------------------------------------------------- /graphics/semaphore.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/semaphore.bmp -------------------------------------------------------------------------------- /sound/levelcomplete.ogg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/sound/levelcomplete.ogg -------------------------------------------------------------------------------- /src/sge/sge_bm_text.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_bm_text.cpp -------------------------------------------------------------------------------- /src/sge/sge_collision.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_collision.h -------------------------------------------------------------------------------- /src/sge/sge_internal.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_internal.h -------------------------------------------------------------------------------- /src/sge/sge_primitives.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_primitives.h -------------------------------------------------------------------------------- /src/sge/sge_rotation.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_rotation.cpp -------------------------------------------------------------------------------- /src/sge/sge_rotation.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_rotation.h -------------------------------------------------------------------------------- /src/sge/sge_surface.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_surface.cpp -------------------------------------------------------------------------------- /src/sge/sge_textpp.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_textpp.cpp -------------------------------------------------------------------------------- /src/sge/sge_tt_text.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_tt_text.cpp -------------------------------------------------------------------------------- /graphics/retroremakes.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/retroremakes.bmp -------------------------------------------------------------------------------- /src/sge/sge_collision.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_collision.cpp -------------------------------------------------------------------------------- /src/sge/sge_primitives.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/src/sge/sge_primitives.cpp -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | #ignore the .o 2 | *.o 3 | *.obj 4 | #ignore the generated libraries also 5 | *.so 6 | *.dll 7 | 8 | -------------------------------------------------------------------------------- /graphics/scoreboard_left.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ptitSeb/roadfighter/HEAD/graphics/scoreboard_left.bmp -------------------------------------------------------------------------------- /src/sge/sge_config.h: -------------------------------------------------------------------------------- 1 | /* SGE Config header (generated automatically) */ 2 | #define SGE_VER 030809 3 | #define _SGE_C_AND_CPP 4 | #define _SGE_HAVE_IMG 5 | #define _SGE_NOTTF 6 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Force CRLF for Windows files: 2 | *.bat text eol=crlf 3 | *.dsp text eol=crlf 4 | *.dsw text eol=crlf 5 | *.sln text eol=crlf 6 | *.vcxproj text eol=crlf 7 | *.vcxproj.filters text eol=crlf 8 | 9 | -------------------------------------------------------------------------------- /src/debug.h: -------------------------------------------------------------------------------- 1 | #ifndef _F1SPIRIT_DEBUG 2 | #define _F1SPIRIT_DEBUG 3 | 4 | #define F1SPIRIT_DEBUG_MESSAGES 5 | 6 | void output_debug_message(const char *fmt, ...); 7 | void close_debug_messages(void); 8 | 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /src/filehandling.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define STRLEN 512 8 | #define GAMENAME "roadfighter" 9 | 10 | enum filetype { GAMEDATA, USERDATA }; 11 | 12 | #ifndef _WIN32 13 | int mkdirp(const char *fqfn, mode_t mode); 14 | #endif 15 | FILE *f1open(const char *f, const char *m, const enum filetype t); 16 | 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | sudo: true 3 | dist: trusty 4 | 5 | compiler: 6 | - g++ 7 | 8 | #Build steps 9 | before_install: 10 | - sudo apt-get install libsdl-mixer1.2-dev libsdl-image1.2-dev libsdl-ttf2.0-dev -y 11 | - git clone https://github.com/ptitSeb/SDL_sound 12 | - cd SDL_sound 13 | - ./autogen.sh 14 | - ./configure --prefix=/usr --enable-sdl2=no 15 | - make 16 | - sudo make install 17 | - cd .. 18 | 19 | script: make LINUX=1 20 | -------------------------------------------------------------------------------- /src/CEnemyNormalCarObject.cpp: -------------------------------------------------------------------------------- 1 | #include "math.h" 2 | 3 | #include "SDL.h" 4 | #include "SDL_ttf.h" 5 | #include "SDL_mixer.h" 6 | 7 | #include "sound.h" 8 | 9 | #include "CTile.h" 10 | #include "CObject.h" 11 | #include "CGame.h" 12 | 13 | extern int ENEMY_SPEED; 14 | extern int ENEMY_HSPEED; 15 | extern int PLAYING_WINDOW; 16 | 17 | 18 | CEnemyNormalCarObject::CEnemyNormalCarObject(int nx,int ny,CTile *t,int start_delay,CGame *g) : CEnemyCarObject(nx,ny,t,start_delay,g) 19 | { 20 | } /* CEnemyNormalCarObject::CEnemyNormalCarObject */ 21 | 22 | 23 | CEnemyNormalCarObject::~CEnemyNormalCarObject(void) 24 | { 25 | } /* CEnemyNormalCarObject::~CEnemyNormalCarObject */ 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/debug.cpp: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | #include "windows.h" 3 | #endif 4 | 5 | #include 6 | #include 7 | 8 | #include "filehandling.h" 9 | 10 | #ifdef KITSCHY_DEBUG_MEMORY 11 | #include "debug_memorymanager.h" 12 | #endif 13 | 14 | FILE *fp = 0; 15 | 16 | void output_debug_message(const char *fmt, ...) 17 | { 18 | char text[256]; 19 | va_list ap; 20 | 21 | if (fmt == 0) 22 | return ; 23 | 24 | va_start(ap, fmt); 25 | vsprintf(text, fmt, ap); 26 | va_end(ap); 27 | 28 | if (fp == 0) 29 | fp = f1open("roadfighter.dbg", "w", USERDATA); 30 | 31 | fprintf(fp, text); 32 | fflush(fp); 33 | } /* glprintf */ 34 | 35 | 36 | 37 | 38 | void close_debug_messages(void) 39 | { 40 | fclose(fp); 41 | fp = 0; 42 | } /* close_debug_messages */ 43 | -------------------------------------------------------------------------------- /src/sound.h: -------------------------------------------------------------------------------- 1 | #ifndef __BRAIN_SDL_SOUND 2 | #define __BRAIN_SDL_SOUND 3 | 4 | typedef Mix_Chunk * SOUNDT; 5 | 6 | bool Sound_initialization(void); 7 | int Sound_initialization(int nc,int nrc); 8 | void Sound_release(void); 9 | 10 | bool Sound_file_test(char *f1); 11 | 12 | SOUNDT Sound_create_sound(char *file); 13 | void Sound_delete_sound(SOUNDT s); 14 | int Sound_play(SOUNDT s); 15 | int Sound_play(SOUNDT s,int volume); 16 | int Sound_play_continuous(SOUNDT s); 17 | int Sound_play_continuous(SOUNDT s,int volume); 18 | void Sound_play_ch(SOUNDT s,int channel); 19 | void Sound_play_ch(SOUNDT s,int channel,int volume); 20 | 21 | void Sound_create_music(char *f1,int times); 22 | void Sound_release_music(void); 23 | void Sound_pause_music(void); 24 | void Sound_unpause_music(void); 25 | 26 | void Sound_music_volume(int volume); 27 | 28 | /* These functions are AGRESIVE! (i.e. they actually STOP SDL_mixer and restart it) */ 29 | void Stop_playback(void); 30 | void Resume_playback(void); 31 | int Resume_playback(int nc,int nr); 32 | 33 | #endif 34 | 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | roadfighter 2 | ==== 3 | 4 | ![roadfighter build status](https://api.travis-ci.org/ptitSeb/roadfighter.png "roadfighter build status") 5 | 6 | This version of roadfighter as been slightly modified. It now support Pandora and ODROID build. 7 | To compile on the Pandora, using the Codeblocks Command Line PND, just type 8 | `make` 9 | 10 | To compile on the ODROID, type 11 | `make ODROID=1` 12 | 13 | To compile on x86 Linux, type 14 | `make LINUX=1` 15 | 16 | Other platform can probably be added easily (like RPi), but will need some slight 17 | changes in the Makefile (contact me or do a pull request if you want / have a new platform) 18 | 19 | Note that you will need SDL_sound library (for SDL1.2). You can find a copy of this lib (that can be built both for SDL1.2 and SDL2) [here](https://github.com/ptitSeb/SDL_sound). Don't forget to configure with `--enable-sdl2=no` if using this version. 20 | 21 | ![sreenshot on Pandora](screenshot.png "screenshot on Pandora") 22 | 23 | The original readme (with detailed how to play) can be found [here](readme.txt) 24 | -------------------------------------------------------------------------------- /src/CExplosionObject.cpp: -------------------------------------------------------------------------------- 1 | #include "SDL.h" 2 | #include "SDL_ttf.h" 3 | #include "SDL_mixer.h" 4 | 5 | #include "sound.h" 6 | 7 | #include "CTile.h" 8 | #include "CObject.h" 9 | #include "CGame.h" 10 | 11 | CExplosionObject::CExplosionObject(int nx,int ny,List *l,int first_tile,int last_tile,CGame *g) 12 | { 13 | int i; 14 | 15 | state=0; 16 | 17 | ntiles=(last_tile-first_tile)+1; 18 | tiles=new CTile *[(last_tile-first_tile)+1]; 19 | 20 | for(i=0;i<(last_tile-first_tile)+1;i++) tiles[i]=l->operator [](i+first_tile); 21 | 22 | game=g; 23 | tile=0; 24 | 25 | x=nx; 26 | y=ny; 27 | draw_x=nx; 28 | draw_y=ny; 29 | constitution=CONSTITUTION_NONE; 30 | 31 | timmer=0; 32 | 33 | } /* CExplosionObject::CExplosionObject */ 34 | 35 | 36 | CExplosionObject::~CExplosionObject(void) 37 | { 38 | } /* CExplosionObject::~CExplosionObject */ 39 | 40 | 41 | 42 | bool CExplosionObject::cycle(unsigned char *keyboard,unsigned char *old_keyboard) 43 | { 44 | timmer++; 45 | 46 | tile=timmer/2; 47 | if (tile>=ntiles) return false; 48 | 49 | return true; 50 | } /* CExplosionObject::cycle */ 51 | -------------------------------------------------------------------------------- /src/CEnemyRacerCarObject.cpp: -------------------------------------------------------------------------------- 1 | #include "math.h" 2 | 3 | #include "SDL.h" 4 | #include "SDL_ttf.h" 5 | #include "SDL_mixer.h" 6 | 7 | #include "sound.h" 8 | 9 | #include "CTile.h" 10 | #include "CObject.h" 11 | #include "CGame.h" 12 | 13 | extern int ENEMY_SPEED; 14 | extern int ENEMY_HSPEED; 15 | extern int PLAYING_WINDOW; 16 | 17 | 18 | CEnemyRacerCarObject::CEnemyRacerCarObject(int nx,int ny,CTile *t,int start_delay,CGame *g) : CEnemyCarObject(nx,ny,t,start_delay,g) 19 | { 20 | advanced=false; 21 | } /* CEnemyRacerCarObject::CEnemyRacerCarObject */ 22 | 23 | 24 | CEnemyRacerCarObject::~CEnemyRacerCarObject(void) 25 | { 26 | } /* CEnemyRacerCarObject::~CEnemyRacerCarObject */ 27 | 28 | 29 | 30 | bool CEnemyRacerCarObject::cycle(unsigned char *keyboard,unsigned char *old_keyboard) 31 | { 32 | bool retval=true; 33 | 34 | retval=CEnemyCarObject::cycle(keyboard,old_keyboard); 35 | 36 | if (!advanced && game->min_distance_to_players(y)<48 && y_speed!=0) { 37 | advanced=true; 38 | if (game->S_caradvance!=0) Sound_play(game->S_caradvance); 39 | } /* if */ 40 | 41 | return retval; 42 | } /* CEnemyRacerCarObject::cycle */ 43 | 44 | -------------------------------------------------------------------------------- /src/CEnemySlidderCarObject.cpp: -------------------------------------------------------------------------------- 1 | #include "math.h" 2 | 3 | #include "SDL.h" 4 | #include "SDL_ttf.h" 5 | #include "SDL_mixer.h" 6 | 7 | #include "sound.h" 8 | 9 | #include "CTile.h" 10 | #include "CObject.h" 11 | #include "CGame.h" 12 | 13 | extern int ENEMY_SPEED; 14 | extern int ENEMY_HSPEED; 15 | extern int PLAYING_WINDOW; 16 | 17 | 18 | CEnemySlidderCarObject::CEnemySlidderCarObject(int nx,int ny,CTile *t,int start_delay,CGame *g) : CEnemyCarObject(nx,ny,t,start_delay,g) 19 | { 20 | } /* CEnemySlidderCarObject::CEnemySlidderCarObject */ 21 | 22 | 23 | CEnemySlidderCarObject::~CEnemySlidderCarObject(void) 24 | { 25 | } /* CEnemySlidderCarObject::~CEnemySlidderCarObject */ 26 | 27 | 28 | 29 | bool CEnemySlidderCarObject::cycle(unsigned char *keyboard,unsigned char *old_keyboard) 30 | { 31 | bool retval=true; 32 | 33 | retval=CEnemyCarObject::cycle(keyboard,old_keyboard); 34 | 35 | if (state==1 && game->min_distance_to_players(y)<192) { 36 | CObject *closest_player=game->find_closest_player(x,y); 37 | if (x>closest_player->get_x()) { 38 | if (following_right_border) distance_to_border+=40; 39 | else distance_to_border-=40; 40 | } else { 41 | if (following_right_border) distance_to_border-=40; 42 | else distance_to_border+=40; 43 | } /* if */ 44 | if (distance_to_border<0) distance_to_border+=80; 45 | state=2; 46 | } /* if */ 47 | 48 | return retval; 49 | } /* CEnemySlidderCarObject::cycle */ 50 | -------------------------------------------------------------------------------- /src/filehandling.cpp: -------------------------------------------------------------------------------- 1 | #include "filehandling.h" 2 | 3 | #ifndef _WIN32 4 | // make (sub)directories including multiple subdirs 5 | int mkdirp(const char *fqfn, mode_t mode) { 6 | char *t, str[STRLEN]; 7 | struct stat stbuf; 8 | int len; 9 | 10 | t=(char *)fqfn; 11 | memset(str, '\0', STRLEN); 12 | 13 | while (*t) { 14 | if (*t == '/') { 15 | len = t-fqfn; 16 | if ((len < STRLEN) && (len > 0)) { 17 | strncpy(str, fqfn, len); 18 | if (stat(str, &stbuf) != 0) 19 | if (mkdir(str, mode) != 0) return(-1); 20 | } 21 | } 22 | t++; 23 | } 24 | 25 | return(0); 26 | } 27 | #endif 28 | 29 | // new fopen() 30 | FILE *f1open(const char *f, const char *m, const enum filetype t) { 31 | #ifdef _WIN32 32 | // nothing changed here, works perfectly :) 33 | return(fopen(f, m)); 34 | #else 35 | // *nix is a bitch ;) 36 | char fname[STRLEN]; 37 | 38 | switch (t) { 39 | case GAMEDATA: 40 | // gamedata is read-only 41 | return(fopen(f, m)); 42 | break; 43 | 44 | case USERDATA: 45 | // userdata is put in $HOME/.GAMENAME/ 46 | snprintf(fname, STRLEN-1, "%s/.%s/%s", getenv("HOME"), GAMENAME, f); 47 | // create subdirs if they don't exist 48 | mkdirp(fname, S_IRWXU | S_IRGRP|S_IXGRP | S_IROTH|S_IXOTH); 49 | // open file 50 | return(fopen(fname, m)); 51 | break; 52 | } 53 | #endif 54 | 55 | // should not be reached 56 | return(NULL); 57 | } 58 | 59 | -------------------------------------------------------------------------------- /src/CTile.h: -------------------------------------------------------------------------------- 1 | #ifndef __RF_TILE_CLASS 2 | #define __RF_TILE_CLASS 3 | 4 | #include "sge/sge_collision.h" 5 | 6 | class CTile { 7 | friend class CObject; 8 | friend class CGame; 9 | 10 | public: 11 | CTile(void); 12 | CTile(int x,int y,int dx,int dy,SDL_Surface *orig,bool collision); 13 | ~CTile(void); 14 | 15 | void draw(int x,int y,SDL_Surface *dest); 16 | void draw_mask(int x,int y,SDL_Surface *dest); 17 | void draw_collision_mask(int x,int y,SDL_Surface *dest); 18 | 19 | void draw_scaled(int x,int y,SDL_Surface *dest,float scale); //unused 20 | void draw_shaded(int x,int y,SDL_Surface *dest,int factor,int r,int g,int b,int a); 21 | void draw_bicolor(int x,int y,SDL_Surface *dest,int factor,int r1,int g1,int b1,int a1,int r2,int g2,int b2,int a2); //unused 22 | 23 | void clear(void); 24 | void free(void); 25 | void instance(CTile *t); 26 | 27 | int get_dx(void) {return r.w;}; 28 | int get_dy(void) {return r.h;}; 29 | 30 | private: 31 | 32 | SDL_Rect r; 33 | SDL_Surface *orig,*mask_visualization,*mask_collision; 34 | sge_cdata *collision_data; 35 | }; 36 | 37 | 38 | 39 | /* TILE_SOURCE CLASS: */ 40 | 41 | class TILE_SOURCE { 42 | friend class CTile; 43 | friend class CGame; 44 | 45 | public: 46 | TILE_SOURCE(void); 47 | TILE_SOURCE(char *filename); 48 | ~TILE_SOURCE(void); 49 | 50 | bool save(FILE *fp); 51 | bool load(FILE *fp); 52 | 53 | bool cmp(char *n); 54 | 55 | private: 56 | SDL_Surface *sfc; 57 | char *fname; 58 | }; 59 | 60 | 61 | #endif 62 | 63 | -------------------------------------------------------------------------------- /src/konami_state.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "SDL.h" 4 | #include "SDL_mixer.h" 5 | #include "SDL_ttf.h" 6 | 7 | #include "sound.h" 8 | 9 | #include "CTile.h" 10 | #include "CObject.h" 11 | #include "CGame.h" 12 | #include "CRoadFighter.h" 13 | #include "auxiliar.h" 14 | 15 | const int konami_fade_time=25; 16 | 17 | int CRoadFighter::konami_cycle(void) 18 | { 19 | if (state_timmer==0) { 20 | konami_state=0; 21 | konami_timmer=0; 22 | } /* if */ 23 | 24 | if (konami_state==0) konami_timmer++; 25 | if (konami_state==1) konami_timmer--; 26 | 27 | if (konami_state==0 && 28 | (state_timmer>=350 || 29 | (keyboard[fire_key] && !old_keyboard[fire_key]) || 30 | (keyboard[SDLK_ESCAPE] && !old_keyboard[SDLK_ESCAPE]))) { 31 | konami_state=1; 32 | if (konami_timmer>konami_fade_time) konami_timmer=konami_fade_time; 33 | } /* if */ 34 | 35 | if (konami_state==1 && konami_timmer<=0) return MENU_STATE; 36 | 37 | return KONAMI_STATE; 38 | } /* CRoadFighter::konami_cycle */ 39 | 40 | 41 | 42 | void CRoadFighter::konami_draw(SDL_Surface *screen) 43 | { 44 | SDL_Rect r; 45 | 46 | r.x=0; 47 | r.y=0; 48 | r.w=konami1_sfc->w; 49 | r.h=konami1_sfc->h; 50 | 51 | SDL_BlitSurface(konami1_sfc,&r,screen,&r); 52 | 53 | r.x=0; 54 | r.y=0; 55 | r.w=konami2_sfc->w; 56 | r.h=state_timmer*2; 57 | 58 | SDL_BlitSurface(konami2_sfc,&r,screen,&r); 59 | 60 | { 61 | float f=float(konami_timmer)*(1.0F/float(konami_fade_time)); 62 | if (f<0.0) f=0.0; 63 | if (f<1.0) surface_fader(screen,f,f,f,0); 64 | } /* if */ 65 | 66 | } /* CRoadFighter::konami_draw */ 67 | -------------------------------------------------------------------------------- /src/CSemaphoreObject.cpp: -------------------------------------------------------------------------------- 1 | #include "SDL.h" 2 | #include "SDL_ttf.h" 3 | #include "SDL_mixer.h" 4 | 5 | #include "sound.h" 6 | 7 | #include "CTile.h" 8 | #include "CObject.h" 9 | #include "CGame.h" 10 | 11 | CSemaphoreObject::CSemaphoreObject(int nx,int ny,CTile *t1,CTile *t2,CTile *t3,CTile *t4,CTile *t5,CGame *g) 12 | { 13 | state=0; 14 | 15 | ntiles=5; 16 | tiles=new CTile *[5]; 17 | tiles[0]=t1; 18 | tiles[1]=t2; 19 | tiles[2]=t3; 20 | tiles[3]=t4; 21 | tiles[4]=t5; 22 | 23 | game=g; 24 | tile=0; 25 | 26 | x=nx; 27 | y=ny; 28 | constitution=CONSTITUTION_NONE; 29 | 30 | timmer=0; 31 | 32 | } /* CSemaphoreObject::CSemaphoreObject */ 33 | 34 | 35 | CSemaphoreObject::~CSemaphoreObject(void) 36 | { 37 | } /* CSemaphoreObject::~CSemaphoreObject */ 38 | 39 | 40 | 41 | bool CSemaphoreObject::cycle(unsigned char *keyboard,unsigned char *old_keyboard) 42 | { 43 | timmer++; 44 | 45 | if (timmer>=SEMAPHORE_TIME*1) tile=1; 46 | if (timmer>=SEMAPHORE_TIME*2) tile=0; 47 | if (timmer>=SEMAPHORE_TIME*3) tile=2; 48 | if (timmer>=SEMAPHORE_TIME*4) tile=0; 49 | if (timmer>=SEMAPHORE_TIME*5) tile=3; 50 | if (timmer>=SEMAPHORE_TIME*6) tile=0; 51 | if (timmer>=SEMAPHORE_TIME*7) tile=4; 52 | 53 | /* sound: */ 54 | if (timmer==SEMAPHORE_TIME*1) if (game->S_redlight!=0) Sound_play(game->S_redlight); 55 | if (timmer==SEMAPHORE_TIME*3) if (game->S_redlight!=0) Sound_play(game->S_redlight); 56 | if (timmer==SEMAPHORE_TIME*5) if (game->S_redlight!=0) Sound_play(game->S_redlight); 57 | // if (timmer==SEMAPHORE_TIME*7) if (game->S_greenlight!=0) Sound_play(game->S_greenlight); 58 | 59 | return true; 60 | } /* CSemaphoreObject::cycle */ 61 | -------------------------------------------------------------------------------- /src/CFuelObject.cpp: -------------------------------------------------------------------------------- 1 | #include "math.h" 2 | 3 | #include "SDL.h" 4 | #include "SDL_ttf.h" 5 | #include "SDL_mixer.h" 6 | 7 | #include "sound.h" 8 | 9 | #include "CTile.h" 10 | #include "CObject.h" 11 | #include "CGame.h" 12 | 13 | extern int ENEMY_SPEED; 14 | extern int ENEMY_HSPEED; 15 | extern int PLAYING_WINDOW; 16 | 17 | 18 | CFuelObject::CFuelObject(int nx,int ny,CTile *t,CGame *g) : CObject(nx,ny,t,CONSTITUTION_FUEL,g) 19 | { 20 | y_speed=0; 21 | y_precision=0; 22 | 23 | state=0; 24 | 25 | x_speed=0; 26 | x_precision=0; 27 | } /* CFuelObject::CFuelObject */ 28 | 29 | 30 | CFuelObject::~CFuelObject(void) 31 | { 32 | } /* CFuelObject::~CFuelObject */ 33 | 34 | 35 | 36 | bool CFuelObject::cycle(unsigned char *keyboard,unsigned char *old_keyboard) 37 | { 38 | y_precision+=y_speed; 39 | while(y_precision>(1<<8)) { 40 | y++; 41 | y_precision-=1<<8; 42 | } /* while */ 43 | while(y_precision<((-1)<<8)) { 44 | y--; 45 | y_precision+=1<<8; 46 | } /* while */ 47 | 48 | x_precision+=x_speed; 49 | while(x_precision>(1<<8)) { 50 | x++; 51 | x_precision-=1<<8; 52 | } /* while */ 53 | while(x_precision<((-1)<<8)) { 54 | x--; 55 | x_precision+=1<<8; 56 | } /* while */ 57 | 58 | y_speed=-ENEMY_SPEED; 59 | 60 | y_speed=-ENEMY_SPEED; 61 | x_speed=0; 62 | if (game->object_collision(16,0,this,CONSTITUTION_SOLID)!=0) { 63 | x_speed=-ENEMY_HSPEED; 64 | } else { 65 | if (game->object_collision(-16,0,this,CONSTITUTION_SOLID)!=0) { 66 | x_speed=ENEMY_HSPEED; 67 | } /* if */ 68 | } /* if */ 69 | 70 | if (game->min_distance_to_players(y)>PLAYING_WINDOW) return false; 71 | 72 | return true; 73 | } /* CFuelObject::cycle */ 74 | 75 | -------------------------------------------------------------------------------- /src/configuration.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "SDL.h" 4 | #include "SDL_mixer.h" 5 | #include "SDL_image.h" 6 | #include "SDL_ttf.h" 7 | 8 | #include "sound.h" 9 | 10 | #include "CTile.h" 11 | #include "CObject.h" 12 | #include "CGame.h" 13 | #include "CRoadFighter.h" 14 | #include "filehandling.h" 15 | 16 | void CRoadFighter::load_configuration(void) 17 | { 18 | int a,b,c; 19 | FILE *fp; 20 | 21 | fp=f1open("RoadFighter.cfg", "r", USERDATA); 22 | if (fp==0) { 23 | default_configuration(); 24 | save_configuration(); 25 | return; 26 | } /* if */ 27 | if (3!=fscanf(fp,"%i %i %i",&a,&b,&c)) { 28 | fclose(fp); 29 | default_configuration(); 30 | save_configuration(); 31 | return; 32 | } /* if */ 33 | left_key=a; 34 | right_key=b; 35 | fire_key=c; 36 | if (3!=fscanf(fp,"%i %i %i",&a,&b,&c)) { 37 | fclose(fp); 38 | default_configuration(); 39 | save_configuration(); 40 | return; 41 | } /* if */ 42 | left2_key=a; 43 | right2_key=b; 44 | fire2_key=c; 45 | if (1!=fscanf(fp,"%i",&a)) { 46 | fclose(fp); 47 | default_configuration(); 48 | save_configuration(); 49 | return; 50 | } /* if */ 51 | if (a==1) game_remake_extras=true; 52 | else game_remake_extras=false; 53 | 54 | } /* CRoadFighter::load_configuration */ 55 | 56 | 57 | void CRoadFighter::save_configuration(void) 58 | { 59 | FILE *fp; 60 | 61 | fp=f1open("RoadFighter.cfg", "w", USERDATA); 62 | if (fp==0) return; 63 | fprintf(fp,"%i %i %i\n",left_key,right_key,fire_key); 64 | fprintf(fp,"%i %i %i\n",left2_key,right2_key,fire2_key); 65 | if (game_remake_extras) fprintf(fp,"1\n"); 66 | else fprintf(fp,"0\n"); 67 | fclose(fp); 68 | } /* CRoadFighter::save_configuration */ 69 | 70 | 71 | void CRoadFighter::default_configuration(void) 72 | { 73 | left_key=SDLK_LEFT; 74 | right_key=SDLK_RIGHT; 75 | #ifdef PANDORA 76 | fire_key=SDLK_PAGEDOWN; 77 | #else 78 | fire_key=SDLK_SPACE; 79 | #endif 80 | 81 | left2_key=SDLK_a; 82 | right2_key=SDLK_d; 83 | fire2_key=SDLK_LSHIFT; 84 | 85 | game_remake_extras=true; 86 | } /* CRoadFighter::default_configuration */ 87 | 88 | -------------------------------------------------------------------------------- /src/presentation_state.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "SDL.h" 4 | #include "SDL_mixer.h" 5 | #include "SDL_ttf.h" 6 | 7 | #include "sound.h" 8 | 9 | #include "CTile.h" 10 | #include "CObject.h" 11 | #include "CGame.h" 12 | #include "CRoadFighter.h" 13 | #include "auxiliar.h" 14 | 15 | const int presentation_fade_time=25; 16 | 17 | int CRoadFighter::presentation_cycle(void) 18 | { 19 | int i; 20 | bool key_pressed; 21 | 22 | if (state_timmer==0) { 23 | presentation_state=0; 24 | presentation_timmer=0; 25 | } /* if */ 26 | 27 | if (presentation_state==0) presentation_timmer++; 28 | if (presentation_state==1) presentation_timmer--; 29 | if (presentation_state==2) presentation_timmer++; 30 | if (presentation_state==3) presentation_timmer--; 31 | 32 | key_pressed=false; 33 | if (state_timmer>=5) { 34 | for(i=0;i=350 || key_pressed)) { 41 | presentation_state=1; 42 | if (presentation_timmer>presentation_fade_time) presentation_timmer=presentation_fade_time; 43 | } /* if */ 44 | if (presentation_state==2 && 45 | (state_timmer>=700 || key_pressed)) { 46 | presentation_state=3; 47 | if (presentation_timmer>presentation_fade_time) presentation_timmer=presentation_fade_time; 48 | } /* if */ 49 | 50 | if (presentation_state==1 && presentation_timmer<=0) presentation_state=2; 51 | if (presentation_state==3 && presentation_timmer<=0) return KONAMI_STATE; 52 | 53 | return PRESENTATION_STATE; 54 | } /* CRoadFighter::presentation_cycle */ 55 | 56 | 57 | 58 | void CRoadFighter::presentation_draw(SDL_Surface *screen) 59 | { 60 | if (presentation_state<2) SDL_BlitSurface(disclaimer_sfc,0,screen,0); 61 | else SDL_BlitSurface(retroremakes_sfc,0,screen,0); 62 | 63 | { 64 | float f=float(presentation_timmer)*(1.0F/float(presentation_fade_time)); 65 | if (f<0.0) f=0.0; 66 | if (f<1.0) surface_fader(screen,f,f,f,0); 67 | } /* if */ 68 | 69 | } /* CRoadFighter::presentation_draw */ 70 | -------------------------------------------------------------------------------- /src/CCarObject.cpp: -------------------------------------------------------------------------------- 1 | #include "SDL.h" 2 | #include "SDL_ttf.h" 3 | #include "SDL_mixer.h" 4 | 5 | #include "CTile.h" 6 | #include "CObject.h" 7 | 8 | CCarObject::CCarObject(void) : CObject() 9 | { 10 | last_collision=0; 11 | } /* CCarObject::CCarObject */ 12 | 13 | 14 | CCarObject::CCarObject(int nx,int ny,CTile *t,CGame *g) : CObject(nx,ny,t,CONSTITUTION_CAR,g) 15 | { 16 | y_speed=0; 17 | y_precision=0; 18 | 19 | state=0; 20 | 21 | x_speed=0; 22 | x_precision=0; 23 | 24 | last_collision=0; 25 | } /* CCarObject::CCarObject */ 26 | 27 | 28 | CCarObject::~CCarObject(void) 29 | { 30 | } /* CCarObject::~CCarObject */ 31 | 32 | 33 | 34 | bool CCarObject::cycle(unsigned char *keyboard,unsigned char *old_keyboard) 35 | { 36 | y_precision+=y_speed; 37 | while(y_precision>(1<<8)) { 38 | y++; 39 | y_precision-=1<<8; 40 | } /* while */ 41 | while(y_precision<((-1)<<8)) { 42 | y--; 43 | y_precision+=1<<8; 44 | } /* while */ 45 | 46 | x_precision+=x_speed; 47 | while(x_precision>(1<<8)) { 48 | x++; 49 | x_precision-=1<<8; 50 | } /* while */ 51 | while(x_precision<((-1)<<8)) { 52 | x--; 53 | x_precision+=1<<8; 54 | } /* while */ 55 | return true; 56 | } /* CCarObject::CCarObject */ 57 | 58 | 59 | void CCarObject::car_collision(CCarObject *car) 60 | { 61 | last_collision=car; 62 | } /* CCarObject::car_collision */ 63 | 64 | 65 | long int CCarObject::compute_next_x(void) 66 | { 67 | long int tmp=x_precision+x_speed; 68 | long int new_x=x; 69 | 70 | while(tmp>(1<<8)) { 71 | new_x++; 72 | tmp-=1<<8; 73 | } /* while */ 74 | while(tmp<((-1)<<8)) { 75 | new_x--; 76 | tmp+=1<<8; 77 | } /* while */ 78 | 79 | return new_x; 80 | } /* CCarObject::compute_next_y */ 81 | 82 | 83 | long int CCarObject::compute_next_y(void) 84 | { 85 | long int tmp=y_precision+y_speed; 86 | long int new_y=y; 87 | 88 | while(tmp>(1<<8)) { 89 | new_y++; 90 | tmp-=1<<8; 91 | } /* while */ 92 | while(tmp<((-1)<<8)) { 93 | new_y--; 94 | tmp+=1<<8; 95 | } /* while */ 96 | 97 | return new_y; 98 | } /* CCarObject::compute_next_y */ 99 | 100 | -------------------------------------------------------------------------------- /src/auxiliar.h: -------------------------------------------------------------------------------- 1 | #ifndef MOG_AUXILIAR 2 | #define MOG_AUXILIAR 3 | 4 | #ifndef _WIN32 5 | 6 | #define min(a,b) ((a)<(b) ? (a) : (b)) 7 | #define max(a,b) ((a)>(b) ? (a) : (b)) 8 | 9 | #endif 10 | //#define abs(a) ((a)<0 ? (-(a)) : (a)) 11 | 12 | 13 | #if SDL_BYTEORDER == SDL_BIG_ENDIAN 14 | // PPC values: 15 | #define AMASK 0xff000000 16 | #define BMASK 0x000000ff 17 | #define GMASK 0x0000ff00 18 | #define RMASK 0x00ff0000 19 | #define AOFFSET 0 20 | #define BOFFSET 3 21 | #define GOFFSET 2 22 | #define ROFFSET 1 23 | 24 | #else 25 | // Intel values: 26 | #define AMASK 0xff000000 27 | #define BMASK 0x000000ff 28 | #define GMASK 0x0000ff00 29 | #define RMASK 0x00ff0000 30 | #define AOFFSET 3 31 | #define BOFFSET 0 32 | #define GOFFSET 1 33 | #define ROFFSET 2 34 | 35 | #endif 36 | 37 | #ifndef _WIN32 38 | #ifndef HAVE_STRLWR 39 | 40 | char *strlwr (char *str); 41 | 42 | #endif 43 | void setupTickCount(); 44 | long GetTickCount(); 45 | #endif 46 | void pause(unsigned int time); 47 | 48 | 49 | void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel); 50 | void maximumpixel(SDL_Surface *surface, int x, int y, Uint32 pixel); 51 | Uint32 getpixel(SDL_Surface *surface, int x, int y); 52 | void draw_rectangle(SDL_Surface *surface, int x, int y, int w, int h, Uint32 pixel); 53 | void draw_line(SDL_Surface *SDL,int x1,int y1,int x2,int y2,Uint32 pixel); 54 | 55 | void surface_fader(SDL_Surface *surface,float r_factor,float g_factor,float b_factor,SDL_Rect *r); 56 | void surface_shader(SDL_Surface *surface,float factor,int red,int green,int blue,int alpha); 57 | void surface_bicolor(SDL_Surface *surface,float factor,int r1,int g1,int b1,int a1,int r2,int g2,int b2,int a2); 58 | 59 | SDL_Surface *load_maskedimage(char *image,char *mask,char *path); 60 | 61 | void surface_automatic_alpha(SDL_Surface *sfc); 62 | void surface_bw(SDL_Surface *sfc,int threshold); 63 | void surface_mask_from_bitmap(SDL_Surface *sfc,SDL_Surface *mask,int x,int y); 64 | 65 | SDL_Surface *multiline_text_surface(char *text,int line_dist,TTF_Font *font,SDL_Color c); 66 | SDL_Surface *multiline_text_surface2(char *text,int line_dist,TTF_Font *font,SDL_Color c1,SDL_Color c2,int line,float glow); 67 | 68 | #endif 69 | 70 | -------------------------------------------------------------------------------- /src/quick_tables.cpp: -------------------------------------------------------------------------------- 1 | #include "string.h" 2 | 3 | #include "SDL.h" 4 | #include "SDL_ttf.h" 5 | #include "SDL_image.h" 6 | #include "SDL_mixer.h" 7 | 8 | #include "sound.h" 9 | 10 | #include "List.h" 11 | 12 | #include "CTile.h" 13 | #include "CObject.h" 14 | #include "CGame.h" 15 | 16 | #include "auxiliar.h" 17 | 18 | 19 | void CGame::init_quick_tables(void) 20 | { 21 | int i; 22 | int part_size; 23 | List l; 24 | CObject *o; 25 | 26 | part_size=dy/QUICK_PARTS; 27 | 28 | /* Background: */ 29 | l.Instance(background); 30 | l.Rewind(); 31 | while(l.Iterate(o)) { 32 | i=o->get_y()/part_size; 33 | if (i<0) i=0; 34 | if (i>=QUICK_PARTS-1) i=QUICK_PARTS-1; 35 | quick_background[i].Add(o); 36 | } /* while */ 37 | 38 | /* Middleground: */ 39 | l.Instance(middleground); 40 | l.Rewind(); 41 | while(l.Iterate(o)) { 42 | i=o->get_y()/part_size; 43 | if (i<0) i=0; 44 | if (i>=QUICK_PARTS-1) i=QUICK_PARTS-1; 45 | quick_middleground[i].Add(o); 46 | } /* while */ 47 | 48 | /* Foreground: */ 49 | l.Instance(foreground); 50 | l.Rewind(); 51 | while(l.Iterate(o)) { 52 | i=o->get_y()/part_size; 53 | if (i<0) i=0; 54 | if (i>=QUICK_PARTS-1) i=QUICK_PARTS-1; 55 | quick_foreground[i].Add(o); 56 | } /* while */ 57 | 58 | } /* CGame:init_quick_tables */ 59 | 60 | 61 | void CGame::delete_quick_tables(void) 62 | { 63 | int i; 64 | 65 | for(i=0;iget_y()+yoffs,o->get_y()+yoffs+o->get_dy(),min,max); 76 | } /* CGame::get_quick_min_max */ 77 | 78 | 79 | 80 | void CGame::get_quick_min_max(long ymin,long ymax,int *min,int *max) 81 | { 82 | int i; 83 | int part_size=dy/QUICK_PARTS; 84 | 85 | i=((ymin-BIGGEST_OBJECT)/part_size)-1; 86 | if (i<0) i=0; 87 | if (i>=QUICK_PARTS-1) i=QUICK_PARTS-1; 88 | *min=i; 89 | 90 | i=(ymax/part_size); 91 | if (i<0) i=0; 92 | if (i>=QUICK_PARTS-1) i=QUICK_PARTS-1; 93 | *max=i; 94 | } /* CGame::get_quick_min_max */ 95 | -------------------------------------------------------------------------------- /src/gameover_state.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "SDL.h" 4 | #include "SDL_mixer.h" 5 | #include "SDL_ttf.h" 6 | 7 | #include "sound.h" 8 | 9 | #include "CTile.h" 10 | #include "CObject.h" 11 | #include "CGame.h" 12 | #include "CRoadFighter.h" 13 | #include "auxiliar.h" 14 | 15 | int gameover_time=25; 16 | 17 | int CRoadFighter::gameover_cycle(void) 18 | { 19 | if (state_timmer==0) { 20 | gameover_state=0; 21 | gameover_timmer=0; 22 | Sound_music_volume(MIX_MAX_VOLUME); 23 | Sound_create_music("sound/gameover",0); 24 | } /* if */ 25 | 26 | if (gameover_state==1) { 27 | int volume=(gameover_timmer*MIX_MAX_VOLUME)/gameover_time; 28 | if (volume<0) volume=0; 29 | if (volume>MIX_MAX_VOLUME) volume=MIX_MAX_VOLUME; 30 | Sound_music_volume(volume); 31 | } 32 | 33 | if (gameover_state==0) gameover_timmer++; 34 | if (gameover_state==1) gameover_timmer--; 35 | 36 | if (gameover_state==0 && 37 | (state_timmer>=gameover_time*6 || 38 | (state_timmer>=gameover_time && 39 | ((keyboard[fire_key] && !old_keyboard[fire_key]) || 40 | (keyboard[SDLK_ESCAPE] && !old_keyboard[SDLK_ESCAPE]))))) { 41 | gameover_state=1; 42 | if (gameover_timmer>=gameover_time) gameover_timmer=gameover_time; 43 | } /* if */ 44 | 45 | if (gameover_state==1 && gameover_timmer<=0) { 46 | Sound_release_music(); 47 | Sound_music_volume(MIX_MAX_VOLUME); 48 | return KONAMI_STATE; 49 | } /* if */ 50 | return GAMEOVER_STATE; 51 | } /* CRoadFighter::gameover_cycle */ 52 | 53 | 54 | 55 | void CRoadFighter::gameover_draw(SDL_Surface *screen) 56 | { 57 | SDL_Rect r; 58 | 59 | SDL_FillRect(screen,0,0); 60 | 61 | /* Draw Scoreboard: */ 62 | if (gameover_state==1) { 63 | if (scoreboard_fade_timmer>0) scoreboard_fade_timmer--; 64 | if (scoreboard_xw) scoreboard_x+=int((screen->w-desired_scoreboard_x)/gameover_time); 65 | if (scoreboard_x>screen->w) scoreboard_x=screen->w; 66 | } /* if */ 67 | scoreboard_draw(scoreboard_x,0,screen); 68 | 69 | 70 | /* Draw text: */ 71 | { 72 | SDL_Surface *text_sfc; 73 | float f=1.0; 74 | 75 | text_sfc=SDL_DisplayFormat(gameover_sfc); 76 | f=float(gameover_timmer)/gameover_time; 77 | if (f>=1.0) f=1.0; 78 | if (f<1.0) surface_fader(text_sfc,f,f,f,0); 79 | r.x=(desired_scoreboard_x)/2-text_sfc->w/2; 80 | r.y=(screen->h/2)-text_sfc->h/2; 81 | r.w=text_sfc->w; 82 | r.h=text_sfc->h; 83 | SDL_BlitSurface(text_sfc,0,screen,&r); 84 | SDL_FreeSurface(text_sfc); 85 | } 86 | 87 | } /* CRoadFighter::gameover_draw */ 88 | -------------------------------------------------------------------------------- /src/CObject.cpp: -------------------------------------------------------------------------------- 1 | #include "SDL.h" 2 | #include "SDL_ttf.h" 3 | #include "SDL_mixer.h" 4 | 5 | #include "CTile.h" 6 | #include "CObject.h" 7 | 8 | CObject::CObject(void) 9 | { 10 | state=0; 11 | ntiles=0; 12 | tiles=0; 13 | 14 | game=0; 15 | tile=0; 16 | 17 | x=0; 18 | y=0; 19 | draw_x=0; 20 | draw_y=0; 21 | constitution=CONSTITUTION_NONE; 22 | } /* CObject::CObject */ 23 | 24 | 25 | CObject::CObject(int nx,int ny,CTile *t,int cons,CGame *g) 26 | { 27 | ntiles=1; 28 | tiles=new CTile *[1]; 29 | tiles[0]=t; 30 | 31 | game=g; 32 | tile=0; 33 | 34 | x=nx; 35 | y=ny; 36 | draw_x=nx; 37 | draw_y=ny; 38 | constitution=cons; 39 | } /* CObject::CObject */ 40 | 41 | 42 | CObject::~CObject(void) 43 | { 44 | int i; 45 | 46 | for(i=0;i=0 && tiledraw(x-sx,y-sy,screen); 64 | } /* CObject::draw */ 65 | 66 | 67 | bool CObject::collision(int offsx,int offsy,CObject *o) 68 | { 69 | CTile *t1=0,*t2=0; 70 | 71 | if (tile>=0 && tiletile>=0 && o->tilentiles) t2=o->tiles[o->tile]; 73 | 74 | if (t1==0 || t2==0) return false; 75 | if (t1->collision_data==0 || t2->collision_data==0) return false; 76 | 77 | if (draw_y+t1->get_dy()draw_y+offsy || 78 | o->draw_y+offsy+t2->get_dy()draw_x+offsx)-draw_x); 84 | tmpy=int((o->draw_y+offsy)-draw_y); 85 | 86 | if (sge_cmcheck(t1->collision_data,0,0,t2->collision_data,tmpx,tmpy)) { 87 | tmpx=sge_get_cx(); 88 | tmpy=sge_get_cy(); 89 | return true; 90 | } /* if */ 91 | } 92 | 93 | return false; 94 | } /* CObject::collision */ 95 | 96 | 97 | int CObject::get_dx(void) 98 | { 99 | if (tile>=0 && tileget_dx(); 100 | 101 | return 0; 102 | } /* CObject::get_dx */ 103 | 104 | 105 | int CObject::get_dy(void) 106 | { 107 | if (tile>=0 && tileget_dy(); 108 | 109 | return 0; 110 | } /* CObject::get_dy */ 111 | 112 | 113 | bool CObject::constitution_test(int cons) 114 | { 115 | if ((constitution&cons)!=0) return true; 116 | 117 | return false; 118 | } /* CObject::constitution_test */ 119 | -------------------------------------------------------------------------------- /src/CEnemyTruckObject.cpp: -------------------------------------------------------------------------------- 1 | #include "math.h" 2 | #include "stdlib.h" 3 | 4 | #include "SDL.h" 5 | #include "SDL_ttf.h" 6 | #include "SDL_mixer.h" 7 | 8 | #include "sound.h" 9 | 10 | #include "CTile.h" 11 | #include "CObject.h" 12 | #include "CGame.h" 13 | 14 | extern int ENEMY_SPEED; 15 | extern int ENEMY_HSPEED; 16 | extern int PLAYING_WINDOW; 17 | 18 | 19 | CEnemyTruckObject::CEnemyTruckObject(int nx,int ny,CTile *t,int start_delay,CGame *g) : CCarObject(nx,ny,t,g) 20 | { 21 | state_timmer=start_delay; 22 | 23 | following_right_border=true; 24 | distance_to_border=-1; 25 | 26 | constitution=CONSTITUTION_SOLID|CONSTITUTION_CAR; 27 | 28 | advanced=false; 29 | } /* CEnemyTruckObject::CEnemyTruckObject */ 30 | 31 | 32 | CEnemyTruckObject::~CEnemyTruckObject(void) 33 | { 34 | } /* CEnemyTruckObject::~CEnemyTruckObject */ 35 | 36 | bool CEnemyTruckObject::cycle(unsigned char *keyboard,unsigned char *old_keyboard) 37 | { 38 | CCarObject::cycle(keyboard,old_keyboard); 39 | 40 | if (state_timmer>0) state_timmer--; 41 | if (state==0 && state_timmer==0) state=1; 42 | 43 | if (state!=0) { 44 | y_speed=-ENEMY_SPEED; 45 | x_speed=0; 46 | if (game->object_collision(8,0,this,CONSTITUTION_SOLID)!=0) { 47 | x_speed=-ENEMY_HSPEED; 48 | } else { 49 | if (game->object_collision(-8,0,this,CONSTITUTION_SOLID)!=0) { 50 | x_speed=ENEMY_HSPEED; 51 | } /* if */ 52 | } /* if */ 53 | 54 | if (x_speed==0 && distance_to_border!=-1) { 55 | int i; 56 | int distance=-1; 57 | for(i=0;distance==-1 && i<=distance_to_border+8;i+=8) { 58 | if (following_right_border) { 59 | if (game->object_collision(i,0,this,CONSTITUTION_SOLID)!=0) distance=i-8; 60 | } else { 61 | if (game->object_collision(-i,0,this,CONSTITUTION_SOLID)!=0) distance=i-8; 62 | } /* if */ 63 | } /* for */ 64 | if (distance==-1) distance=distance_to_border+8; 65 | if (following_right_border) { 66 | if (distance<=distance_to_border-8) x_speed=-ENEMY_HSPEED; 67 | if (distance>=distance_to_border+8) x_speed=ENEMY_HSPEED; 68 | } else { 69 | if (distance<=distance_to_border-8) x_speed=ENEMY_HSPEED; 70 | if (distance>=distance_to_border+8) x_speed=-ENEMY_HSPEED; 71 | } /* if */ 72 | } /* if */ 73 | } else { 74 | y_speed=0; 75 | } /* if */ 76 | 77 | if (game->min_distance_to_players(y)>PLAYING_WINDOW) return false; 78 | 79 | if (!advanced && game->min_distance_to_players(y)<48 && y_speed!=0) { 80 | advanced=true; 81 | if (game->S_caradvance!=0 && (rand()%3)==0) Sound_play(game->S_truck); 82 | } /* if */ 83 | 84 | return true; 85 | } /* CEnemyTruckObject::cycle */ 86 | 87 | 88 | -------------------------------------------------------------------------------- /src/CRoadFighter.h: -------------------------------------------------------------------------------- 1 | #ifndef __CROADFIGHTER_CLASS 2 | #define __CROADFIGHTER_CLASS 3 | 4 | #define QUIT_STATE -1 5 | #define KONAMI_STATE 0 6 | #define MENU_STATE 1 7 | #define DEMO_STATE 2 8 | #define PLAYING_STATE 3 9 | #define INTERLEVEL_STATE 4 10 | #define GAMEOVER_STATE 5 11 | 12 | #define PRESENTATION_STATE 6 13 | 14 | #define FONT_SIZE 24 15 | 16 | 17 | class CRoadFighter { 18 | public: 19 | CRoadFighter(void); 20 | ~CRoadFighter(void); 21 | 22 | bool cycle(void); 23 | void draw(SDL_Surface *screen); 24 | 25 | /* Individual state functions: */ 26 | int presentation_cycle(void); 27 | void presentation_draw(SDL_Surface *screen); 28 | 29 | int konami_cycle(void); 30 | void konami_draw(SDL_Surface *screen); 31 | 32 | int menu_cycle(void); 33 | void menu_draw(SDL_Surface *screen); 34 | 35 | int interlevel_cycle(void); 36 | void interlevel_draw(SDL_Surface *screen); 37 | 38 | int playing_cycle(void); 39 | void playing_draw(SDL_Surface *screen); 40 | 41 | int gameover_cycle(void); 42 | void gameover_draw(SDL_Surface *screen); 43 | 44 | void load_configuration(void); 45 | void save_configuration(void); 46 | void default_configuration(void); 47 | 48 | private: 49 | 50 | void scoreboard_draw(int x,int y,SDL_Surface *screen); 51 | 52 | 53 | int state,state_timmer; 54 | int current_level; 55 | int high_score; 56 | CGame *game; 57 | 58 | /* keyboard: */ 59 | int left_key,right_key,fire_key; 60 | int left2_key,right2_key,fire2_key; 61 | 62 | /* Graphic data: */ 63 | SDL_Surface *disclaimer_sfc,*retroremakes_sfc; 64 | SDL_Surface *konami1_sfc,*konami2_sfc; 65 | SDL_Surface *tittle_sfc; 66 | SDL_Surface *arrow_sfc; 67 | SDL_Surface *scoreboard_sfc,*scoreboard2_sfc,*scoreboardleft_sfc; 68 | SDL_Surface *gamemap_sfc; 69 | SDL_Surface *minicar1_sfc,*minicar2_sfc; 70 | SDL_Surface *levelintro_sfc; 71 | SDL_Surface *gameover_sfc; 72 | SDL_Surface *credits_sfc,*credits2_sfc; 73 | CTile *minicar1_tile,*minicar2_tile; 74 | 75 | /* Sound data: */ 76 | SOUNDT S_menu_move,S_menu_select,S_menu_in,S_menu_out; 77 | // SOUNDT M_menu,M_ingame,M_start,M_gameover,M_levelcomplete; 78 | 79 | /* Individual state data: */ 80 | int presentation_state; 81 | int presentation_timmer; 82 | 83 | int konami_state; 84 | int konami_timmer; 85 | 86 | int menu_current_menu; 87 | int menu_state; 88 | int menu_effect; 89 | int menu_timmer; 90 | char *menu_tittle_text; 91 | char *menu_options_text; 92 | int menu_nitems; 93 | int menu_item; 94 | int menu_redefining_key; 95 | int menu_credits_timmer; 96 | 97 | int game_mode; 98 | int n_players; 99 | bool game_remake_extras; 100 | 101 | int interlevel_state; 102 | int interlevel_timmer; 103 | int scoreboard_x,desired_scoreboard_x; 104 | int scoreboard_fade_timmer; 105 | 106 | int gameover_state; 107 | int gameover_timmer; 108 | 109 | int endsequence_state; 110 | int endsequence_timmer; 111 | 112 | bool playing_reachedend; 113 | 114 | unsigned char *keyboard,old_keyboard[SDLK_LAST]; 115 | 116 | TTF_Font *font1; 117 | TTF_Font *font2big,*font2medium,*font2small; 118 | 119 | /* REPLAYS: */ 120 | FILE *replay_fp; 121 | }; 122 | 123 | #endif 124 | 125 | -------------------------------------------------------------------------------- /src/CEnemyCarObject.cpp: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | #include 3 | #include 4 | #else 5 | #include 6 | #include 7 | #endif 8 | #include "math.h" 9 | 10 | #include "SDL.h" 11 | #include "SDL_ttf.h" 12 | #include "SDL_mixer.h" 13 | 14 | #include "sound.h" 15 | 16 | #include "CTile.h" 17 | #include "CObject.h" 18 | #include "CGame.h" 19 | 20 | #include "auxiliar.h" 21 | 22 | extern int MAX_SPEED; 23 | extern int ENEMY_SPEED; 24 | extern int ENEMY_HSPEED; 25 | extern int PLAYING_WINDOW; 26 | 27 | CEnemyCarObject::CEnemyCarObject(int nx,int ny,CTile *t,int start_delay,CGame *g) : CCarObject(nx,ny,t,g) 28 | { 29 | state_timmer=start_delay; 30 | 31 | following_right_border=true; 32 | distance_to_border=-1; 33 | last_collision=0; 34 | 35 | slide_timmer=0; 36 | } /* CEnemyCarObject::CEnemyCarObject */ 37 | 38 | 39 | CEnemyCarObject::~CEnemyCarObject(void) 40 | { 41 | } /* CEnemyCarObject::~CEnemyCarObject */ 42 | 43 | 44 | 45 | bool CEnemyCarObject::cycle(unsigned char *keyboard,unsigned char *old_keyboard) 46 | { 47 | CCarObject::cycle(keyboard,old_keyboard); 48 | 49 | if (state_timmer>0) state_timmer--; 50 | if (state==0 && state_timmer==0) state=1; 51 | 52 | if (last_collision!=0) { 53 | if (last_collision->get_x()get_y_speed(),y_speed); 56 | slide_timmer=8; 57 | 58 | last_collision=0; 59 | } /* if */ 60 | 61 | if (state!=0) { 62 | y_speed=-ENEMY_SPEED; 63 | x_speed=0; 64 | if (game->object_collision(8,0,this,CONSTITUTION_SOLID)!=0) { 65 | x_speed=-ENEMY_HSPEED; 66 | slide_timmer=0; 67 | } else { 68 | if (game->object_collision(-8,0,this,CONSTITUTION_SOLID)!=0) { 69 | x_speed=ENEMY_HSPEED; 70 | slide_timmer=0; 71 | } /* if */ 72 | } /* if */ 73 | 74 | if (slide_timmer>0) { 75 | slide_timmer--; 76 | if (slide_direction==1) x_speed=int(ENEMY_HSPEED); 77 | if (slide_direction==-1) x_speed=-int(ENEMY_HSPEED); 78 | y_speed=slide_speed; 79 | } /* if */ 80 | 81 | if (x_speed==0 && distance_to_border!=-1) { 82 | int i; 83 | int distance=-1; 84 | for(i=0;distance==-1 && i<=distance_to_border+8;i+=8) { 85 | if (following_right_border) { 86 | if (game->object_collision(i,0,this,CONSTITUTION_SOLID)!=0) distance=i-8; 87 | } else { 88 | if (game->object_collision(-i,0,this,CONSTITUTION_SOLID)!=0) distance=i-8; 89 | } /* if */ 90 | } /* for */ 91 | if (distance==-1) distance=distance_to_border+8; 92 | if (following_right_border) { 93 | if (distance<=distance_to_border-8) x_speed=-ENEMY_HSPEED; 94 | if (distance>=distance_to_border+8) x_speed=ENEMY_HSPEED; 95 | } else { 96 | if (distance<=distance_to_border-8) x_speed=ENEMY_HSPEED; 97 | if (distance>=distance_to_border+8) x_speed=-ENEMY_HSPEED; 98 | } /* if */ 99 | } /* if */ 100 | 101 | { 102 | CObject *o=0; 103 | 104 | o=game->object_collision(0,0,this,CONSTITUTION_SOLID); 105 | if (o!=0 && o->constitution_test(CONSTITUTION_CAR)) { 106 | CObject *o=new CExplosionObject(x-16,y-32,&game->explosion_tiles,0,11,game); 107 | game->objects.Add(o); 108 | return false; 109 | } else { 110 | /* Car collision: */ 111 | o=game->object_collision(0,0,this,CONSTITUTION_CAR); 112 | if (o!=0) { 113 | CCarObject *co=(CCarObject *)o; 114 | 115 | co->car_collision(this); 116 | car_collision(co); 117 | } /* if */ 118 | } /* if */ 119 | } 120 | } else { 121 | y_speed=0; 122 | } /* if */ 123 | 124 | if (game->min_distance_to_players(y)>PLAYING_WINDOW) return false; 125 | 126 | return true; 127 | } /* CEnemyCarObject::cycle */ 128 | 129 | -------------------------------------------------------------------------------- /src/CEnemyFastCarObject.cpp: -------------------------------------------------------------------------------- 1 | #include "math.h" 2 | 3 | #include "SDL.h" 4 | #include "SDL_ttf.h" 5 | #include "SDL_mixer.h" 6 | 7 | #include "sound.h" 8 | 9 | #include "CTile.h" 10 | #include "CObject.h" 11 | #include "CGame.h" 12 | 13 | extern int ENEMY_SPEED; 14 | extern int ENEMY_HSPEED; 15 | extern int PLAYING_WINDOW; 16 | 17 | 18 | int FENEMY_SPEED=(24<<8); 19 | int FENEMY_HSPEED=32*24; 20 | 21 | CEnemyFastCarObject::CEnemyFastCarObject(int nx,int ny,CTile *t,int start_delay,CGame *g) : CEnemyCarObject(nx,ny,t,start_delay,g) 22 | { 23 | } /* CEnemyFastCarObject::CEnemyFastCarObject */ 24 | 25 | 26 | CEnemyFastCarObject::~CEnemyFastCarObject(void) 27 | { 28 | } /* CEnemyFastCarObject::~CEnemyFastCarObject */ 29 | 30 | 31 | 32 | bool CEnemyFastCarObject::cycle(unsigned char *keyboard,unsigned char *old_keyboard) 33 | { 34 | CCarObject::cycle(keyboard,old_keyboard); 35 | 36 | if (state_timmer>0) state_timmer--; 37 | if (state==0 && state_timmer==0) state=1; 38 | 39 | if (last_collision!=0) { 40 | if (last_collision->get_x()object_collision(8,-32,this,CONSTITUTION_SOLID)!=0) { 51 | x_speed=-FENEMY_HSPEED; 52 | slide_timmer=0; 53 | } else { 54 | if (game->object_collision(-8,-32,this,CONSTITUTION_SOLID)!=0) { 55 | x_speed=FENEMY_HSPEED; 56 | slide_timmer=0; 57 | } /* if */ 58 | } /* if */ 59 | 60 | if (slide_timmer>0) { 61 | slide_timmer--; 62 | if (slide_direction==1) x_speed=FENEMY_HSPEED; 63 | if (slide_direction==-1) x_speed=-FENEMY_HSPEED; 64 | } /* if */ 65 | 66 | if (x_speed==0) { 67 | if (game->object_collision(16,-64,this,CONSTITUTION_CAR)!=0 || 68 | game->object_collision(16,-32,this,CONSTITUTION_CAR)!=0 || 69 | game->object_collision(16,0,this,CONSTITUTION_CAR)!=0) { 70 | x_speed=-FENEMY_HSPEED; 71 | slide_timmer=0; 72 | } else { 73 | if (game->object_collision(-16,-64,this,CONSTITUTION_CAR)!=0 || 74 | game->object_collision(-16,-32,this,CONSTITUTION_CAR)!=0 || 75 | game->object_collision(-16,0,this,CONSTITUTION_CAR)!=0) { 76 | x_speed=FENEMY_HSPEED; 77 | slide_timmer=0; 78 | } /* if */ 79 | } /* if */ 80 | } /* if */ 81 | 82 | if (x_speed==0 && distance_to_border!=-1) { 83 | int i; 84 | int distance=-1; 85 | for(i=0;distance==-1 && i<=distance_to_border+8;i+=8) { 86 | if (following_right_border) { 87 | if (game->object_collision(i,0,this,CONSTITUTION_SOLID)!=0) distance=i-8; 88 | } else { 89 | if (game->object_collision(-i,0,this,CONSTITUTION_SOLID)!=0) distance=i-8; 90 | } /* if */ 91 | } /* for */ 92 | if (distance==-1) distance=distance_to_border+8; 93 | if (following_right_border) { 94 | if (distance<=distance_to_border-8) x_speed=-FENEMY_HSPEED; 95 | if (distance>=distance_to_border+8) x_speed=FENEMY_HSPEED; 96 | } else { 97 | if (distance<=distance_to_border-8) x_speed=FENEMY_HSPEED; 98 | if (distance>=distance_to_border+8) x_speed=-FENEMY_HSPEED; 99 | } /* if */ 100 | } /* if */ 101 | 102 | { 103 | CObject *o=0; 104 | 105 | /* Car collision: */ 106 | o=game->object_collision(0,0,this,CONSTITUTION_CAR); 107 | if (o!=0) { 108 | CCarObject *co=(CCarObject *)o; 109 | 110 | co->car_collision(this); 111 | car_collision(co); 112 | } /* if */ 113 | } 114 | } else { 115 | y_speed=0; 116 | } /* if */ 117 | 118 | if (game->min_distance_to_players(y)>PLAYING_WINDOW) return false; 119 | 120 | return true; 121 | } /* CEnemyFastCarObject::cycle */ 122 | 123 | -------------------------------------------------------------------------------- /src/playing_state.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "SDL.h" 4 | #include "SDL_mixer.h" 5 | #include "SDL_ttf.h" 6 | 7 | #include "time.h" 8 | 9 | #include "sound.h" 10 | 11 | #include "CTile.h" 12 | #include "CObject.h" 13 | #include "CGame.h" 14 | #include "CRoadFighter.h" 15 | #include "auxiliar.h" 16 | #include "filehandling.h" 17 | 18 | bool record_replay=false; 19 | bool load_replay=false; 20 | 21 | extern int start_level; 22 | 23 | int CRoadFighter::playing_cycle(void) 24 | { 25 | if (state_timmer==0) { 26 | if (record_replay) { 27 | unsigned int seed; 28 | replay_fp=f1open("replay.txt", "w+", USERDATA); 29 | seed=(unsigned int)time(NULL); 30 | fprintf(replay_fp,"%u\n",seed); 31 | srand(seed); 32 | } else { 33 | if (load_replay) { 34 | unsigned int seed; 35 | replay_fp=f1open("replay.txt", "r+", USERDATA); 36 | fscanf(replay_fp,"%u",&seed); 37 | srand(seed); 38 | } /* if */ 39 | } /* if */ 40 | } /* if */ 41 | 42 | if (record_replay) { 43 | int i; 44 | for(i=0;icycle(keyboard,old_keyboard)) { 72 | if (game->level_completed()) { 73 | current_level++; 74 | 75 | if (record_replay || load_replay) { 76 | fclose(replay_fp); 77 | replay_fp=0; 78 | } /* if */ 79 | return INTERLEVEL_STATE; 80 | } else { 81 | if (game->backspace_pressed) { 82 | if (record_replay || load_replay) { 83 | fclose(replay_fp); 84 | replay_fp=0; 85 | } /* if */ 86 | delete game; 87 | game=0; 88 | current_level=start_level; 89 | return INTERLEVEL_STATE; 90 | } else { 91 | gameover_state=0; 92 | if (record_replay || load_replay) { 93 | fclose(replay_fp); 94 | replay_fp=0; 95 | } /* if */ 96 | return GAMEOVER_STATE; 97 | } /* if */ 98 | } /* if */ 99 | } else { 100 | if (!playing_reachedend && game->level_completed()) { 101 | playing_reachedend=true; 102 | Sound_create_music("sound/levelcomplete",0); 103 | } /* if */ 104 | } /* if */ 105 | 106 | if (!playing_reachedend) { 107 | int volume=(game->get_game_timmer()*MIX_MAX_VOLUME)/25; 108 | if (volume<0) volume=0; 109 | if (volume>MIX_MAX_VOLUME) volume=MIX_MAX_VOLUME; 110 | Sound_music_volume(volume); 111 | } /* if */ 112 | 113 | /* Scores: */ 114 | { 115 | List l; 116 | int *itmp; 117 | game->get_scores(&l); 118 | l.Rewind(); 119 | while(l.Iterate(itmp)) if ((*itmp)>high_score) high_score=*itmp; 120 | } 121 | 122 | return PLAYING_STATE; 123 | } /* CRoadFighter::playing_cycle */ 124 | 125 | 126 | 127 | void CRoadFighter::playing_draw(SDL_Surface *screen) 128 | { 129 | SDL_Rect r; 130 | 131 | SDL_FillRect(screen,0,0); 132 | 133 | scoreboard_draw(scoreboard_x,0,screen); 134 | 135 | /* Draw game: */ 136 | if (n_players==1) { 137 | r.x=(desired_scoreboard_x-352); 138 | r.y=0; 139 | r.w=352; 140 | r.h=screen->h; 141 | } else { 142 | r.x=0; 143 | r.y=0; 144 | r.w=scoreboard_x; 145 | r.h=screen->h; 146 | } /* if */ 147 | game->draw(screen,r); 148 | 149 | } /* CRoadFighter::playing_draw */ 150 | -------------------------------------------------------------------------------- /src/CGame.h: -------------------------------------------------------------------------------- 1 | #ifndef __CROADFIGHTER_GAME_CLASS 2 | #define __CROADFIGHTER_GAME_CLASS 3 | 4 | #define SEMAPHORE_TIME 25 5 | 6 | #define QUICK_PARTS 256 7 | #define BIGGEST_OBJECT 384 /* This is used to compute the Quick parts */ 8 | 9 | class CTyreMark { 10 | public: 11 | long int x,y,x2,y2; 12 | }; 13 | 14 | class CGame { 15 | friend class CPlayerCarObject; 16 | friend class CEnemyCarObject; 17 | friend class CEnemyRacerCarObject; 18 | friend class CEnemyFastCarObject; 19 | friend class CEnemySlidderCarObject; 20 | friend class CEnemyTruckObject; 21 | friend class CFuelObject; 22 | friend class CSemaphoreObject; 23 | 24 | friend class CRoadFighter; 25 | 26 | public: 27 | CGame(char *mapname,int mode,int left_key,int right_key,int fire_key,int score,int current_level,bool extras); 28 | CGame(char *mapname,int mode, 29 | int left_key1,int right_key1,int fire_key1, 30 | int left_key2,int right_key2,int fire_key2, 31 | int score1,int score2,int current_level,bool extras); 32 | ~CGame(void); 33 | 34 | bool cycle(unsigned char *keyboard,unsigned char *old_keyboard); 35 | void draw(SDL_Surface *sfc,SDL_Rect vp); 36 | 37 | bool level_completed(void); 38 | 39 | void get_speeds(List *l); 40 | void get_fuels(List *l); 41 | void get_positions(List *l); 42 | void get_scores(List *l); 43 | int get_game_timmer(void) {return game_timmer;}; 44 | 45 | 46 | CObject *object_collision(int xoffs,int yoffs,CObject *o,int constitution); 47 | 48 | int get_dx(void) {return dx;}; 49 | int get_dy(void) {return dy;}; 50 | 51 | bool esc_pressed; 52 | bool backspace_pressed; 53 | 54 | private: 55 | 56 | void init_game(char *mapname); 57 | 58 | bool load_map(char *mapname); 59 | void draw(SDL_Surface *sfc,SDL_Rect vp,CCarObject *focusing,float *sy,int *cp_delay); 60 | 61 | void init_quick_tables(void); 62 | void delete_quick_tables(void); 63 | void get_quick_min_max(CObject *o,long yoffs,int *min,int *max); 64 | void get_quick_min_max(long ymin,long ymax,int *min,int *max); 65 | 66 | CObject *add_enemy_car(int type,long y); 67 | CObject *add_obstacle(int type,long y); 68 | long min_distance_to_players(long y); 69 | long min_distance_to_car(long y); 70 | CObject *find_closest_player(long x,long y); 71 | long min_distance_to_other_players(long y,CObject *player); 72 | bool first_player(CObject *player); 73 | 74 | 75 | int dx; 76 | int dy; 77 | int game_state; /* 0: appearing & playing, 1: disappearing */ 78 | int game_timmer; 79 | int game_mode; 80 | int current_level; 81 | bool game_remake_extras; 82 | bool paused; 83 | 84 | /* Graphics: */ 85 | List tile_sources; 86 | List tiles[256]; 87 | 88 | SDL_Surface *player1_car,*player2_car,*enemy_cars,*fuel_sfc; 89 | SDL_Surface *empty_sfc,*fuelscores_sfc,*obstacles_sfc; 90 | SDL_Surface /**start_sfc,*/*checkpoint_sfc,*goal_sfc; 91 | SDL_Surface *pause_sfc,*explosion_sfc; 92 | 93 | List player_tiles; 94 | List enemy_tiles; 95 | List extra_tiles; 96 | List explosion_tiles; 97 | 98 | TTF_Font *font; 99 | 100 | /* Sound data: */ 101 | SOUNDT S_takefuel,S_redlight,S_greenlight,S_crash,S_water; 102 | SOUNDT S_carstart,S_fuelempty,S_caradvance,S_collision; 103 | SOUNDT S_truck; 104 | Mix_Chunk *S_carengine,*S_carskid; 105 | 106 | /* Background: */ 107 | List background; 108 | List middleground; 109 | List foreground; 110 | 111 | /* Tyre marks: */ 112 | List tyre_marks; 113 | 114 | /* Quick back and fore access: */ 115 | List quick_background[QUICK_PARTS]; 116 | List quick_middleground[QUICK_PARTS]; 117 | List quick_foreground[QUICK_PARTS]; 118 | 119 | /* Weather: */ 120 | 121 | /* Objects: */ 122 | List objects,todelete; 123 | 124 | /* Focusing objects: */ 125 | List focusing_objects; 126 | List checkpoint_delay; 127 | List focusing_fy; 128 | List focusing_next_car; 129 | List focusing_next_car_index; 130 | 131 | int start_delay; /* Delay due to a semaphore, etc. at the start of the game */ 132 | int start_delay2; /* Delay that the music has to wait before starting (due to semaphores) */ 133 | /* It is also used for the START logo */ 134 | int fastcar_counter; 135 | 136 | }; 137 | 138 | #endif 139 | 140 | -------------------------------------------------------------------------------- /src/CObject.h: -------------------------------------------------------------------------------- 1 | #ifndef __RF_OBJECT_CLASS 2 | #define __RF_OBJECT_CLASS 3 | 4 | #define CONSTITUTION_NONE 1 5 | #define CONSTITUTION_SOLID 2 6 | #define CONSTITUTION_CAR 4 7 | #define CONSTITUTION_PLAYER 8 8 | #define CONSTITUTION_FUEL 16 9 | #define CONSTITUTION_WATER 32 10 | #define CONSTITUTION_OIL 64 11 | 12 | #include "List.h" 13 | 14 | class CObject { 15 | friend class CGame; 16 | 17 | public: 18 | CObject(); 19 | CObject(int x,int y,CTile *t,int constitution,class CGame *game); /* Simple constructor */ 20 | ~CObject(void); 21 | 22 | virtual bool cycle(unsigned char *keyboard,unsigned char *old_keyboard); 23 | virtual void draw(int sx,int sy,SDL_Surface *screen); 24 | bool collision(int offsx,int offst,CObject *o); 25 | 26 | long get_x(void) {return x;}; 27 | long get_y(void) {return y;}; 28 | int get_dx(void); 29 | int get_dy(void); 30 | 31 | void set_state(int s) {state=s;}; 32 | int get_state(void) {return state;}; 33 | 34 | bool constitution_test(int cons); 35 | 36 | protected: 37 | int state; /* 0 - Stopped 38 | 1 - ... */ 39 | int constitution; 40 | 41 | CGame *game; 42 | CTile **tiles; 43 | int ntiles,tile; 44 | 45 | long x,y; 46 | long draw_x,draw_y; 47 | }; 48 | 49 | class CSemaphoreObject : public CObject { 50 | public: 51 | CSemaphoreObject(int x,int y,CTile *t1,CTile *t2,CTile *t3,CTile *t4,CTile *t5,class CGame *game); 52 | ~CSemaphoreObject(void); 53 | 54 | virtual bool cycle(unsigned char *keyboard,unsigned char *old_keyboard); 55 | 56 | protected: 57 | int timmer; 58 | }; 59 | 60 | 61 | class CCarObject : public CObject { 62 | public: 63 | CCarObject(void); 64 | CCarObject(int x,int y,CTile *t,class CGame *game); 65 | ~CCarObject(void); 66 | 67 | virtual bool cycle(unsigned char *keyboard,unsigned char *old_keyboard); 68 | 69 | int get_y_speed(void) {return y_speed;}; 70 | void car_collision(CCarObject *car); 71 | 72 | long int compute_next_x(void); 73 | long int compute_next_y(void); 74 | 75 | protected: 76 | CCarObject *last_collision; 77 | 78 | long int y_precision,x_precision; 79 | int y_speed,x_speed; 80 | }; 81 | 82 | 83 | class CFuelObject : public CObject { 84 | public: 85 | CFuelObject(int x,int y,CTile *t,class CGame *game); 86 | ~CFuelObject(void); 87 | 88 | virtual bool cycle(unsigned char *keyboard,unsigned char *old_keyboard); 89 | 90 | protected: 91 | int y_precision,x_precision; 92 | int y_speed,x_speed; 93 | }; 94 | 95 | 96 | class CPlayerCarObject : public CCarObject { 97 | public: 98 | CPlayerCarObject(int x,int y,List *l,int first_tile,int last_tile, 99 | int lk,int rk,int fk,int sc,int init_delay,class CGame *game); 100 | ~CPlayerCarObject(void); 101 | 102 | virtual bool cycle(unsigned char *keyboard,unsigned char *old_keyboard); 103 | virtual void draw(int sx,int sy,SDL_Surface *screen); 104 | 105 | 106 | int get_fuel(void) {return fuel;}; 107 | int get_score(void) {return score;}; 108 | 109 | void reach_goal(void); 110 | 111 | protected: 112 | int car_tile(int angle); /* in degrees */ 113 | void tyre_coordinates(int angle,int *x1,int *y1,int *x2,int *y2); 114 | 115 | /* int state; 0 - Starting 116 | 1 - Driving 117 | 2 - Bouncing right 118 | 3 - Bouncing left 119 | 4 - Exploding 120 | 5 - Sliding right 121 | 6 - Slidding left */ 122 | 123 | int sound_timmer; 124 | int state_timmer; 125 | int rotating_angle; 126 | int blinking_time; 127 | int old_angle; 128 | 129 | int enginesound_channel,skidsound_channel; 130 | Mix_Chunk S_carengine_working; 131 | Mix_Chunk S_carskid_working; 132 | 133 | int score; 134 | int bonus,next_bonus,bonus_timmer; 135 | int fuel; 136 | int left_key,right_key,fire_key; 137 | 138 | bool goal_reached; 139 | }; 140 | 141 | 142 | 143 | class CEnemyCarObject : public CCarObject { 144 | friend class CGame; 145 | 146 | public: 147 | CEnemyCarObject(int x,int y,CTile *t,int start_delay,class CGame *game); 148 | ~CEnemyCarObject(void); 149 | 150 | virtual bool cycle(unsigned char *keyboard,unsigned char *old_keyboard); 151 | 152 | protected: 153 | int slide_direction; 154 | int slide_speed; 155 | int slide_timmer; 156 | 157 | int state_timmer; 158 | bool following_right_border; 159 | int distance_to_border; 160 | 161 | }; 162 | 163 | /* Green cars */ 164 | class CEnemyNormalCarObject : public CEnemyCarObject { 165 | friend class CGame; 166 | 167 | public: 168 | CEnemyNormalCarObject(int x,int y,CTile *t,int start_delay,class CGame *game); 169 | ~CEnemyNormalCarObject(void); 170 | 171 | protected: 172 | 173 | }; 174 | 175 | /* Blue cars */ 176 | class CEnemyRacerCarObject : public CEnemyCarObject { 177 | friend class CGame; 178 | 179 | public: 180 | CEnemyRacerCarObject(int x,int y,CTile *t,int start_delay,class CGame *game); 181 | ~CEnemyRacerCarObject(void); 182 | 183 | virtual bool cycle(unsigned char *keyboard,unsigned char *old_keyboard); 184 | 185 | protected: 186 | bool advanced; 187 | 188 | }; 189 | 190 | /* Fast Blue cars */ 191 | class CEnemyFastCarObject : public CEnemyCarObject { 192 | friend class CGame; 193 | 194 | public: 195 | CEnemyFastCarObject(int x,int y,CTile *t,int start_delay,class CGame *game); 196 | ~CEnemyFastCarObject(void); 197 | 198 | virtual bool cycle(unsigned char *keyboard,unsigned char *old_keyboard); 199 | 200 | protected: 201 | 202 | }; 203 | 204 | /* Pink cars */ 205 | class CEnemySlidderCarObject : public CEnemyCarObject { 206 | friend class CGame; 207 | 208 | public: 209 | CEnemySlidderCarObject(int x,int y,CTile *t,int start_delay,class CGame *game); 210 | ~CEnemySlidderCarObject(void); 211 | 212 | virtual bool cycle(unsigned char *keyboard,unsigned char *old_keyboard); 213 | 214 | protected: 215 | 216 | }; 217 | 218 | /* Trucks */ 219 | class CEnemyTruckObject : public CCarObject { 220 | friend class CGame; 221 | 222 | public: 223 | CEnemyTruckObject(int x,int y,CTile *t,int start_delay,class CGame *game); 224 | ~CEnemyTruckObject(void); 225 | 226 | virtual bool cycle(unsigned char *keyboard,unsigned char *old_keyboard); 227 | 228 | protected: 229 | int state_timmer; 230 | bool following_right_border; 231 | int distance_to_border; 232 | 233 | bool advanced; 234 | }; 235 | 236 | 237 | class CExplosionObject : public CObject { 238 | public: 239 | CExplosionObject(int x,int y,List *l,int first_tile,int last_tile,class CGame *game); 240 | ~CExplosionObject(void); 241 | 242 | virtual bool cycle(unsigned char *keyboard,unsigned char *old_keyboard); 243 | 244 | protected: 245 | int timmer; 246 | }; 247 | 248 | 249 | #endif 250 | 251 | -------------------------------------------------------------------------------- /src/CTile.cpp: -------------------------------------------------------------------------------- 1 | #include "assert.h" 2 | 3 | #include "stdio.h" 4 | #include "string.h" 5 | 6 | #include "SDL.h" 7 | #include "SDL_ttf.h" 8 | #include "SDL_image.h" 9 | #include "sge/sge.h" 10 | 11 | #include "CTile.h" 12 | #include "math.h" 13 | 14 | #include "auxiliar.h" 15 | 16 | 17 | CTile::CTile(void) 18 | { 19 | r.x=0; 20 | r.y=0; 21 | r.h=0; 22 | r.w=0; 23 | orig=0; 24 | mask_visualization=0; 25 | mask_collision=0; 26 | collision_data=0; 27 | } /* CTile::CTile */ 28 | 29 | 30 | CTile::CTile(int x,int y,int dx,int dy,SDL_Surface *o,bool collision) 31 | { 32 | 33 | r.x=x; 34 | r.y=y; 35 | r.h=dy; 36 | r.w=dx; 37 | 38 | orig=SDL_CreateRGBSurface(0,dx,dy,32,RMASK,GMASK,BMASK,AMASK); 39 | SDL_SetAlpha(orig,0,SDL_ALPHA_OPAQUE); 40 | SDL_BlitSurface(o,&r,orig,0); 41 | 42 | SDL_SetAlpha(orig,SDL_SRCALPHA,SDL_ALPHA_OPAQUE); 43 | surface_mask_from_bitmap(orig,o,r.x+r.w,r.y); 44 | mask_visualization=0; 45 | 46 | if (collision) { 47 | SDL_Rect r2; 48 | 49 | r2.x=r.x+(r.w*2); 50 | r2.y=r.y; 51 | r2.w=r.w; 52 | r2.h=r.h; 53 | mask_collision=SDL_CreateRGBSurface(0,r.w,r.h,32,RMASK,GMASK,BMASK,AMASK); 54 | SDL_BlitSurface(o,&r2,mask_collision,0); 55 | surface_bw(mask_collision,128); 56 | collision_data=sge_make_cmap(mask_collision); 57 | } else { 58 | mask_collision=0; 59 | collision_data=0; 60 | } /* if */ 61 | } /* CTile::CTile */ 62 | 63 | 64 | CTile::~CTile(void) 65 | { 66 | free(); 67 | } /* CTile::CTile */ 68 | 69 | 70 | void CTile::draw(int x,int y,SDL_Surface *dest) 71 | { 72 | SDL_Rect d; 73 | 74 | if (orig!=0) { 75 | d.x=x; 76 | d.y=y; 77 | d.w=r.w; 78 | d.h=r.h; 79 | SDL_BlitSurface(orig,0,dest,&d); 80 | // SDL_BlitSurface(mask_collision,0,dest,&d); 81 | } /* if */ 82 | } /* CTile::draw */ 83 | 84 | 85 | void CTile::draw_collision_mask(int x,int y,SDL_Surface *dest) 86 | { 87 | SDL_Rect d; 88 | 89 | if (orig!=0) { 90 | if (mask_collision!=0) { 91 | d.x=x; 92 | d.y=y; 93 | d.w=r.w; 94 | d.h=r.h; 95 | SDL_BlitSurface(mask_collision,0,dest,&d); 96 | } /* if */ 97 | } /* if */ 98 | } /* CTile::draw_collision_mask */ 99 | 100 | 101 | void CTile::draw_shaded(int x,int y,SDL_Surface *dest,int factor,int red,int green,int blue,int alpha) 102 | { 103 | SDL_Rect d; 104 | 105 | if (orig!=0) { 106 | SDL_Surface *tmp; 107 | d.x=0; 108 | d.y=0; 109 | d.w=r.w; 110 | d.h=r.h; 111 | tmp=SDL_DisplayFormatAlpha(orig); 112 | surface_shader(tmp,float(factor)/100.0F,red,green,blue,alpha); 113 | d.x=x; 114 | d.y=y; 115 | d.w=r.w; 116 | d.h=r.h; 117 | SDL_BlitSurface(tmp,0,dest,&d); 118 | SDL_FreeSurface(tmp); 119 | } /* if */ 120 | } /* CTile::draw_shaded */ 121 | 122 | 123 | void CTile::draw_bicolor(int x,int y,SDL_Surface *dest,int factor,int r1,int g1,int b1,int a1,int r2,int g2,int b2,int a2) 124 | { 125 | SDL_Rect d; 126 | 127 | if (orig!=0) { 128 | SDL_Surface *tmp; 129 | d.x=0; 130 | d.y=0; 131 | d.w=r.w; 132 | d.h=r.h; 133 | tmp=SDL_DisplayFormatAlpha(orig); 134 | surface_bicolor(tmp,float(factor)/100.0F,r1,g1,b1,a1,r2,g2,b2,a2); 135 | d.x=x; 136 | d.y=y; 137 | d.w=r.w; 138 | d.h=r.h; 139 | SDL_BlitSurface(tmp,0,dest,&d); 140 | SDL_FreeSurface(tmp); 141 | } /* if */ 142 | } /* CTile::draw_bicolor */ 143 | 144 | 145 | void CTile::draw_scaled(int x,int y,SDL_Surface *dest,float scale) 146 | { 147 | if (orig!=0) sge_transform(orig,dest,0,scale,scale,0,0,x,y,0); 148 | } /* CTile::draw_scaled */ 149 | 150 | 151 | void CTile::draw_mask(int x,int y,SDL_Surface *dest) 152 | { 153 | SDL_Rect d; 154 | 155 | if (orig!=0) { 156 | if (mask_visualization==0) { 157 | int i,j; 158 | 159 | mask_visualization=SDL_CreateRGBSurface(SDL_HWSURFACE,r.w,r.h,32,0,0,0,0); 160 | for(i=0;iformat,&r,&g,&b,&a); 169 | 170 | color=SDL_MapRGBA(mask_visualization->format,a,a,a,0); 171 | SDL_LockSurface(mask_visualization); 172 | putpixel(mask_visualization,i,j,color); 173 | SDL_UnlockSurface(mask_visualization); 174 | } /* for */ 175 | } /* for */ 176 | } /* if */ 177 | 178 | d.x=x; 179 | d.y=y; 180 | d.w=r.w; 181 | d.h=r.h; 182 | SDL_BlitSurface(mask_visualization,0,dest,&d); 183 | } /* if */ 184 | } /* CTile::draw_mask */ 185 | 186 | 187 | void CTile::clear(void) 188 | { 189 | orig=0; 190 | mask_visualization=0; 191 | mask_collision=0; 192 | collision_data=0; 193 | } /* CTile::clear */ 194 | 195 | 196 | void CTile::free(void) 197 | { 198 | if (orig!=0) SDL_FreeSurface(orig); 199 | orig=0; 200 | if (mask_visualization!=0) SDL_FreeSurface(mask_visualization); 201 | mask_visualization=0; 202 | 203 | if (mask_collision!=0) SDL_FreeSurface(mask_collision); 204 | mask_collision=0; 205 | 206 | if (collision_data!=0) sge_destroy_cmap(collision_data); 207 | collision_data=0; 208 | } /* CTile::free */ 209 | 210 | 211 | void CTile::instance(CTile *t) 212 | { 213 | r=t->r; 214 | orig=t->orig; 215 | mask_visualization=t->mask_visualization; 216 | mask_collision=t->mask_collision; 217 | collision_data=t->collision_data; 218 | 219 | } /* CTile::instace */ 220 | 221 | 222 | 223 | 224 | 225 | TILE_SOURCE::TILE_SOURCE(void) 226 | { 227 | fname=0; 228 | sfc=0; 229 | } /* TILE_SOURCE::TILE_SOURCE */ 230 | 231 | 232 | TILE_SOURCE::TILE_SOURCE(char *filename) 233 | { 234 | SDL_Surface *tmp_sfc; 235 | 236 | fname=new char[strlen(filename)+1]; 237 | strcpy(fname,filename); 238 | tmp_sfc=IMG_Load(fname); 239 | 240 | sfc = SDL_CreateRGBSurface(SDL_HWSURFACE,tmp_sfc->w,tmp_sfc->h,32,0,0,0,AMASK); 241 | SDL_SetAlpha(sfc,0,SDL_ALPHA_OPAQUE); 242 | SDL_BlitSurface(tmp_sfc,0,sfc,0); 243 | SDL_FreeSurface(tmp_sfc); 244 | } /* TILE_SOURCE::TILE_SOURCE */ 245 | 246 | 247 | TILE_SOURCE::~TILE_SOURCE(void) 248 | { 249 | delete fname; 250 | fname=0; 251 | SDL_FreeSurface(sfc); 252 | } /* TILE_SOURCE::~TILE_SOURCE */ 253 | 254 | 255 | bool TILE_SOURCE::save(FILE *fp) 256 | { 257 | fprintf(fp,"%s\n",fname); 258 | 259 | return true; 260 | } /* TILE_SOURCE::save */ 261 | 262 | 263 | bool TILE_SOURCE::load(FILE *fp) 264 | { 265 | char tmp[256]; 266 | SDL_Surface *tmp_sfc; 267 | 268 | if (1!=fscanf(fp,"%s",tmp)) return false; 269 | 270 | if (fname!=0) delete fname; 271 | fname=new char[strlen(tmp)+1]; 272 | strcpy(fname,tmp); 273 | tmp_sfc=IMG_Load(fname); 274 | 275 | sfc = SDL_CreateRGBSurface(SDL_HWSURFACE,tmp_sfc->w,tmp_sfc->h,32,0,0,0,AMASK); 276 | SDL_SetAlpha(sfc,0,SDL_ALPHA_OPAQUE); 277 | SDL_BlitSurface(tmp_sfc,0,sfc,0); 278 | SDL_FreeSurface(tmp_sfc); 279 | 280 | return true; 281 | } /* TILE_SOURCE::load */ 282 | 283 | 284 | bool TILE_SOURCE::cmp(char *n) 285 | { 286 | if (strcmp(n,fname)==0) return true; 287 | 288 | return false; 289 | } /* TILE_SOURCE::cmp */ 290 | 291 | 292 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #ifdef _WIN32 2 | #include 3 | #include 4 | #else 5 | #include 6 | #include 7 | #endif 8 | 9 | #include 10 | #include 11 | #include "SDL.h" 12 | #include "SDL_mixer.h" 13 | #include "SDL_ttf.h" 14 | 15 | #include "sound.h" 16 | 17 | #include "CTile.h" 18 | #include "CObject.h" 19 | #include "CGame.h" 20 | #include "CRoadFighter.h" 21 | #include "auxiliar.h" 22 | 23 | #include "debug.h" 24 | 25 | 26 | /* GLOBAL VARIABLES INITIALIZATION: */ 27 | 28 | const int REDRAWING_PERIOD=27; /* This is for 35fps */ 29 | // const int REDRAWING_PERIOD=40; /* This is for 25fps */ 30 | 31 | int SCREEN_X=512; 32 | int SCREEN_Y=384; 33 | const int COLOUR_DEPTH=32; 34 | const char *application_name="Road Fighter v1.0"; 35 | 36 | #ifdef _WIN32 37 | bool fullscreen=true; 38 | #else 39 | bool fullscreen=false; 40 | #endif 41 | 42 | int init_time=0; 43 | SDL_Surface *screen_sfc; 44 | CRoadFighter *game=0; 45 | int screen_flags= /* SDL_GLSDL | SDL_DOUBLEBUF | */ 46 | /* SDL_HWSURFACE | SDL_DOUBLEBUF | */ 47 | 0; 48 | 49 | int start_level=1; 50 | 51 | 52 | /* AUXILIAR FUNCTION DEFINITION: */ 53 | 54 | SDL_Surface* initializeSDL(int moreflags) 55 | { 56 | char VideoName[256]; 57 | SDL_Surface *screen; 58 | 59 | //int flags = SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_HWPALETTE; 60 | int flags = screen_flags|moreflags; 61 | if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO)<0) return 0; 62 | 63 | output_debug_message("Initializing SDL video subsystem.\n"); 64 | if ((SDL_Init(SDL_INIT_VIDEO)) == -1) 65 | { 66 | output_debug_message("Couldn't initialize video subsystem: %s\n", SDL_GetError()); 67 | exit(-1); 68 | } 69 | SDL_VideoDriverName (VideoName, sizeof (VideoName)); 70 | output_debug_message("SDL driver used: %s\n", VideoName); 71 | // Set the environment variable SDL_VIDEODRIVER to override 72 | // For Linux: x11 (default), dga, fbcon, directfb, svgalib, 73 | // ggi, aalib 74 | // For Windows: directx (default), windib 75 | output_debug_message("SDL video subsystem initialized.\n"); 76 | 77 | atexit(SDL_Quit); 78 | SDL_WM_SetCaption(application_name, 0); 79 | if (fullscreen) SDL_ShowCursor(SDL_DISABLE); 80 | Sound_initialization(); 81 | 82 | pause(1000); 83 | 84 | screen = SDL_SetVideoMode(SCREEN_X, SCREEN_Y, COLOUR_DEPTH, flags); 85 | 86 | if (screen == NULL) { 87 | output_debug_message("Couldn't set %ix%ix%i", SCREEN_X, SCREEN_Y, COLOUR_DEPTH); 88 | if (fullscreen) output_debug_message(",fullscreen,"); 89 | output_debug_message(" video mode: %s\n",SDL_GetError ()); 90 | exit(-1); 91 | } else { 92 | output_debug_message("Set the video resolution to: %ix%ix%i", 93 | SDL_GetVideoSurface()->w, SDL_GetVideoSurface()->h, 94 | SDL_GetVideoSurface()->format->BitsPerPixel); 95 | if (fullscreen) output_debug_message(",fullscreen"); 96 | output_debug_message("\n"); 97 | SDL_ShowCursor(SDL_DISABLE); 98 | } /* if */ 99 | 100 | TTF_Init(); 101 | 102 | SDL_EnableUNICODE(1); 103 | 104 | return screen; 105 | } /* initializeSDL */ 106 | 107 | 108 | void finalizeSDL() 109 | { 110 | TTF_Quit(); 111 | // Sound_release(); 112 | SDL_Quit(); 113 | } /* finalizeSDL */ 114 | 115 | 116 | 117 | #ifdef _WIN32 118 | int PASCAL WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, 119 | LPSTR lpCmdLine, int nCmdShow) 120 | { 121 | { 122 | int tmp; 123 | if (1==sscanf(lpCmdLine,"%i",&tmp)) { 124 | start_level=tmp; 125 | if (start_level<1 || start_level>6) start_level=1; 126 | } /* if */ 127 | } 128 | 129 | #else 130 | int main(int argc, char** argv) 131 | { 132 | setupTickCount(); 133 | 134 | { 135 | int tmp; 136 | if (argc==2 && 137 | 1==sscanf(argv[1],"%i",&tmp)) { 138 | start_level=tmp; 139 | if (start_level<1 || start_level>6) start_level=1; 140 | } /* if */ 141 | } 142 | #endif 143 | 144 | int time,act_time; 145 | SDL_Event event; 146 | bool quit = false; 147 | 148 | 149 | time=init_time=GetTickCount(); 150 | screen_sfc = initializeSDL((fullscreen ? SDL_FULLSCREEN : 0)); 151 | if (screen_sfc==0) return 0; 152 | 153 | game=new CRoadFighter(); 154 | 155 | while (!quit) { 156 | while( SDL_PollEvent( &event ) ) { 157 | switch( event.type ) { 158 | /* Keyboard event */ 159 | case SDL_KEYDOWN: 160 | // quit 161 | if (event.key.keysym.sym==SDLK_F12) { 162 | quit = true; 163 | } 164 | if (event.key.keysym.sym==SDLK_F4) { 165 | SDLMod modifiers; 166 | modifiers=SDL_GetModState(); 167 | if ((modifiers&KMOD_ALT)!=0) { 168 | quit=true; 169 | } 170 | } 171 | #ifdef __APPLE__ 172 | // different quit shortcut on OSX: apple+Q 173 | if (event.key.keysym.sym == SDLK_q) { 174 | SDLMod modifiers; 175 | modifiers = SDL_GetModState(); 176 | if ((modifiers&KMOD_META) != 0) { 177 | quit = true; 178 | } 179 | } 180 | #endif 181 | // fullscreen 182 | /* 183 | FIXME: the code below is a big copy/paste; it should be in a separate function in stead 184 | */ 185 | 186 | #ifdef __APPLE__ 187 | if (event.key.keysym.sym == SDLK_f) { 188 | SDLMod modifiers; 189 | 190 | modifiers=SDL_GetModState(); 191 | 192 | if ((modifiers&KMOD_META) != 0) { 193 | Stop_playback(); 194 | /* Toogle FULLSCREEN mode: */ 195 | if (fullscreen) fullscreen=false; 196 | else fullscreen=true; 197 | SDL_QuitSubSystem(SDL_INIT_VIDEO); 198 | SDL_InitSubSystem(SDL_INIT_VIDEO); 199 | if (SDL_WasInit(SDL_INIT_VIDEO)) { 200 | screen_sfc = SDL_SetVideoMode(SCREEN_X, SCREEN_Y, COLOUR_DEPTH, 201 | (fullscreen ? SDL_FULLSCREEN : 0) | screen_flags); 202 | SDL_WM_SetCaption(application_name, 0); 203 | SDL_ShowCursor(SDL_DISABLE); 204 | } else { 205 | quit = true; 206 | } /* if */ 207 | Resume_playback(); 208 | } /* if */ 209 | } /* if */ 210 | #endif 211 | 212 | if (event.key.keysym.sym==SDLK_RETURN) { 213 | SDLMod modifiers; 214 | 215 | modifiers=SDL_GetModState(); 216 | 217 | if ((modifiers&KMOD_ALT)!=0) { 218 | Stop_playback(); 219 | /* Toogle FULLSCREEN mode: */ 220 | if (fullscreen) fullscreen=false; 221 | else fullscreen=true; 222 | SDL_QuitSubSystem(SDL_INIT_VIDEO); 223 | SDL_InitSubSystem(SDL_INIT_VIDEO); 224 | if (SDL_WasInit(SDL_INIT_VIDEO)) { 225 | screen_sfc = SDL_SetVideoMode(SCREEN_X, SCREEN_Y, COLOUR_DEPTH, 226 | (fullscreen ? SDL_FULLSCREEN : 0) | screen_flags); 227 | SDL_WM_SetCaption(application_name, 0); 228 | SDL_ShowCursor(SDL_DISABLE); 229 | } else { 230 | quit = true; 231 | } /* if */ 232 | Resume_playback(); 233 | } /* if */ 234 | } /* if */ 235 | break; 236 | 237 | /* SDL_QUIT event (window close) */ 238 | case SDL_QUIT: 239 | quit = true; 240 | break; 241 | } /* switch */ 242 | } /* while */ 243 | 244 | act_time=GetTickCount(); 245 | if (act_time-time>=REDRAWING_PERIOD) { 246 | if ((act_time-init_time)>=1000) init_time=act_time; 247 | 248 | time+=REDRAWING_PERIOD; 249 | if ((act_time-time)>2*REDRAWING_PERIOD) time=act_time; 250 | 251 | if (!game->cycle()) quit=true; 252 | SDL_SetClipRect(screen_sfc, 0); 253 | game->draw(screen_sfc); 254 | SDL_Flip(screen_sfc); 255 | } /* if */ 256 | SDL_Delay(1); 257 | } 258 | 259 | delete game; 260 | 261 | finalizeSDL(); 262 | 263 | return 0; 264 | } /* main */ 265 | 266 | 267 | -------------------------------------------------------------------------------- /src/loadmg2.cpp: -------------------------------------------------------------------------------- 1 | #include "string.h" 2 | 3 | #include "SDL.h" 4 | #include "SDL_ttf.h" 5 | #include "SDL_image.h" 6 | #include "SDL_mixer.h" 7 | 8 | #include "sound.h" 9 | 10 | #include "CTile.h" 11 | #include "CObject.h" 12 | #include "CGame.h" 13 | 14 | #include "auxiliar.h" 15 | #include "filehandling.h" 16 | 17 | bool CGame::load_map(char *mapname) 18 | { 19 | FILE *fp; 20 | int i,j,k,n; 21 | int i_tmp; 22 | int current_object; 23 | int semaphore_object; 24 | int semaphore_tiles[5][2]; 25 | List l; 26 | TILE_SOURCE *source; 27 | char tmp[256]; 28 | 29 | fp=f1open(mapname, "r", GAMEDATA); 30 | if (fp==0) return false; 31 | 32 | /* Load map: */ 33 | 34 | /* Tile sources: */ 35 | if (2!=fscanf(fp,"%s %i",tmp,&n)) return false; 36 | for(i=0;iload(fp); 39 | tile_sources.Add(source); 40 | } /* for */ 41 | 42 | /* Tiles: */ 43 | for(j=0;j<256;j++) { 44 | if (2!=fscanf(fp,"%s %i",tmp,&n)) return false; 45 | tiles[j].Delete(); 46 | for(i=0;icmp(tmp)) { 59 | found=true; 60 | t=new CTile(i1,i2,i3,i4,source->sfc,(collision_mask_type==2 ? true:false)); 61 | } /* if */ 62 | } /* while */ 63 | 64 | if (t!=0) tiles[j].Add(t); 65 | } /* for */ 66 | } /* for */ 67 | 68 | /* Objects: */ 69 | if (2!=fscanf(fp,"%s %i",tmp,&n)) return false; 70 | current_object=0; 71 | semaphore_object=0; 72 | for(i=0;i 2 | #include 3 | #include "SDL.h" 4 | #include "SDL_image.h" 5 | #include "SDL_mixer.h" 6 | #include "SDL_ttf.h" 7 | 8 | #include "sound.h" 9 | 10 | #include "CTile.h" 11 | #include "CObject.h" 12 | #include "CGame.h" 13 | #include "CRoadFighter.h" 14 | #include "auxiliar.h" 15 | 16 | #include "debug.h" 17 | 18 | int interlevel_time=25; 19 | int nlevels=6; 20 | extern int SCREEN_X; 21 | extern int SCREEN_Y; 22 | extern int start_level; 23 | 24 | char *maps[6]={"maps/level1.mg2", 25 | "maps/level2.mg2", 26 | "maps/level3.mg2", 27 | "maps/level4.mg2", 28 | "maps/level5.mg2", 29 | "maps/level6.mg2"}; 30 | 31 | 32 | int CRoadFighter::interlevel_cycle(void) 33 | { 34 | if (state_timmer==0) { 35 | 36 | output_debug_message("CRoadFighter::interlevel_cycle: cycle 0.\n"); 37 | 38 | int score1=0,score2=0; 39 | 40 | if (levelintro_sfc!=0) SDL_FreeSurface(levelintro_sfc); 41 | 42 | Sound_music_volume(MIX_MAX_VOLUME); 43 | if (current_level>start_level && game!=0) { 44 | List l; 45 | game->get_scores(&l); 46 | score1=*l[0]; 47 | if (n_players>1 && l.Length()>1) score2=*l[1]; 48 | } else { 49 | Sound_create_music("sound/start",0); 50 | } /* if */ 51 | 52 | if (current_level>nlevels) { 53 | current_level=1; 54 | game_mode++; 55 | if (game_mode>=3) game_mode=3; 56 | } /* if */ 57 | 58 | if (current_level<6) { 59 | SDL_FreeSurface(scoreboard2_sfc); 60 | if (n_players>1) scoreboard2_sfc=IMG_Load("graphics/s_board12p.bmp"); 61 | else scoreboard2_sfc=IMG_Load("graphics/s_board11p.bmp"); 62 | } else { 63 | if (n_players>1) scoreboard2_sfc=IMG_Load("graphics/s_board22p.bmp"); 64 | else scoreboard2_sfc=IMG_Load("graphics/s_board21p.bmp"); 65 | } /* if */ 66 | 67 | desired_scoreboard_x=SCREEN_X-scoreboard_sfc->w; 68 | if (n_players>1) desired_scoreboard_x=SCREEN_X-128; 69 | else desired_scoreboard_x=SCREEN_X-144; 70 | 71 | if (current_level==1) levelintro_sfc=IMG_Load("graphics/stage1.jpg"); 72 | if (current_level==2) levelintro_sfc=IMG_Load("graphics/stage2.jpg");; 73 | if (current_level==3) levelintro_sfc=IMG_Load("graphics/stage3.jpg");; 74 | if (current_level==4) levelintro_sfc=IMG_Load("graphics/stage4.jpg");; 75 | if (current_level==5) levelintro_sfc=IMG_Load("graphics/stage5.jpg");; 76 | if (current_level==6) levelintro_sfc=IMG_Load("graphics/stage6.jpg");; 77 | 78 | /* Create the game: */ 79 | delete game; 80 | game=0; 81 | if (n_players==1) { 82 | game=new CGame(maps[current_level-1],game_mode,left_key,right_key,fire_key,score1,current_level,game_remake_extras); 83 | } else { 84 | game=new CGame(maps[current_level-1],game_mode,left_key,right_key,fire_key, 85 | left2_key,right2_key,fire2_key,score1,score2,current_level,game_remake_extras); 86 | } /* if */ 87 | interlevel_state=0; 88 | interlevel_timmer=0; 89 | if (current_level==1) interlevel_state=3; 90 | 91 | output_debug_message("CRoadFighter::interlevel_cycle: game created.\n"); 92 | 93 | } /* if */ 94 | 95 | switch(interlevel_state) { 96 | case 0:/* Appearing map */ 97 | if (state_timmer>=interlevel_time) { 98 | output_debug_message("CRoadFighter::interlevel_cycle: going to state 1.\n"); 99 | interlevel_state=1; 100 | interlevel_timmer=0; 101 | } else { 102 | interlevel_timmer++; 103 | } /* if */ 104 | break; 105 | case 1:/* Advancing car */ 106 | if (state_timmer>=interlevel_time*4 || 107 | (interlevel_timmer>=(interlevel_time*2) && 108 | ((keyboard[fire_key] && !old_keyboard[fire_key]) || 109 | (keyboard[SDLK_ESCAPE] && !old_keyboard[SDLK_ESCAPE])))) { 110 | output_debug_message("CRoadFighter::interlevel_cycle: going to state 2.\n"); 111 | interlevel_state=2; 112 | if (interlevel_timmer>=interlevel_time) interlevel_timmer=interlevel_time; 113 | } else { 114 | interlevel_timmer++; 115 | } /* if */ 116 | break; 117 | case 2:/* Disappearing map */ 118 | if (interlevel_timmer<=0) { 119 | output_debug_message("CRoadFighter::interlevel_cycle: going to state 3.\n"); 120 | interlevel_state=3; 121 | interlevel_timmer=0; 122 | } else { 123 | interlevel_timmer--; 124 | } /* if */ 125 | break; 126 | case 3:/* Appearing text */ 127 | if (interlevel_timmer>=interlevel_time*5 || 128 | (interlevel_timmer>=interlevel_time && 129 | ((keyboard[fire_key] && !old_keyboard[fire_key]) || 130 | (keyboard[SDLK_ESCAPE] && !old_keyboard[SDLK_ESCAPE])))) { 131 | output_debug_message("CRoadFighter::interlevel_cycle: going to state 4.\n"); 132 | interlevel_state=4; 133 | if (interlevel_timmer>=interlevel_time) interlevel_timmer=interlevel_time; 134 | } else { 135 | interlevel_timmer++; 136 | } /* if */ 137 | break; 138 | case 4:/* Disappearing text */ 139 | Sound_music_volume((interlevel_timmer*MIX_MAX_VOLUME)/interlevel_time); 140 | if (interlevel_timmer<=0) { 141 | output_debug_message("CRoadFighter::interlevel_cycle: going to playing state.\n"); 142 | Sound_release_music(); 143 | Sound_music_volume(MIX_MAX_VOLUME); 144 | playing_reachedend=false; 145 | return PLAYING_STATE; 146 | } else interlevel_timmer--; 147 | break; 148 | } /* switch */ 149 | 150 | return INTERLEVEL_STATE; 151 | } /* CRoadFighter::interlevel_cycle */ 152 | 153 | 154 | 155 | void CRoadFighter::interlevel_draw(SDL_Surface *screen) 156 | { 157 | SDL_Rect r; 158 | 159 | SDL_FillRect(screen,0,0); 160 | 161 | switch(interlevel_state) { 162 | 163 | case 0:// Appearing map 164 | { 165 | float f=float(interlevel_timmer)/float(interlevel_time); 166 | r.x=(desired_scoreboard_x)/2-(gamemap_sfc->w)/2; 167 | r.y=(screen->h)/2-(gamemap_sfc->h)/2; 168 | r.w=gamemap_sfc->w; 169 | r.h=gamemap_sfc->h; 170 | SDL_BlitSurface(gamemap_sfc,0,screen,&r); 171 | 172 | // Draw the car: 173 | if ((interlevel_timmer>>3)&0x01!=0) { 174 | int car_x=(desired_scoreboard_x)/2-minicar1_tile->get_dx()/2; 175 | int car_y=(screen->h)/2+(gamemap_sfc->h)/2 - 176 | (current_level-2)*((gamemap_sfc->h)/6) - 177 | minicar1_tile->get_dy()/2; 178 | 179 | minicar1_tile->draw(car_x,car_y,screen); 180 | } 181 | 182 | 183 | if (f<1.0) surface_fader(screen,f,f,f,0); 184 | } 185 | break; 186 | case 1:// Advancing car 187 | r.x=(desired_scoreboard_x)/2-(gamemap_sfc->w)/2; 188 | r.y=(screen->h)/2-(gamemap_sfc->h)/2; 189 | r.w=gamemap_sfc->w; 190 | r.h=gamemap_sfc->h; 191 | SDL_BlitSurface(gamemap_sfc,0,screen,&r); 192 | // Draw the car: 193 | if ((interlevel_timmer>>3)&0x01!=0) { 194 | int car_x=(desired_scoreboard_x)/2-minicar1_tile->get_dx()/2; 195 | int car_y=(screen->h)/2+(gamemap_sfc->h)/2 - 196 | (current_level-2)*((gamemap_sfc->h)/6) - 197 | minicar1_tile->get_dy()/2; 198 | int v=interlevel_timmer; 199 | 200 | if (v>=interlevel_time*2) v=interlevel_time*2; 201 | 202 | car_y-=(v*((gamemap_sfc->h)/6))/(interlevel_time*2); 203 | minicar1_tile->draw(car_x,car_y,screen); 204 | } 205 | break; 206 | case 2:// Disappearing map 207 | { 208 | float f=float(interlevel_timmer)/float(interlevel_time); 209 | r.x=(desired_scoreboard_x)/2-(gamemap_sfc->w)/2; 210 | r.y=(screen->h)/2-(gamemap_sfc->h)/2; 211 | r.w=gamemap_sfc->w; 212 | r.h=gamemap_sfc->h; 213 | SDL_BlitSurface(gamemap_sfc,0,screen,&r); 214 | 215 | // Draw the car: 216 | if ((interlevel_timmer>>3)&0x01!=0) { 217 | int car_x=(desired_scoreboard_x)/2-minicar1_tile->get_dx()/2; 218 | int car_y=(screen->h)/2+(gamemap_sfc->h)/2 - 219 | (current_level-1)*((gamemap_sfc->h)/6) - 220 | minicar1_tile->get_dy()/2; 221 | 222 | minicar1_tile->draw(car_x,car_y,screen); 223 | } 224 | 225 | 226 | if (f<1.0) surface_fader(screen,f,f,f,0); 227 | } 228 | break; 229 | 230 | case 3:// Appearing text 231 | case 4:// Disappearing text 232 | { 233 | SDL_Color c; 234 | SDL_Surface *text_sfc; 235 | char text[80]; 236 | int v=255; 237 | float f=1.0; 238 | 239 | if (levelintro_sfc!=0) { 240 | 241 | text_sfc=SDL_DisplayFormat(levelintro_sfc); 242 | 243 | f=float(interlevel_timmer)/interlevel_time; 244 | if (f>=1.0) f=1.0; 245 | 246 | if (f<1.0) surface_fader(text_sfc,f,f,f,0); 247 | r.x=(desired_scoreboard_x)/2-text_sfc->w/2; 248 | r.y=(screen->h/2)-text_sfc->h; 249 | r.w=text_sfc->w; 250 | r.h=text_sfc->h; 251 | SDL_BlitSurface(text_sfc,0,screen,&r); 252 | SDL_FreeSurface(text_sfc); 253 | } else { 254 | sprintf(text,"STAGE %.2i",current_level); 255 | 256 | v=(interlevel_timmer*255)/interlevel_time; 257 | if (v>=255) v=255; 258 | c.r=c.g=c.b=v; 259 | text_sfc=TTF_RenderText_Blended(font2big,text,c); 260 | r.x=(desired_scoreboard_x)/2-text_sfc->w/2; 261 | r.y=(screen->h/2)-text_sfc->h; 262 | r.w=text_sfc->w; 263 | r.h=text_sfc->h; 264 | SDL_BlitSurface(text_sfc,0,screen,&r); 265 | SDL_FreeSurface(text_sfc); 266 | } // if 267 | } 268 | break; 269 | } // switch 270 | 271 | /* Draw Scoreboard: */ 272 | if (scoreboard_x==-1) { 273 | scoreboard_x=screen->w; 274 | } else { 275 | if (scoreboard_x>desired_scoreboard_x) { 276 | scoreboard_x-=int((screen->w-desired_scoreboard_x)/interlevel_time); 277 | if (scoreboard_fade_timmer<25) scoreboard_fade_timmer++; 278 | } /* if */ 279 | if (scoreboard_x 1 ? "stereo" : "mono", audio_bufsize); 59 | #endif 60 | 61 | MIX_VERSION (&compile_version); 62 | #ifdef __DEBUG_MESSAGES 63 | output_debug_message(" compiled with SDL_mixer version: %d.%d.%d\n", 64 | compile_version.major, 65 | compile_version.minor, 66 | compile_version.patch); 67 | output_debug_message(" running with SDL_mixer version: %d.%d.%d\n", 68 | Mix_Linked_Version()->major, 69 | Mix_Linked_Version()->minor, 70 | Mix_Linked_Version()->patch); 71 | #endif 72 | 73 | if (nc>0) n_channels=Mix_AllocateChannels(nc); 74 | if (nrc>0) Mix_ReserveChannels(nrc); 75 | 76 | return n_channels; 77 | } /* Sound_init */ 78 | 79 | void Sound_release(void) 80 | { 81 | Sound_release_music(); 82 | if (sound_enabled) { 83 | // Sound_Quit(); 84 | Mix_CloseAudio(); 85 | } /* if */ 86 | sound_enabled=false; 87 | } /* Sound_release */ 88 | 89 | 90 | void Stop_playback(void) 91 | { 92 | if (sound_enabled) { 93 | Sound_pause_music(); 94 | // Mix_HookMusic(0, 0); 95 | Mix_CloseAudio(); 96 | sound_enabled=false; 97 | } /* if */ 98 | } /* Stop_playback */ 99 | 100 | void Resume_playback(void) 101 | { 102 | Resume_playback(0,0); 103 | } /* Resume_playback */ 104 | 105 | 106 | int Resume_playback(int nc,int nrc) 107 | { 108 | char SoundcardName[256]; 109 | int audio_rate = 44100; 110 | int audio_channels = 2; 111 | int audio_bufsize = AUDIO_BUFFER; 112 | Uint16 audio_format = AUDIO_S16; 113 | SDL_version compile_version; 114 | n_channels=8; 115 | 116 | sound_enabled=true; 117 | #ifdef __DEBUG_MESSAGES 118 | output_debug_message("Initializing SDL_mixer.\n"); 119 | #endif 120 | if (Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_bufsize)) { 121 | sound_enabled=false; 122 | #ifdef __DEBUG_MESSAGES 123 | output_debug_message("Unable to open audio: %s\n", Mix_GetError()); 124 | output_debug_message("Running the game without audio.\n"); 125 | #endif 126 | return -1; 127 | } /* if */ 128 | 129 | SDL_AudioDriverName (SoundcardName, sizeof (SoundcardName)); 130 | Mix_QuerySpec (&audio_rate, &audio_format, &audio_channels); 131 | #ifdef __DEBUG_MESSAGES 132 | output_debug_message(" opened %s at %d Hz %d bit %s, %d bytes audio buffer\n", 133 | SoundcardName, audio_rate, audio_format & 0xFF, 134 | audio_channels > 1 ? "stereo" : "mono", audio_bufsize); 135 | #endif 136 | 137 | MIX_VERSION (&compile_version); 138 | #ifdef __DEBUG_MESSAGES 139 | output_debug_message(" compiled with SDL_mixer version: %d.%d.%d\n", 140 | compile_version.major, 141 | compile_version.minor, 142 | compile_version.patch); 143 | output_debug_message(" running with SDL_mixer version: %d.%d.%d\n", 144 | Mix_Linked_Version()->major, 145 | Mix_Linked_Version()->minor, 146 | Mix_Linked_Version()->patch); 147 | #endif 148 | 149 | if (nc>0) n_channels=Mix_AllocateChannels(nc); 150 | if (nrc>0) Mix_ReserveChannels(nrc); 151 | 152 | Sound_unpause_music(); 153 | 154 | return n_channels; 155 | } /* Resume_playback */ 156 | 157 | 158 | /* a check to see if file is readable and greater than zero */ 159 | int file_check(char *fname) 160 | { 161 | FILE *fp; 162 | 163 | if ((fp=f1open(fname, "r", GAMEDATA))!=NULL) { 164 | if (fseek(fp,0L, SEEK_END)==0 && ftell(fp)>0) { 165 | fclose(fp); 166 | return true; 167 | } /* if */ 168 | /* either the file could not be read (==-1) or size was zero (==0) */ 169 | #ifdef __DEBUG_MESSAGES 170 | output_debug_message("ERROR in file_check(): the file %s is corrupted.\n", fname); 171 | #endif 172 | fclose(fp); 173 | exit(1); 174 | } /* if */ 175 | return false; 176 | } /* file_check */ 177 | 178 | 179 | 180 | SOUNDT Sound_create_sound(char *file) 181 | { 182 | int n_ext=6; 183 | char *ext[6]={".WAV",".OGG",".MP3",".wav",".ogg",".mp3"}; 184 | char name[256]; 185 | int i; 186 | 187 | if (sound_enabled) { 188 | for(i=0;i127) volume=127; 358 | Mix_VolumeMusic(volume); 359 | } /* Sound_music_volume */ 360 | -------------------------------------------------------------------------------- /src/List.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #ifndef GENERIC_LIST 4 | #define GENERIC_LIST 5 | 6 | /* 7 | Funciones para LISTAS: 8 | 9 | void Delete() 10 | void Instance(List &l) 11 | void Rewind(void) 12 | void Forward(void) 13 | void Next(void) 14 | void Prev(void) 15 | T *GetObj(void) 16 | void SetObj(T *o) 17 | LLink *GetPos(void) 18 | bool EmptyP() 19 | bool EndP() 20 | bool LastP() 21 | bool BeginP() 22 | void Insert(T *o) 23 | void Add(T *o) 24 | void AddAfter(LLink *pos,T *o) 25 | void AddBefore(LLink *pos,T *o) 26 | bool Iterate(T *&o) 27 | T *ExtractIni(void) 28 | T *Extract(void) 29 | bool MemberP(T *o) 30 | T *MemberGet(T *o) 31 | bool MemberRefP(T *o) 32 | int Length() 33 | void Copy(List l) 34 | void Synchronize(List *l); 35 | void Append(List l) 36 | bool DeleteElement(T *o) 37 | T *GetRandom(void) 38 | int SearchObjRef(T *o) 39 | int SearchObj(T *o) 40 | void SetNoOriginal(void) 41 | void SetOriginal(void) 42 | void Sort(bool *p(T *o1,T *o2)) 43 | 44 | 45 | bool operator==(List &l) 46 | T *operator[](int index) 47 | */ 48 | 49 | template class LLink { 50 | public: 51 | LLink(T *o,LLink *n=0) { 52 | obj=o;next=n; 53 | }; 54 | ~LLink() {delete obj; 55 | if (next!=0) delete next;}; 56 | inline LLink *Getnext() {return next;}; 57 | inline void Setnext(LLink *n) {next=n;}; 58 | inline T *GetObj() {return obj;}; 59 | inline void SetObj(T *o) {obj=o;}; 60 | 61 | void Anade(T *o) { 62 | if (next==0) { 63 | LLink *node=new LLink(o); 64 | next=node; 65 | } else { 66 | next->Anade(o); 67 | } 68 | }; 69 | 70 | private: 71 | T *obj; 72 | LLink *next; 73 | }; 74 | 75 | template class List { 76 | public: 77 | List() {list=0;act=0;top=0;original=true;}; 78 | ~List() { 79 | if (original) { 80 | T *o; 81 | while(!EmptyP()) { 82 | o=ExtractIni(); 83 | delete o; 84 | } /* while */ 85 | delete list; 86 | } /* if */ 87 | }; 88 | List(List &l) {list=l.list;act=list;top=l.top;original=false;}; 89 | 90 | void Delete() { 91 | if (original) { 92 | T *o; 93 | while(!EmptyP()) { 94 | o=ExtractIni(); 95 | delete o; 96 | } /* while */ 97 | delete list; 98 | } /* if */ 99 | list=0; 100 | act=0; 101 | top=0; 102 | }; 103 | 104 | void Instance(List &l) {list=l.list;act=list;top=l.top;original=false;}; 105 | void Rewind(void) {act=list;}; 106 | void Forward(void) {act=top;}; 107 | void Next(void) { 108 | if (act!=0) act=act->Getnext(); 109 | }; 110 | 111 | void Prev(void) { 112 | LLink *tmp; 113 | 114 | if (act!=list) { 115 | tmp=list; 116 | while(tmp->Getnext()!=act) tmp=tmp->Getnext(); 117 | act=tmp; 118 | } /* if */ 119 | }; 120 | 121 | T *GetObj(void) {return act->GetObj();}; 122 | void SetObj(T *o) {act->SetObj(o);}; 123 | 124 | LLink *GetPos(void) {return act;}; 125 | bool EmptyP() {return list==0;}; 126 | bool EndP() {return act==0;}; 127 | bool LastP() {return act==top;}; 128 | bool BeginP() {return act==list;}; 129 | 130 | void Insert(T *o) { 131 | if (list==0) { 132 | list=new LLink(o); 133 | top=list; 134 | } else { 135 | list=new LLink(o,list); 136 | } /* if */ 137 | }; 138 | 139 | void Add(T *o) { 140 | if (list==0) { 141 | list=new LLink(o); 142 | top=list; 143 | } else { 144 | top->Anade(o); 145 | top=top->Getnext(); 146 | } /* if */ 147 | }; 148 | 149 | void AddAfter(LLink *pos,T *o) 150 | { 151 | if (pos==0) { 152 | if (list==0) { 153 | list=new LLink(o); 154 | top=list; 155 | } else { 156 | list=new LLink(o,list); 157 | } /* if */ 158 | } else { 159 | LLink *nl=new LLink(o); 160 | 161 | nl->Setnext(pos->Getnext()); 162 | pos->Setnext(nl); 163 | if (nl->Getnext()==0) top=nl; 164 | } /* if */ 165 | } /* AddAfter */ 166 | 167 | void AddBefore(LLink *pos,T *o) 168 | { 169 | if (pos==list) { 170 | if (list==0) { 171 | list=new LLink(o); 172 | top=list; 173 | } else { 174 | list=new LLink(o,list); 175 | } /* if */ 176 | } else { 177 | LLink *l,*nl=new LLink(o); 178 | 179 | l=list; 180 | while(l->Getnext()!=pos) l=l->Getnext(); 181 | l->Setnext(nl); 182 | nl->Setnext(pos); 183 | 184 | if (pos==0) top=nl; 185 | } /* if */ 186 | } /* AddBefore */ 187 | 188 | T *operator[](int index) { 189 | LLink *tmp=list; 190 | while(tmp!=0 && index>0) { 191 | tmp=tmp->Getnext(); 192 | index--; 193 | } /* while */ 194 | if (tmp==0) throw; 195 | return tmp->GetObj(); 196 | }; 197 | 198 | bool Iterate(T *&o) { 199 | if (EndP()) return false; 200 | o=act->GetObj(); 201 | act=act->Getnext(); 202 | return true; 203 | } /* Iterate */ 204 | 205 | T *ExtractIni(void) { 206 | LLink *tmp; 207 | T *o; 208 | 209 | if (list==0) return 0; 210 | o=list->GetObj(); 211 | tmp=list; 212 | list=list->Getnext(); 213 | tmp->Setnext(0); 214 | if (act==tmp) act=list; 215 | if (top==act) top=0; 216 | tmp->SetObj(0); 217 | delete tmp; 218 | return o; 219 | } /* ExtractIni */ 220 | 221 | T *Extract(void) { 222 | LLink *tmp,*tmp2=0; 223 | T *o; 224 | 225 | if (list==0) return 0; 226 | tmp=list; 227 | while(tmp->Getnext()!=0) { 228 | tmp2=tmp; 229 | tmp=tmp->Getnext(); 230 | } /* while */ 231 | o=tmp->GetObj(); 232 | if (tmp2==0) { 233 | list=0; 234 | top=0; 235 | act=0; 236 | } else { 237 | tmp2->Setnext(0); 238 | top=tmp2; 239 | } /* if */ 240 | 241 | if (act==tmp) act=top; 242 | tmp->SetObj(0); 243 | delete tmp; 244 | return o; 245 | } /* Extract */ 246 | 247 | bool MemberP(T *o) { 248 | LLink *tmp; 249 | tmp=list; 250 | while(tmp!=0) { 251 | if (*(tmp->GetObj())==*o) return true; 252 | tmp=tmp->Getnext(); 253 | } /* while */ 254 | return false; 255 | } /* MemberP */ 256 | 257 | T *MemberGet(T *o) { 258 | LLink *tmp; 259 | tmp=list; 260 | while(tmp!=0) { 261 | if (*(tmp->GetObj())==*o) return tmp->GetObj(); 262 | tmp=tmp->Getnext(); 263 | } /* while */ 264 | return 0; 265 | } /* MemberGet */ 266 | 267 | bool MemberRefP(T *o) { 268 | LLink *tmp; 269 | tmp=list; 270 | while(tmp!=0) { 271 | if (tmp->GetObj()==o) return true; 272 | tmp=tmp->Getnext(); 273 | } /* while */ 274 | return false; 275 | } /* MemberRefP */ 276 | 277 | int Length() { 278 | LLink *tmp; 279 | int count=0; 280 | 281 | tmp=list; 282 | while(tmp!=0) { 283 | tmp=tmp->Getnext(); 284 | count++; 285 | } /* while */ 286 | return count; 287 | }; 288 | 289 | void Copy(List l) { 290 | List ltmp; 291 | T *o; 292 | Delete(); 293 | original=true; 294 | 295 | ltmp.Instance(l); 296 | ltmp.Rewind(); 297 | while(ltmp.Iterate(o)) { 298 | o=new T(*o); 299 | Add(o); 300 | } /* while */ 301 | Synchronize(&l); 302 | } /* Copy */ 303 | 304 | 305 | void Synchronize(List *l) 306 | { 307 | LLink *ll; 308 | 309 | ll=l->list; 310 | act=list; 311 | while(ll!=0 && ll!=l->act) { 312 | ll=ll->Getnext(); 313 | if (act!=0) act=act->Getnext(); 314 | } /* while */ 315 | } /* Synchronize */ 316 | 317 | 318 | void Append(List l) { 319 | T *o; 320 | 321 | l.Rewind(); 322 | while(l.Iterate(o)) { 323 | o=new T(*o); 324 | Add(o); 325 | } /* while */ 326 | } /* Append */ 327 | 328 | 329 | bool DeleteElement(T *o) 330 | { 331 | LLink *tmp1,*tmp2; 332 | 333 | tmp1=list; 334 | tmp2=0; 335 | while(tmp1!=0 && tmp1->GetObj()!=o) { 336 | tmp2=tmp1; 337 | tmp1=tmp1->Getnext(); 338 | } /* while */ 339 | 340 | if (tmp1!=0) { 341 | if (tmp2==0) { 342 | /* Eliminar el primer elemento de la lista: */ 343 | list=list->Getnext(); 344 | tmp1->Setnext(0); 345 | if (act==tmp1) act=list; 346 | tmp1->SetObj(0); 347 | delete tmp1; 348 | } else { 349 | /* Eliminar un elemento intermedio: */ 350 | tmp2->Setnext(tmp1->Getnext()); 351 | if (act==tmp1) act=tmp1->Getnext(); 352 | if (top==tmp1) top=tmp2; 353 | tmp1->Setnext(0); 354 | tmp1->SetObj(0); 355 | delete tmp1; 356 | } /* if */ 357 | return true; 358 | } else { 359 | return false; 360 | } /* if */ 361 | 362 | } /* DeleteElement */ 363 | 364 | T *GetRandom(void) { 365 | int i,l=Length(); 366 | i=((rand()*l)/RAND_MAX); 367 | if (i==l) i=l-1; 368 | 369 | return operator[](i); 370 | } /* GetRandom */ 371 | 372 | bool operator==(List &l) { 373 | LLink *tmp1,*tmp2; 374 | 375 | tmp1=list; 376 | tmp2=l.list; 377 | while(tmp1!=0 && tmp2!=0) { 378 | if (!((*(tmp1->GetObj()))==(*(tmp2->GetObj())))) return false; 379 | tmp1=tmp1->Getnext(); 380 | tmp2=tmp2->Getnext(); 381 | } /* while */ 382 | return tmp1==tmp2; 383 | } /* == */ 384 | 385 | 386 | int SearchObjRef(T *o) 387 | { 388 | LLink *tmp; 389 | int pos=0; 390 | 391 | tmp=list; 392 | while(tmp!=0) { 393 | if ((tmp->GetObj())==o) return pos; 394 | tmp=tmp->Getnext(); 395 | pos++; 396 | } /* while */ 397 | return -1; 398 | } /* SearchObj */ 399 | 400 | int SearchObj(T *o) 401 | { 402 | LLink *tmp; 403 | int pos=0; 404 | 405 | tmp=list; 406 | while(tmp!=0) { 407 | if (*(tmp->GetObj())==*o) return pos; 408 | tmp=tmp->Getnext(); 409 | pos++; 410 | } /* while */ 411 | return -1; 412 | } /* SearchObj */ 413 | 414 | 415 | void Sort(bool (*p)(T *o1,T *o2)) 416 | { 417 | LLink *l1,*l2; 418 | T* tmp; 419 | 420 | l1=0; 421 | l2=list; 422 | while(l2!=0) { 423 | if (l1!=0 && l2!=0) { 424 | if (!(*p)(l1->GetObj(),l2->GetObj())) { 425 | tmp=l1->GetObj(); 426 | l1->SetObj(l2->GetObj()); 427 | l2->SetObj(tmp); 428 | } /* if */ 429 | } /* if */ 430 | l1=l2; 431 | l2=l2->Getnext(); 432 | } /* while */ 433 | } /* Sort */ 434 | 435 | 436 | void SetNoOriginal(void) {original=false;} 437 | void SetOriginal(void) {original=true;} 438 | 439 | private: 440 | bool original; 441 | LLink *list,*top; 442 | LLink *act; 443 | }; 444 | 445 | 446 | 447 | #endif 448 | 449 | -------------------------------------------------------------------------------- /src/CPlayerCarObject.cpp: -------------------------------------------------------------------------------- 1 | #include "math.h" 2 | #include "stdlib.h" 3 | 4 | #include "SDL.h" 5 | #include "SDL_ttf.h" 6 | #include "SDL_mixer.h" 7 | 8 | #include "sound.h" 9 | 10 | #include "CTile.h" 11 | #include "CObject.h" 12 | #include "CGame.h" 13 | 14 | extern int MIN_SPEED; 15 | extern int MAX_SPEED; 16 | extern int MAX_ACCEL_RATE; 17 | extern int BRAKE_RATE; 18 | extern int BRAKE_RATE_NO_FUEL; 19 | extern int MAX_HSPEED; 20 | extern int BOUNCE_HSPEED; 21 | extern int MAX_FUEL; 22 | extern int FUEL_RECHARGE; 23 | extern int FUEL_LOSS; 24 | 25 | extern int ENEMY_SPEED; 26 | 27 | const int explosion_tiles=1; 28 | 29 | 30 | CPlayerCarObject::CPlayerCarObject(int nx,int ny,List *l,int first_tile,int last_tile,int lk,int rk,int fk,int sc,int init_delay,CGame *g) 31 | { 32 | int i; 33 | ntiles=(last_tile-first_tile)+1; 34 | tiles=new CTile *[(last_tile-first_tile)+1]; 35 | 36 | for(i=0;i<(last_tile-first_tile)+1;i++) tiles[i]=l->operator [](i+first_tile); 37 | 38 | game=g; 39 | tile=car_tile(0); 40 | old_angle=rotating_angle=0; 41 | 42 | x=nx; 43 | y=ny; 44 | constitution=CONSTITUTION_PLAYER|CONSTITUTION_CAR; 45 | 46 | y_speed=0; 47 | y_precision=0; 48 | 49 | x_speed=0; 50 | x_precision=0; 51 | 52 | fuel=int(MAX_FUEL*0.95); 53 | score=sc; 54 | 55 | left_key=lk; 56 | right_key=rk; 57 | fire_key=fk; 58 | 59 | state=0; 60 | state_timmer=init_delay; 61 | blinking_time=init_delay; 62 | 63 | bonus=0; 64 | next_bonus=300; 65 | bonus_timmer=0; 66 | 67 | last_collision=0; 68 | 69 | sound_timmer=0; 70 | 71 | enginesound_channel=-1; 72 | if (game->S_carengine != 0) { 73 | S_carengine_working.allocated=1; 74 | S_carengine_working.abuf=new Uint8[game->S_carengine->alen]; 75 | S_carengine_working.alen=game->S_carengine->alen; 76 | S_carengine_working.volume=MIX_MAX_VOLUME; 77 | } 78 | 79 | skidsound_channel=-1; 80 | if (game->S_carengine != 0) { 81 | S_carskid_working.allocated=1; 82 | S_carskid_working.abuf=new Uint8[game->S_carskid->alen]; 83 | S_carskid_working.alen=game->S_carskid->alen; 84 | S_carskid_working.volume=MIX_MAX_VOLUME; 85 | } 86 | 87 | goal_reached=false; 88 | } /* CPlayerCarObject::CPlayerCarObject */ 89 | 90 | 91 | CPlayerCarObject::~CPlayerCarObject(void) 92 | { 93 | } /* CPlayerCarObject::~CPlayerCarObject */ 94 | 95 | 96 | 97 | bool CPlayerCarObject::cycle(unsigned char *keyboard,unsigned char *old_keyboard) 98 | { 99 | float f=float(-y_speed)/MAX_SPEED; 100 | 101 | if (bonus_timmer>0) bonus_timmer--; 102 | 103 | if (last_collision) { 104 | if (state!=4) { 105 | /* Collision with a car: */ 106 | if (last_collision->get_x()-32) { 131 | score+=(-y_speed)>>10; 132 | 133 | if (goal_reached && y_speed0) { 138 | /* Accelerate/Brake: */ 139 | if (keyboard[fire_key]) { 140 | float f=float(-y_speed)/MAX_SPEED; 141 | y_speed+=int((1.0-f)*MAX_ACCEL_RATE); 142 | } else { 143 | y_speed+=BRAKE_RATE; 144 | } /* if */ 145 | } else { 146 | y_speed+=BRAKE_RATE_NO_FUEL; 147 | } /* if */ 148 | } /* if */ 149 | 150 | 151 | /* Move left/right: */ 152 | if (f<0.1) f=f*2; 153 | else f=(((f-0.1F)/0.9F)*0.8F)+0.2F; 154 | 155 | if (keyboard[left_key]) { 156 | if (!keyboard[right_key] || 157 | !old_keyboard[left_key] || 158 | (x_speed<0 && !old_keyboard[right_key])) { 159 | x_speed=-int(MAX_HSPEED*f); 160 | } /* if */ 161 | } /* if */ 162 | 163 | if (keyboard[right_key]) { 164 | if (!keyboard[left_key] || 165 | !old_keyboard[right_key] || 166 | (x_speed>0 && !old_keyboard[left_key])) { 167 | x_speed=int(MAX_HSPEED*f); 168 | } /* if */ 169 | } /* if */ 170 | 171 | if (!keyboard[right_key] && !keyboard[left_key]) x_speed=0; 172 | 173 | } else { 174 | y_speed+=BRAKE_RATE_NO_FUEL; 175 | } /* if */ 176 | 177 | break; 178 | 179 | case 2: 180 | /* BOUNCING RIGHT: */ 181 | rotating_angle=0; 182 | tile=car_tile(0); 183 | if (y>0) { 184 | score+=(-y_speed)>>10; 185 | 186 | if (fuel>0) { 187 | /* Accelerate/Brake: */ 188 | if (keyboard[fire_key]) { 189 | float f=float(-y_speed)/MAX_SPEED; 190 | y_speed+=int((1.0-f)*MAX_ACCEL_RATE); 191 | } else { 192 | y_speed+=BRAKE_RATE; 193 | } /* if */ 194 | } else { 195 | y_speed+=BRAKE_RATE_NO_FUEL; 196 | } /* if */ 197 | 198 | } else { 199 | y_speed+=BRAKE_RATE_NO_FUEL; 200 | } /* if */ 201 | 202 | x_speed=BOUNCE_HSPEED; 203 | state_timmer++; 204 | if (state_timmer>=10) state=1; 205 | break; 206 | 207 | case 3: 208 | /* BOUNCING LEFT: */ 209 | rotating_angle=0; 210 | tile=car_tile(0); 211 | if (y>0) { 212 | score+=(-y_speed)>>10; 213 | 214 | if (fuel>0) { 215 | /* Accelerate/Brake: */ 216 | if (keyboard[fire_key]) { 217 | float f=float(-y_speed)/MAX_SPEED; 218 | y_speed+=int((1.0-f)*MAX_ACCEL_RATE); 219 | } else { 220 | y_speed+=BRAKE_RATE; 221 | } /* if */ 222 | } else { 223 | y_speed+=BRAKE_RATE_NO_FUEL; 224 | } /* if */ 225 | 226 | } else { 227 | y_speed+=BRAKE_RATE_NO_FUEL; 228 | } /* if */ 229 | 230 | x_speed=-BOUNCE_HSPEED; 231 | state_timmer++; 232 | if (state_timmer>=10) state=1; 233 | break; 234 | 235 | case 4: 236 | if (state_timmer==0) { 237 | CObject *o=new CExplosionObject(x-16,y-32,&game->explosion_tiles,0,11,game); 238 | game->objects.Add(o); 239 | } /* if */ 240 | rotating_angle=0; 241 | next_bonus=300; 242 | x_speed=0; 243 | y_speed=0; 244 | state_timmer++; 245 | tile=ntiles-1; 246 | if (state_timmer>=75) { 247 | blinking_time=32; 248 | tile=car_tile(0); 249 | state=1; 250 | /* Look for the center of the road: */ 251 | if (!game->object_collision(8,0,this,CONSTITUTION_SOLID)!=0) { 252 | int i,j; 253 | bool found=false; 254 | 255 | for(i=4;!found && draw_x+iget_dx();i+=4) { 256 | if (game->object_collision(i,0,this,CONSTITUTION_SOLID)!=0) { 257 | j=x+i; 258 | found=true; 259 | } /* if */ 260 | } /* for */ 261 | if (found) { 262 | draw_x=x=((draw_x+4)+(j-4))/2; 263 | } else { 264 | draw_x=x=(game->get_dx()/2)-16; 265 | } /* if */ 266 | 267 | } else { 268 | if (!game->object_collision(-8,0,this,CONSTITUTION_SOLID)!=0) { 269 | int i,j; 270 | bool found=false; 271 | 272 | for(i=-4;!found && draw_x+i>0;i-=4) { 273 | if (game->object_collision(i,0,this,CONSTITUTION_SOLID)!=0) { 274 | j=x+i; 275 | found=true; 276 | } /* if */ 277 | } /* for */ 278 | if (found) { 279 | draw_x=x=((draw_x-4)+(j+4))/2; 280 | } else { 281 | draw_x=x=(game->get_dx()/2)-16; 282 | } /* if */ 283 | } else { 284 | draw_x=x=(game->get_dx()/2)-8; 285 | } /* if */ 286 | } /* if */ 287 | } /* if */ 288 | break; 289 | 290 | case 5: 291 | /* SLIDDING RIGHT: */ 292 | x_speed=MAX_HSPEED; 293 | if (state_timmer<16) { 294 | if (keyboard[right_key] && !old_keyboard[right_key]) state=1; 295 | rotating_angle=-45; 296 | } else { 297 | if ((-y_speed)<=0.75F*MAX_SPEED) state=1; 298 | else rotating_angle-=10; 299 | } /* if */ 300 | tile=car_tile(rotating_angle); 301 | state_timmer++; 302 | break; 303 | 304 | case 6: 305 | /* SLIDDING LEFT: */ 306 | x_speed=-MAX_HSPEED; 307 | if (state_timmer<16) { 308 | if (keyboard[left_key] && !old_keyboard[left_key]) state=1; 309 | rotating_angle=45; 310 | } else { 311 | if ((-y_speed)<=0.75F*MAX_SPEED) state=1; 312 | else rotating_angle+=10; 313 | } /* if */ 314 | tile=car_tile(rotating_angle); 315 | state_timmer++; 316 | break; 317 | 318 | } /* switch */ 319 | 320 | sound_timmer++; 321 | if (fuel0 && 322 | (sound_timmer%45)==0) { 323 | if (game->S_fuelempty!=0) Sound_play(game->S_fuelempty); 324 | } /* if */ 325 | 326 | if (state!=4 && y>0) { 327 | if (fuel>0 && game->S_carengine!=0) { 328 | if ((sound_timmer&0x07)==0) { 329 | 330 | float f; 331 | unsigned int i,j,k; 332 | Sint16 *ip,*ip2; 333 | /* 334 | // 2 octave range: 0.25 - 1.0 335 | f=(3.0F*(float(-y_speed)/MAX_SPEED)+1.0F)/4.0F; 336 | if (f<0.25F) f=0.25F; 337 | if (f>1.0F) f=1.0F; 338 | */ 339 | /* 340 | // 1 octave range: 0.5 - 1.0 341 | f=((float(-y_speed)/MAX_SPEED)+1.0F)/2.0F; 342 | if (f<0.5F) f=0.5F; 343 | if (f>1.0F) f=1.0F; 344 | */ 345 | 346 | 347 | // 3 tones lower, and end 4 above: 0.8408964 - 1.2599210 348 | f=0.8408964F + (1.259921F-0.8408964F)*(float(-y_speed)/MAX_SPEED); 349 | if (f<0.8408964F) f=0.8408964F; 350 | if (f>1.2599210F) f=1.2599210F; 351 | 352 | 353 | ip=(Sint16 *)S_carengine_working.abuf; 354 | ip2=(Sint16 *)game->S_carengine->abuf; 355 | for(i=0,j=0;iS_carengine->alen && 356 | ((unsigned int)(j*f))*4S_carengine->alen;i+=4,j++) { 357 | k=(unsigned int)(j*f); 358 | if (game->focusing_objects.Length()==1) { 359 | ip[j*2]=ip2[k*2]; /* L */ 360 | ip[j*2+1]=ip2[k*2+1]; /* R */ 361 | } else { 362 | if (game->focusing_objects[0]==this) { 363 | ip[j*2]=0; /* L */ 364 | ip[j*2+1]=(ip2[k*2+1]+ip2[k*2])>>1; /* R */ 365 | } else { 366 | ip[j*2]=(ip2[k*2+1]+ip2[k*2])>>1; /* L */ 367 | ip[j*2+1]=0; /* R */ 368 | } /* if */ 369 | } /* if */ 370 | } /* if */ 371 | 372 | if (enginesound_channel==-1) { 373 | enginesound_channel=Mix_PlayChannel(-1,&S_carengine_working,0); 374 | } else { 375 | Mix_HaltChannel(enginesound_channel); 376 | Mix_PlayChannel(enginesound_channel,&S_carengine_working,0); 377 | } /* if */ 378 | 379 | if (state==5 || state==6) { 380 | float f; 381 | unsigned int i,j,k; 382 | Sint16 *ip,*ip2; 383 | 384 | if (state_timmer<16) { 385 | f=1.0; 386 | } else { 387 | f=1.5; 388 | } /* if */ 389 | 390 | ip=(Sint16 *)S_carskid_working.abuf; 391 | ip2=(Sint16 *)game->S_carskid->abuf; 392 | for(i=0,j=0;iS_carskid->alen && 393 | ((unsigned int)(j*f))*4S_carskid->alen;i+=4,j++) { 394 | k=(unsigned int)(j*f); 395 | ip[j*2]=ip2[k*2]; /* L */ 396 | ip[j*2+1]=ip2[k*2+1]; /* R */ 397 | } /* if */ 398 | 399 | if (skidsound_channel==-1) { 400 | skidsound_channel=Mix_PlayChannel(-1,&S_carskid_working,0); 401 | } else { 402 | Mix_HaltChannel(skidsound_channel); 403 | Mix_PlayChannel(skidsound_channel,&S_carskid_working,0); 404 | } /* if */ 405 | } else { 406 | if (skidsound_channel!=-1) { 407 | Mix_HaltChannel(skidsound_channel); 408 | skidsound_channel=-1; 409 | } /* if */ 410 | } /* if */ 411 | } /* if */ 412 | } /* if */ 413 | } else { 414 | if (enginesound_channel!=-1) { 415 | Mix_HaltChannel(enginesound_channel); 416 | enginesound_channel=-1; 417 | } /* if */ 418 | if (skidsound_channel!=-1) { 419 | Mix_HaltChannel(skidsound_channel); 420 | skidsound_channel=-1; 421 | } /* if */ 422 | } /* if */ 423 | 424 | if (state!=4 && state!=0) { 425 | /* COMMON TO ALL STATES: */ 426 | CObject *o=0; 427 | 428 | if (goal_reached && fuel<=0) fuel=1; 429 | 430 | /* Lose fuel: */ 431 | if (fuel>0 && !goal_reached) { 432 | fuel--; 433 | if (fuel>=MAX_FUEL) fuel=MAX_FUEL; 434 | if (fuel<0) fuel=0; 435 | } /* if */ 436 | 437 | /* Take fuel: */ 438 | o=game->object_collision(0,0,this,CONSTITUTION_FUEL); 439 | if (o!=0) { 440 | fuel+=FUEL_RECHARGE; 441 | if (fuel>=MAX_FUEL) fuel=MAX_FUEL; 442 | game->todelete.Add(o); 443 | bonus=next_bonus; 444 | score+=next_bonus; 445 | bonus_timmer=64; 446 | if (next_bonus==800) next_bonus=1000; 447 | if (next_bonus==500) next_bonus=800; 448 | if (next_bonus==300) next_bonus=500; 449 | if (game->S_takefuel!=0) Sound_play(game->S_takefuel); 450 | } /* if */ 451 | 452 | /* Wall collision: */ 453 | o=game->object_collision(0,0,this,CONSTITUTION_SOLID); 454 | if (o!=0) { 455 | /* CRASH AGAINST A ROAD WALL: */ 456 | if ((-y_speed)>0.75F*MAX_SPEED || 457 | o->constitution_test(CONSTITUTION_CAR)) { 458 | if (fuel>FUEL_LOSS*2) fuel-=FUEL_LOSS; 459 | state=4; 460 | state_timmer=0; 461 | y_speed=0; 462 | x_speed=0; 463 | if (game->S_crash!=0) Sound_play(game->S_crash); 464 | } else { 465 | if (game->object_collision(8,0,this,CONSTITUTION_SOLID)!=0) { 466 | state_timmer=0; 467 | state=3; 468 | if (game->S_collision!=0) Sound_play(game->S_collision); 469 | } else { 470 | if (game->object_collision(-8,0,this,CONSTITUTION_SOLID)!=0) { 471 | state_timmer=0; 472 | state=2; 473 | if (game->S_collision!=0) Sound_play(game->S_collision); 474 | } else { 475 | /* CRASH ???????? */ 476 | state=4; 477 | state_timmer=0; 478 | y_speed=0; 479 | x_speed=0; 480 | if (game->S_crash!=0) Sound_play(game->S_crash); 481 | } /* if */ 482 | } /* if */ 483 | } /* if */ 484 | } else { 485 | /* Car collision: */ 486 | o=game->object_collision(0,0,this,CONSTITUTION_CAR); 487 | if (o!=0) { 488 | CCarObject *co=(CCarObject *)o; 489 | 490 | if (last_collision==0 && game->S_collision!=0) Sound_play(game->S_collision); 491 | 492 | co->car_collision(this); 493 | car_collision(co); 494 | } else { 495 | o=game->object_collision(0,0,this,CONSTITUTION_OIL); 496 | if (o!=0 && (-y_speed)>0.75*MAX_SPEED) { 497 | last_collision=this; 498 | } else { 499 | o=game->object_collision(0,0,this,CONSTITUTION_WATER); 500 | if (o!=0) { 501 | if ((-y_speed)>0.75*MAX_SPEED) { 502 | if (game->S_water!=0) Sound_play(game->S_water); 503 | y_speed=-int(0.5*MAX_SPEED); 504 | } /* if */ 505 | } /* if */ 506 | } /* if */ 507 | } /* if */ 508 | } /* if */ 509 | } /* if */ 510 | 511 | if (blinking_time>0) blinking_time--; 512 | 513 | if (y_speed>-MIN_SPEED) y_speed=-MIN_SPEED; 514 | if (y_speed<-MAX_SPEED) y_speed=-MAX_SPEED; 515 | 516 | /* TYRE MARKS: */ 517 | if (game->game_remake_extras) { 518 | if ((state==5 || state==6) && tile<8) { 519 | int a,b,c,d; 520 | int e,f,g,h; 521 | 522 | tyre_coordinates(rotating_angle,&a,&b,&c,&d); 523 | tyre_coordinates(old_angle,&e,&f,&g,&h); 524 | 525 | /* Create new mark: */ 526 | CTyreMark *r; 527 | 528 | r=new CTyreMark(); 529 | r->x=x+e; 530 | r->y=y+f; 531 | r->x2=compute_next_x()+a; 532 | r->y2=compute_next_y()+b; 533 | if (r->y!=r->y2) game->tyre_marks.Add(r); 534 | else delete r; 535 | 536 | r=new CTyreMark(); 537 | r->x=x+g; 538 | r->y=y+h; 539 | r->x2=compute_next_x()+c; 540 | r->y2=compute_next_y()+d; 541 | if (r->y!=r->y2) game->tyre_marks.Add(r); 542 | else delete r; 543 | 544 | } /* if */ 545 | } /* if */ 546 | 547 | CCarObject::cycle(keyboard,old_keyboard); 548 | 549 | if (y<-33) y=-33; 550 | 551 | old_angle=rotating_angle; 552 | 553 | return true; 554 | } /* CPlayerCarObject::cycle */ 555 | 556 | 557 | void CPlayerCarObject::draw(int sx,int sy,SDL_Surface *screen) 558 | { 559 | draw_x=x; 560 | draw_y=y; 561 | 562 | if (tile>=0 && tile0) { 564 | int f=int(sin(double(blinking_time)/2)*50+50); 565 | tiles[tile]->draw_shaded(x-sx,y-sy,screen,f,-1,-1,-1,0); 566 | } else { 567 | tiles[tile]->draw(x-sx,y-sy,screen); 568 | } /* if */ 569 | } /* if */ 570 | 571 | if (fuel<=0) { 572 | game->extra_tiles[1]->draw((x-sx)+16-game->extra_tiles[1]->get_dx()/2, 573 | (y-sy)-game->extra_tiles[1]->get_dy(), 574 | screen); 575 | } else { 576 | if (bonus>0 && bonus_timmer>0) { 577 | int j=2; 578 | if (bonus==500) j=3; 579 | if (bonus==800) j=4; 580 | if (bonus==1000) j=5; 581 | game->extra_tiles[j]->draw((x-sx)+16-game->extra_tiles[j]->get_dx()/2, 582 | (y-sy)-game->extra_tiles[j]->get_dy(), 583 | screen); 584 | } /* if */ 585 | } /* if */ 586 | 587 | } /* CPlayerCarObject::draw */ 588 | 589 | int CPlayerCarObject::car_tile(int angle) 590 | { 591 | long nt=ntiles-explosion_tiles; 592 | 593 | while(angle<0) angle+=360; 594 | while(angle>=360) angle-=360; 595 | 596 | return (angle*nt)/360; 597 | } /* CPlayerCarObject::car_tile */ 598 | 599 | 600 | void CPlayerCarObject::tyre_coordinates(int angle,int *x1,int *y1,int *x2,int *y2) 601 | { 602 | int x1v[8]={6,16,23,27, 21,16,8,5}; 603 | int y1v[8]={7,3,8,16, 25,25,22,12}; 604 | int x2v[8]={21,27,23,16, 6,5,8,16}; 605 | int y2v[8]={7,12,22,25, 25,16,8,3}; 606 | long nt=ntiles-explosion_tiles; 607 | float tmp; 608 | int tile,tile2; 609 | 610 | while(angle<0) angle+=360; 611 | while(angle>=360) angle-=360; 612 | 613 | tmp=float(float(angle)*float(nt))/360.0F; 614 | tile=int(floor(tmp)); 615 | tmp=tmp-tile; 616 | tile2=(tile+1)%8; 617 | 618 | *x1=int(x1v[tile2]*tmp+x1v[tile]*(1.0-tmp)); 619 | *y1=int(y1v[tile2]*tmp+y1v[tile]*(1.0-tmp)); 620 | *x2=int(x2v[tile2]*tmp+x2v[tile]*(1.0-tmp)); 621 | *y2=int(y2v[tile2]*tmp+y2v[tile]*(1.0-tmp)); 622 | } /* CPlayerCarObject::tyre_coordinates */ 623 | 624 | 625 | void CPlayerCarObject::reach_goal(void) 626 | { 627 | goal_reached=true; 628 | } /* CPlayerCarObject::reach_goal */ 629 | -------------------------------------------------------------------------------- /src/CGame.cpp: -------------------------------------------------------------------------------- 1 | #include "string.h" 2 | #include "stdlib.h" 3 | #include "math.h" 4 | 5 | #include "SDL.h" 6 | #include "SDL_ttf.h" 7 | #include "SDL_image.h" 8 | #include "SDL_mixer.h" 9 | 10 | #include "sound.h" 11 | 12 | #include "CTile.h" 13 | #include "CObject.h" 14 | #include "CGame.h" 15 | 16 | #include "auxiliar.h" 17 | 18 | extern int MAX_SPEED; 19 | int PLAYING_WINDOW=384+64; 20 | int CAR_APPEARING_OFFSET=384+32; 21 | 22 | // Player: 23 | int MIN_SPEED=0; 24 | int MAX_SPEED=(24<<8); 25 | int MAX_ACCEL_RATE=-48; 26 | int BRAKE_RATE=16; 27 | int BRAKE_RATE_NO_FUEL=64; 28 | int MAX_HSPEED=768; 29 | int BOUNCE_HSPEED=880; 30 | int MAX_FUEL=2048; 31 | int FUEL_RECHARGE=384; 32 | int FUEL_LOSS=256; 33 | 34 | // Enemy: 35 | int ENEMY_SPEED=(13<<8); 36 | int ENEMY_HSPEED=416; 37 | int CAR_INTERVAL=38; 38 | 39 | // Obstacles: 40 | int obstacle_chance[4][6]={{-1,-1,25,20,18,15}, 41 | {50,25,20,18,15,12}, 42 | {50,25,20,18,15,12}, 43 | {50,25,20,18,15,12}}; 44 | 45 | int obstacle_oil[4][6]={{50,50,50,50,50,50}, 46 | {50,50,48,47,45,44}, 47 | {48,47,45,43,42,40}, 48 | {48,47,45,43,42,40}}; 49 | 50 | int obstacle_water[4][6]={{50,50,50,50,50,50}, 51 | {50,50,47,46,45,44}, 52 | {47,46,45,42,41,40}, 53 | {47,46,45,42,41,40}}; 54 | 55 | int obstacle_rock[4][6]={{0,0,0,0,0,0}, 56 | {0,0,5,7,10,12}, 57 | {5,7,10,15,17,20}, 58 | {5,7,10,15,17,20}}; 59 | 60 | // Fast cars: 61 | int fastcar_chance[4][6]={{-1,-1,-1,-1,-1,-1}, 62 | {-1,-1,25,23,20,18}, 63 | {40,37,35,33,30,25}, 64 | {40,37,35,33,30,25}}; 65 | 66 | const int fade_time=25; 67 | const int default_start_delay=50; 68 | 69 | 70 | void CGame::init_game(char *mapname) 71 | { 72 | CObject *o; 73 | 74 | game_timmer=0; 75 | game_state=0; 76 | start_delay=default_start_delay; 77 | 78 | if (!load_map(mapname)) throw; 79 | 80 | init_quick_tables(); 81 | 82 | font=TTF_OpenFont("fonts/tanglewo.ttf",16); 83 | 84 | player1_car=IMG_Load("graphics/car1.bmp"); 85 | player2_car=IMG_Load("graphics/car2.bmp"); 86 | 87 | player_tiles.Add(new CTile(0,0,32,32,player1_car,true)); 88 | player_tiles.Add(new CTile(0,32,32,32,player1_car,true)); 89 | player_tiles.Add(new CTile(0,64,32,32,player1_car,true)); 90 | player_tiles.Add(new CTile(0,96,32,32,player1_car,true)); 91 | player_tiles.Add(new CTile(0,128,32,32,player1_car,true)); 92 | player_tiles.Add(new CTile(0,160,32,32,player1_car,true)); 93 | player_tiles.Add(new CTile(0,192,32,32,player1_car,true)); 94 | player_tiles.Add(new CTile(0,224,32,32,player1_car,true)); 95 | player_tiles.Add(new CTile(0,256,32,32,player1_car,true)); 96 | 97 | player_tiles.Add(new CTile(0,0,32,32,player2_car,true)); 98 | player_tiles.Add(new CTile(0,32,32,32,player2_car,true)); 99 | player_tiles.Add(new CTile(0,64,32,32,player2_car,true)); 100 | player_tiles.Add(new CTile(0,96,32,32,player2_car,true)); 101 | player_tiles.Add(new CTile(0,128,32,32,player2_car,true)); 102 | player_tiles.Add(new CTile(0,160,32,32,player2_car,true)); 103 | player_tiles.Add(new CTile(0,192,32,32,player2_car,true)); 104 | player_tiles.Add(new CTile(0,224,32,32,player2_car,true)); 105 | player_tiles.Add(new CTile(0,256,32,32,player2_car,true)); 106 | 107 | enemy_cars=IMG_Load("graphics/enemycars.bmp"); 108 | 109 | enemy_tiles.Add(new CTile(0,0,32,32,enemy_cars,true)); 110 | enemy_tiles.Add(new CTile(0,32,32,32,enemy_cars,true)); 111 | enemy_tiles.Add(new CTile(0,64,32,32,enemy_cars,true)); 112 | enemy_tiles.Add(new CTile(0,96,32,64,enemy_cars,true)); 113 | 114 | fuel_sfc=IMG_Load("graphics/fuel.bmp"); 115 | 116 | 117 | if (start_delay!=default_start_delay) { /* There is a SEMAPHORE */ 118 | o=new CEnemyRacerCarObject((dx/2)-30,dy-176,enemy_tiles[0],start_delay,this); 119 | objects.Add(o); 120 | o=new CEnemyRacerCarObject((dx/2)+14,dy-176,enemy_tiles[0],start_delay,this); 121 | objects.Add(o); 122 | o=new CEnemyRacerCarObject((dx/2)-30,dy-224,enemy_tiles[0],start_delay,this); 123 | objects.Add(o); 124 | o=new CEnemyRacerCarObject((dx/2)+14,dy-224,enemy_tiles[0],start_delay,this); 125 | objects.Add(o); 126 | o=new CEnemyRacerCarObject((dx/2)-30,dy-272,enemy_tiles[0],start_delay,this); 127 | objects.Add(o); 128 | o=new CEnemyRacerCarObject((dx/2)+14,dy-272,enemy_tiles[0],start_delay,this); 129 | objects.Add(o); 130 | o=new CEnemyRacerCarObject((dx/2)-30,dy-320,enemy_tiles[0],start_delay,this); 131 | objects.Add(o); 132 | o=new CEnemyRacerCarObject((dx/2)+14,dy-320,enemy_tiles[0],start_delay,this); 133 | objects.Add(o); 134 | o=new CEnemyRacerCarObject((dx/2)-30,dy-368,enemy_tiles[0],start_delay,this); 135 | objects.Add(o); 136 | o=new CEnemyRacerCarObject((dx/2)+14,dy-368,enemy_tiles[0],start_delay,this); 137 | objects.Add(o); 138 | } /* if */ 139 | 140 | empty_sfc=IMG_Load("graphics/empty.bmp"); 141 | fuelscores_sfc=IMG_Load("graphics/fuel_scores.bmp"); 142 | // start_sfc=IMG_Load("graphics/start.bmp"); 143 | checkpoint_sfc=IMG_Load("graphics/checkpoint.bmp"); 144 | goal_sfc=IMG_Load("graphics/goal.bmp"); 145 | obstacles_sfc=IMG_Load("graphics/obstacles.bmp"); 146 | pause_sfc=IMG_Load("graphics/pause.bmp"); 147 | explosion_sfc=IMG_Load("graphics/explosion.bmp"); 148 | 149 | extra_tiles.Add(new CTile(0,0,32,32,fuel_sfc,true)); /* 0 */ 150 | 151 | extra_tiles.Add(new CTile(0,0,empty_sfc->w/2,empty_sfc->h,empty_sfc,false)); /* 1 */ 152 | extra_tiles.Add(new CTile(0,0,fuelscores_sfc->w/2,fuelscores_sfc->h/4,fuelscores_sfc,false)); 153 | extra_tiles.Add(new CTile(0,fuelscores_sfc->h/4,fuelscores_sfc->w/2,fuelscores_sfc->h/4,fuelscores_sfc,false)); 154 | extra_tiles.Add(new CTile(0,fuelscores_sfc->h/2,fuelscores_sfc->w/2,fuelscores_sfc->h/4,fuelscores_sfc,false)); 155 | extra_tiles.Add(new CTile(0,3*(fuelscores_sfc->h/4),fuelscores_sfc->w/2,fuelscores_sfc->h/4,fuelscores_sfc,false)); 156 | 157 | extra_tiles.Add(new CTile(0,0,obstacles_sfc->w/3,obstacles_sfc->h/3,obstacles_sfc,true)); /* 6 */ 158 | extra_tiles.Add(new CTile(0,(obstacles_sfc->h/3),obstacles_sfc->w/3,obstacles_sfc->h/3,obstacles_sfc,true)); 159 | extra_tiles.Add(new CTile(0,2*(obstacles_sfc->h/3),obstacles_sfc->w/3,obstacles_sfc->h/3,obstacles_sfc,true)); 160 | 161 | extra_tiles.Add(new CTile(0,0,pause_sfc->w/2,pause_sfc->h,pause_sfc,false)); /* 9 */ 162 | 163 | extra_tiles.Add(new CTile(0,0,checkpoint_sfc->w/2,checkpoint_sfc->h,checkpoint_sfc,false)); /* 10 */ 164 | extra_tiles.Add(new CTile(0,0,goal_sfc->w/2,goal_sfc->h,goal_sfc,false)); /* 11 */ 165 | 166 | 167 | explosion_tiles.Add(new CTile(0,0,64,64,explosion_sfc,false)); 168 | explosion_tiles.Add(new CTile(0,64,64,64,explosion_sfc,false)); 169 | explosion_tiles.Add(new CTile(0,128,64,64,explosion_sfc,false)); 170 | explosion_tiles.Add(new CTile(0,192,64,64,explosion_sfc,false)); 171 | explosion_tiles.Add(new CTile(0,256,64,64,explosion_sfc,false)); 172 | explosion_tiles.Add(new CTile(0,320,64,64,explosion_sfc,false)); 173 | explosion_tiles.Add(new CTile(0,384,64,64,explosion_sfc,false)); 174 | explosion_tiles.Add(new CTile(0,448,64,64,explosion_sfc,false)); 175 | explosion_tiles.Add(new CTile(0,512,64,64,explosion_sfc,false)); 176 | explosion_tiles.Add(new CTile(0,576,64,64,explosion_sfc,false)); 177 | explosion_tiles.Add(new CTile(0,640,64,64,explosion_sfc,false)); 178 | explosion_tiles.Add(new CTile(0,704,64,64,explosion_sfc,false)); 179 | 180 | MAX_FUEL=2500; 181 | FUEL_RECHARGE=400; 182 | FUEL_LOSS=225; 183 | CAR_INTERVAL=38; 184 | 185 | if (game_mode==1) { 186 | MAX_FUEL=1800; 187 | FUEL_RECHARGE=300; 188 | FUEL_LOSS=150; 189 | CAR_INTERVAL=24; 190 | } /* if */ 191 | if (game_mode==2) { 192 | MAX_FUEL=1300; 193 | FUEL_RECHARGE=275; 194 | FUEL_LOSS=75; 195 | CAR_INTERVAL=16; 196 | } /* if */ 197 | if (game_mode==3) { 198 | MAX_FUEL=1250; 199 | FUEL_RECHARGE=200; 200 | FUEL_LOSS=100; 201 | CAR_INTERVAL=12; 202 | } /* if */ 203 | 204 | S_takefuel=Sound_create_sound("sound/takefuel"); 205 | S_redlight=Sound_create_sound("sound/redlight"); 206 | S_greenlight=Sound_create_sound("sound/greenlight"); 207 | S_crash=Sound_create_sound("sound/car_crash"); 208 | S_carstart=Sound_create_sound("sound/car_start"); 209 | S_fuelempty=Sound_create_sound("sound/fuelempty"); 210 | S_caradvance=Sound_create_sound("sound/car_pass"); 211 | S_carengine=Sound_create_sound("sound/car_running"); 212 | S_carskid=Sound_create_sound("sound/car_brake"); 213 | S_water=Sound_create_sound("sound/water"); 214 | S_collision=Sound_create_sound("sound/collision"); 215 | S_truck=Sound_create_sound("sound/truck"); 216 | 217 | fastcar_counter=0; 218 | esc_pressed=false; 219 | backspace_pressed=false; 220 | paused=false; 221 | } /* CGame::init_game */ 222 | 223 | 224 | CGame::CGame(char *mapname,int mode,int left_key,int right_key,int fire_key,int score,int cl,bool extras) 225 | { 226 | CObject *o; 227 | 228 | game_mode=mode; 229 | 230 | init_game(mapname); 231 | current_level=cl; 232 | 233 | game_remake_extras=extras; 234 | 235 | if (start_delay!=default_start_delay) { /* There is a SEMAPHORE */ 236 | o=new CEnemyRacerCarObject((dx/2)+14,dy-128,enemy_tiles[0],start_delay,this); 237 | objects.Add(o); 238 | } /* if */ 239 | 240 | o=new CPlayerCarObject((dx/2)-30,dy-128,&player_tiles,0,8, 241 | left_key,right_key,fire_key,score,start_delay+8,this); 242 | objects.Add(o); 243 | focusing_objects.Add(o); 244 | checkpoint_delay.Add(new int(-1)); 245 | focusing_fy.Add(new float(0.66F)); 246 | focusing_next_car.Add(new int(CAR_INTERVAL)); 247 | focusing_next_car_index.Add(new int(0)); 248 | } /* CGame::CGame */ 249 | 250 | 251 | 252 | CGame::CGame(char *mapname,int mode,int left_key1,int right_key1,int fire_key1, 253 | int left_key2,int right_key2,int fire_key2, 254 | int score1,int score2,int cl,bool extras) 255 | { 256 | CObject *o; 257 | 258 | game_mode=mode; 259 | 260 | init_game(mapname); 261 | current_level=cl; 262 | 263 | game_remake_extras=extras; 264 | 265 | o=new CPlayerCarObject((dx/2)-30,dy-128,&player_tiles,0,8, 266 | left_key1,right_key1,fire_key1,score1,start_delay+8,this); 267 | objects.Add(o); 268 | focusing_objects.Add(o); 269 | checkpoint_delay.Add(new int(-1)); 270 | focusing_fy.Add(new float(0.66F)); 271 | focusing_next_car.Add(new int(CAR_INTERVAL)); 272 | focusing_next_car_index.Add(new int(0)); 273 | 274 | o=new CPlayerCarObject((dx/2)+14,dy-128,&player_tiles,9,17, 275 | left_key2,right_key2,fire_key2,score2,start_delay+8,this); 276 | objects.Add(o); 277 | focusing_objects.Add(o); 278 | checkpoint_delay.Add(new int(-1)); 279 | focusing_fy.Add(new float(0.66F)); 280 | focusing_next_car.Add(new int(CAR_INTERVAL)); 281 | focusing_next_car_index.Add(new int(0)); 282 | 283 | } /* CGame::CGame */ 284 | 285 | 286 | CGame::~CGame(void) 287 | { 288 | delete_quick_tables(); 289 | 290 | TTF_CloseFont(font); 291 | 292 | SDL_FreeSurface(player1_car); 293 | SDL_FreeSurface(player2_car); 294 | 295 | SDL_FreeSurface(empty_sfc); 296 | SDL_FreeSurface(fuelscores_sfc); 297 | // SDL_FreeSurface(start_sfc); 298 | SDL_FreeSurface(checkpoint_sfc); 299 | SDL_FreeSurface(goal_sfc); 300 | SDL_FreeSurface(obstacles_sfc); 301 | SDL_FreeSurface(pause_sfc); 302 | 303 | while(!focusing_objects.EmptyP()) focusing_objects.ExtractIni(); 304 | 305 | while(Mix_Playing(-1)!=0); 306 | 307 | Sound_delete_sound(S_takefuel); 308 | Sound_delete_sound(S_redlight); 309 | Sound_delete_sound(S_greenlight); 310 | Sound_delete_sound(S_crash); 311 | Sound_delete_sound(S_carstart); 312 | Sound_delete_sound(S_fuelempty); 313 | Sound_delete_sound(S_caradvance); 314 | Sound_delete_sound(S_carengine); 315 | Sound_delete_sound(S_carskid); 316 | Sound_delete_sound(S_water); 317 | Sound_delete_sound(S_collision); 318 | Sound_delete_sound(S_truck); 319 | } /* CGame::~CGame */ 320 | 321 | 322 | void CGame::get_speeds(List *lr) 323 | { 324 | List l; 325 | CObject *o; 326 | CCarObject *co; 327 | 328 | l.Instance(focusing_objects); 329 | l.Rewind(); 330 | while(l.Iterate(o)) { 331 | co=(CCarObject *)o; 332 | lr->Add(new int(co->get_y_speed())); 333 | } /* while */ 334 | 335 | } /* CGame::get_speeds */ 336 | 337 | 338 | void CGame::get_fuels(List *lr) 339 | { 340 | List l; 341 | CObject *o; 342 | CPlayerCarObject *co; 343 | 344 | l.Instance(focusing_objects); 345 | l.Rewind(); 346 | while(l.Iterate(o)) { 347 | co=(CPlayerCarObject *)o; 348 | lr->Add(new int(co->get_fuel())); 349 | } /* while */ 350 | 351 | } /* CGame::get_fuels */ 352 | 353 | 354 | void CGame::get_positions(List *lr) 355 | { 356 | List l; 357 | CObject *o; 358 | CCarObject *co; 359 | 360 | l.Instance(focusing_objects); 361 | l.Rewind(); 362 | while(l.Iterate(o)) { 363 | float f; 364 | co=(CCarObject *)o; 365 | f=float(co->get_y())/float(dy-48); 366 | if (f<0.0) f=0.0; 367 | if (f>1.0) f=1.0; 368 | lr->Add(new float(f)); 369 | } /* while */ 370 | 371 | } /* CGame::get_positions */ 372 | 373 | 374 | void CGame::get_scores(List *lr) 375 | { 376 | List l; 377 | CObject *o; 378 | CPlayerCarObject *co; 379 | 380 | l.Instance(focusing_objects); 381 | l.Rewind(); 382 | while(l.Iterate(o)) { 383 | co=(CPlayerCarObject *)o; 384 | lr->Add(new int(co->get_score())); 385 | } /* while */ 386 | 387 | } /* CGame::get_scores */ 388 | 389 | 390 | bool CGame::level_completed(void) 391 | { 392 | List l; 393 | CObject *o; 394 | bool completed=false; 395 | 396 | /* Test is level completed: */ 397 | l.Instance(focusing_objects); 398 | l.Rewind(); 399 | while(l.Iterate(o)) { 400 | CPlayerCarObject *cpo=(CPlayerCarObject *)o; 401 | if (o->get_y()>=-32 && cpo->get_fuel()>0) return false; 402 | if (o->get_y()<-32) completed=true; 403 | } /* while */ 404 | 405 | return completed; 406 | } /* CGame::level_completed */ 407 | 408 | 409 | 410 | bool CGame::cycle(unsigned char *keyboard,unsigned char *old_keyboard) 411 | { 412 | List l; 413 | CObject *o; 414 | 415 | if (keyboard[SDLK_F1] && !old_keyboard[SDLK_F1]) { 416 | if (paused) paused=false; 417 | else paused=true; 418 | } /* if */ 419 | 420 | if (paused) return true; 421 | 422 | if (start_delay>0) { 423 | start_delay--; 424 | start_delay2=25; 425 | if (start_delay==0) { 426 | if (S_greenlight!=0) Sound_play(S_greenlight); 427 | start_delay2=25; 428 | } /* if */ 429 | } else { 430 | if (start_delay2>0) { 431 | start_delay2--; 432 | if (start_delay2==0) { 433 | if ((current_level%2)==1) Sound_create_music("sound/game_theme",-1); 434 | else Sound_create_music("sound/game_theme2",-1); 435 | } /* if */ 436 | } /* if */ 437 | } /* if */ 438 | 439 | if (game_state==0 && game_timmer==0) { 440 | if (S_carstart!=0) Sound_play(S_carstart); 441 | } /* if */ 442 | 443 | 444 | if (keyboard[SDLK_ESCAPE] && !old_keyboard[SDLK_ESCAPE] && game_state==0) { 445 | game_state=1; 446 | game_timmer=fade_time; 447 | esc_pressed=true; 448 | } /* if */ 449 | 450 | if (keyboard[SDLK_BACKSPACE] && !old_keyboard[SDLK_BACKSPACE] && game_state==0) { 451 | game_state=1; 452 | game_timmer=fade_time; 453 | backspace_pressed=true; 454 | } /* if */ 455 | 456 | l.Instance(background); 457 | l.Rewind(); 458 | while(l.Iterate(o)) o->cycle(keyboard,old_keyboard); 459 | 460 | l.Instance(middleground); 461 | l.Rewind(); 462 | while(l.Iterate(o)) o->cycle(keyboard,old_keyboard); 463 | 464 | l.Instance(foreground); 465 | l.Rewind(); 466 | while(l.Iterate(o)) o->cycle(keyboard,old_keyboard); 467 | 468 | l.Instance(objects); 469 | l.Rewind(); 470 | while(l.Iterate(o)) { 471 | // if (start_delay==0 && o->get_state()==0) o->set_state(1); 472 | if (!o->cycle(keyboard,old_keyboard)) todelete.Add(o); 473 | } /* while */ 474 | 475 | while(!todelete.EmptyP()) { 476 | o=todelete.ExtractIni(); 477 | objects.DeleteElement(o); 478 | delete o; 479 | o=0; 480 | } /* while */ 481 | 482 | if (game_state==0) game_timmer++; 483 | if (game_state==1) game_timmer--; 484 | 485 | /* Add cars to the race: */ 486 | { 487 | 488 | /* Very simple rule: add a car 512 pixels before each racer (if this new car is */ 489 | /* not very close to another racer): */ 490 | List l; 491 | List l2,l3; 492 | int *ip,*ip2; 493 | CObject *o; 494 | CCarObject *co; 495 | int new_car_y=-1; 496 | 497 | l.Instance(focusing_objects); 498 | l.Rewind(); 499 | l2.Instance(focusing_next_car); 500 | l2.Rewind(); 501 | l3.Instance(focusing_next_car_index); 502 | l3.Rewind(); 503 | while(l.Iterate(o) && l2.Iterate(ip) && l3.Iterate(ip2)) { 504 | 505 | co=(CCarObject *)o; 506 | if ((-co->get_y_speed())>0.8F*MAX_SPEED) *ip=(*ip)-1; 507 | 508 | if ((*ip)<=0) { 509 | new_car_y=o->get_y()-CAR_APPEARING_OFFSET; 510 | if ((first_player(o) || 511 | min_distance_to_other_players(new_car_y,o)>PLAYING_WINDOW) && 512 | min_distance_to_car(new_car_y)>64) { 513 | /* Change this in function of the level: */ 514 | int *pattern; 515 | int pattern1[]={0,1,0,0,0,4, 516 | 0,1,0,0,0,0,0,2,0,1,0,1,0,4, 517 | 0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,4,-1,6}; 518 | int pattern2[]={0,1,0,2,0,0,0,4, 519 | 0,0,2,2,0,2,0,0,0,2,0,4, 520 | 2,2,2,0,0,0,1,0,1,0,0,0,4,-1,8}; 521 | /* gpgbppg tggWggbtggpgg gpgbtggObgpgbppg ... */ 522 | int pattern3[]={0,2,0,1,2,2,0,4, 523 | 3,0,0,0,0,1,3,0,0,2,0,0,4, 524 | 0,2,0,1,3,0,0,1,0,2,0,1,2,2,0,4,-1,8}; 525 | /* gbtggpg tggbtggptgg tgggtggpgggbtggpg ... */ 526 | int pattern4[]={0,1,3,0,0,2,0,4, 527 | 3,0,0,1,3,0,0,2,3,0,0,4, 528 | 3,0,0,0,3,0,0,2,0,0,0,1,3,0,0,2,0,4,-1,8}; 529 | /* tggbppppg pgpgbpptggbtgpptggbppppg ... */ 530 | int pattern5[]={3,0,0,1,2,2,2,2,0,4, 531 | 2,0,2,0,1,2,2,3,0,0,1,3,0,2,2,3,0,0,1,2,2,2,2,0,4,-1,10}; 532 | /* gggpppgpppg tggpppgbtgpptggggggpppgpppg ... */ 533 | int pattern6[]={0,0,0,2,2,2,0,2,2,2,0,4, 534 | 3,0,0,2,2,2,0,1,3,0,2,2,3,0,0,0,0,0,0,2,2,2,0,2,2,2,0,-1,10}; 535 | 536 | pattern=pattern1; 537 | if (current_level==2) pattern=pattern2; 538 | if (current_level==3) pattern=pattern3; 539 | if (current_level==4) pattern=pattern4; 540 | if (current_level==5) pattern=pattern5; 541 | if (current_level==6) pattern=pattern6; 542 | if (pattern[*ip2]==-1) *ip2=pattern[(*ip2)+1]; 543 | 544 | if (pattern[*ip2]==0) add_enemy_car(0,new_car_y); 545 | if (pattern[*ip2]==1) add_enemy_car(1,new_car_y); 546 | if (pattern[*ip2]==2) add_enemy_car(2,new_car_y); 547 | if (pattern[*ip2]==3) add_enemy_car(3,new_car_y); 548 | if (pattern[*ip2]==4) add_enemy_car(4,new_car_y); 549 | 550 | if (obstacle_chance[game_mode][current_level-1]!=-1 && 551 | (rand()%obstacle_chance[game_mode][current_level-1])==0) { 552 | int i=rand()%100; 553 | if (ifastcar_chance[game_mode][current_level-1]) { 568 | fastcar_counter=0; 569 | add_enemy_car(5,o->get_y()+128); 570 | } /* if */ 571 | 572 | if (CAR_INTERVAL==16) { 573 | *ip=CAR_INTERVAL+(rand()%16)-8; 574 | } else if (CAR_INTERVAL==12) { 575 | *ip=CAR_INTERVAL+(rand()%16)-8; 576 | } else { 577 | *ip=CAR_INTERVAL; 578 | } /* if */ 579 | (*ip2)++; 580 | } /* if */ 581 | } /* if */ 582 | } /* while */ 583 | } 584 | 585 | /* Test if all the players are out of fuel: */ 586 | if (game_state==0) { 587 | bool found=false; 588 | l.Instance(focusing_objects); 589 | l.Rewind(); 590 | while(l.Iterate(o)) { 591 | CPlayerCarObject *pco=(CPlayerCarObject *)o; 592 | if (pco->get_fuel()>0 || pco->get_y_speed()!=0) found=true; 593 | } /* while */ 594 | 595 | if (!found) { 596 | /* All out of fuel: */ 597 | game_state=1; 598 | game_timmer=fade_time*2; 599 | } /* if */ 600 | } 601 | 602 | /* Test if level completed: */ 603 | if (game_state==0 && level_completed()) { 604 | game_state=1; 605 | game_timmer=fade_time*4; 606 | } /* if */ 607 | 608 | if (game_state==1 && game_timmer<0) return false; 609 | return true; 610 | } /* CGame::cycle */ 611 | 612 | 613 | void CGame::draw(SDL_Surface *sfc,SDL_Rect vp) 614 | { 615 | if (focusing_objects.Length()>0) { 616 | SDL_Rect vp2; 617 | int dx; 618 | List l; 619 | CObject *o; 620 | List l2; 621 | List l3; 622 | float *fy; 623 | int *cp_delay; 624 | 625 | dx=vp.w/focusing_objects.Length(); 626 | vp2.x=vp.x+(focusing_objects.Length()-1)*dx; 627 | vp2.y=vp.y; 628 | if (focusing_objects.Length()>1) vp2.w=dx-1; 629 | else vp2.w=dx; 630 | vp2.h=vp.h; 631 | 632 | l.Instance(focusing_objects); 633 | l2.Instance(focusing_fy); 634 | l3.Instance(checkpoint_delay); 635 | l.Rewind(); 636 | l2.Rewind(); 637 | l3.Rewind(); 638 | while(l.Iterate(o) && l2.Iterate(fy) && l3.Iterate(cp_delay)) { 639 | /* draw a viewport: */ 640 | draw(sfc,vp2,(CCarObject *)o,fy,cp_delay); 641 | vp2.x-=dx; 642 | } /* while */ 643 | 644 | } /* if */ 645 | 646 | { 647 | float f=float(game_timmer)/float(fade_time); 648 | if (f<0) f=0; 649 | if (f>=1.0) f=1.0; 650 | if (f<1.0) surface_fader(sfc,f,f,f,&vp); 651 | } 652 | 653 | if (paused) { 654 | surface_fader(sfc,0.5F,0.5F,0.5F,&vp); 655 | extra_tiles[9]->draw(vp.x+vp.w/2-extra_tiles[9]->get_dx()/2,vp.y+vp.h/2-64,sfc); 656 | } /* if */ 657 | 658 | } /* CGame::draw */ 659 | 660 | 661 | void CGame::draw(SDL_Surface *sfc,SDL_Rect logic_vp,CCarObject *focusing,float *fy,int *cp_delay) 662 | { 663 | List l; 664 | CObject *o; 665 | int sx,sy; 666 | float f=0.0; 667 | SDL_Rect vp=logic_vp; 668 | 669 | { 670 | f=float(-focusing->get_y_speed())/MAX_SPEED; 671 | f=0.66F + (0.85F-0.66F)*f; 672 | *fy=(2*(*fy)+f)/3; 673 | } 674 | 675 | sx=focusing->get_x()-vp.w/2; 676 | sy=int(focusing->get_y()-vp.h*(*fy)); 677 | if (sx+vp.w>dx) sx=dx-vp.w; 678 | if (sy+vp.h>dy) sy=dy-vp.h; 679 | if (sx<0) sx=0; 680 | if (sy<0) sy=0; 681 | if (vp.w>dx) { 682 | vp.x=logic_vp.x+vp.w-dx; 683 | vp.w=dx; 684 | } /* if */ 685 | sx-=vp.x; 686 | sy-=vp.y; 687 | SDL_SetClipRect(sfc,&vp); 688 | 689 | if (game_remake_extras && current_level==3) { 690 | /* 128-96 */ 691 | /* Water animation for level 3: */ 692 | List l; 693 | CTile *t; 694 | 695 | l.Instance(tiles[3]); 696 | l.Rewind(); 697 | while(l.Iterate(t)) { 698 | if (t->r.x==0 && t->r.y==0 && t->r.w==128 && t->r.h==96) { 699 | SDL_Surface *tmp=SDL_CreateRGBSurface(0,128,96,32,0,0,0,0); 700 | SDL_Rect r1,r2; 701 | r1.x=0; 702 | r1.y=0; 703 | r1.w=128; 704 | r1.h=96; 705 | r2.x=0; 706 | r2.y=0; 707 | r2.w=128; 708 | r2.h=96; 709 | SDL_BlitSurface(t->orig,&r1,tmp,&r2); 710 | r1.x=1; 711 | r1.w=127; 712 | SDL_BlitSurface(tmp,&r1,t->orig,&r2); 713 | r1.x=0; 714 | r1.w=1; 715 | r2.x=127; 716 | SDL_BlitSurface(tmp,&r1,t->orig,&r2); 717 | SDL_FreeSurface(tmp); 718 | } /* if */ 719 | } /* if */ 720 | } /* if */ 721 | 722 | { 723 | int i; 724 | int min=0,max=0; 725 | 726 | get_quick_min_max(sy+vp.y,sy+vp.y+vp.h,&min,&max); 727 | 728 | for(i=min;i<=max;i++) { 729 | l.Instance(quick_background[i]); 730 | l.Rewind(); 731 | while(l.Iterate(o)) o->draw(sx,sy,sfc); 732 | } /* for */ 733 | 734 | for(i=min;i<=max;i++) { 735 | l.Instance(quick_middleground[i]); 736 | l.Rewind(); 737 | while(l.Iterate(o)) o->draw(sx,sy,sfc); 738 | } /* for */ 739 | 740 | 741 | /* TYRE MARKS: */ 742 | if (game_remake_extras) { 743 | List l; 744 | CTyreMark *r; 745 | 746 | l.Instance(tyre_marks); 747 | l.Rewind(); 748 | while(l.Iterate(r)) { 749 | draw_line(sfc,r->x-sx,r->y-sy,r->x2-sx,r->y2-sy,0); 750 | draw_line(sfc,r->x+1-sx,r->y-sy,r->x2+1-sx,r->y2-sy,0); 751 | } /* if */ 752 | } /* if */ 753 | 754 | l.Instance(objects); 755 | l.Rewind(); 756 | while(l.Iterate(o)) o->draw(sx,sy,sfc); 757 | 758 | 759 | for(i=min;i<=max;i++) { 760 | l.Instance(quick_foreground[i]); 761 | l.Rewind(); 762 | while(l.Iterate(o)) o->draw(sx,sy,sfc); 763 | } /* for */ 764 | } 765 | 766 | /* Draw overlays: */ 767 | if (focusing->get_y()<384) { 768 | (*cp_delay)++; 769 | ((CPlayerCarObject *)focusing)->reach_goal(); 770 | } /* if */ 771 | 772 | if ((*cp_delay)>=0) { 773 | int i; 774 | int x1,x2; 775 | CTile *tile=0; 776 | 777 | if (current_level==6) tile=extra_tiles[11]; 778 | else tile=extra_tiles[10]; 779 | 780 | if (vp.w>=tile->get_dx()) { 781 | int amp; 782 | int offs; 783 | 784 | amp=*cp_delay; 785 | if (amp<0) amp=0; 786 | if (amp>128) amp=128; 787 | amp=int((128-amp)*(128-amp)/128); 788 | if (amp<0) amp=0; 789 | 790 | offs=int(cos(float((*cp_delay)*(*cp_delay))/500.0)*amp); 791 | if (offs<0) offs=-offs; 792 | 793 | tile->draw(vp.x+(vp.w/2)-(tile->get_dx()/2),vp.y+64-offs,sfc); 794 | } else { 795 | x1=-tile->get_dx(); 796 | x2=(vp.w-tile->get_dx())/2; 797 | i=*cp_delay; 798 | 799 | tile->draw(vp.x+x1+((x2-x1)/32)*i,vp.y+32,sfc); 800 | } /* if */ 801 | 802 | } /* if */ 803 | 804 | 805 | 806 | SDL_SetClipRect(sfc,0); 807 | 808 | } /* CGame::draw */ 809 | 810 | 811 | CObject *CGame::object_collision(int xoffs,int yoffs,CObject *o,int constitution) 812 | { 813 | List l; 814 | CObject *o2; 815 | 816 | if ((constitution&CONSTITUTION_SOLID)!=0) { 817 | int i; 818 | int min=0,max=0; 819 | 820 | get_quick_min_max(o,yoffs,&min,&max); 821 | 822 | for(i=min;i<=max;i++) { 823 | l.Instance(quick_background[i]); 824 | l.Rewind(); 825 | while(l.Iterate(o2)) 826 | if (o2->collision(xoffs,yoffs,o)) return o2; 827 | 828 | l.Instance(quick_middleground[i]); 829 | l.Rewind(); 830 | while(l.Iterate(o2)) 831 | if (o2->collision(xoffs,yoffs,o)) return o2; 832 | 833 | l.Instance(quick_foreground[i]); 834 | l.Rewind(); 835 | while(l.Iterate(o2)) 836 | if (o2->collision(xoffs,yoffs,o)) return o2; 837 | } /* for */ 838 | 839 | } /* if */ 840 | 841 | 842 | l.Instance(objects); 843 | l.Rewind(); 844 | while(l.Iterate(o2)) if (o2!=o && 845 | o2->constitution_test(constitution) && 846 | o2->collision(xoffs,yoffs,o)) return o2; 847 | 848 | return 0; 849 | } /* CGame::object_collision */ 850 | 851 | 852 | CObject *CGame::add_enemy_car(int type,long y) 853 | { 854 | CObject *o=0; 855 | int i,j; 856 | int left=0,right=dx; 857 | bool coll,last_coll; 858 | 859 | if (type==0) o=(CObject *)new CEnemyNormalCarObject(0,y,enemy_tiles[1],0,this); 860 | if (type==1) o=(CObject *)new CEnemyRacerCarObject(0,y,enemy_tiles[0],0,this); 861 | if (type==2) o=(CObject *)new CEnemySlidderCarObject(0,y,enemy_tiles[2],0,this); 862 | if (type==3) o=(CObject *)new CEnemyTruckObject(0,y,enemy_tiles[3],0,this); 863 | if (type==4) o=(CObject *)new CFuelObject(0,y,extra_tiles[0],this); 864 | if (type==5) o=(CObject *)new CEnemyFastCarObject(0,y,enemy_tiles[0],0,this); 865 | 866 | if (o==0) return 0; 867 | 868 | /* Find a proper 'x': */ 869 | coll=last_coll=false; 870 | for(i=0,j=0;iright) { 886 | delete o; 887 | return 0; 888 | } /* if */ 889 | 890 | if (type==0 || 891 | type==1 || 892 | type==2 || 893 | type==5) { 894 | CEnemyCarObject *po=(CEnemyCarObject *)o; 895 | po->x=int(left+8+(rand()%(right-left-16))); 896 | if (abs(po->x-left)x-right)) { 897 | po->following_right_border=false; 898 | po->distance_to_border=(po->x-left); 899 | } else { 900 | po->following_right_border=true; 901 | po->distance_to_border=(right-po->x); 902 | } /* if */ 903 | } /* if */ 904 | if (type==3) o->x=int(left+8+(rand()%(right-left-16))); 905 | if (type==4) o->x=(left+right)/2; 906 | 907 | objects.Insert(o); 908 | 909 | return o; 910 | } /* CGame::add_enemy_car */ 911 | 912 | 913 | CObject *CGame::add_obstacle(int type,long y) 914 | { 915 | CObject *o=0; 916 | int i,j; 917 | int left=0,right=dx; 918 | bool coll,last_coll; 919 | 920 | if (type==0) o=(CObject *)new CObject(0,y,extra_tiles[6],CONSTITUTION_OIL,this); 921 | if (type==1) o=(CObject *)new CObject(0,y,extra_tiles[7],CONSTITUTION_WATER,this); 922 | if (type==2) o=(CObject *)new CObject(0,y,extra_tiles[8],CONSTITUTION_SOLID,this); 923 | 924 | if (o==0) return 0; 925 | 926 | /* Find a proper 'x': */ 927 | coll=last_coll=false; 928 | for(i=0,j=0;ix=int(left+8+(rand()%(right-left-16))); 950 | objects.Insert(o); 951 | 952 | return o; 953 | } /* CGame::add_obstacle */ 954 | 955 | 956 | long CGame::min_distance_to_players(long y) 957 | { 958 | /* Compute de distance to the closest player: */ 959 | List l; 960 | CObject *o; 961 | long mindistance=PLAYING_WINDOW*2,distance; 962 | 963 | l.Instance(focusing_objects); 964 | l.Rewind(); 965 | while(l.Iterate(o)) { 966 | distance=abs(o->get_y()-y); 967 | if (mindistance>distance) mindistance=distance; 968 | } /* while */ 969 | 970 | return mindistance; 971 | } /* CGAme::min_distance_to_players */ 972 | 973 | 974 | long CGame::min_distance_to_other_players(long y,CObject *player) 975 | { 976 | /* Compute de distance to the closest player: */ 977 | List l; 978 | CObject *o; 979 | long mindistance=PLAYING_WINDOW*2,distance; 980 | 981 | l.Instance(focusing_objects); 982 | l.Rewind(); 983 | while(l.Iterate(o)) { 984 | if (o!=player) { 985 | distance=abs(o->get_y()-y); 986 | if (mindistance>distance) mindistance=distance; 987 | } /* if */ 988 | } /* while */ 989 | 990 | return mindistance; 991 | } /* CGAme::min_distance_to_other_players */ 992 | 993 | 994 | long CGame::min_distance_to_car(long y) 995 | { 996 | /* Compute de distance to the closest car: */ 997 | List l; 998 | CObject *o; 999 | long mindistance=PLAYING_WINDOW*2,distance; 1000 | 1001 | l.Instance(objects); 1002 | l.Rewind(); 1003 | while(l.Iterate(o)) { 1004 | distance=abs(o->get_y()-y); 1005 | if (mindistance l; 1015 | CObject *o,*first_player=0; 1016 | 1017 | l.Instance(focusing_objects); 1018 | l.Rewind(); 1019 | while(l.Iterate(o)) { 1020 | if (first_player==0 || o->get_y()get_y()) first_player=o; 1021 | } /* while */ 1022 | 1023 | if (first_player==player) return true; 1024 | 1025 | return false; 1026 | } /* CGame::first_player */ 1027 | 1028 | 1029 | CObject *CGame::find_closest_player(long x,long y) 1030 | { 1031 | /* Compute de distance to the further player: */ 1032 | List l; 1033 | CObject *o; 1034 | long mindistance=0,distance; 1035 | CObject *closest=0; 1036 | 1037 | l.Instance(focusing_objects); 1038 | l.Rewind(); 1039 | while(l.Iterate(o)) { 1040 | distance=abs(o->get_y()-y)+abs(o->get_x()-x); 1041 | if (closest==0 || distance