ref: 8704f54821db7652060336480bde2579a7ed52cc
parent: 2c1bc1ec75ce27072fa50967ca79a469d80796ba
author: qwx <qwx@sciops.net>
date: Wed Jan 29 23:25:02 EST 2025
snd: move sfx and music to its own proc
--- a/fns.h
+++ b/fns.h
@@ -90,10 +90,10 @@
uchar* opl2out(uchar*, int);
void opl2wr(int, int);
void opl2init(int);
-void sndstep(void);
void stopsfx(void);
int lastsfx(void);
void sfxatt(int, int, int, int);
+void locksfx(int);
void sfx(int);
void stopmus(void);
void mus(int);
--- a/gm.c
+++ b/gm.c
@@ -1435,8 +1435,7 @@
tl->tl++; /* flip switch */
gm.end = oplr->tl->p0 == MTsetec ? EDsetec : EDup;
stopmus();
- sfx(Slvlend);
- sfxlck++;
+ locksfx(Slvlend);
return;
/* bug: 1<<6 may be set around pushwalls and cause memory
* corruption if this check goes through by writing past the
--- a/snd.c
+++ b/snd.c
@@ -10,6 +10,15 @@
int sfxon, muson, pcmon;
int sfxlck;
+typedef struct Snd Snd;
+struct Snd{
+ int n;
+ int att;
+ int x;
+ int y;
+ int lock;
+};
+
enum{
Rate = 44100,
PcmHz = 7000,
@@ -31,10 +40,10 @@
static Sfx *sfxd, *pcmd;
static Dat *imfd;
static vlong stc, sdt, mdt;
-static int sfd = -1;
static Pcmconv *pcmc;
static uchar sbuf[Nbuf], *pcmbuf;
static int bufsz, leftover;
+static Channel *musc, *sndc;
static u8int ratt[][30] = {
{8,8,8,8,8,8,8,7,7,7,7,7,7,6,0,0,0,0,0,1,3,5,8,8,8,8,8,8,8,8},
@@ -119,26 +128,6 @@
sdt = stc + ImfHz / SfxHz;
}
-/* this spins constantly even when there's no music being played continuously,
- * in essence only because some sound effects need an echo to play correctly.
- * it sucks. */
-static int
-opl2step(void)
-{
- uchar *p, *e;
-
- if(!muson && !sfxon)
- return -1;
- for(p=sbuf, e=p+sizeof sbuf; p<e; stc++){
- if(stc == sdt && sfxd != nil)
- alcmd();
- if(stc == mdt && imfd != nil)
- imfcmd();
- p = opl2out(p, Nsamp);
- }
- return 0;
-}
-
static void
setvol(void)
{
@@ -167,6 +156,54 @@
rvol = 16 - ratt[x][nelem(latt)+y];
}
+static void
+killsfx(void)
+{
+ stopal();
+ pcm = pcme = nil;
+ pcmd = nil;
+}
+
+int
+lastsfx(void)
+{
+ if(pcm < pcme)
+ return pcmd - sfxs;
+ else if(sfxd != nil)
+ return sfxd - sfxs;
+ return -1;
+}
+
+static void
+killmus(void)
+{
+ int i;
+
+ killsfx();
+ if(!muson && !sfxon)
+ return;
+ for(i=Roct+1; i<Roct+9; i++)
+ opl2wr(i, 0);
+ imf = nil;
+ imfd = nil;
+}
+
+static void
+playmus(int n)
+{
+ Dat *d;
+
+ d = imfs+n;
+ if(!muson || d == imfd)
+ return;
+ killmus();
+ if(n < 0)
+ return;
+ mdt = stc;
+ imfd = d;
+ imf = d->p;
+}
+
static uchar *
mix(uchar *s, uchar *p, int n)
{
@@ -195,6 +232,23 @@
return s;
}
+static int
+opl2step(void)
+{
+ uchar *p, *e;
+
+ if(!muson && !sfxon)
+ return -1;
+ for(p=sbuf, e=p+sizeof sbuf; p<e; stc++){
+ if(stc == sdt && sfxd != nil)
+ alcmd();
+ if(stc == mdt && imfd != nil)
+ imfcmd();
+ p = opl2out(p, Nsamp);
+ }
+ return 0;
+}
+
static void
pcmstep(void)
{
@@ -226,50 +280,19 @@
pcm = e;
}
-void
-sndstep(void)
+static void
+playsfx(Snd *snd)
{
- if(sfd < 0)
- return;
- if(opl2step() < 0){
- if(!pcmon)
- return;
- memset(sbuf, 0, sizeof sbuf);
- }
- pcmstep();
- if(!nosleep && write(sfd, sbuf, sizeof sbuf) != sizeof sbuf)
- sysfatal("sndstep: %r\n");
-}
-
-void
-stopsfx(void)
-{
- if(sfd < 0)
- return;
- stopal();
- pcm = pcme = nil;
- pcmd = nil;
-}
-
-int
-lastsfx(void)
-{
- if(pcm < pcme)
- return pcmd - sfxs;
- else if(sfxd != nil)
- return sfxd - sfxs;
- return -1;
-}
-
-void
-sfxatt(int n, int att, int x, int y)
-{
Sfx *s;
uchar *r, *i;
- if(sfd < 0 || sfxlck)
+ if(sfxlck)
return;
- s = sfxs+n;
+ if(snd->n < 0){
+ killsfx();
+ return;
+ }
+ s = sfxs + snd->n;
if(pcmon && s->pcm != nil){
if(pcm < pcme && s->pri < pcmd->pri)
return;
@@ -276,9 +299,9 @@
pcmd = s;
pcm = s->pcm->p;
pcme = s->pcm->e;
- if(atton = att){
- attx = x;
- atty = y;
+ if(atton = snd->att){
+ attx = snd->x;
+ atty = snd->y;
}
}else if(sfxon){
if(sfxd != nil && s->pri < sfxd->pri)
@@ -293,52 +316,63 @@
while(r < inst + sizeof inst)
opl2wr(*r++, *i++);
}
+ if(snd->lock)
+ sfxlck = 1;
}
void
-sfx(int n)
+mus(int n)
{
- sfxatt(n, 0, 0, 0);
+ send(musc, &n);
}
void
stopmus(void)
{
- int i;
+ int n;
- if(sfd < 0)
- return;
- stopsfx();
- if(!muson && !sfxon)
- return;
- for(i=Roct+1; i<Roct+9; i++)
- opl2wr(i, 0);
- imf = nil;
- imfd = nil;
+ n = -1;
+ send(musc, &n);
}
void
-mus(int n)
+sfxatt(int n, int att, int x, int y)
{
- Dat *d;
+ Snd s;
- d = imfs+n;
- if(sfd < 0 || !muson || d == imfd)
- return;
- stopmus();
- mdt = stc;
- imfd = d;
- imf = d->p;
+ s = (Snd){n, att, x, y, 0},
+ send(sndc, &s);
}
void
-initsnd(void)
+locksfx(int n)
{
- int n, fd;
+ Snd s;
+
+ s = (Snd){n, 0, 0, 0, 1},
+ send(sndc, &s);
+}
+
+void
+sfx(int n)
+{
+ sfxatt(n, 0, 0, 0);
+}
+
+void
+stopsfx(void)
+{
+ sfxatt(-1, 0, 0, 0);
+}
+
+static void
+sndproc(void *)
+{
+ int fd, n, m;
Pcmdesc i, o;
+ Snd snd;
- fd = open("/dev/audio", OWRITE);
- if(fd < 0){
+ if((fd = open("/dev/audio", OWRITE)) < 0){
fprint(2, "initsnd: %r\n");
return;
}
@@ -354,5 +388,38 @@
opl2wr(Rwse, 0x20);
opl2wr(Ropm, 0);
opl2wr(Rfed, 0);
- sfd = fd;
+ enum{
+ Amus,
+ Asfx,
+ };
+ Alt a[] = {
+ [Amus] {musc, &m, CHANRCV},
+ [Asfx] {sndc, &snd, CHANRCV},
+ {nil, nil, CHANNOBLK},
+ };
+ for(;;){
+ switch(alt(a)){
+ default: break;
+ case Amus: playmus(m); break;
+ case Asfx: playsfx(&snd); break;
+ }
+ if(opl2step() < 0){
+ if(!pcmon)
+ continue;
+ memset(sbuf, 0, sizeof sbuf);
+ }
+ pcmstep();
+ if(write(fd, sbuf, sizeof sbuf) != sizeof sbuf)
+ sysfatal("sndproc: %r");
+ }
+}
+
+void
+initsnd(void)
+{
+ if((sndc = chancreate(sizeof(Snd), 1)) == nil
+ || (musc = chancreate(sizeof(int), 1)) == nil)
+ sysfatal("chancreate: %r");
+ if(proccreate(sndproc, nil, mainstacksize) < 0)
+ sysfatal("proccreate: %r");
}
--- a/wl3d.c
+++ b/wl3d.c
@@ -290,7 +290,6 @@
resetfb();
}
step();
- sndstep();
t = nsec();
tc = (t - t0) / Td;
if(tc <= 0)
--
⑨