/** ** Wait for interactive input event for one frame. ** ** Handles system events, joystick, keyboard, mouse. ** Handles the network messages. ** Handles the sound queue. ** ** All events available are fetched. Sound and network only if available. ** Returns if the time for one frame is over. */ void WaitEventsOneFrame() { ++FrameCounter; Uint32 ticks = SDL_GetTicks(); if (ticks > NextFrameTicks) { // We are too slow :( ++SlowFrameCounter; } InputMouseTimeout(*GetCallbacks(), ticks); InputKeyTimeout(*GetCallbacks(), ticks); CursorAnimate(ticks); int interrupts = 0; for (;;) { // Time of frame over? This makes the CPU happy. :( ticks = SDL_GetTicks(); if (!interrupts && ticks < NextFrameTicks) { SDL_Delay(NextFrameTicks - ticks); ticks = SDL_GetTicks(); } while (ticks >= NextFrameTicks) { ++interrupts; FrameFraction += FrameRemainder; if (FrameFraction > 10) { FrameFraction -= 10; ++NextFrameTicks; } NextFrameTicks += FrameTicks; } SDL_Event event[1]; const int i = SDL_PollEvent(event); if (i) { // Handle SDL event SdlDoEvent(*GetCallbacks(), *event); } // Network int s = 0; if (IsNetworkGame()) { s = NetworkFildes.HasDataToRead(0); if (s > 0) { GetCallbacks()->NetworkEvent(); } } // No more input and time for frame over: return if (!i && s <= 0 && interrupts) { break; } } handleInput(NULL); if (!SkipGameCycle--) { SkipGameCycle = SkipFrames; } }
/** ** Wait for interactive input event for one frame. ** ** Handles system events, joystick, keyboard, mouse. ** Handles the network messages. ** Handles the sound queue. ** ** All events available are fetched. Sound and network only if available. ** Returns if the time for one frame is over. */ void WaitEventsOneFrame() { struct timeval tv; fd_set rfds; fd_set wfds; Socket maxfd; int i; int s = 0; SDL_Event event[1]; Uint32 ticks; int interrupts; ++FrameCounter; ticks = SDL_GetTicks(); if (ticks > NextFrameTicks) { // We are too slow :( ++SlowFrameCounter; } InputMouseTimeout(GetCallbacks(), ticks); InputKeyTimeout(GetCallbacks(), ticks); CursorAnimate(ticks); interrupts = 0; for (;;) { // // Time of frame over? This makes the CPU happy. :( // ticks = SDL_GetTicks(); if (!interrupts && ticks < NextFrameTicks) { SDL_Delay(NextFrameTicks - ticks); ticks = SDL_GetTicks(); } while (ticks >= NextFrameTicks) { ++interrupts; FrameFraction += FrameRemainder; if (FrameFraction > 10) { FrameFraction -= 10; ++NextFrameTicks; } NextFrameTicks += FrameTicks; } // // Prepare select // maxfd = 0; tv.tv_sec = tv.tv_usec = 0; FD_ZERO(&rfds); FD_ZERO(&wfds); // // Network // if (IsNetworkGame()) { if (NetworkFildes > maxfd) { maxfd = NetworkFildes; } FD_SET(NetworkFildes, &rfds); } #if 0 s = select(maxfd + 1, &rfds, &wfds, NULL, (i = SDL_PollEvent(event)) ? &tv : NULL); #else // QUICK HACK to fix the event/timer problem // The timer code didn't interrupt the select call. // Perhaps I could send a signal to the process // Not very nice, but this is the problem if you use other libraries // The event handling of SDL is wrong designed = polling only. // There is hope on SDL 1.3 which will have this fixed. //s = select(maxfd + 1, &rfds, &wfds, NULL, &tv); //printf("PollEvent\n"); i = SDL_PollEvent(event); #endif if (i) { // Handle SDL event SdlDoEvent(GetCallbacks(), event); } if (s > 0) { // // Network // if (IsNetworkGame() && FD_ISSET(NetworkFildes, &rfds) ) { GetCallbacks()->NetworkEvent(); } } // // No more input and time for frame over: return // if (!i && s <= 0 && interrupts) { break; } } handleInput(NULL); if (!SkipGameCycle--) { SkipGameCycle = SkipFrames; } if (!UseOpenGL && (GameRunning || Editor.Running || PatchEditorRunning)) { Video.ClearScreen(); } }
/** ** Wait for interactive input event for one frame. ** ** Handles system events, joystick, keyboard, mouse. ** Handles the network messages. ** Handles the sound queue. ** ** All events available are fetched. Sound and network only if available. ** Returns if the time for one frame is over. ** ** @param callbacks Call backs that handle the events. */ global void WaitEventsOneFrame(const EventCallback* callbacks) { struct timeval tv; fd_set rfds; fd_set wfds; int maxfd; Uint32 i; SDL_Event event[1]; if( SoundFildes==-1 ) { SoundOff=1; } InputMouseTimeout(callbacks,SDL_GetTicks()); for(;;) { #if 1 static Uint32 LastTick; // // Time of frame over? This makes the CPU happy. :( // i=WinCE_GetTicks(); while( i>=LastTick ) { ++VideoInterrupts; LastTick+=(100*1000/CYCLES_PER_SECOND)/VideoSyncSpeed; } #endif // // Prepare select // maxfd=0; tv.tv_sec=tv.tv_usec=0; FD_ZERO(&rfds); FD_ZERO(&wfds); // // 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); } #if 0 maxfd=select(maxfd+1,&rfds,&wfds,NULL ,(i=SDL_PollEvent(event)) ? &tv : NULL); #else // QUICK HACK to fix the event/timer problem // The timer code didn't interrupt the select call. // Perhaps I could send a signal to the process // Not very nice, but this is the problem if you use other libraries // The event handling of SDL is wrong designed = polling only. // There is hope on SDL 1.3 which will have this fixed. maxfd=select(maxfd+1,&rfds,&wfds,NULL,&tv); i=SDL_PollEvent(event); #endif if ( i ) { // Handle SDL event SdlDoEvent(callbacks,event); } if( maxfd>0 ) { // // Sound // if( !SoundOff && !SoundThreadRunning && FD_ISSET(SoundFildes,&wfds) ) { callbacks->SoundReady(); } // // Not more input and network in syn and time for frame over // if( !i && NetworkInSync && VideoInterrupts ) { break; } // // Network // if( NetworkFildes!=-1 && FD_ISSET(NetworkFildes,&rfds) ) { callbacks->NetworkEvent(); } } // // Not more input and time for frame over: return // if( !i && VideoInterrupts ) { break; } } // // Prepare return, time for one frame is over. // VideoInterrupts=0; }