quake: migrate to SDL_mixer and add background music

Kind of skippy and only supports WAV. MP3 would be nice, especially if
using Rockbox's codec.

Change-Id: I0bba195603da32da1e4d1dcf2ee821fa5696824a
This commit is contained in:
Franklin Wei 2019-08-04 14:58:37 -04:00 committed by Solomon Peachy
parent f5d31fc1c4
commit 54b3b6f797
4 changed files with 150 additions and 33 deletions

View file

@ -1,4 +1,4 @@
progs/quake/cd_null.c progs/quake/cd_rockbox.c
progs/quake/chase.c progs/quake/chase.c
progs/quake/cl_demo.c progs/quake/cl_demo.c
progs/quake/cl_input.c progs/quake/cl_input.c

View file

@ -190,6 +190,8 @@
#define EOF (-1) #define EOF (-1)
#define LOAD_XPM #define LOAD_XPM
#define WAV_MUSIC
#define MID_MUSIC #define MID_MUSIC
#define USE_TIMIDITY_MIDI #define USE_TIMIDITY_MIDI

View file

@ -0,0 +1,123 @@
/*
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of 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 of
MERCHANTABILITY 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 License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* Background music for Rockbox. Uses SDL_mixer and plays from
* /.rockbox/quake/%02d.wav */
#include "quakedef.h"
#include "SDL_mixer.h"
#define MUSIC_DIR ROCKBOX_DIR "/quake"
#if 1
static Mix_Music *mus = NULL;
#else
static int musfile = -1;
static int musfile_len, musfile_pos;
#define MP3_CHUNK 1024*512
static char mp3buf[MP3_CHUNK];
static void get_mp3(const void **start, size_t *size)
{
if(musfile >= 0)
{
int len = MIN(musfile_len - musfile_pos, MP3_CHUNK);
Sys_FileRead(musfile, mp3buf, len);
*start = mp3buf;
*size = len;
musfile_pos += len;
}
}
#endif
void CDAudio_Play(byte track, qboolean looping)
{
char path[MAX_PATH];
snprintf(path, sizeof(path), "%s/%02d.wav", MUSIC_DIR, track - 1);
rb->splashf(HZ, "playing %s", path);
#if 1
mus = Mix_LoadMUS(path);
if(!mus)
{
rb->splashf(HZ, "Failed: %s", Mix_GetError());
return;
}
Mix_PlayMusic(mus, looping ? -1 : 0);
#else
musfile_len = Sys_FileOpenRead(path, &musfile);
musfile_pos = 0;
rb->mp3_play_data(NULL, 0, get_mp3);
#endif
}
void CDAudio_Stop(void)
{
if ( (Mix_PlayingMusic()) || (Mix_PausedMusic()) )
Mix_HaltMusic();
}
void CDAudio_Pause(void)
{
Mix_PauseMusic();
}
void CDAudio_Resume(void)
{
Mix_ResumeMusic();
}
void CDAudio_Update(void)
{
//Mix_VolumeMusic(bgmvolume.value * SDL_MIX_MAXVOLUME);
}
int CDAudio_Init(void)
{
rb->splashf(HZ, "CD Init");
if(Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024)==-1) {
rb->splashf(HZ, "Mix_OpenAudio: %s\n", Mix_GetError());
return -1;
}
return 0;
}
void CDAudio_Shutdown(void)
{
if(mus)
Mix_FreeMusic(mus);
CDAudio_Stop();
}

View file

@ -2,6 +2,7 @@
#include <stdio.h> #include <stdio.h>
#include "SDL_audio.h" #include "SDL_audio.h"
#include "SDL_byteorder.h" #include "SDL_byteorder.h"
#include "SDL_mixer.h"
#include "quakedef.h" #include "quakedef.h"
static dma_t the_shm; static dma_t the_shm;
@ -11,7 +12,7 @@ extern int desired_speed;
extern int desired_bits; extern int desired_bits;
// SDL hereby demands `len' samples in stream, *NOW*! // SDL hereby demands `len' samples in stream, *NOW*!
static void paint_audio(void *unused, Uint8 *stream, int len) static void paint_audio(int chan, Uint8 *stream, int len, void *unused)
{ {
if ( shm ) { if ( shm ) {
shm->buffer = stream; shm->buffer = stream;
@ -46,49 +47,40 @@ qboolean SNDDMA_Init(void)
} }
desired.channels = 2; desired.channels = 2;
desired.samples = 1024; desired.samples = 1024;
desired.callback = paint_audio; //desired.callback = paint_audio;
if( Mix_OpenAudio(desired_speed, desired.format, desired.channels, desired.samples) < 0 )
{
Con_Printf("Couldn't open SDL audio: %s\n", Mix_GetError());
return 0;
}
Mix_RegisterEffect(0, paint_audio, NULL, NULL);
#if 0
/* Open the audio device */ /* Open the audio device */
if ( SDL_OpenAudio(&desired, &obtained) < 0 ) { if ( SDL_OpenAudio(&desired, &obtained) < 0 ) {
Con_Printf("Couldn't open SDL audio: %s\n", SDL_GetError()); Con_Printf("Couldn't open SDL audio: %s\n", SDL_GetError());
return 0; return 0;
} }
#endif
void *blank_buf = (Uint8 *)malloc(4096);
memset(blank_buf, 0, 4096);
Mix_Chunk *blank = Mix_QuickLoad_RAW(blank_buf, 4096);
Mix_PlayChannel(0, blank, -1);
/* Make sure we can support the audio format */
switch (obtained.format) {
case AUDIO_U8:
/* Supported */
break;
case AUDIO_S16LSB:
case AUDIO_S16MSB:
if ( ((obtained.format == AUDIO_S16LSB) &&
(SDL_BYTEORDER == SDL_LIL_ENDIAN)) ||
((obtained.format == AUDIO_S16MSB) &&
(SDL_BYTEORDER == SDL_BIG_ENDIAN)) ) {
/* Supported */
break;
}
/* Unsupported, fall through */;
default:
/* Not supported -- force SDL to do our bidding */
SDL_CloseAudio();
if ( SDL_OpenAudio(&desired, NULL) < 0 ) {
Con_Printf("Couldn't open SDL audio: %s\n",
SDL_GetError());
return 0;
}
memcpy(&obtained, &desired, sizeof(desired));
break;
}
SDL_PauseAudio(0); SDL_PauseAudio(0);
/* Fill the audio DMA information block */ /* Fill the audio DMA information block */
shm = &the_shm; shm = &the_shm;
shm->splitbuffer = 0; shm->splitbuffer = 0;
shm->samplebits = (obtained.format & 0xFF); shm->samplebits = (desired.format & 0xFF);
shm->speed = obtained.freq; shm->speed = desired.freq;
shm->channels = obtained.channels; shm->channels = desired.channels;
shm->samples = obtained.samples*shm->channels; shm->samples = desired.samples*shm->channels;
shm->samplepos = 0; shm->samplepos = 0;
shm->submission_chunk = 1; shm->submission_chunk = 1;
shm->buffer = NULL; shm->buffer = NULL;