예제 #1
0
/**
**	Wait for interactive input event.
**
**	Handles X11 events, keyboard, mouse.
**	Video interrupt for sync.
**	Network messages.
**	Sound queue.
**
**	We must handle atlast one X11 event
**
**	FIXME:	the initialition could be moved out of the loop
*/
global void WaitEventsAndKeepSync(void)
{
#if 0
    int connection;
    int sound;
    fd_set readfd;
    fd_set writefd;
    int maxfd;

    sound=0;
    for( ;; ) {
	if( XPending(TheDisplay) ) {
	    DoEvent();
	}
	if( VideoInterrupts ) {
	    return;
	}
	FD_ZERO(&readfd);

	maxfd=connection=ConnectionNumber(TheDisplay);
	FD_SET(connection,&readfd);

	FD_ZERO(&writefd);
#ifndef USE_THREAD
	if( !SoundOff && (sound=SoundFildes)!=-1 ) {
	    if( sound>maxfd ) {
		maxfd=sound;
	    }
	    FD_SET(sound,&writefd);
	}
#else
	if( !SoundOff && !SoundThreadRunning && (sound=SoundFildes)!=-1 ) {
	    if( sound>maxfd ) {
		maxfd=sound;
	    }
	    FD_SET(sound,&writefd);
	}
#endif
	if( NetworkFildes!=-1 ) {
	    if( NetworkFildes>maxfd ) {
		maxfd=NetworkFildes;
	    }
	    FD_SET(NetworkFildes,&readfd);
	}
	maxfd=select(maxfd+1,&readfd,&writefd,0,0);

	if( VideoInterrupts ) {
	    return;
	}
	if( maxfd!=-1 ) {
#ifndef USE_THREAD
	    if( !SoundOff && sound!=-1 && FD_ISSET(sound,&writefd) ) {
		WriteSound();
		continue;
	    }
#else
	    if( !SoundOff && !SoundThreadRunning && sound!=-1
		&& FD_ISSET(sound,&writefd) ) {
		WriteSound();
		continue;
	    }
#endif
	    if( NetworkFildes!=-1 && FD_ISSET(NetworkFildes,&readfd) ) {
		NetworkEvent();
		continue;
	    }
	    DoEvent();
	}
    }
#endif
    struct timeval tv;
    fd_set rfds;
    fd_set wfds;
    int maxfd;
    int* xfd;
    int n;
    int i;
    int morex;
    int connection;

    connection=ConnectionNumber(TheDisplay);

    for( ;; ) {
	//
	//	Prepare select
	//
	tv.tv_sec=0;
	tv.tv_usec=0;

	FD_ZERO(&rfds);
	FD_ZERO(&wfds);
	maxfd=0;

	//
	//	X11 how many events already in que
	//
	xfd=NULL;
	morex=XQLength(TheDisplay);
	if( !morex ) {
	    //
	    //	X11 connections number
	    //
	    maxfd=connection;
	    FD_SET(connection,&rfds);

	    //
	    //	Get all X11 internal connections
	    //
	    if( !XInternalConnectionNumbers(TheDisplay,&xfd,&n) ) {
		DebugLevel0(__FUNCTION__": out of memory\n");
		abort();
	    }
	    for( i=n; i--; ) {
		FD_SET(xfd[i],&rfds);
		if( xfd[i]>maxfd ) {
		    maxfd=xfd[i];
		}
	    }
	}

	//
	//	Network
	//
	if( NetworkFildes!=-1 ) {
	    if( NetworkFildes>maxfd ) {
		maxfd=NetworkFildes;
	    }
	    FD_SET(NetworkFildes,&rfds);
	}

	//
	//	Sound
	//
	if( !SoundOff && !SoundThreadRunning ) {
	    if( SoundFildes>maxfd ) {
		maxfd=SoundFildes;
	    }
	    FD_SET(SoundFildes,&wfds);
	}

	maxfd=select(maxfd+1,&rfds,&wfds,NULL,morex ? &tv : NULL);

	//
	//	X11
	//
	if( maxfd>0 ) {
	    if( !morex ) {
		for( i=n; i--; ) {
		    if( FD_ISSET(xfd[i],&rfds) ) {
			XProcessInternalConnection(TheDisplay,xfd[i]);
		    }
		}
		XFree(xfd);
		if( FD_ISSET(connection,&rfds) ) {
		    XEventsQueued(TheDisplay,QueuedAfterReading);
		}
		morex=XQLength(TheDisplay);
	    }
	}

	if( morex ) {			// handle new + *OLD* x11 events
	    DoEvent();
	}

	if( maxfd>0 ) {
	    //
	    //	Network
	    //
	    if( NetworkFildes!=-1 && FD_ISSET(NetworkFildes,&rfds) ) {
		NetworkEvent();
	    }

	    //
	    //	Network in sync and time for frame over: return
	    //
	    if( !morex && NetworkInSync && VideoInterrupts ) {
		return;
	    }

	    //
	    //	Sound
	    //
	    if( !SoundOff && !SoundThreadRunning
			&& FD_ISSET(SoundFildes,&wfds) ) {
		WriteSound();
	    }
	}

	//
	//	Network in sync and time for frame over: return
	//
	if( !morex && NetworkInSync && VideoInterrupts ) {
	    return;
	}
    }
}
예제 #2
0
/**
**	Wait for interactive input event.
**
**	Handles X11 events, keyboard, mouse.
**	Video interrupt for sync.
**	Network messages.
**	Sound queue.
**
**	We must handle atlast one X11 event
**
**	FIXME:	the initialition could be moved out of the loop
*/
global void WaitEventsAndKeepSync(void)
{
#ifndef USE_WIN32
    struct timeval tv;
    fd_set rfds;
    fd_set wfds;
    int maxfd;
#endif
    SDL_Event event[1];

    for(;;) {
	// Not very nice, but this is the problem if you use other libraries
	// The event handling of SDL is very buggy and wrong designed.
	if( SDL_PollEvent(event) ) {
	    // Handle SDL event
	    DoEvent(event);
	} else {
#ifndef USE_WIN32
	    //
	    //	Prepare select
	    //
	    tv.tv_sec=0;
	    tv.tv_usec=0;
	    FD_ZERO(&rfds);
	    FD_ZERO(&wfds);
	    maxfd=0;

	    //
	    //	Network
	    //
	    if( NetworkFildes!=-1 ) {
		if( NetworkFildes>maxfd ) {
		    maxfd=NetworkFildes;
		}
		FD_SET(NetworkFildes,&rfds);
	    }

	    //
	    //	Sound
	    //
	    if( !SoundOff && !SoundThreadRunning ) {
		if( SoundFildes>maxfd ) {
		    maxfd=SoundFildes;
		}
		FD_SET(SoundFildes,&wfds);
	    }

	    maxfd=select(maxfd+1,&rfds,&wfds,NULL
		    ,SDL_PollEvent(NULL) ? &tv : NULL);

	    if( maxfd>0 ) {
		//
		//	Network
		//
		if( NetworkFildes!=-1 && FD_ISSET(NetworkFildes,&rfds) ) {
		    NetworkEvent();
		}

		//
		//	Network in sync and time for frame over: return
		//
		if( NetworkInSync && VideoInterrupts ) {
		    return;
		}

		//
		//	Sound
		//
		if( !SoundOff && !SoundThreadRunning
			    && FD_ISSET(SoundFildes,&wfds) ) {
		    WriteSound();
		}
	    }
#endif
	}

	//
	//	Network in sync and time for frame over: return
	//
	if(NetworkInSync && VideoInterrupts) {
	    return;
	}
    }
}
예제 #3
0
파일: sdl.cpp 프로젝트: RenaKunisaki/fceux
/**
 * Update the video, audio, and input subsystems with the provided
 * video (XBuf) and audio (Buffer) information.
 */
