ref: c2239f90fcf09b0cc54c9ff284ad15784b3fafbf
parent: 68f10f24e4b06bfb645839f517ef8c68b898b393
author: Sigrid Solveig Haflínudóttir <[email protected]>
date: Mon Nov 6 22:27:28 EST 2023
portable sound
--- a/Makefile
+++ b/Makefile
@@ -66,6 +66,7 @@
r_surf.o\
sbar.o\
screen.o\
+ snd.o\
span.o\
span_alpha.o\
sv_main.o\
@@ -77,7 +78,7 @@
unix/net_udp.o\
unix/qk1.o\
unix/seprint.o\
- unix/snd.o\
+ unix/snd_sdl.o\
unix/vid.o\
view.o\
wad.o\
--- a/fns.h
+++ b/fns.h
@@ -58,3 +58,7 @@
char *lerr(void);
int sys_mkdir(char *path);
+
+void sndwrite(uchar *buf, long sz);
+void sndclose(void);
+int sndopen(void);
--- a/host.c
+++ b/host.c
@@ -664,7 +664,7 @@
NET_Shutdown ();
shutcd();
- shutsnd();
+ sndclose();
IN_Shutdown ();
}
--- a/mkfile
+++ b/mkfile
@@ -69,6 +69,7 @@
screen.$O\
sbar.$O\
snd.$O\
+ snd_plan9.$O\
sv_main.$O\
sv_move.$O\
sv_phys.$O\
--- a/snd.c
+++ b/snd.c
@@ -1,5 +1,4 @@
#include "quakedef.h"
-#include <thread.h>
cvar_t volume = {"volume", "0.7", 1};
@@ -34,7 +33,7 @@
static Chan *chans, *che;
-static int afd = -1, mixbufi;
+static int ainit, mixbufi;
static uchar mixbufs[2][Snbuf], *mixbuf = mixbufs[0];
static vlong sndt, sampt;
static int nsamp;
@@ -486,43 +485,12 @@
}
}
-static void
-auproc(void *p)
-{
- long sz;
- uchar *m;
-
- for(;;){
- if((sz = recvul(p)) == 0)
- break;
- m = mixbufs[0];
- if(sz < 0){
- m = mixbufs[1];
- sz = -sz;
- }
- if(write(afd, m, sz) != sz){
- Con_DPrintf("sndwrite: %r\n");
- shutsnd();
- break;
- }
- }
- chanclose(p);
- threadexits(nil);
-}
-
void
stepsnd(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
{
long ns;
Chan *c, *sum;
- static Channel *ach;
- if(afd < 0)
- return;
- if(ach == nil){
- ach = chancreate(sizeof(ulong), 0);
- proccreate(auproc, ach, 4096);
- }
VectorCopy(origin, listener_origin);
VectorCopy(forward, listener_forward);
VectorCopy(right, listener_right);
@@ -559,7 +527,7 @@
sndt = nanosec() - Te9 / Fpsmax;
nsamp = (nanosec() - sndt) / (Te9 / Srate);
if(!cls.timedemo)
- nsamp = nsamp + 15 & ~15;
+ nsamp = (nsamp + 15) & ~15;
if(nsamp > Ssamp)
nsamp = Ssamp;
ns = nsamp * Sblk;
@@ -566,8 +534,8 @@
samplesfx();
sampt += nsamp;
if(ns != 0){
- sendul(ach, mixbufi == 0 ? ns : -ns);
- mixbufi = (mixbufi + 1) % 2;
+ sndwrite(mixbuf, ns);
+ mixbufi = (mixbufi + 1) % nelem(mixbufs);
mixbuf = mixbufs[mixbufi];
}
sndt = nanosec();
@@ -576,7 +544,7 @@
void
stopallsfx(void)
{
- if(afd < 0)
+ if(!ainit)
return;
memset(chans, 0, sizeof(*chans)*Nchan);
che = chans + Sstat;
@@ -587,7 +555,7 @@
{
Chan *c, *e;
- if(afd < 0)
+ if(!ainit)
return;
c = chans;
e = chans + Ndyn;
@@ -633,7 +601,7 @@
Chan *c, *c2, *e;
sfxcache_t *sc;
- if(afd < 0 || sfx == nil)
+ if(!ainit || sfx == nil)
return;
if(c = pickchan(entn, entch), c == nil)
return;
@@ -669,7 +637,7 @@
{
Sfx *sfx;
- if(afd < 0)
+ if(!ainit)
return;
sfx = precachesfx(s);
startsfx(cl.viewentity, -1, sfx, vec3_origin, 1, 1);
@@ -734,7 +702,7 @@
{
Sfx *sfx;
- if(afd < 0)
+ if(!ainit)
return;
sfx = findsfx(s);
Cache_Check(&sfx->cu);
@@ -745,7 +713,7 @@
{
Sfx *sfx;
- if(afd < 0)
+ if(!ainit)
return nil;
sfx = findsfx(s);
sfx->map = map;
@@ -830,22 +798,14 @@
map++;
}
-void
-shutsnd(void)
-{
- if(afd < 0)
- return;
- close(afd);
- afd = -1;
-}
-
int
initsnd(void)
{
int i, j, *p;
- if(afd = open("/dev/audio", OWRITE), afd < 0)
+ if(sndopen() != 0)
return -1;
+ ainit = 1;
for(p=scalt[1], i=8; i<8*nelem(scalt); i+=8)
for(j=0; j<256; j++)
*p++ = (char)j * i;
--- /dev/null
+++ b/snd_plan9.c
@@ -1,0 +1,58 @@
+#include "quakedef.h"
+#include <thread.h>
+
+static int afd;
+static QLock alock;
+static uchar *mixbuf;
+
+static void
+auproc(void *p)
+{
+ long sz, n;
+
+ for(;;){
+ if((sz = recvul(p)) < 1)
+ break;
+ qlock(&alock);
+ n = write(afd, mixbuf, sz);
+ qunlock(&alock);
+ if(n != sz){
+ Con_DPrintf("sndwrite: %r\n");
+ break;
+ }
+ }
+ chanclose(p);
+ threadexits(nil);
+}
+
+void
+sndwrite(uchar *buf, long sz)
+{
+ static Channel *ach;
+
+ if(afd < 0)
+ return;
+ if(ach == nil){
+ ach = chancreate(sizeof(ulong), 0);
+ proccreate(auproc, ach, 4096);
+ }
+ qlock(&alock);
+ sendul(ach, sz);
+ mixbuf = buf;
+ qunlock(&alock);
+}
+
+void
+sndclose(void)
+{
+ close(afd);
+ afd = -1;
+}
+
+int
+sndopen(void)
+{
+ if((afd = open("/dev/audio", OWRITE)) < 0)
+ return -1;
+ return 0;
+}
--- a/unix/qk1.c
+++ b/unix/qk1.c
@@ -21,6 +21,12 @@
return mkdir(path, 0770);
}
+int
+nrand(int n)
+{
+ return random() % n;
+}
+
void
fatal(char *fmt, ...)
{
--- a/unix/snd.c
+++ /dev/null
@@ -1,61 +1,0 @@
-#include "quakedef.h"
-
-cvar_t volume = {"volume", "0.7", 1};
-
-void
-stepsnd(vec3_t origin, vec3_t forward, vec3_t right, vec3_t up)
-{
-}
-
-void
-stopallsfx(void)
-{
-}
-
-void
-stopsfx(int n, int ch)
-{
-}
-
-void
-startsfx(int entn, int entch, Sfx *sfx, vec3_t zp, float vol, float att)
-{
-}
-
-void
-localsfx(char *s)
-{
-}
-
-void
-staticsfx(Sfx *sfx, vec3_t zp, float vol, float att)
-{
-}
-
-void
-touchsfx(char *s)
-{
-}
-
-Sfx *
-precachesfx(char *s)
-{
- return nil;
-}
-
-void
-sfxbegin(void)
-{
-}
-
-void
-shutsnd(void)
-{
-}
-
-int
-initsnd(void)
-{
- Cvar_RegisterVariable(&volume);
- return -1;
-}
--- /dev/null
+++ b/unix/snd_sdl.c
@@ -1,0 +1,47 @@
+#include "quakedef.h"
+#include <SDL.h>
+
+static SDL_AudioDeviceID adev;
+
+void
+sndwrite(uchar *buf, long sz)
+{
+ if(adev != 0 && SDL_QueueAudio(adev, buf, sz) != 0){
+ Con_Printf("sndwrite: %s\n", SDL_GetError());
+ sndclose();
+ }
+}
+
+void
+sndclose(void)
+{
+ if(adev != 0){
+ SDL_CloseAudioDevice(adev);
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ adev = 0;
+ }
+}
+
+int
+sndopen(void)
+{
+ SDL_AudioSpec got, want = {
+ .freq = 44100,
+ .format = AUDIO_S16LSB,
+ .channels = 2,
+ .samples = 441,
+ 0,
+ };
+
+ if(SDL_InitSubSystem(SDL_INIT_AUDIO) != 0){
+err:
+ Con_Printf("sndopen: %s\n", SDL_GetError());
+ return -1;
+ }
+ if((adev = SDL_OpenAudioDevice(nil, 0, &want, &got, SDL_AUDIO_ALLOW_SAMPLES_CHANGE)) == 0){
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ goto err;
+ }
+ SDL_PauseAudioDevice(adev, 0);
+ return 0;
+}
--- a/unix/u.h
+++ b/unix/u.h
@@ -47,3 +47,4 @@
#define werrstr(fmt, ...) do{snprint(lasterr, sizeof(lasterr), fmt, __VA_ARGS__); }while(0)
char *seprint(char *, char *, char *, ...);
+int nrand(int);
--- a/unix/vid.c
+++ b/unix/vid.c
@@ -26,20 +26,7 @@
vid.width = 320;
if(vid.height < 160)
vid.height = 160;
- if(d_pzbuffer != nil){
- D_FlushCaches();
- free(d_pzbuffer);
- d_pzbuffer = nil;
- }
- // alloc an extra line in case we want to wrap, and allocate the z-buffer
- hunkvbuf = vid.width * vid.height * sizeof *d_pzbuffer;
- scachesz = D_SurfaceCacheForRes(vid.width, vid.height);
- hunkvbuf += scachesz;
- d_pzbuffer = emalloc(hunkvbuf);
- surfcache = (byte *)d_pzbuffer + vid.width * vid.height * sizeof *d_pzbuffer;
- D_InitCaches(surfcache, scachesz);
-
vid.rowbytes = vid.width;
vid.aspect = (float)vid.height / (float)vid.width * (320.0/240.0);
vid.conrowbytes = vid.rowbytes;
@@ -59,6 +46,20 @@
vid.buffer = vidbuffer;
vid.conbuffer = vid.buffer;
+
+ if(d_pzbuffer != nil){
+ D_FlushCaches();
+ free(d_pzbuffer);
+ d_pzbuffer = nil;
+ }
+
+ // alloc an extra line in case we want to wrap, and allocate the z-buffer
+ hunkvbuf = vid.width * vid.height * sizeof *d_pzbuffer;
+ scachesz = D_SurfaceCacheForRes(vid.width, vid.height);
+ hunkvbuf += scachesz;
+ d_pzbuffer = emalloc(hunkvbuf);
+ surfcache = (byte *)d_pzbuffer + vid.width * vid.height * sizeof *d_pzbuffer;
+ D_InitCaches(surfcache, scachesz);
}
void