diff --git a/README.md b/README.md index d8c60c8..bf5e67b 100644 --- a/README.md +++ b/README.md @@ -1,75 +1,90 @@ -BlockoFighter -============= +# BlockoFighter -A 3D two-player arena combat game, featuring characters similar to a popular construction toy. +A 3D two-player arena combat game, featuring characters similar to a popular +construction toy. -![ScreenShot1](screens/screenshot1.jpg) ![ScreenShot2](screens/screenshot2.jpg) ![ScreenShot3](screens/screenshot3.jpg) +![ScreenShot1](screens/screenshot1.jpg) ![ScreenShot2](screens/screenshot2.jpg) +![ScreenShot3](screens/screenshot3.jpg) -About ------ +## About -BlockoFighter is a humorous beat-em-up game which originally started as a school project during a course in computer graphics. The first version called LegoFighter was finished under Christmas 2001 and now, after many months of work and idle time, we are finally presenting BlockoFighter - the second version of the game. +BlockoFighter is a humorous beat-em-up game which originally started as a school +project during a course in computer graphics. The first version called +LegoFighter was finished under Christmas 2001 and now, after many months of work +and idle time, we are finally presenting BlockoFighter - the second version of +the game. -The game has been completely rewritten and there are many improvements which include sound effects and music, a full 3D arena and a nice physics engine. The backbones for the game are OpenGL and SDL. +The game has been completely rewritten and there are many improvements which +include sound effects and music, a full 3D arena and a nice physics engine. The +backbones for the game are OpenGL and SDL. -This version of the game was made as an entry for the game development competition at the Assembly 2002 demo party. It placed third (kudos to the winner, Stair Dismount ;) +This version of the game was made as an entry for the game development +competition at the Assembly 2002 demo party. It placed third (kudos to the +winner, Stair Dismount ;) -Blockofighter is a two-player game where two Blocko men (they may look like LEGO characters but they are not) encounter in a fierce battle which occurs in a rectangular arena located in the spectacular fjords of scenic Lapland. The fighting is so intense that severed limbs or heads are not a rare sight. Furious breakdancing moves are available for skilled players who want to fight with style. West side! +Blockofighter is a two-player game where two Blocko men (they may look like LEGO +characters but they are not) encounter in a fierce battle which occurs in a +rectangular arena located in the spectacular fjords of scenic Lapland. The +fighting is so intense that severed limbs or heads are not a rare sight. Furious +breakdancing moves are available for skilled players who want to fight with +style. West side! -How to play ------------ +## How to play Use arrows, enter and esc to navigate in menus. -| Action | Player 1 | Player 2 | -|:---------------|:-------------:|:------------:| -| Move forward | Up arrow | E | -| Move backward | Down arrow | D | -| Turn left | Left arrow | S | -| Turn right | Right arrow | F | -| Jump | ¨ or ] | Q | -| Hit | ' or \ | A | +| Action | Player 1 | Player 2 | +| :------------ | :---------: | :------: | +| Move forward | Up arrow | E | +| Move backward | Down arrow | D | +| Turn left | Left arrow | S | +| Turn right | Right arrow | F | +| Jump | ¨ or ] | Q | +| Hit | ' or \ | A | -Requirements ------------- +## Requirements Minimal system requirements are: -* Windows or GNU/Linux operating system -* OpenGL 2.0 (or better) compatible graphics card, with at least 64MB graphical memory -* At least 1GHz CPU -* At least 512MB RAM +- Windows or GNU/Linux operating system +- OpenGL 2.0 (or better) compatible graphics card, with at least 64MB graphical + memory +- At least 1GHz CPU +- At least 512MB RAM Software dependencies are: -* [SDL 1.2](http://www.libsdl.org/) -* [SDL_Image 1.2](http://www.libsdl.org/) -* [FMOD](http://www.fmod.org) +- [SDL 2.0](http://www.libsdl.org/) +- [SDL_image 2.0](http://www.libsdl.org/) +- [SDL_mixer 2.0](http://www.libsdl.org/) -Compiling ---------- +## Compiling -Use the provided Makefile (altering it if necessary), and build the game using the `make` command. You can then run the program using the compiled executable, from the main project directory. +Use the provided Makefile (altering it if necessary), and build the game using +the `make` command. You can then run the program using the compiled executable, +from the main project directory. -Credits -------- +## Credits -* Miika Sell - Original source code -* Juha Kaarlas - Original source code -* [Michaël Lemaire](http://thunderk.net) - Current maintainer -* Osmand - Music -* Forge - Sound effects +- Miika Sell - Original source code +- Juha Kaarlas - Original source code +- [Michaël Lemaire](http://thunderk.net) - Current maintainer +- Osmand - Music +- Forge - Sound effects -Links ------ +## Links The project is hosted on [GitHub](https://github.com/thunderk/blockofighter). -The original demoscene release is presented on [pouët.net](http://www.pouet.net/prod.php?which=7195). +The original demoscene release is presented on +[pouët.net](http://www.pouet.net/prod.php?which=7195). -License -------- +## License -This source code is available under the terms of the [Mozilla Public License](http://www.mozilla.org/MPL/2.0/). Read the full license terms in the LICENSE file. +This source code is available under the terms of the +[Mozilla Public License](http://www.mozilla.org/MPL/2.0/). Read the full license +terms in the LICENSE file. -LEGO® is a trademark of the LEGO Group of companies which does not sponsor, authorize or endorse this program. Any resemblance with LEGO® bricks is purely coincidental or made as a tribute, with no commercial claim whatsoever. +LEGO® is a trademark of the LEGO Group of companies which does not sponsor, +authorize or endorse this program. Any resemblance with LEGO® bricks is purely +coincidental or made as a tribute, with no commercial claim whatsoever. diff --git a/src/audio.cpp b/src/audio.cpp index 623b0c3..d518613 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -2,6 +2,7 @@ #include #include +#include #include "audio.h" @@ -15,6 +16,7 @@ struct soundlist { }; soundlist *allsounds = NULL; +Sound *current_music = NULL; Sound::Sound(Sound *source) { memcpy(this, source, sizeof(Sound)); @@ -56,46 +58,29 @@ bool endsWith(char *str1, char *str2) { void Sound::load(char *filename, int type, bool loops) { this->filename = filename; if (type == SOUNDTYPE_AUTODETECT) { - if (endsWith(filename, "mp3") || endsWith(filename, "mp2") || - endsWith(filename, "ogg")) + if (endsWith(filename, "mp3") || endsWith(filename, "ogg")) type = SOUNDTYPE_STREAM; if (endsWith(filename, "wav") || endsWith(filename, "raw")) type = SOUNDTYPE_SAMPLE; + } - if (endsWith(filename, "s3m") || endsWith(filename, "xm") || - endsWith(filename, "it") || endsWith(filename, "mid") || - endsWith(filename, "rmi") || endsWith(filename, "sgr") || - endsWith(filename, "mod")) - type = SOUNDTYPE_MODULE; - } -#ifdef AUDIO_FMOD - sample = NULL; - module = NULL; - stream = NULL; - this->type = type; - if (type == SOUNDTYPE_MODULE) { - module = FMUSIC_LoadSong(filename); - this->loops = false; - } else if (type == SOUNDTYPE_SAMPLE) { - if (loops) { - sample = - FSOUND_Sample_Load(FSOUND_FREE, filename, FSOUND_LOOP_NORMAL, 0, 0); - FSOUND_Sample_SetMode(sample, FSOUND_LOOP_NORMAL); + this->chunk = NULL; + this->music = NULL; + if (type == SOUNDTYPE_SAMPLE) { + this->chunk = Mix_LoadWAV(filename); + if (this->chunk) { } else { - sample = FSOUND_Sample_Load(FSOUND_FREE, filename, FSOUND_LOOP_OFF, 0, 0); - FSOUND_Sample_SetMode(sample, FSOUND_LOOP_OFF); + printf("Error while loading sample %s: %s\n", filename, Mix_GetError()); } - this->loops = loops; } else if (type == SOUNDTYPE_STREAM) { - if (loops) { - stream = FSOUND_Stream_Open(filename, FSOUND_LOOP_NORMAL, 0, 0); - } else { - stream = FSOUND_Stream_Open(filename, FSOUND_LOOP_OFF, 0, 0); + this->music = Mix_LoadMUS(filename); + if (!this->music) { + printf("Error while loading music %s: %s\n", filename, Mix_GetError()); } - this->loops = loops; } -#endif + + this->loops = loops; stopcallback = NULL; soundlist *node = new soundlist; node->sound = this; @@ -114,22 +99,22 @@ bool Sound::play() { finished = false; fademode = SOUND_FADENONE; minduration = 0; -#ifdef AUDIO_FMOD - if (type == SOUNDTYPE_MODULE) { - FMUSIC_PlaySong(module); - FMUSIC_SetMasterVolume(module, (int)(volume * 256)); - } else if (type == SOUNDTYPE_SAMPLE) { - channel = FSOUND_PlaySound(FSOUND_FREE, sample); + if (chunk) { + channel = -1; + /*channel = FSOUND_PlaySound(FSOUND_FREE, sample); FSOUND_SetVolume(channel, (int)(volume * 256)); if (!loops) { running = false; finished = false; + }*/ + } else if (music) { + if (Mix_PlayMusic(music, loops)) { + printf("Failed to play music\n"); + } else { + current_music = this; } - } else if (type == SOUNDTYPE_STREAM) { - channel = FSOUND_Stream_Play(FSOUND_FREE, stream); - FSOUND_SetVolume(channel, (int)(volume * 256)); + Mix_VolumeMusic((int)(volume * MIX_MAX_VOLUME)); } -#endif // printf("Done: %f\n", volume); return true; } @@ -140,50 +125,34 @@ void Sound::play(int minduration) { } void Sound::stop() { -#ifdef AUDIO_FMOD - if (type == SOUNDTYPE_MODULE) { - FMUSIC_StopSong(module); - } else if (type == SOUNDTYPE_SAMPLE) { - FSOUND_StopSound(channel); - } else if (type == SOUNDTYPE_STREAM) { - FSOUND_Stream_Stop(stream); + if (chunk && channel >= 0) { + Mix_HaltChannel(channel); + } else if (music && current_music == this) { + // FIXME only if it is THIS music playing + Mix_HaltMusic(); } -#endif } void Sound::setVolume(float volume) { -#ifdef AUDIO_FMOD - if (type == SOUNDTYPE_MODULE) { - FMUSIC_SetMasterVolume(module, (int)(volume * 256)); - } else if (type == SOUNDTYPE_SAMPLE) { - FSOUND_SetVolume(channel, (int)(volume * 256)); - } else if (type == SOUNDTYPE_STREAM) { - FSOUND_SetVolume(channel, (int)(volume * 256)); + if (chunk && channel >= 0) { + Mix_Volume(channel, (int)(volume * MIX_MAX_VOLUME)); + } else if (music && current_music == this) { + Mix_VolumeMusic((int)(volume * MIX_MAX_VOLUME)); } -#endif this->volume = volume; } -#ifdef AUDIO_FMOD -signed char streamendcallback(FSOUND_STREAM *stream, void *buff, int len, - int param) { - Sound *sound = (Sound *)param; +void streamendcallback(Sound* sound) { sound->setFinished(); - return true; } -#endif void Sound::setStopCallback(STOPCALLBACK callback) { stopcallback = callback; -#ifdef AUDIO_FMOD - if (type == SOUNDTYPE_MODULE) { - } else if (type == SOUNDTYPE_SAMPLE) { + if (chunk && channel >= 0) { // NOT SUPPORTED - } else if (type == SOUNDTYPE_STREAM) { - // FSOUND_Stream_SetEndCallback(stream, - // (FSOUND_STREAMCALLBACK)streamendcallback, (int)this); + } else if (music) { + //Mix_HookMusicFinished(std::bind(callback, this)); } -#endif } void Sound::setFinished(void) { finished = true; } @@ -249,15 +218,13 @@ void Sound::fadeOut(int length) { } void initAudio(void) { -#ifdef AUDIO_FMOD - FSOUND_Init(44100, 32, 0); -#endif + Mix_Init(MIX_INIT_MP3 | MIX_INIT_OGG); + Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024); } void uninitAudio(void) { -#ifdef AUDIO_FMOD - FSOUND_Close(); -#endif + Mix_CloseAudio(); + Mix_Quit(); } void updateAudio(void) { diff --git a/src/audio.h b/src/audio.h index b57bdf3..f73e1b1 100644 --- a/src/audio.h +++ b/src/audio.h @@ -1,30 +1,24 @@ #ifndef __AUDIO_H_INCLUDED__ #define __AUDIO_H_INCLUDED__ -#ifdef AUDIO_FMOD -#include -#endif +#include "SDL_mixer.h" class Sound; typedef void (*STOPCALLBACK)(Sound *sound); #define SOUNDTYPE_AUTODETECT 0 -#define SOUNDTYPE_MODULE 1 -#define SOUNDTYPE_STREAM 2 -#define SOUNDTYPE_SAMPLE 3 +#define SOUNDTYPE_STREAM 1 +#define SOUNDTYPE_SAMPLE 2 #define BGSONG DATAPATH "boom.mp3" class Sound { private: -#ifdef AUDIO_FMOD - int type; - FMUSIC_MODULE *module; - FSOUND_STREAM *stream; - FSOUND_SAMPLE *sample; + Mix_Chunk *chunk; + Mix_Music *music; int channel; -#endif + bool loops; bool finished; bool running;