shithub: qk1

Download patch

ref: c2239f90fcf09b0cc54c9ff284ad15784b3fafbf
parent: 68f10f24e4b06bfb645839f517ef8c68b898b393
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
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