/* * This software is licensed under the terms of the MIT-License * See COPYING for further information. * --- * Copyright (C) 2011, Lukas Weber */ #include "audio.h" #include "resource.h" #include "global.h" #include "list.h" #include "taisei_err.h" #include "bgm.h" #ifdef OGG_SUPPORT_ENABLED #include #include "ogg.h" #endif struct current_bgm_t current_bgm = { .name = NULL }; char *saved_bgm; int init_bgm(int *argc, char *argv[]) { if (tconfig.intval[NO_MUSIC]) return 1; if (!init_alut_if_needed(argc, argv)) return 0; alGenSources(1, &resources.bgmsrc); if(warn_alut_error("creating music sources")) { tconfig.intval[NO_MUSIC] = 1; unload_alut_if_needed(); return 0; } return 1; } void shutdown_bgm(void) { current_bgm.name = NULL; alDeleteSources(1, &resources.bgmsrc); warn_alut_error("deleting music sources"); if(resources.state & RS_BgmLoaded) { printf("-- freeing music\n"); delete_music(); resources.state &= ~RS_BgmLoaded; } tconfig.intval[NO_MUSIC] = 1; unload_alut_if_needed(); } char *get_bgm_desc(Bgm_desc *source, char *name) { for(; source; source = source->next) if(strcmp(source->name, name) == 0) return source->value; return NULL; } void delete_bgm_description(void **descs, void *desc) { free(((Bgm_desc *)desc)->name); free(((Bgm_desc *)desc)->value); delete_element(descs, desc); } void load_bgm_descriptions(const char *path) { const char *fname = "/bgm.conf"; char *fullname = malloc(strlen(path)+strlen(fname)+1); if (fullname == NULL) return; strcpy(fullname, path); strcat(fullname, fname); FILE *fp = fopen(fullname, "rt"); if (fp == NULL) return; char line[256]; while(fgets(line, sizeof(line), fp)) { char *rem; while ((rem = strchr(line,'\n')) != NULL) *rem='\0'; while ((rem = strchr(line,'\r')) != NULL) *rem='\0'; while ((rem = strchr(line,'\t')) != NULL) *rem=' '; if ((rem = strchr(line,' ' )) == NULL) { if (strlen(line) > 0) warnx("load_bgm_description():\n!- illegal string format. See README."); continue; } *(rem++)='\0'; Bgm_desc *desc = create_element((void **)&resources.bgm_descriptions, sizeof(Bgm_desc)); desc->name = strdup(line); desc->value = malloc(strlen(rem) + 6); if (!desc->name || !desc->value) { delete_bgm_description((void**)resources.bgm_descriptions, desc); warnx("load_bgm_description():\n!- strdup() failed"); continue; } strcpy(desc->value, "BGM: "); strcat(desc->value, rem); printf ("Music %s is now known as \"%s\".\n", desc->name, desc->value); } fclose(fp); return; } Sound *load_bgm(char *filename, const char *type) { return load_sound_or_bgm(filename, &resources.music, "bgm/", type); } void start_bgm(char *name) { if(tconfig.intval[NO_MUSIC]) return; if(!name || strcmp(name, "") == 0) { stop_bgm(); return; } // if BGM has changed, change it and start from beginning if (!current_bgm.name || strcmp(name, current_bgm.name)) { current_bgm.name = realloc(current_bgm.name, strlen(name) + 1); if(current_bgm.name == NULL) errx(-1,"start_bgm():\n!- realloc error with music '%s'", name); strcpy(current_bgm.name, name); if((current_bgm.data = get_snd(resources.music, name)) == NULL) { warnx("start_bgm():\n!- BGM '%s' not exist", current_bgm.name); free(current_bgm.name); current_bgm.name = NULL; stop_bgm(); return; } alSourceRewind(resources.bgmsrc); warn_alut_error("rewinding music source"); alSourcei(resources.bgmsrc, AL_BUFFER, current_bgm.data->alsnd); warn_alut_error("changing buffer of music source"); alSourcei(resources.bgmsrc, AL_LOOPING, AL_TRUE); warn_alut_error("looping music source"); } // otherwise, do not change anything and continue ALint play; alGetSourcei(resources.bgmsrc,AL_SOURCE_STATE,&play); warn_alut_error("checking state of music source"); // Support drawing BGM title in game loop current_bgm.started_at = ((current_bgm.title = get_bgm_desc(resources.bgm_descriptions, current_bgm.name)) != NULL) ? global.frames : -1; if(play != AL_PLAYING) { alSourcePlay(resources.bgmsrc); warn_alut_error("starting playback of music source"); printf("Started %s\n", (current_bgm.title ? current_bgm.title : current_bgm.name)); } } void continue_bgm(void) { start_bgm(current_bgm.name); } void stop_bgm(void) { if (tconfig.intval[NO_MUSIC] || !current_bgm.name) return; ALint play; alGetSourcei(resources.bgmsrc,AL_SOURCE_STATE,&play); warn_alut_error("checking state of music source"); if(play == AL_PLAYING) { alSourcePause(resources.bgmsrc); warn_alut_error("pausing music source"); printf("BGM stopped.\n"); } else { printf("stop_bgm(): No BGM was playing.\n"); } } void save_bgm(void) { free(saved_bgm); // Deal with consequent saves without restore. saved_bgm = current_bgm.name ? strdup(current_bgm.name) : NULL; } void restore_bgm(void) { start_bgm(saved_bgm); free(saved_bgm); saved_bgm = NULL; } void set_bgm_volume(float gain) { if(tconfig.intval[NO_MUSIC]) return; printf("BGM volume: %f\n", gain); alSourcef(resources.bgmsrc,AL_GAIN, gain); warn_alut_error("changing gain of music source"); } void delete_music(void) { delete_all_elements((void **)&resources.bgm_descriptions, delete_bgm_description); delete_all_elements((void **)&resources.music, delete_sound); }