diff --git a/Makefile b/Makefile index 81da7b8a..93f847ff 100644 --- a/Makefile +++ b/Makefile @@ -82,7 +82,7 @@ $(if $(shell test "$(GL)" -ge 3 -a "$(SDL)" -lt 2 && echo fail), \ $(error "GL >= 3 only supported with SDL >= 2")) # library headers -CFLAGS+= `pkg-config --cflags $(SDL_) $(LUA) $(LUA)-socket libenet libpng zlib openal` +CFLAGS+= `pkg-config --cflags $(SDL_) $(LUA) $(LUA)-socket libenet libpng zlib openal ogg vorbisfile` ifeq ($(MACOSX),1) CFLAGS += -DMACOSX endif @@ -95,7 +95,7 @@ ifeq ($(STATIC),1) LIB+= -Wl,-dn PKG_CFG_OPTS= --static endif -LIB+= `pkg-config $(PKG_CFG_OPTS) --libs $(LUA) $(LUA)-socket libenet libpng zlib openal` -lm +LIB+= `pkg-config $(PKG_CFG_OPTS) --libs $(LUA) $(LUA)-socket libenet libpng zlib openal ogg vorbisfile` -lm ifeq ($(STATIC),1) LIB+= -Wl,-dy endif diff --git a/main.c b/main.c index 7ef81573..ce8cfc47 100644 --- a/main.c +++ b/main.c @@ -523,6 +523,11 @@ static bool AppInit( char * lpCmdLine ) // exclusively grab input in fullscreen mode input_grab( render_info.fullscreen ); + if(!InitMusic()){ + Msg("InitMusic failed.\n"); + return false; + } + // SetSoundLevels( NULL ); @@ -611,6 +616,10 @@ int main( int argc, char* argv[] ) while( !QuitRequested ) { + //Start Music Loop + if(!MusicLoop()) + goto FAILURE; + // process system events if(!handle_events()) goto FAILURE; diff --git a/music.c b/music.c new file mode 100644 index 00000000..6bf21c9a --- /dev/null +++ b/music.c @@ -0,0 +1,194 @@ +#include "oct2.h" +#include "sound.h" +#include +#include +#include +#include +#include +#include +#include + +#define MAX_PATH 500 + +char pcmout[16 * 4098]; + +typedef struct music_buffer_t music_buffer_t; +music_buffer_t *music_buffer; + +char MusicPath[MAX_PATH]; + +struct music_buffer_t { + ALuint id[16]; + ALuint source; + int current_section; + OggVorbis_File vf; + vorbis_info *vi; + ALuint released[16]; + ALint count; + bool eof; +}; + +music_buffer_t *music_load(music_buffer_t *buffer, const char *path) { + ALenum format; + FILE *fp; + fp = file_open(path, "rb"); + if (!fp) { + DebugPrintf(stderr, "could not open file %s", path); + return 0; + } + if (ov_open_callbacks(fp, &buffer->vf, NULL, 0, OV_CALLBACKS_DEFAULT) < 0) { + DebugPrintf(stderr, "input does not appear to be in an ogg bitstream"); + return 0; + } + buffer->vi = ov_info(&buffer->vf, -1); + int i; + for (i = 0; i < 16; i++) { + long pos = 0; + while (pos < sizeof(pcmout)) { + long ret = ov_read(&buffer->vf, pcmout + pos, sizeof(pcmout) - pos, + 0, 2, 1, &buffer->current_section); + pos += ret; + if (ret == 0) { + break; + } + } + alBufferData(buffer->id[i], AL_FORMAT_STEREO16, pcmout, pos, + buffer->vi->rate); + } + buffer->eof = false; + alSourceQueueBuffers(buffer->source, 16, + buffer->id); // cole added address of on 2-24-2017 + alSourcePlay(buffer->source); + return buffer; +} + +void music_play() { + alGetSourcei(music_buffer->source, AL_BUFFERS_PROCESSED, + &music_buffer->count); + alSourceUnqueueBuffers(music_buffer->source, music_buffer->count, + music_buffer->released); + int i; + for (i = 0; i < music_buffer->count; i++) { + long pos = 0; + while (pos < sizeof(pcmout)) { + long ret = + ov_read(&music_buffer->vf, pcmout + pos, sizeof(pcmout) - pos, + 0, 2, 1, &music_buffer->current_section); + pos += ret; + if (ret == 0) { + music_buffer->eof = true; + break; + } + } + alBufferData(music_buffer->released[i], AL_FORMAT_STEREO16, pcmout, pos, + music_buffer->vi->rate); + } + alSourceQueueBuffers(music_buffer->source, music_buffer->count, + music_buffer->released); +} + +void music_cleanup() { + int i; + for (i = 0; i < 16; i++) { + alSourcei(music_buffer->id[i], AL_BUFFER, NULL); + } + alSourceStopv(1, &music_buffer->source); // may not need + alDeleteSources(1, &music_buffer->source); + for (i = 0; i < 16; i++) { + alDeleteBuffers(16, &music_buffer->id[i]); + } + // TODO: this seems like the only ALUT dep? + // no need to import all of ALUT then... + // we should not exit audio since rest of game depends on it? + // any other cleanup we could do? + // alutExit(); +} + +bool InitMusic() { + ALenum error; + if (music_buffer) { + music_cleanup(); + free(music_buffer); + } + music_buffer = malloc(sizeof(music_buffer_t)); + if (!music_buffer) { + DebugPrintf("sound_load: failed to malloc buffer\n"); + return false; + } + // clear error code + alGetError(); + alGenBuffers(16, music_buffer->id); + if ((error = alGetError()) != AL_NO_ERROR) { + DebugPrintf("alGenBuffers: %s\n", alGetString(error)); + free(music_buffer); + return false; + } + alGenSources(1, &music_buffer->source); + return true; +} + +char *trackmap(const char *folderpath, const char *filename) { + const size_t length = strlen(folderpath) + strlen(filename) + 1; + char *path = malloc(sizeof(char) * length); + snprintf(path, length, "%s%s", folderpath, filename); + if (folder_exists(path) == 0) { + DebugPrintf("Path to %s missing, creating default\n", path); + touch_file(path); + } + FILE *f = file_open(path, "r"); + if (!f) { + DebugPrintf(stderr, "could not open file %s", path); + return NULL; + } + const int16_t buf = 128; + int16_t ch = 0; + int16_t tot = 0; + while (!feof(f)) { + ch = fgetc(f); + if (ch == '\n') { + tot++; + } + } + fclose(f); + f = file_open(path, "r"); + free(path); + char line[tot][buf]; + int i = 0; + while (fgets(line[i], buf, f)) { + // get rid of ending \n from fgets + line[i][strlen(line[i]) - 1] = '\0'; + i++; + } + fclose(f); + return line[LevelNum]; +} + +bool MusicLoop() { + if (music_buffer->eof) { + if (!InitMusic()) { + Msg("InitMusic failed.\n"); + return false; + } + music_buffer = music_load(music_buffer, MusicPath); + if (!music_buffer) { + return false; + } + } else { + if (LoadLevel) { + const char *trackname = trackmap("data/sound/music/", "music.dat"); + char path[MAX_PATH]; + if (!trackname) { + return false; + } + strncpy(&path, trackname, MAX_PATH - 1); + // sprintf(MusicPath,"data\\sound\\music\\%s.ogg", path,MAX_PATH-1); + // //couldnt get this to work!!! + sprintf(&MusicPath, "data/sound/music/%s.ogg", path, MAX_PATH - 1); + LoadLevel = false; + music_buffer->eof = true; + } else { + music_play(); + } + } + return true; +} diff --git a/oct2.c b/oct2.c index 33b6534a..1fd83b63 100755 --- a/oct2.c +++ b/oct2.c @@ -549,6 +549,7 @@ extern int FontSourceHeight; extern int PlayerSort[MAX_PLAYERS]; extern int16_t NumOfActivePlayers; +bool LoadLevel; int16_t LevelNum = 0 ; int16_t NewLevelNum = 0 ; int16_t NumLevels = 0; @@ -2218,6 +2219,7 @@ bool ChangeLevel( void ) // return true; LevelNum = NewLevelNum; + LoadLevel = true; //NumGoldBars = 0; diff --git a/oct2.h b/oct2.h index 20172715..b12fccc1 100644 --- a/oct2.h +++ b/oct2.h @@ -7,5 +7,6 @@ extern char ShortLevelNames[MAXLEVELS][MAX_SHORT_LEVEL_NAME]; extern int16_t NewLevelNum; - +extern int16_t LevelNum; +extern bool LoadLevel; #endif // OCT2_INCLUDED