aboutsummaryrefslogtreecommitdiffstats
path: root/QW/client/snd_sdl.c
diff options
context:
space:
mode:
authorwyatt8740 <wyatt8740@users.noreply.github.com>2023-10-01 23:53:17 -0400
committerwyatt8740 <wyatt8740@users.noreply.github.com>2023-10-02 00:00:01 -0400
commit72d9253ab2e5e0630c824c7130a40b7158323bc9 (patch)
treefc12bd36b3eb63ef6aeae213018d4f89981a08f4 /QW/client/snd_sdl.c
parent68254ebe0411236d178ead073d5c176faae732a1 (diff)
downloadquake-pum-72d9253ab2e5e0630c824c7130a40b7158323bc9.tar.gz
Got X11 QuakeWorld to build (no GLQuakeWorld yet!).
Added support for 24-bit color depth (ripped out of WinQuake, which appears to have a newer version of vid_x.c). Also, added SDL audio code (almost directly translated from WinQuake/netquake code).
Diffstat (limited to 'QW/client/snd_sdl.c')
-rw-r--r--QW/client/snd_sdl.c215
1 files changed, 215 insertions, 0 deletions
diff --git a/QW/client/snd_sdl.c b/QW/client/snd_sdl.c
new file mode 100644
index 0000000..a65758c
--- /dev/null
+++ b/QW/client/snd_sdl.c
@@ -0,0 +1,215 @@
+/*
+ * snd_sdl.c - SDL audio driver for Hexen II: Hammer of Thyrion (uHexen2)
+ * based on implementations found in the quakeforge and ioquake3 projects.
+ *
+ * Copyright (C) 1999-2005 Id Software, Inc.
+ * Copyright (C) 2005-2012 O.Sezer <sezero@users.sourceforge.net>
+ * Copyright (C) 2010-2014 QuakeSpasm developers
+ *
+ * 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 lat er 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "quakedef.h"
+
+#if defined(SDL_FRAMEWORK) || defined(NO_SDL_CONFIG)
+#if defined(USE_SDL2)
+#include <SDL2/SDL.h>
+#else
+#include <SDL/SDL.h>
+#endif
+#else
+#include "SDL.h"
+#endif
+
+static int buffersize;
+
+
+static void SDLCALL paint_audio (void *unused, Uint8 *stream, int len)
+{
+ int pos, tobufend;
+ int len1, len2;
+
+ if (!shm)
+ { /* shouldn't happen, but just in case */
+ memset(stream, 0, len);
+ return;
+ }
+
+ pos = (shm->samplepos * (shm->samplebits / 8));
+ if (pos >= buffersize)
+ shm->samplepos = pos = 0;
+
+ tobufend = buffersize - pos; /* bytes to buffer's end. */
+ len1 = len;
+ len2 = 0;
+
+ if (len1 > tobufend)
+ {
+ len1 = tobufend;
+ len2 = len - len1;
+ }
+
+ memcpy(stream, shm->buffer + pos, len1);
+
+ if (len2 <= 0)
+ {
+ shm->samplepos += (len1 / (shm->samplebits / 8));
+ }
+ else
+ { /* wraparound? */
+ memcpy(stream + len1, shm->buffer, len2);
+ shm->samplepos = (len2 / (shm->samplebits / 8));
+ }
+
+ if (shm->samplepos >= buffersize)
+ shm->samplepos = 0;
+}
+
+qboolean SNDDMA_Init (dma_t *dma)
+{
+ SDL_AudioSpec desired;
+ int tmp, val;
+ char drivername[128];
+
+ if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
+ {
+ Con_Printf("Couldn't init SDL audio: %s\n", SDL_GetError());
+ return false;
+ }
+
+ /* Set up the desired format */
+/* desired.freq = snd_mixspeed.value;*/
+ desired.freq = 44100;
+ desired.format = (loadas8bit.value) ? AUDIO_U8 : AUDIO_S16SYS;
+ desired.channels = 2; /* = desired_channels; */
+ if (desired.freq <= 11025)
+ desired.samples = 256;
+ else if (desired.freq <= 22050)
+ desired.samples = 512;
+ else if (desired.freq <= 44100)
+ desired.samples = 1024;
+ else if (desired.freq <= 56000)
+ desired.samples = 2048; /* for 48 kHz */
+ else
+ desired.samples = 4096; /* for 96 kHz */
+ desired.callback = paint_audio;
+ desired.userdata = NULL;
+
+ /* Open the audio device */
+ if (SDL_OpenAudio(&desired, NULL) == -1)
+ {
+ Con_Printf("Couldn't open SDL audio: %s\n", SDL_GetError());
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ return false;
+ }
+ /* i think i'm just zeroing dma mem here */
+ memset ((void *) dma, 0, sizeof(dma_t));
+ /*shm = dma;*/
+ shm = &sn;
+
+ /* Fill the audio DMA information block */
+ /* Since we passed NULL as the 'obtained' spec to SDL_OpenAudio(),
+ * SDL will convert to hardware format for us if needed, hence we
+ * directly use the desired values here. */
+ shm->samplebits = (desired.format & 0xFF); /* first byte of format is bits */
+/* shm->signed8 = (desired.format == AUDIO_S8);*/
+ shm->speed = desired.freq;
+ shm->channels = desired.channels;
+ tmp = (desired.samples * desired.channels) * 10;
+ if (tmp & (tmp - 1))
+ { /* make it a power of two */
+ val = 1;
+ while (val < tmp)
+ val <<= 1;
+
+ tmp = val;
+ }
+ shm->samples = tmp;
+ shm->samplepos = 0;
+ shm->submission_chunk = 1;
+
+ Con_Printf ("SDL audio spec : %d Hz, %d samples, %d channels\n",
+ desired.freq, desired.samples, desired.channels);
+#if defined(USE_SDL2)
+ {
+ const char *driver = SDL_GetCurrentAudioDriver();
+ const char *device = SDL_GetAudioDeviceName(0, SDL_FALSE);
+ snprintf(drivername, sizeof(drivername), "%s - %s",
+ driver != NULL ? driver : "(UNKNOWN)",
+ device != NULL ? device : "(UNKNOWN)");
+ }
+#else
+ if (SDL_AudioDriverName(drivername, sizeof(drivername)) == NULL)
+ strcpy(drivername, "(UNKNOWN)");
+#endif
+ buffersize = shm->samples * (shm->samplebits / 8);
+ Con_Printf ("SDL audio driver: %s, %d bytes buffer\n", drivername, buffersize);
+
+ shm->buffer = (unsigned char *) calloc (1, buffersize);
+// if (!shm->buffer)
+ if (!shm->buffer || shm->buffer == (unsigned char *)-1)
+ {
+ SDL_CloseAudio();
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ shm = NULL;
+ Con_Printf ("Failed allocating memory for SDL audio\n");
+ return false;
+ }
+
+ SDL_PauseAudio(0);
+
+ return true;
+}
+
+int SNDDMA_GetDMAPos (void)
+{
+ return shm->samplepos;
+}
+
+void SNDDMA_Shutdown (void)
+{
+ if (shm)
+ {
+ Con_Printf ("Shutting down SDL sound\n");
+ SDL_CloseAudio();
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ if (shm->buffer)
+ free (shm->buffer);
+ shm->buffer = NULL;
+ shm = NULL;
+ }
+}
+
+void SNDDMA_LockBuffer (void)
+{
+ SDL_LockAudio ();
+}
+
+void SNDDMA_Submit (void)
+{
+ SDL_UnlockAudio();
+}
+
+void SNDDMA_BlockSound (void)
+{
+ SDL_PauseAudio(1);
+}
+
+void SNDDMA_UnblockSound (void)
+{
+ SDL_PauseAudio(0);
+}
+