⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unix.cpp

📁 SFC游戏模拟器 snes9x 1.43 的原代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	so.sound_switch ^= 1 << c;    S9xSetSoundControl (so.sound_switch);}static void SoundTrigger (){    if (Settings.APUEnabled && !so.mute_sound)	S9xProcessSound (NULL);}void StopTimer (){    struct itimerval timeout;    timeout.it_interval.tv_sec = 0;    timeout.it_interval.tv_usec = 0;    timeout.it_value.tv_sec = 0;    timeout.it_value.tv_usec = 0;    if (setitimer (ITIMER_REAL, &timeout, NULL) < 0)	perror ("setitimer");}void InitTimer (){    struct itimerval timeout;    struct sigaction sa;    #ifdef USE_THREADS    if (Settings.ThreadSound)    {	pthread_mutex_init (&mutex, NULL);	pthread_create (&thread, NULL, S9xProcessSound, NULL);	return;    }#endif    sa.sa_handler = (SIG_PF) SoundTrigger;#if defined (SA_RESTART)    sa.sa_flags = SA_RESTART;#else    sa.sa_flags = 0;#endif    #ifndef NOSOUND //FIXME: Kludge to get calltree running. Remove later.    sigemptyset (&sa.sa_mask);    sigaction (SIGALRM, &sa, NULL);        timeout.it_interval.tv_sec = 0;    timeout.it_interval.tv_usec = 10000;    timeout.it_value.tv_sec = 0;    timeout.it_value.tv_usec = 10000;    if (setitimer (ITIMER_REAL, &timeout, NULL) < 0)	perror ("setitimer");#endif}void S9xSyncSpeed (){#ifdef _NETPLAY_SUPPORT    if (Settings.NetPlay)    {	// XXX: Send joypad position update to server	// XXX: Wait for heart beat from server	S9xNetPlaySendJoypadUpdate (joypads [0]);	if (!S9xNetPlayCheckForHeartBeat ())	{	    do	    {		CHECK_SOUND ();		S9xProcessEvents (FALSE);	    } while (!S9xNetPlayCheckForHeartBeat ());	    IPPU.RenderThisFrame = TRUE;	    IPPU.SkippedFrames = 0;	}	else	{	    if (IPPU.SkippedFrames < 10)	    {		IPPU.SkippedFrames++;		IPPU.RenderThisFrame = FALSE;	    }	    else	    {		IPPU.RenderThisFrame = TRUE;		IPPU.SkippedFrames = 0;	    }	}    }    else#endif#if 0    if (Settings.SoundSync == 2)    {	IPPU.RenderThisFrame = TRUE;	IPPU.SkippedFrames = 0;	return;    }#endif    if (Settings.TurboMode)    {        if(++IPPU.FrameSkip >= Settings.TurboSkipFrames)        {            IPPU.FrameSkip = 0;            IPPU.SkippedFrames = 0;            IPPU.RenderThisFrame = TRUE;        }        else        {            ++IPPU.SkippedFrames;            IPPU.RenderThisFrame = FALSE;        }        return;    }    #ifdef __sgi    /* BS: saves on CPU usage */    sginap(1);#endif    /* Check events */        static struct timeval next1 = {0, 0};    struct timeval now;    CHECK_SOUND(); S9xProcessEvents(FALSE);    while (gettimeofday (&now, NULL) < 0) ;        /* If there is no known "next" frame, initialize it now */    if (next1.tv_sec == 0) { next1 = now; ++next1.tv_usec; }    /* If we're on AUTO_FRAMERATE, we'll display frames always     * only if there's excess time.     * Otherwise we'll display the defined amount of frames.     */    unsigned limit = Settings.SkipFrames == AUTO_FRAMERATE                     ? (timercmp(&next1, &now, <) ? 10 : 1)                     : Settings.SkipFrames;        IPPU.RenderThisFrame = ++IPPU.SkippedFrames >= limit;    if(IPPU.RenderThisFrame)    {        IPPU.SkippedFrames = 0;    }    else    {        /* If we were behind the schedule, check how much it is */        if(timercmp(&next1, &now, <))        {            unsigned lag =                (now.tv_sec - next1.tv_sec) * 1000000               + now.tv_usec - next1.tv_usec;            if(lag >= 1000000)            {                /* More than a second behind means probably                 * pause. The next line prevents the magic                 * fast-forward effect.                 */                next1 = now;            }        }    }        /* Delay until we're completed this frame */    /* Can't use setitimer because the sound code already could     * be using it. We don't actually need it either.     */    while(timercmp(&next1, &now, >))    {        /* If we're ahead of time, sleep a while */        unsigned timeleft =            (next1.tv_sec - now.tv_sec) * 1000000           + next1.tv_usec - now.tv_usec;        //fprintf(stderr, "<%u>", timeleft);        usleep(timeleft);        CHECK_SOUND(); S9xProcessEvents(FALSE);        while (gettimeofday (&now, NULL) < 0) ;        /* Continue with a while-loop because usleep()         * could be interrupted by a signal         */    }    /* Calculate the timestamp of the next frame. */    next1.tv_usec += Settings.FrameTime;    if (next1.tv_usec >= 1000000)    {        next1.tv_sec += next1.tv_usec / 1000000;        next1.tv_usec %= 1000000;    }}static long log2 (long num){    long n = 0;    while (num >>= 1)	n++;    return (n);}#if 0 /* Dead code  20031117 */static long power (int num, int pow){    long val = num;    int i;        if (pow == 0)	return (1);    for (i = 1; i < pow; i++)	val *= num;    return (val);}#endif /* BS: the SGI sound routines. */#if !defined(NOSOUND) && defined(__sgi)char	*sgi_sound = "SGI/IRIX sound by Sherman";#include <audio.h>static int Rates[8] ={    0, 8000, 11025, 16000, 22050, 32000, 44100, 48000};static int BufferSizes [8] ={#if 1 /*BS: double buffer size */    0, 512, 512, 512, 1024, 1024, 2048, 2048#else    0, 256, 256, 256, 512, 512, 1024, 1024#endif};bool8 S9xOpenSoundDevice (int mode, bool8 stereo, int buffer_size){    /* SGI version */	long	channels = -1,		sampsize = -1,		samprate = -1,		compress = -1,		device = -1,		interleave = -1,		outsize = -1;	ALconfig al_config;	long	al_params[2] = {			AL_OUTPUT_RATE, -1		};	al_config = ALnewconfig();#if 1 /* by not doing this, num channels will remain at current setting */	/* number of channels can only be changed before port is open. */	channels = stereo ? 2 : 1;	if (ALsetchannels(al_config, channels)) {		perror("ERROR with ALsetchannels");	}	channels = ALgetchannels(al_config);#  if 0	printf("channels now = %ld\n", channels);#  endif#endif	so.stereo = channels - 1;	/* unforunately, this must be called before opening the port.  It'd */	/*   be nice to have a little more info before calling this, but    */	/*   we'll have to guess for now.  Not reducing the queue size      */	/*   results in a delay between events and the corresponding sounds.*/	if (ALsetqueuesize(al_config, (long)(BufferSizes[mode&7]*channels*3))) {		perror("ERROR with ALsetqueuesize");	}	/* open the audio port */	so.al_port = ALopenport("Snes9x audio", "w", al_config);	if (so.al_port == 0) {		return (FALSE);	}	/* get the current settings of the audio port */	al_config = ALgetconfig(so.al_port);	channels = ALgetchannels(al_config);	sampsize = ALgetwidth(al_config);	outsize = ALgetfillable(so.al_port);	ALgetparams(AL_DEFAULT_DEVICE, al_params, 2);	samprate = al_params[1];#if 0	/* print machines current settings */	printf("channels = %ld\n", channels);	printf("sampsize = %ld\n", sampsize);	printf("samprate = %ld\n", samprate);	printf("outsize =  %ld\n", outsize);	printf("compress = %ld\n", compress);	printf("device =   %ld\n", device);	printf("interleave=%ld\n", interleave);#endif	/* do not encode */	so.encoded = 0;#if 1 /* by not doing this, rate will be left at current setting */	samprate = Rates [mode & 7];	al_params[1] = samprate;	ALsetparams(AL_DEFAULT_DEVICE, al_params, 2);	ALgetparams(AL_DEFAULT_DEVICE, al_params, 2);	samprate = al_params[1];# if 0	printf("samprate now = %ld\n", samprate);#endif#endif	so.playback_rate = samprate;#if 0 /* by not doing this, sample size will be left at current setting */	if (ALsetwidth(al_config, AL_SAMPLE_8)) {		perror("ERROR with ALsetwidth");	}	if (ALsetconfig(so.al_port, al_config)) {		perror("ERROR with ALsetconfig");	}	sampsize = ALgetwidth(al_config);	printf("sampsize now = %ld\n", sampsize);#endif	/* set the sample size */	switch (sampsize) {	case AL_SAMPLE_8:		so.sixteen_bit = 0;		break;	case AL_SAMPLE_16:		so.sixteen_bit = 1;		break;	case AL_SAMPLE_24:	default:		so.sixteen_bit = 1;		break;	}	/* choose a buffer size based on the sample rate, and increase as nece*/	for (int i = 1; i < 7; i++)	if (samprate <= Rates [i])	    break;	so.buffer_size = BufferSizes [i];	if (so.stereo)		so.buffer_size *= 2;	if (so.sixteen_bit)		so.buffer_size *= 2;	if (so.buffer_size > MAX_BUFFER_SIZE*4)		so.buffer_size = MAX_BUFFER_SIZE*4;	printf("SGI sound successfully opened\n");	printf ("  Rate: %d, Buffer size: %d, 16-bit: %s, Stereo: %s, Encoded: %s\n",	    so.playback_rate, so.buffer_size, so.sixteen_bit ? "yes" : "no",	    so.stereo ? "yes" : "no", so.encoded ? "yes" : "no");	return (TRUE);}void S9xUnixProcessSound (void){    /* SGI version */    uint8		Buf[MAX_BUFFER_SIZE*4];    int			buf_size;    signed short	*audio_buf;    CPU.Flags &= ~PROCESS_SOUND_FLAG;    if (so.al_port == 0)	return;    if (Settings.APUEnabled == FALSE) {	printf("why am I hear? alport = %p\n", so.al_port);	return;    }    int sample_count = so.buffer_size;    if (so.sixteen_bit)	sample_count >>= 1;    /* BS: return if buffer is full */    if (ALgetfillable(so.al_port) < so.buffer_size) {#if 0	printf("error: fillable space only = %ld\n", ALgetfillable(so.al_port));#endif	return;    }    S9xMixSamples (Buf, sample_count);    if (!so.mute_sound) {	    buf_size = sample_count;	    audio_buf = (signed short *)Buf;#if 0	    printf("about to write buffer %p size %d\n", audio_buf, buf_size);#endif	    if (ALwritesamps(so.al_port, audio_buf, buf_size)) {		perror("ERROR with ALwritesamps");	    }    }}#endif#if !defined(NOSOUND) && defined(__sun)static int Rates[8] ={    0, 8000, 11025, 16000, 22050, 32000, 37800, 44100};static int BufferSizes [8] ={    0, 256, 256, 256, 512, 512, 1024, 1024};bool8 S9xOpenSoundDevice (int mode, bool8 stereo, int buffer_size){    /* SUN version */    int i;    if ((so.sound_fd = open ("/dev/audio", O_WRONLY)) < 0)	return (FALSE);    audio_info_t audio;    AUDIO_INITINFO (&audio);    audio.play.sample_rate = Rates [mode & 7];    audio.play.channels = stereo ? 2 : 1;    audio.play.precision = 16;    audio.play.encoding = AUDIO_ENCODING_LINEAR;    ioctl (so.sound_fd, AUDIO_SETINFO, &audio);    if (ioctl (so.sound_fd, AUDIO_GETINFO, &audio) != 0)	return (FALSE);    so.stereo = audio.play.channels - 1;    so.playback_rate = audio.play.sample_rate;    so.encoded = audio.play.encoding != AUDIO_ENCODING_LINEAR;    so.sixteen_bit = audio.play.precision == 16;    for (i = 1; i < 7; i++)	if (audio.play.sample_rate <= Rates [i])	    break;    so.buffer_size = BufferSizes [i];    if (buffer_size > 0)    if (so.stereo)	so.buffer_size *= 2;    if (so.sixteen_bit)	so.buffer_size *= 2;    if (so.buffer_size > MAX_BUFFER_SIZE)	so.buffer_size = MAX_BUFFER_SIZE;    so.last_eof = -1;    printf ("Rate: %d, Buffer size: %d, 16-bit: %s, Stereo: %s, Encoded: %s\n",	    so.playback_rate, so.buffer_size, so.sixteen_bit ? "yes" : "no",	    so.stereo ? "yes" : "no", so.encoded ? "yes" : "no");    return (TRUE);}#endif#if !defined(NOSOUND) && defined(__linux)static int Rates[8] ={    0, 8000, 11025, 16000, 22050, 32000, 44100, 48000};static int BufferSizes [8] ={    0, 256, 256, 256, 512, 512, 1024, 1024};bool8 S9xOpenSoundDevice (int mode, bool8 stereo, int buffer_size){    /* Linux version (OSS) */    int J, K;    if ((so.sound_fd = open ("/dev/dsp", O_WRONLY)) < 0)    {	perror ("/dev/dsp");	return (FALSE);    }#ifdef MMAP_SOUND    if (ioctl (so.sound_fd, SNDCTL_DSP_GETCAPS, &J) < 0)    {	perror ("ioctl SNDCTL_DSP_GETCAPS");    }    else    {	if (J & DSP_CAP_MMAP)	    printf ("DSP_CAP_MMAP supported\n");    }    void *ptr;    if ((ptr = mmap (0, so.buffer_size * 3, PROT_WRITE, 0, so.sound_fd, 0)) == 0)	fprintf (stderr, "mmap failed\n");    J = 0;    if (ioctl (so.sound_fd, SNDCTL_DSP_SETTRIGGER, &J) < 0)	perror ("ioctl SNDCTL_DSP_SETTRIGGER");#endif    //Test and check back to http://snes9x.com/forum/topic.asp?TOPIC_ID=8512//    J = AFMT_U8;    J = AFMT_S16_NE;    if (ioctl (so.sound_fd, SNDCTL_DSP_SETFMT, &J) < 0)    {	perror ("ioctl SNDCTL_DSP_SETFMT");	return (FALSE);    }    if (J != AFMT_S16_NE)    {	so.sixteen_bit = FALSE;	J = AFMT_U8;	if (ioctl (so.sound_fd, SNDCTL_DSP_SETFMT, &J) < 0)	{	    perror ("ioctl SNDCTL_DSP_SETFMT");	    return (FALSE);	}    }    else	so.sixteen_bit = TRUE;    so.stereo = stereo;    if (ioctl (so.sound_fd, SNDCTL_DSP_STEREO, &so.stereo) < 0)    {	perror ("ioctl SNDCTL_DSP_STEREO");	return (FALSE);    }        so.playback_rate = Rates[mode & 0x07];    if (ioctl (so.sound_fd, SNDCTL_DSP_SPEED, &so.playback_rate) < 0)    {	perror ("ioctl SNDCTL_DSP_SPEED");	return (FALSE);    }    S9xSetPlaybackRate (so.playback_rate);    if (buffer_size == 0)	buffer_size = BufferSizes [mode & 7];    if (buffer_size > MAX_BUFFER_SIZE / 4)	buffer_size = MAX_BUFFER_SIZE / 4;    if (so.sixteen_bit)	buffer_size *= 2;    if (so.stereo)	buffer_size *= 2;    int power2 = log2 (buffer_size);    J = K = power2 | (3 << 16);    if (ioctl (so.sound_fd, SNDCTL_DSP_SETFRAGMENT, &J) < 0)    {	perror ("ioctl SNDCTL_DSP_SETFRAGMENT");	return (FALSE);    }    ioctl (so.sound_fd, SNDCTL_DSP_GETBLKSIZE, &so.buffer_size);    #ifdef MMAP_SOUND    J = PCM_ENABLE_OUTPUT;    if (ioctl (so.sound_fd, SNDCTL_DSP_SETTRIGGER, &J) < 0)	perror ("ioctl SNDCTL_DSP_SETTRIGGER");#endif#if 0    buffmem_desc buff;    buff.size = so.buffer_size * 3;    buff.buffer = ptr;    if (ioctl (so.sound_fd, SNDCTL_DSP_MAPOUTBUF, &buff) < 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -