1
0
Fork 0

Restored music playing

This commit is contained in:
Michaël Lemaire 2021-06-10 20:06:20 +02:00
parent 03b74c0dd0
commit 0546de832d
3 changed files with 109 additions and 133 deletions

107
README.md
View file

@ -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. Use arrows, enter and esc to navigate in menus.
| Action | Player 1 | Player 2 | | Action | Player 1 | Player 2 |
|:---------------|:-------------:|:------------:| | :------------ | :---------: | :------: |
| Move forward | Up arrow | E | | Move forward | Up arrow | E |
| Move backward | Down arrow | D | | Move backward | Down arrow | D |
| Turn left | Left arrow | S | | Turn left | Left arrow | S |
| Turn right | Right arrow | F | | Turn right | Right arrow | F |
| Jump | ¨ or ] | Q | | Jump | ¨ or ] | Q |
| Hit | ' or \ | A | | Hit | ' or \ | A |
Requirements ## Requirements
------------
Minimal system requirements are: Minimal system requirements are:
* Windows or GNU/Linux operating system - Windows or GNU/Linux operating system
* OpenGL 2.0 (or better) compatible graphics card, with at least 64MB graphical memory - OpenGL 2.0 (or better) compatible graphics card, with at least 64MB graphical
* At least 1GHz CPU memory
* At least 512MB RAM - At least 1GHz CPU
- At least 512MB RAM
Software dependencies are: Software dependencies are:
* [SDL 1.2](http://www.libsdl.org/) - [SDL 2.0](http://www.libsdl.org/)
* [SDL_Image 1.2](http://www.libsdl.org/) - [SDL_image 2.0](http://www.libsdl.org/)
* [FMOD](http://www.fmod.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 - Miika Sell - Original source code
* Juha Kaarlas - Original source code - Juha Kaarlas - Original source code
* [Michaël Lemaire](http://thunderk.net) - Current maintainer - [Michaël Lemaire](http://thunderk.net) - Current maintainer
* Osmand - Music - Osmand - Music
* Forge - Sound effects - Forge - Sound effects
Links ## Links
-----
The project is hosted on [GitHub](https://github.com/thunderk/blockofighter). 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.

View file

@ -2,6 +2,7 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <functional>
#include "audio.h" #include "audio.h"
@ -15,6 +16,7 @@ struct soundlist {
}; };
soundlist *allsounds = NULL; soundlist *allsounds = NULL;
Sound *current_music = NULL;
Sound::Sound(Sound *source) { Sound::Sound(Sound *source) {
memcpy(this, source, sizeof(Sound)); memcpy(this, source, sizeof(Sound));
@ -56,46 +58,29 @@ bool endsWith(char *str1, char *str2) {
void Sound::load(char *filename, int type, bool loops) { void Sound::load(char *filename, int type, bool loops) {
this->filename = filename; this->filename = filename;
if (type == SOUNDTYPE_AUTODETECT) { if (type == SOUNDTYPE_AUTODETECT) {
if (endsWith(filename, "mp3") || endsWith(filename, "mp2") || if (endsWith(filename, "mp3") || endsWith(filename, "ogg"))
endsWith(filename, "ogg"))
type = SOUNDTYPE_STREAM; type = SOUNDTYPE_STREAM;
if (endsWith(filename, "wav") || endsWith(filename, "raw")) if (endsWith(filename, "wav") || endsWith(filename, "raw"))
type = SOUNDTYPE_SAMPLE; type = SOUNDTYPE_SAMPLE;
}
if (endsWith(filename, "s3m") || endsWith(filename, "xm") || this->chunk = NULL;
endsWith(filename, "it") || endsWith(filename, "mid") || this->music = NULL;
endsWith(filename, "rmi") || endsWith(filename, "sgr") || if (type == SOUNDTYPE_SAMPLE) {
endsWith(filename, "mod")) this->chunk = Mix_LoadWAV(filename);
type = SOUNDTYPE_MODULE; if (this->chunk) {
}
#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);
} else { } else {
sample = FSOUND_Sample_Load(FSOUND_FREE, filename, FSOUND_LOOP_OFF, 0, 0); printf("Error while loading sample %s: %s\n", filename, Mix_GetError());
FSOUND_Sample_SetMode(sample, FSOUND_LOOP_OFF);
} }
this->loops = loops;
} else if (type == SOUNDTYPE_STREAM) { } else if (type == SOUNDTYPE_STREAM) {
if (loops) { this->music = Mix_LoadMUS(filename);
stream = FSOUND_Stream_Open(filename, FSOUND_LOOP_NORMAL, 0, 0); if (!this->music) {
} else { printf("Error while loading music %s: %s\n", filename, Mix_GetError());
stream = FSOUND_Stream_Open(filename, FSOUND_LOOP_OFF, 0, 0);
} }
this->loops = loops;
} }
#endif
this->loops = loops;
stopcallback = NULL; stopcallback = NULL;
soundlist *node = new soundlist; soundlist *node = new soundlist;
node->sound = this; node->sound = this;
@ -114,22 +99,22 @@ bool Sound::play() {
finished = false; finished = false;
fademode = SOUND_FADENONE; fademode = SOUND_FADENONE;
minduration = 0; minduration = 0;
#ifdef AUDIO_FMOD if (chunk) {
if (type == SOUNDTYPE_MODULE) { channel = -1;
FMUSIC_PlaySong(module); /*channel = FSOUND_PlaySound(FSOUND_FREE, sample);
FMUSIC_SetMasterVolume(module, (int)(volume * 256));
} else if (type == SOUNDTYPE_SAMPLE) {
channel = FSOUND_PlaySound(FSOUND_FREE, sample);
FSOUND_SetVolume(channel, (int)(volume * 256)); FSOUND_SetVolume(channel, (int)(volume * 256));
if (!loops) { if (!loops) {
running = false; running = false;
finished = 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) { Mix_VolumeMusic((int)(volume * MIX_MAX_VOLUME));
channel = FSOUND_Stream_Play(FSOUND_FREE, stream);
FSOUND_SetVolume(channel, (int)(volume * 256));
} }
#endif
// printf("Done: %f\n", volume); // printf("Done: %f\n", volume);
return true; return true;
} }
@ -140,50 +125,34 @@ void Sound::play(int minduration) {
} }
void Sound::stop() { void Sound::stop() {
#ifdef AUDIO_FMOD if (chunk && channel >= 0) {
if (type == SOUNDTYPE_MODULE) { Mix_HaltChannel(channel);
FMUSIC_StopSong(module); } else if (music && current_music == this) {
} else if (type == SOUNDTYPE_SAMPLE) { // FIXME only if it is THIS music playing
FSOUND_StopSound(channel); Mix_HaltMusic();
} else if (type == SOUNDTYPE_STREAM) {
FSOUND_Stream_Stop(stream);
} }
#endif
} }
void Sound::setVolume(float volume) { void Sound::setVolume(float volume) {
#ifdef AUDIO_FMOD if (chunk && channel >= 0) {
if (type == SOUNDTYPE_MODULE) { Mix_Volume(channel, (int)(volume * MIX_MAX_VOLUME));
FMUSIC_SetMasterVolume(module, (int)(volume * 256)); } else if (music && current_music == this) {
} else if (type == SOUNDTYPE_SAMPLE) { Mix_VolumeMusic((int)(volume * MIX_MAX_VOLUME));
FSOUND_SetVolume(channel, (int)(volume * 256));
} else if (type == SOUNDTYPE_STREAM) {
FSOUND_SetVolume(channel, (int)(volume * 256));
} }
#endif
this->volume = volume; this->volume = volume;
} }
#ifdef AUDIO_FMOD void streamendcallback(Sound* sound) {
signed char streamendcallback(FSOUND_STREAM *stream, void *buff, int len,
int param) {
Sound *sound = (Sound *)param;
sound->setFinished(); sound->setFinished();
return true;
} }
#endif
void Sound::setStopCallback(STOPCALLBACK callback) { void Sound::setStopCallback(STOPCALLBACK callback) {
stopcallback = callback; stopcallback = callback;
#ifdef AUDIO_FMOD if (chunk && channel >= 0) {
if (type == SOUNDTYPE_MODULE) {
} else if (type == SOUNDTYPE_SAMPLE) {
// NOT SUPPORTED // NOT SUPPORTED
} else if (type == SOUNDTYPE_STREAM) { } else if (music) {
// FSOUND_Stream_SetEndCallback(stream, //Mix_HookMusicFinished(std::bind(callback, this));
// (FSOUND_STREAMCALLBACK)streamendcallback, (int)this);
} }
#endif
} }
void Sound::setFinished(void) { finished = true; } void Sound::setFinished(void) { finished = true; }
@ -249,15 +218,13 @@ void Sound::fadeOut(int length) {
} }
void initAudio(void) { void initAudio(void) {
#ifdef AUDIO_FMOD Mix_Init(MIX_INIT_MP3 | MIX_INIT_OGG);
FSOUND_Init(44100, 32, 0); Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024);
#endif
} }
void uninitAudio(void) { void uninitAudio(void) {
#ifdef AUDIO_FMOD Mix_CloseAudio();
FSOUND_Close(); Mix_Quit();
#endif
} }
void updateAudio(void) { void updateAudio(void) {

View file

@ -1,30 +1,24 @@
#ifndef __AUDIO_H_INCLUDED__ #ifndef __AUDIO_H_INCLUDED__
#define __AUDIO_H_INCLUDED__ #define __AUDIO_H_INCLUDED__
#ifdef AUDIO_FMOD #include "SDL_mixer.h"
#include <fmod.h>
#endif
class Sound; class Sound;
typedef void (*STOPCALLBACK)(Sound *sound); typedef void (*STOPCALLBACK)(Sound *sound);
#define SOUNDTYPE_AUTODETECT 0 #define SOUNDTYPE_AUTODETECT 0
#define SOUNDTYPE_MODULE 1 #define SOUNDTYPE_STREAM 1
#define SOUNDTYPE_STREAM 2 #define SOUNDTYPE_SAMPLE 2
#define SOUNDTYPE_SAMPLE 3
#define BGSONG DATAPATH "boom.mp3" #define BGSONG DATAPATH "boom.mp3"
class Sound { class Sound {
private: private:
#ifdef AUDIO_FMOD Mix_Chunk *chunk;
int type; Mix_Music *music;
FMUSIC_MODULE *module;
FSOUND_STREAM *stream;
FSOUND_SAMPLE *sample;
int channel; int channel;
#endif
bool loops; bool loops;
bool finished; bool finished;
bool running; bool running;