void
FCEUD_Update(uint8 *XBuf,
			 int32 *Buffer,
			 int Count)
{
	extern int FCEUDnetplay;

	#ifdef CREATE_AVI
	if(LoggingEnabled == 2 || (eoptions&EO_NOTHROTTLE))
	{
	  if(LoggingEnabled == 2)
	  {
		int16* MonoBuf = new int16[Count];
		int n;
		for(n=0; n<Count; ++n)
			MonoBuf[n] = Buffer[n] & 0xFFFF;
		NESVideoLoggingAudio
		 (
		  MonoBuf, 
		  FSettings.SndRate, 16, 1,
		  Count
		 );
		delete [] MonoBuf;
	  }
	  Count /= 2;
	  if(inited & 1)
	  {
		if(Count > GetWriteSound()) Count = GetWriteSound();
		if (!mutecapture)
		  if(Count > 0 && Buffer) WriteSound(Buffer,Count);   
	  }
	  if(inited & 2)
		FCEUD_UpdateInput();
	  if(XBuf && (inited & 4)) BlitScreen(XBuf);
	  
	  //SpeedThrottle();
		return;
	 }
	#endif
	
	int ocount = Count;
	// apply frame scaling to Count
	Count = (int)(Count / g_fpsScale);
	if(Count) {
		int32 can=GetWriteSound();
		static int uflow=0;
		int32 tmpcan;

		// don't underflow when scaling fps
		if(can >= GetMaxSound() && g_fpsScale==1.0) uflow=1;	/* Go into massive underflow mode. */

		if(can > Count) can=Count;
		else uflow=0;

		#ifdef CREATE_AVI
		if (!mutecapture)
		#endif
		  WriteSound(Buffer,can);

		//if(uflow) puts("Underflow");
		tmpcan = GetWriteSound();
		// don't underflow when scaling fps
		if(g_fpsScale>1.0 || ((tmpcan < Count*0.90) && !uflow)) {
			if(XBuf && (inited&4) && !(NoWaiting & 2))
				BlitScreen(XBuf);
			Buffer+=can;
			Count-=can;
			if(Count) {
				if(NoWaiting) {
					can=GetWriteSound();
					if(Count>can) Count=can;
					#ifdef CREATE_AVI
					if (!mutecapture)
					#endif
					  WriteSound(Buffer,Count);
				} else {
					while(Count>0) {
						#ifdef CREATE_AVI
						if (!mutecapture)
						#endif
						  WriteSound(Buffer,(Count<ocount) ? Count : ocount);
						Count -= ocount;
					}
				}
			}
		} //else puts("Skipped");
		else if(!NoWaiting && FCEUDnetplay && (uflow || tmpcan >= (Count * 1.8))) {
			if(Count > tmpcan) Count=tmpcan;
			while(tmpcan > 0) {
				//	printf("Overwrite: %d\n", (Count <= tmpcan)?Count : tmpcan);
				#ifdef CREATE_AVI
				if (!mutecapture)
				#endif
				  WriteSound(Buffer, (Count <= tmpcan)?Count : tmpcan);
				tmpcan -= Count;
			}
		}

	} else {
		if(!NoWaiting && (!(eoptions&EO_NOTHROTTLE) || FCEUI_EmulationPaused()))
		while (SpeedThrottle())
		{
			FCEUD_UpdateInput();
		}
		if(XBuf && (inited&4)) {
			BlitScreen(XBuf);
		}
	}
	FCEUD_UpdateInput();
	//if(!Count && !NoWaiting && !(eoptions&EO_NOTHROTTLE))
	// SpeedThrottle();
	//if(XBuf && (inited&4))
	//{
	// BlitScreen(XBuf);
	//}
	//if(Count)
	// WriteSound(Buffer,Count,NoWaiting);
	//FCEUD_UpdateInput();
}