📄 sdlmusic.c
字号:
/*Copyright (C) 2003-2004 Ryan C. Gordon. and James BentlerThis program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.Originally written by Ryan C. Gordon. (icculus@clutteredmind.org)Adapted to work with JonoF's port by James Bentler (bentler@cs.umn.edu)*//* * A reimplementation of Jim Dose's FX_MAN routines, using SDL_mixer 1.2. * Whee. FX_MAN is also known as the "Apogee Sound System", or "ASS" for * short. How strangely appropriate that seems. */#include <stdio.h>#include <stdlib.h>#include <stdarg.h>#include <string.h>#include <assert.h>#include <dirent.h>#include <errno.h>#include "duke3d.h"#include "cache1d.h"#if (!defined __WATCOMC__)#define cdecl#endif#define _NEED_SDLMIXER 1#include "sdl_inc.h"#include "music.h"#define __FX_TRUE (1 == 1)#define __FX_FALSE (!__FX_TRUE)#define DUKESND_DEBUG "DUKESND_DEBUG"#ifndef min#define min(a, b) (((a) < (b)) ? (a) : (b))#endif#ifndef max#define max(a, b) (((a) > (b)) ? (a) : (b))#endifint32_t MUSIC_ErrorCode = MUSIC_Ok;static char warningMessage[80];static char errorMessage[80];static FILE *debug_file = NULL;static int32_t initialized_debugging = 0;static int32_t external_midi = 0;static int32_t music_initialized = 0;static int32_t music_context = 0;static int32_t music_loopflag = MUSIC_PlayOnce;static Mix_Music *music_musicchunk = NULL;// static char *music_songdata = NULL;// This gets called all over the place for information and debugging messages.// If the user set the DUKESND_DEBUG environment variable, the messages// go to the file that is specified in that variable. Otherwise, they// are ignored for the expense of the function call. If DUKESND_DEBUG is// set to "-" (without the quotes), then the output goes to stdout.static void musdebug(const char *fmt, ...){ va_list ap; if (debug_file) { fprintf(debug_file, "DUKEMUS: "); va_start(ap, fmt); vfprintf(debug_file, fmt, ap); va_end(ap); fprintf(debug_file, "\n"); fflush(debug_file); } // if} // musdebugstatic void init_debugging(void){ const char *envr; if (initialized_debugging) return; envr = getenv(DUKESND_DEBUG); if (envr != NULL) { if (Bstrcmp(envr, "-") == 0) debug_file = stdout; else debug_file = fopen(envr, "w"); if (debug_file == NULL) fprintf(stderr, "DUKESND: -WARNING- Could not open debug file!\n"); else setbuf(debug_file, NULL); } // if initialized_debugging = 1;} // init_debuggingstatic void setErrorMessage(const char *msg){ Bstrncpy(errorMessage, msg, sizeof(errorMessage)); // strncpy() doesn't add the null char if there isn't room... errorMessage[sizeof(errorMessage) - 1] = '\0'; musdebug("Error message set to [%s].", errorMessage);} // setErrorMessage// The music functions...char *MUSIC_ErrorString(int32_t ErrorNumber){ switch (ErrorNumber) { case MUSIC_Warning: return(warningMessage); case MUSIC_Error: return(errorMessage); case MUSIC_Ok: return("OK; no error."); case MUSIC_ASSVersion: return("Incorrect sound library version."); case MUSIC_SoundCardError: return("General sound card error."); case MUSIC_InvalidCard: return("Invalid sound card."); case MUSIC_MidiError: return("MIDI error."); case MUSIC_MPU401Error: return("MPU401 error."); case MUSIC_TaskManError: return("Task Manager error."); //case MUSIC_FMNotDetected: // return("FM not detected error."); case MUSIC_DPMI_Error: return("DPMI error."); default: return("Unknown error."); } // switch assert(0); // shouldn't hit this point. return(NULL);} // MUSIC_ErrorStringint32_t MUSIC_Init(int32_t SoundCard, int32_t Address){ // Use an external MIDI player if the user has specified to do so char *command = getenv("EDUKE32_MUSIC_CMD"); const SDL_version *linked = Mix_Linked_Version(); if (SDL_VERSIONNUM(linked->major,linked->minor,linked->patch) < MIX_REQUIREDVERSION) { // reject running with SDL_Mixer versions older than what is stated in sdl_inc.h initprintf("You need at least v%d.%d.%d of SDL_mixer for music\n",SDL_MIXER_MIN_X,SDL_MIXER_MIN_Y,SDL_MIXER_MIN_Z); return(MUSIC_Error); } external_midi = (command != NULL && command[0] != 0); if (external_midi) Mix_SetMusicCMD(command); init_debugging(); musdebug("INIT! card=>%d, address=>%d...", SoundCard, Address); if (music_initialized) { setErrorMessage("Music system is already initialized."); return(MUSIC_Error); } // if SoundCard = 1; music_initialized = 1; return(MUSIC_Ok);} // MUSIC_Initint32_t MUSIC_Shutdown(void){ musdebug("shutting down sound subsystem."); // TODO - make sure this is being called from the menu -- SA if (external_midi) Mix_SetMusicCMD(NULL); MUSIC_StopSong(); music_context = 0; music_initialized = 0; music_loopflag = MUSIC_PlayOnce; return(MUSIC_Ok);} // MUSIC_Shutdownvoid MUSIC_SetMaxFMMidiChannel(int32_t channel){ musdebug("STUB ... MUSIC_SetMaxFMMidiChannel(%d).\n", channel);} // MUSIC_SetMaxFMMidiChannelvoid MUSIC_SetVolume(int32_t volume){ volume = max(0, volume); volume = min(volume, 255); Mix_VolumeMusic(volume >> 1); // convert 0-255 to 0-128.} // MUSIC_SetVolumevoid MUSIC_SetMidiChannelVolume(int32_t channel, int32_t volume){ musdebug("STUB ... MUSIC_SetMidiChannelVolume(%d, %d).\n", channel, volume);} // MUSIC_SetMidiChannelVolumevoid MUSIC_ResetMidiChannelVolumes(void){ musdebug("STUB ... MUSIC_ResetMidiChannelVolumes().\n");} // MUSIC_ResetMidiChannelVolumesint32_t MUSIC_GetVolume(void){ return(Mix_VolumeMusic(-1) << 1); // convert 0-128 to 0-255.} // MUSIC_GetVolumevoid MUSIC_SetLoopFlag(int32_t loopflag){ music_loopflag = loopflag;} // MUSIC_SetLoopFlagint32_t MUSIC_SongPlaying(void){ return((Mix_PlayingMusic()) ? __FX_TRUE : __FX_FALSE);} // MUSIC_SongPlayingvoid MUSIC_Continue(void){ if (Mix_PausedMusic()) Mix_ResumeMusic();} // MUSIC_Continuevoid MUSIC_Pause(void){ Mix_PauseMusic();} // MUSIC_Pauseint32_t MUSIC_StopSong(void){ //if (!fx_initialized) if (!Mix_QuerySpec(NULL, NULL, NULL)) { setErrorMessage("Need FX system initialized, too. Sorry."); return(MUSIC_Error); } // if if ((Mix_PlayingMusic()) || (Mix_PausedMusic())) Mix_HaltMusic(); if (music_musicchunk) Mix_FreeMusic(music_musicchunk);// if (music_songdata)// Bfree(music_songdata); music_musicchunk = NULL;// music_songdata = NULL; return(MUSIC_Ok);} // MUSIC_StopSong// Duke3D-specific. --ryan.// void MUSIC_PlayMusic(char *_filename)int32_t MUSIC_PlaySong(char *song, int32_t loopflag){ MUSIC_StopSong(); music_musicchunk = Mix_LoadMUS_RW(SDL_RWFromMem((char *) song, g_musicSize)); if (music_musicchunk != NULL) { Mix_PlayMusic(music_musicchunk, (loopflag == MUSIC_LoopSong)?-1:0); } // if return MUSIC_Ok;}void MUSIC_SetContext(int32_t context){ musdebug("STUB ... MUSIC_SetContext().\n"); music_context = context;} // MUSIC_SetContextint32_t MUSIC_GetContext(void){ return(music_context);} // MUSIC_GetContextvoid MUSIC_SetSongTick(uint32_t PositionInTicks){ UNREFERENCED_PARAMETER(PositionInTicks); musdebug("STUB ... MUSIC_SetSongTick().\n");} // MUSIC_SetSongTickvoid MUSIC_SetSongTime(uint32_t milliseconds){ UNREFERENCED_PARAMETER(milliseconds); musdebug("STUB ... MUSIC_SetSongTime().\n");}// MUSIC_SetSongTimevoid MUSIC_SetSongPosition(int32_t measure, int32_t beat, int32_t tick){ UNREFERENCED_PARAMETER(measure); UNREFERENCED_PARAMETER(beat); UNREFERENCED_PARAMETER(tick); musdebug("STUB ... MUSIC_SetSongPosition().\n");} // MUSIC_SetSongPositionvoid MUSIC_GetSongPosition(songposition *pos){ UNREFERENCED_PARAMETER(pos); musdebug("STUB ... MUSIC_GetSongPosition().\n");} // MUSIC_GetSongPositionvoid MUSIC_GetSongLength(songposition *pos){ UNREFERENCED_PARAMETER(pos); musdebug("STUB ... MUSIC_GetSongLength().\n");} // MUSIC_GetSongLengthint32_t MUSIC_FadeVolume(int32_t tovolume, int32_t milliseconds){ UNREFERENCED_PARAMETER(tovolume); Mix_FadeOutMusic(milliseconds); return(MUSIC_Ok);} // MUSIC_FadeVolumeint32_t MUSIC_FadeActive(void){ return((Mix_FadingMusic() == MIX_FADING_OUT) ? __FX_TRUE : __FX_FALSE);} // MUSIC_FadeActivevoid MUSIC_StopFade(void){ musdebug("STUB ... MUSIC_StopFade().\n");} // MUSIC_StopFadevoid MUSIC_RerouteMidiChannel(int32_t channel, int32_t cdecl(*function)(int32_t event, int32_t c1, int32_t c2)){ UNREFERENCED_PARAMETER(channel); UNREFERENCED_PARAMETER(function); musdebug("STUB ... MUSIC_RerouteMidiChannel().\n");} // MUSIC_RerouteMidiChannelvoid MUSIC_RegisterTimbreBank(char *timbres){ UNREFERENCED_PARAMETER(timbres); musdebug("STUB ... MUSIC_RegisterTimbreBank().\n");} // MUSIC_RegisterTimbreBankvoid MUSIC_Update(void){}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -