/* always start with reliable default values */
setLevelInfoToDefaults();
- if (!(file = fopen(filename, "r")))
+ if (!(file = fopen(filename, MODE_READ)))
{
Error(ERR_WARN, "cannot read level '%s' - creating new level", filename);
return;
char *oldest_possible_cookie;
FILE *file;
- if (!(file = fopen(filename, "w")))
+ if (!(file = fopen(filename, MODE_WRITE)))
{
Error(ERR_WARN, "cannot save level file '%s'", filename);
return;
/* at least one (default: the first) player participates in every tape */
num_participating_players = 1;
- if (!(file = fopen(filename, "r")))
+ if (!(file = fopen(filename, MODE_READ)))
return;
/* check file identifier */
}
}
- if (!(file = fopen(filename, "w")))
+ if (!(file = fopen(filename, MODE_WRITE)))
{
Error(ERR_WARN, "cannot save level recording file '%s'", filename);
return;
highscore[i].Score = 0;
}
- if (!(file = fopen(filename, "r")))
+ if (!(file = fopen(filename, MODE_READ)))
return;
/* check file identifier */
InitScoreDirectory(leveldir_current->filename);
- if (!(file = fopen(filename, "w")))
+ if (!(file = fopen(filename, MODE_WRITE)))
{
Error(ERR_WARN, "cannot save score for level %d", level_nr);
return;
FILE *file;
- if (!(file = fopen(filename, "r")))
+ if (!(file = fopen(filename, MODE_READ)))
{
Error(ERR_WARN, "cannot open configuration file '%s'", filename);
return NULL;
filename = getPath2(getUserLevelDir(getLoginName()), LEVELINFO_FILENAME);
- if (!(file = fopen(filename, "w")))
+ if (!(file = fopen(filename, MODE_WRITE)))
{
Error(ERR_WARN, "cannot write level info file '%s'", filename);
free(filename);
filename = getPath2(getSetupDir(), SETUP_FILENAME);
- if (!(file = fopen(filename, "w")))
+ if (!(file = fopen(filename, MODE_WRITE)))
{
Error(ERR_WARN, "cannot write setup file '%s'", filename);
free(filename);
filename = getPath2(getSetupDir(), LEVELSETUP_FILENAME);
- if (!(file = fopen(filename, "w")))
+ if (!(file = fopen(filename, MODE_WRITE)))
{
Error(ERR_WARN, "cannot write setup file '%s'", filename);
free(filename);
filename = getPath2(getLevelSetupDir(level_subdir), LEVELSETUP_FILENAME);
- if (!(file = fopen(filename, "w")))
+ if (!(file = fopen(filename, MODE_WRITE)))
{
Error(ERR_WARN, "cannot write setup file '%s'", filename);
free(filename);
chmod(filename, SETUP_PERMS);
}
+/* LocalWords: Rocks'n
+ */
OpenDoor(DOOR_OPEN_ALL);
if (setup.sound_music)
- PlaySoundLoop(background_loop[level_nr % num_bg_loops]);
+ PlayMusic(background_loop[level_nr % num_bg_loops]);
KeyboardAutoRepeatOff();
if (setup.sound_music)
{
setup.sound_music = FALSE;
- FadeSound(background_loop[level_nr % num_bg_loops]);
+ FadeMusic();
}
else if (audio.loops_available)
{
setup.sound = setup.sound_music = TRUE;
- PlaySoundLoop(background_loop[level_nr % num_bg_loops]);
+ PlayMusic(background_loop[level_nr % num_bg_loops]);
}
break;
{
int i;
- OpenAudio(&audio);
+ OpenAudio();
AllocSoundArray(NUM_SOUNDS);
FILE *error_file;
filename = getPath2(getUserDataDir(), ERROR_FILENAME);
- error_file = fopen(filename, "a");
+ error_file = fopen(filename, MODE_APPEND);
free(filename);
return error_file;
FILE *error_file;
filename = getPath2(getUserDataDir(), ERROR_FILENAME);
- error_file = fopen(filename, "r");
+ error_file = fopen(filename, MODE_READ);
free(filename);
if (error_file != NULL)
freeze_mouse_flag = FALSE;
}
-Bool MSDOSOpenAudio(void)
+void MSDOSOpenAudio(void)
{
- return allegro_init_audio();
+ if (allegro_init_audio())
+ {
+ audio.sound_available = TRUE;
+ audio.music_available = TRUE;
+ audio.loops_available = TRUE;
+ audio.sound_enabled = TRUE;
+ }
}
void MSDOSCloseAudio(void)
void AllegroDrawLine(Drawable, int, int, int, int, Pixel);
-Bool MSDOSOpenAudio(void);
+void MSDOSOpenAudio(void);
void MSDOSCloseAudio(void);
void NetworkServer(int, int);
errno_pcx = PCX_Success;
- if (!(file = fopen(filename, "r")))
+ if (!(file = fopen(filename, MODE_READ)))
{
errno_pcx = PCX_OpenFailed;
return NULL;
***********************************************************/
#include "system.h"
+#include "sound.h"
#include "misc.h"
/* audio functions */
/* ========================================================================= */
-inline boolean SDLOpenAudio(void)
+inline void SDLOpenAudio(void)
{
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
{
Error(ERR_WARN, "SDL_InitSubSystem() failed: %s", SDL_GetError());
- return FALSE;
+ return;
}
- if (Mix_OpenAudio(22050, AUDIO_S16, 2, 512) < 0)
+ if (Mix_OpenAudio(DEFAULT_AUDIO_SAMPLE_RATE, AUDIO_S16,
+ AUDIO_STEREO_CHANNELS,
+ DEFAULT_AUDIO_FRAGMENT_SIZE) < 0)
{
Error(ERR_WARN, "Mix_OpenAudio() failed: %s", SDL_GetError());
- return FALSE;
+ return;
}
- Mix_Volume(-1, SDL_MIX_MAXVOLUME / 4);
- Mix_VolumeMusic(SDL_MIX_MAXVOLUME / 4);
+ audio.sound_available = TRUE;
+ audio.music_available = TRUE;
+ audio.loops_available = TRUE;
+ audio.sound_enabled = TRUE;
+
+ /* determine number of available channels */
+ audio.channels = Mix_AllocateChannels(MIX_CHANNELS);
+
+ if (!audio.mods_available) /* reserve first channel for music loops */
+ {
+ if (Mix_ReserveChannels(1) == 1)
+ audio.music_channel = 0;
+ else
+ audio.music_available = FALSE;
+ }
- return TRUE;
+ Mix_Volume(-1, SOUND_MAX_VOLUME);
+ Mix_VolumeMusic(SOUND_MAX_VOLUME);
}
inline void SDLCloseAudio(void)
Bitmap *SDLLoadImage(char *);
-inline boolean SDLOpenAudio(void);
+inline void SDLOpenAudio(void);
inline void SDLCloseAudio(void);
#endif /* SDL_H */
#include <unistd.h>
#include <fcntl.h>
+#include "system.h"
#include "sound.h"
#include "misc.h"
return audio_fd;
}
-void UnixOpenAudio(struct AudioSystemInfo *audio)
+void UnixOpenAudio(void)
{
static char *audio_device_name[] =
{
close(audio_fd);
- audio->device_name = audio_device_name[i];
- audio->sound_available = TRUE;
- audio->sound_enabled = TRUE;
+ audio.device_name = audio_device_name[i];
+ audio.sound_available = TRUE;
+ audio.sound_enabled = TRUE;
#if defined(AUDIO_STREAMING_DSP)
- audio->loops_available = TRUE;
+ audio.music_available = TRUE;
+ audio.loops_available = TRUE;
#endif
}
-void UnixCloseAudio(struct AudioSystemInfo *audio)
+void UnixCloseAudio(void)
{
- if (audio->device_fd)
- close(audio->device_fd);
+ if (audio.device_fd)
+ close(audio.device_fd);
}
#endif /* PLATFORM_UNIX */
byte *sample_ptr;
long sample_size;
static long max_sample_size = 0;
- static long fragment_size = 0;
- /* Even if the stereo flag is used as being boolean, it must be
- defined as an integer, else 'ioctl()' will fail! */
+ static long fragment_size = DEFAULT_AUDIO_FRAGMENT_SIZE;
+ int sample_rate = DEFAULT_AUDIO_SAMPLE_RATE;
int stereo = TRUE;
-#if 0
- int sample_rate = 8000;
-#else
- int sample_rate = 22050;
-#endif
+ /* 'ioctl()' expects pointer to integer value for stereo flag
+ (boolean is defined as 'char', which will not work here) */
if (playing_sounds ||
(audio.device_fd = OpenAudioDevice(audio.device_name)) >= 0)
{
if (!playing_sounds) /* we just opened the audio device */
{
- /* 2 buffers / 512 bytes, giving 1/16 second resolution */
- /* (with stereo the effective buffer size will shrink to 256) */
- fragment_size = 0x00020009;
+ unsigned long fragment_spec = 0;
+
+ /* determine logarithm (log2) of the fragment size */
+ for (fragment_spec=0; (1 << fragment_spec) < fragment_size;
+ fragment_spec++);
+
+ /* use two fragments (play one fragment, prepare the other);
+ one fragment would result in interrupted audio output, more
+ than two fragments would raise audio output latency to much */
+ fragment_spec |= 0x00020000;
+
+ /* Example for fragment specification:
+ - 2 buffers / 512 bytes (giving 1/16 second resolution for 8 kHz)
+ - (with stereo the effective buffer size will shrink to 256)
+ => fragment_size = 0x00020009 */
- if (ioctl(audio.device_fd,SNDCTL_DSP_SETFRAGMENT,&fragment_size) < 0)
+ if (ioctl(audio.device_fd,SNDCTL_DSP_SETFRAGMENT,&fragment_spec) < 0)
Error(ERR_EXIT_SOUND_SERVER,
"cannot set fragment size of /dev/dsp - no sounds");
FD_SET(audio.soundserver_pipe[0], &sound_fdset);
/* first clear the last premixing buffer */
- memset(premix_last_buffer,0,fragment_size*sizeof(int));
+ memset(premix_last_buffer, 0, fragment_size * sizeof(int));
for(i=0;i<MAX_SOUNDS_PLAYING;i++)
{
}
/* put last mixing buffer to final playing buffer */
- for(i=0;i<fragment_size;i++)
+ for(i=0; i<fragment_size; i++)
{
if (premix_last_buffer[i]<-255)
playing_buffer[i] = 0;
}
/* finally play the sound fragment */
- write(audio.device_fd, playing_buffer,fragment_size);
+ write(audio.device_fd, playing_buffer, fragment_size);
}
/* if no sounds playing, free device for other sound programs */
#if !defined(PLATFORM_MSDOS)
- if ((file = fopen(filename, "r")) == NULL)
+ if ((file = fopen(filename, MODE_READ)) == NULL)
{
Error(ERR_WARN, "cannot open sound file '%s' - no sounds", filename);
return FALSE;
return TRUE;
}
+void PlayMusic(int nr)
+{
+ if (!audio.music_available)
+ return;
+
+#if defined(TARGET_SDL)
+ if (audio.mods_available)
+ {
+ Mix_VolumeMusic(SOUND_MAX_VOLUME);
+ /* start playing module */
+ }
+ else /* play music loop */
+ {
+ Mix_Volume(audio.music_channel, SOUND_MAX_VOLUME);
+ Mix_PlayChannel(audio.music_channel, Sound[nr].mix_chunk, -1);
+ }
+#else
+ audio.music_nr = nr;
+ PlaySoundLoop(nr);
+#endif
+}
+
void PlaySound(int nr)
{
PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_NO_LOOP);
snd_ctrl.data_len = Sound[nr].data_len;
#if defined(TARGET_SDL)
-
- Mix_Volume(-1, SDL_MIX_MAXVOLUME / 4);
- Mix_VolumeMusic(SDL_MIX_MAXVOLUME / 4);
-
+ Mix_Volume(-1, SOUND_MAX_VOLUME);
Mix_PlayChannel(-1, Sound[nr].mix_chunk, (loop ? -1 : 0));
-
-#else
-#if !defined(PLATFORM_MSDOS)
+#elif defined(PLATFORM_UNIX)
if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
{
Error(ERR_WARN, "cannot pipe to child process - no sounds");
audio.sound_available = audio.sound_enabled = FALSE;
return;
}
-#else
+#elif defined(PLATFORM_MSDOS)
sound_handler(snd_ctrl);
#endif
+}
+
+void FadeMusic(void)
+{
+#if defined(TARGET_SDL)
+ if (audio.mods_available)
+ Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
+ else
+ Mix_FadeOutChannel(audio.music_channel, SOUND_FADING_INTERVAL);
+#else
+ FadeSound(audio.music_nr);
#endif
}
StopSoundExt(-1, SSND_FADE_ALL_SOUNDS);
}
+void StopMusic(void)
+{
+#if defined(TARGET_SDL)
+ if (audio.mods_available)
+ Mix_HaltMusic();
+ else
+ Mix_HaltChannel(audio.music_channel);
+#else
+ StopSound(audio.music_nr);
+#endif
+}
+
void StopSound(int nr)
{
StopSoundExt(nr, SSND_STOP_SOUND);
if (SSND_FADING(method))
{
- Mix_FadeOutChannel(-1, 1000);
- Mix_FadeOutMusic(1000);
+ int i;
+
+ for (i=0; i<audio.channels; i++)
+ if (i != audio.music_channel || snd_ctrl.stop_all_sounds)
+ Mix_FadeOutChannel(i, SOUND_FADING_INTERVAL);
+ if (snd_ctrl.stop_all_sounds)
+ Mix_FadeOutMusic(SOUND_FADING_INTERVAL);
}
else
{
- Mix_HaltChannel(-1);
- Mix_HaltMusic();
+ int i;
+
+ for (i=0; i<audio.channels; i++)
+ if (i != audio.music_channel || snd_ctrl.stop_all_sounds)
+ Mix_HaltChannel(i);
+ if (snd_ctrl.stop_all_sounds)
+ Mix_HaltMusic();
}
#else
#define AUDIO_STREAMING_DSP
#endif
+#define AUDIO_SAMPLE_RATE_8000 8000
+#define AUDIO_SAMPLE_RATE_22050 22050
+
+#define AUDIO_FRAGMENT_SIZE_512 512
+#define AUDIO_FRAGMENT_SIZE_1024 1024
+#define AUDIO_FRAGMENT_SIZE_2048 2048
+#define AUDIO_FRAGMENT_SIZE_4096 4096
+
+#define AUDIO_MONO_CHANNEL 1
+#define AUDIO_STEREO_CHANNELS 2
+
+#if defined(TARGET_SDL)
+/* one second fading interval == 1000 ticks (milliseconds) */
+#define SOUND_FADING_INTERVAL 1000
+#define SOUND_MAX_VOLUME (SDL_MIX_MAXVOLUME / 4)
+#endif
+
+#define DEFAULT_AUDIO_SAMPLE_RATE AUDIO_SAMPLE_RATE_22050
+#define DEFAULT_AUDIO_FRAGMENT_SIZE_UNIX AUDIO_FRAGMENT_SIZE_512
+#define DEFAULT_AUDIO_FRAGMENT_SIZE_WIN32 AUDIO_FRAGMENT_SIZE_2048
+
+#if defined(PLATFORM_UNIX)
+#define DEFAULT_AUDIO_FRAGMENT_SIZE DEFAULT_AUDIO_FRAGMENT_SIZE_UNIX
+#else
+#define DEFAULT_AUDIO_FRAGMENT_SIZE DEFAULT_AUDIO_FRAGMENT_SIZE_WIN32
+#endif
+
#if !defined(PLATFORM_MSDOS)
-#define MAX_SOUNDS_PLAYING 16
+#define MAX_SOUNDS_PLAYING 16
#else
-#define MAX_SOUNDS_PLAYING 8
+#define MAX_SOUNDS_PLAYING 8
#endif
#if !defined(PLATFORM_HPUX)
};
/* general sound functions */
-void UnixOpenAudio(struct AudioSystemInfo *);
-void UnixCloseAudio(struct AudioSystemInfo *);
+void UnixOpenAudio(void);
+void UnixCloseAudio(void);
/* sound server functions */
void SoundServer(void);
/* sound client functions */
void AllocSoundArray(int);
boolean LoadSound(int, char *);
+void PlayMusic(int);
void PlaySound(int);
void PlaySoundStereo(int, int);
void PlaySoundLoop(int);
void PlaySoundExt(int, int, int, boolean);
+void FadeMusic(void);
void FadeSound(int);
void FadeSounds(void);
+void StopMusic(void);
void StopSound(int);
void StopSounds(void);
void StopSoundExt(int, int);
#endif
#if !defined(PLATFORM_UNIX)
+ program.userdata_directory = "userdata";
initErrorFile();
#endif
/* audio functions */
/* ========================================================================= */
-inline boolean OpenAudio(struct AudioSystemInfo *audio)
+inline void OpenAudio(void)
{
- audio->sound_available = FALSE;
- audio->loops_available = FALSE;
- audio->sound_enabled = FALSE;
- audio->soundserver_pipe[0] = audio->soundserver_pipe[1] = 0;
- audio->soundserver_pid = 0;
- audio->device_name = NULL;
- audio->device_fd = 0;
+ /* always start with reliable default values */
+ audio.sound_available = FALSE;
+ audio.music_available = FALSE;
+ audio.loops_available = FALSE;
+ audio.mods_available = FALSE;
+ audio.sound_enabled = FALSE;
+
+ audio.soundserver_pipe[0] = audio.soundserver_pipe[1] = 0;
+ audio.soundserver_pid = 0;
+ audio.device_name = NULL;
+ audio.device_fd = 0;
+
+ audio.channels = 0;
+ audio.music_channel = 0;
+ audio.music_nr = 0;
#if defined(TARGET_SDL)
- if (SDLOpenAudio())
- {
- audio->sound_available = TRUE;
- audio->loops_available = TRUE;
- audio->sound_enabled = TRUE;
- }
+ SDLOpenAudio();
#elif defined(PLATFORM_MSDOS)
- if (MSDOSOpenAudio())
- {
- audio->sound_available = TRUE;
- audio->loops_available = TRUE;
- audio->sound_enabled = TRUE;
- }
+ MSDOSOpenAudio();
#elif defined(PLATFORM_UNIX)
- UnixOpenAudio(audio);
+ UnixOpenAudio();
#endif
-
- return audio->sound_available;
}
-inline void CloseAudio(struct AudioSystemInfo *audio)
+inline void CloseAudio(void)
{
#if defined(TARGET_SDL)
SDLCloseAudio();
#elif defined(PLATFORM_MSDOS)
MSDOSCloseAudio();
#elif defined(PLATFORM_UNIX)
- UnixCloseAudio(audio);
+ UnixCloseAudio();
#endif
- audio->sound_available = FALSE;
- audio->loops_available = FALSE;
- audio->sound_enabled = FALSE;
+ audio.sound_enabled = FALSE;
}
inline void SetAudioMode(boolean enabled)
/* contant definitions */
-#define DEFAULT_DEPTH 0
+/* the additional 'b' is needed for Win32 to open files in binary mode */
+#define MODE_READ "rb"
+#define MODE_WRITE "wb"
+#define MODE_APPEND "ab"
-#define FULLSCREEN_NOT_AVAILABLE FALSE
-#define FULLSCREEN_AVAILABLE TRUE
+#define DEFAULT_DEPTH 0
+
+#define FULLSCREEN_NOT_AVAILABLE FALSE
+#define FULLSCREEN_AVAILABLE TRUE
/* values for button_status */
#define MB_NOT_PRESSED FALSE
struct AudioSystemInfo
{
boolean sound_available;
+ boolean music_available;
boolean loops_available;
+ boolean mods_available;
boolean sound_enabled;
+
int soundserver_pipe[2];
int soundserver_pid;
char *device_name;
int device_fd;
+
+ int channels;
+ int music_channel;
+ int music_nr;
};
struct GfxInfo
Bitmap *LoadImage(char *);
-inline boolean OpenAudio(struct AudioSystemInfo *);
-inline void CloseAudio(struct AudioSystemInfo *);
+inline void OpenAudio(void);
+inline void CloseAudio(void);
inline void SetAudioMode(boolean);
inline void InitEventFilter(EventFilter);