games/nes: best commit (fixed audio and timing)
This commit is contained in:
parent
ad9047ab2c
commit
9486df09c2
|
@ -5,10 +5,11 @@
|
||||||
#include "dat.h"
|
#include "dat.h"
|
||||||
#include "fns.h"
|
#include "fns.h"
|
||||||
|
|
||||||
|
enum { MAXBUF = 2000 };
|
||||||
|
|
||||||
u8int apuseq, apuctr[10];
|
u8int apuseq, apuctr[10];
|
||||||
static int fd;
|
static int fd;
|
||||||
|
static short sbuf[2*MAXBUF], *sbufp;
|
||||||
enum { RATE = 44100 };
|
|
||||||
|
|
||||||
int
|
int
|
||||||
targperiod(int i)
|
targperiod(int i)
|
||||||
|
@ -204,31 +205,36 @@ dmc(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
sample(short *s)
|
audiosample(void)
|
||||||
{
|
{
|
||||||
double d;
|
double d;
|
||||||
|
|
||||||
|
if(sbufp == nil)
|
||||||
|
return;
|
||||||
d = 95.88 / (8128.0 / (0.01 + pulse(0) + pulse(1)) + 100);
|
d = 95.88 / (8128.0 / (0.01 + pulse(0) + pulse(1)) + 100);
|
||||||
d += 159.79 / (1.0 / (0.01 + tri()/8227.0 + noise()/12241.0 + dmc()/22638.0) + 100.0);
|
d += 159.79 / (1.0 / (0.01 + tri()/8227.0 + noise()/12241.0 + dmc()/22638.0) + 100.0);
|
||||||
*s++ = d * 20000;
|
if(sbufp < sbuf + nelem(sbuf) - 1){
|
||||||
*s = d * 20000;
|
*sbufp++ = d * 20000;
|
||||||
|
*sbufp++ = d * 20000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
int
|
||||||
audioproc(void *)
|
audioout(void)
|
||||||
{
|
{
|
||||||
static short samples[500 * 2];
|
int rc;
|
||||||
int i;
|
|
||||||
|
|
||||||
for(;;){
|
if(sbufp == nil)
|
||||||
if(paused)
|
return -1;
|
||||||
memset(samples, 0, sizeof samples);
|
if(sbufp == sbuf)
|
||||||
else
|
return 0;
|
||||||
for(i = 0; i < sizeof samples/4; i++)
|
rc = write(fd, sbuf, (sbufp - sbuf) * 2);
|
||||||
sample(samples + 2 * i);
|
if(rc > 0)
|
||||||
write(fd, samples, sizeof samples);
|
sbufp -= (rc+1)/2;
|
||||||
}
|
if(sbufp < sbuf)
|
||||||
|
sbufp = sbuf;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -237,7 +243,7 @@ initaudio(void)
|
||||||
fd = open("/dev/audio", OWRITE);
|
fd = open("/dev/audio", OWRITE);
|
||||||
if(fd < 0)
|
if(fd < 0)
|
||||||
return;
|
return;
|
||||||
proccreate(audioproc, nil, 8192);
|
sbufp = sbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
u8int apulen[32] = {
|
u8int apulen[32] = {
|
||||||
|
|
|
@ -76,6 +76,8 @@ enum {
|
||||||
MILLION = 1000000,
|
MILLION = 1000000,
|
||||||
BILLION = 1000000000,
|
BILLION = 1000000000,
|
||||||
APUDIV = 89490,
|
APUDIV = 89490,
|
||||||
|
RATE = 44100,
|
||||||
|
SAMPDIV = FREQ / RATE,
|
||||||
SAVEFREQ = FREQ/5,
|
SAVEFREQ = FREQ/5,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -11,3 +11,5 @@ void put8(u8int);
|
||||||
int get8(void);
|
int get8(void);
|
||||||
void apustep(void);
|
void apustep(void);
|
||||||
void initaudio(void);
|
void initaudio(void);
|
||||||
|
void audiosample(void);
|
||||||
|
int audioout(void);
|
||||||
|
|
|
@ -13,7 +13,7 @@ uchar *prg, *chr;
|
||||||
int scale;
|
int scale;
|
||||||
Rectangle picr;
|
Rectangle picr;
|
||||||
Image *tmp, *bg;
|
Image *tmp, *bg;
|
||||||
int clock, ppuclock, apuclock, syncclock, syncfreq, checkclock, msgclock, saveclock, sleeps;
|
int clock, ppuclock, apuclock, sampclock, msgclock, saveclock;
|
||||||
Mousectl *mc;
|
Mousectl *mc;
|
||||||
int keys, paused, savereq, loadreq, oflag, savefd = -1;
|
int keys, paused, savereq, loadreq, oflag, savefd = -1;
|
||||||
int mirr;
|
int mirr;
|
||||||
|
@ -184,7 +184,6 @@ threadmain(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int t, h, sflag;
|
int t, h, sflag;
|
||||||
Point p;
|
Point p;
|
||||||
uvlong old, new, diff;
|
|
||||||
|
|
||||||
scale = 1;
|
scale = 1;
|
||||||
h = 240;
|
h = 240;
|
||||||
|
@ -231,8 +230,6 @@ threadmain(int argc, char **argv)
|
||||||
|
|
||||||
pc = memread(0xFFFC) | memread(0xFFFD) << 8;
|
pc = memread(0xFFFC) | memread(0xFFFD) << 8;
|
||||||
rP = FLAGI;
|
rP = FLAGI;
|
||||||
syncfreq = FREQ / 30;
|
|
||||||
old = nsec();
|
|
||||||
for(;;){
|
for(;;){
|
||||||
if(savereq){
|
if(savereq){
|
||||||
savestate("nes.save");
|
savestate("nes.save");
|
||||||
|
@ -250,8 +247,9 @@ threadmain(int argc, char **argv)
|
||||||
clock += t;
|
clock += t;
|
||||||
ppuclock += t;
|
ppuclock += t;
|
||||||
apuclock += t;
|
apuclock += t;
|
||||||
syncclock += t;
|
sampclock += t;
|
||||||
checkclock += t;
|
//syncclock += t;
|
||||||
|
//checkclock += t;
|
||||||
while(ppuclock >= 4){
|
while(ppuclock >= 4){
|
||||||
ppustep();
|
ppustep();
|
||||||
ppuclock -= 4;
|
ppuclock -= 4;
|
||||||
|
@ -260,24 +258,9 @@ threadmain(int argc, char **argv)
|
||||||
apustep();
|
apustep();
|
||||||
apuclock -= APUDIV;
|
apuclock -= APUDIV;
|
||||||
}
|
}
|
||||||
if(syncclock >= syncfreq){
|
if(sampclock >= SAMPDIV){
|
||||||
sleep(10);
|
audiosample();
|
||||||
sleeps++;
|
sampclock -= SAMPDIV;
|
||||||
syncclock = 0;
|
|
||||||
}
|
|
||||||
if(checkclock >= FREQ){
|
|
||||||
new = nsec();
|
|
||||||
diff = new - old - sleeps * 10 * MILLION;
|
|
||||||
diff = BILLION - diff;
|
|
||||||
if(diff <= 0)
|
|
||||||
syncfreq = FREQ;
|
|
||||||
else
|
|
||||||
syncfreq = ((vlong)FREQ) * 10 * MILLION / diff;
|
|
||||||
if(syncfreq < FREQ / 100)
|
|
||||||
syncfreq = FREQ / 100;
|
|
||||||
old = new;
|
|
||||||
checkclock = 0;
|
|
||||||
sleeps = 0;
|
|
||||||
}
|
}
|
||||||
if(msgclock > 0){
|
if(msgclock > 0){
|
||||||
msgclock -= t;
|
msgclock -= t;
|
||||||
|
|
|
@ -255,6 +255,8 @@ flush(void)
|
||||||
extern Rectangle picr;
|
extern Rectangle picr;
|
||||||
extern Image *tmp, *bg;
|
extern Image *tmp, *bg;
|
||||||
extern Mousectl *mc;
|
extern Mousectl *mc;
|
||||||
|
static vlong old, diff;
|
||||||
|
vlong new;
|
||||||
Mouse m;
|
Mouse m;
|
||||||
Point p;
|
Point p;
|
||||||
int h;
|
int h;
|
||||||
|
@ -282,6 +284,15 @@ flush(void)
|
||||||
loadimage(screen, picr, pic + oflag*8*256*4*scale*scale, 256*h*4*scale*scale);
|
loadimage(screen, picr, pic + oflag*8*256*4*scale*scale, 256*h*4*scale*scale);
|
||||||
flushimage(display, 1);
|
flushimage(display, 1);
|
||||||
memset(pic, sizeof pic, 0);
|
memset(pic, sizeof pic, 0);
|
||||||
|
if(audioout() < 0){
|
||||||
|
new = nsec();
|
||||||
|
if(old != 0){
|
||||||
|
diff = BILLION/60 - (new - old);
|
||||||
|
if(diff >= MILLION)
|
||||||
|
sleep(diff/MILLION);
|
||||||
|
}
|
||||||
|
old = new;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in a new issue