void IN_Frame(void)
{
	qboolean loading;
	qboolean fullscreen = qtrue;

	IN_JoyMove();
	IN_ProcessEvents();

	// If not DISCONNECTED (main menu) or ACTIVE (in game), we're loading
	loading = !!(cls.state != CA_DISCONNECTED && cls.state != CA_ACTIVE);

	if (!fullscreen && (  (Key_GetCatcher() & KEYCATCH_CONSOLE) ||
			loading || !SDL_GetWindowGrab(SDLvidscreen)  ))
	{
		if (mouseActive)
			IN_DeactivateMouse();
	}
	else
	{
		if (!mouseActive)
			IN_ActivateMouse();
	}

	/* in case we had to delay actual restart of video system... */
	if ((vidRestartTime != 0) && (vidRestartTime < Sys_Milliseconds()))
	{
		vidRestartTime = 0;
		Cbuf_AddText("vid_restart");
	}
}
Exemple #2
0
void IN_Frame() {
    bool loading;

    if (in_xbox360ControllerAvailable->integer) {
        IN_Xbox360ControllerMove();
    } else {
        IN_JoyMove();
    }

    // If not DISCONNECTED (main menu) or ACTIVE (in game), we're loading
    loading = (cls.state != CA_DISCONNECTED && cls.state != CA_ACTIVE);

    if (cls.keyCatchers & KEYCATCH_CONSOLE) {
        // Console is down in windowed mode
        IN_DeactivateMouse(false);
    } else if (loading) {
        // Loading in windowed mode
        IN_DeactivateMouse(true);
    } else if (!(SDL_GetWindowFlags(window) & SDL_WINDOW_INPUT_FOCUS)) {
        // Window doesn't have focus
        IN_DeactivateMouse(false);
    } else if (com_minimized->integer) {
        // Minimized
        IN_DeactivateMouse(true);
    } else {
        IN_ActivateMouse();
    }

    IN_ProcessEvents(dropInput);
}
Exemple #3
0
void
IN_Frame(void)
{
	qbool loading;

	IN_JoyMove( );
	IN_ProcessEvents( );

	/* If not DISCONNECTED (main menu) or ACTIVE (in game), we're loading */
	loading = !!(clc.state != CA_DISCONNECTED && clc.state != CA_ACTIVE);

	if(!cvargeti("r_fullscreen") && (Key_GetCatcher( ) & KEYCATCH_CONSOLE)){
		/* Console is down in windowed mode */
		IN_DeactivateMouse( );
	}else if(!cvargeti("r_fullscreen") && loading){
		/* Loading in windowed mode */
		IN_DeactivateMouse( );
	}else if(!(SDL_GetAppState() & SDL_APPINPUTFOCUS)){
		/* Window not got focus */
		IN_DeactivateMouse( );
	}else
		IN_ActivateMouse( );

	/* in case we had to delay actual restart of video system... */
	if((vidRestartTime != 0) && (vidRestartTime < sysmillisecs())){
		vidRestartTime = 0;
		cbufaddstr("vid_restart");
	}
}
/*
===============
IN_Frame
===============
*/
void IN_Frame( void )
{
	qboolean loading;

	IN_JoyMove( );
	IN_ProcessEvents( );

	// If not DISCONNECTED (main menu) or ACTIVE (in game), we're loading
	loading = !!( cls.state != CA_DISCONNECTED && cls.state != CA_ACTIVE );

	if( !r_fullscreen->integer && ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) )
	{
		// Console is down in windowed mode
		IN_DeactivateMouse( );
	}
	else if( !r_fullscreen->integer && loading )
	{
		// Loading in windowed mode
		IN_DeactivateMouse( );
	}
	else if( !( SDL_GetAppState() & SDL_APPINPUTFOCUS ) )
	{
		// Window not got focus
		IN_DeactivateMouse( );
	}
	else
		IN_ActivateMouse( );
}
void IN_Frame()
{
	if ( in_xbox360ControllerAvailable->integer )
	{
		IN_Xbox360ControllerMove();
	}
	else
	{
		IN_JoyMove();
	}

	if ( cls.keyCatchers & KEYCATCH_CONSOLE )
	{
		// Console is down in windowed mode
		IN_SetFocus( false );
	}
	else if ( !( SDL_GetWindowFlags( window ) & SDL_WINDOW_INPUT_FOCUS ) )
	{
		// Window doesn't have focus
		IN_SetFocus( false );
	}
	else if ( com_minimized->integer )
	{
		// Minimized
		IN_SetFocus( false );
	}
	else
	{
		IN_SetFocus( true );
	}

	IN_ProcessEvents( dropInput );
}
Exemple #6
0
/*
===============
IN_Frame
===============
*/
void IN_Frame(void)
{
	qboolean        loading;

	IN_JoyMove();
	IN_ProcessEvents();

	// If not DISCONNECTED (main menu) or ACTIVE (in game), we're loading
	loading = (cls.state != CA_DISCONNECTED && cls.state != CA_ACTIVE);

	if(!cls.glconfig.isFullscreen && (Key_GetCatcher() & KEYCATCH_CONSOLE))
	{
		// Console is down in windowed mode
		IN_DeactivateMouse();
	}
	else if(!cls.glconfig.isFullscreen && loading)
	{
		// Loading in windowed mode
		IN_DeactivateMouse();
	}
	else if(!( SDL_GetWindowFlags(SDL_window) & SDL_WINDOW_INPUT_FOCUS))
	{
		// Window not got focus
		IN_DeactivateMouse();
	}
	else
		IN_ActivateMouse();

	// In case we had to delay actual restart of video system
	if( ( vidRestartTime != 0 ) && ( vidRestartTime < Sys_Milliseconds( ) ) )
	{
		vidRestartTime = 0;
		Cbuf_AddText( "vid_restart\n" );
	}
}
Exemple #7
0
/*
===============
IN_Frame
===============
*/
void IN_Frame( void )
{
	qboolean loading;

	IN_JoyMove( );
	IN_ProcessEvents( );

	// If not DISCONNECTED (main menu) or ACTIVE (in game), we're loading
	loading = ( clc.state != CA_DISCONNECTED && clc.state != CA_ACTIVE );

	if( !Cvar_VariableIntegerValue("r_fullscreen") && ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) )
	{
		// Console is down in windowed mode
		IN_DeactivateMouse( );
	}
	else if( !Cvar_VariableIntegerValue("r_fullscreen") && loading )
	{
		// Loading in windowed mode
		IN_DeactivateMouse( );
	}
	else if( !( SDL_GetAppState() & SDL_APPINPUTFOCUS ) )
	{
		// Window not got focus
		IN_DeactivateMouse( );
	}
	else
		IN_ActivateMouse( );

	/* in case we had to delay actual restart of video system... */
	if ( (vidRestartTime != 0) && (vidRestartTime < Sys_Milliseconds()) )
	{
		vidRestartTime = 0;
		Cbuf_AddText( "vid_restart\n" );
	}
}
Exemple #8
0
void IN_Frame (void) {
	qboolean loading;

	IN_JoyMove( );

	// If not DISCONNECTED (main menu) or ACTIVE (in game), we're loading
	loading = (qboolean)( cls.state != CA_DISCONNECTED && cls.state != CA_ACTIVE );

	if( !cls.glconfig.isFullscreen && ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) )
	{
		// Console is down in windowed mode
		IN_DeactivateMouse( );
	}
	else if( !cls.glconfig.isFullscreen && loading )
	{
		// Loading in windowed mode
		IN_DeactivateMouse( );
	}
	else if( !( SDL_GetWindowFlags( SDL_window ) & SDL_WINDOW_INPUT_FOCUS ) )
	{
		// Window not got focus
		IN_DeactivateMouse( );
	}
	else
		IN_ActivateMouse( );

	IN_ProcessEvents( );
}
Exemple #9
0
///////////////////////////////////////////////////////////////////////////
//
//	IN_ReadControl() - Reads the device associated with the specified
//		player and fills in the control info struct
//
///////////////////////////////////////////////////////////////////////////
void
IN_ReadControl(int player,ControlInfo *info)
{
	word		buttons;
	int			dx,dy;
	Motion		mx,my;

	dx = dy = 0;
	mx = my = motion_None;
	buttons = 0;

	IN_ProcessEvents();

    if (Keyboard[KbdDefs.upleft])
        mx = motion_Left,my = motion_Up;
    else if (Keyboard[KbdDefs.upright])
        mx = motion_Right,my = motion_Up;
    else if (Keyboard[KbdDefs.downleft])
        mx = motion_Left,my = motion_Down;
    else if (Keyboard[KbdDefs.downright])
        mx = motion_Right,my = motion_Down;

    if (Keyboard[KbdDefs.up])
        my = motion_Up;
    else if (Keyboard[KbdDefs.down])
        my = motion_Down;

    if (Keyboard[KbdDefs.left])
        mx = motion_Left;
    else if (Keyboard[KbdDefs.right])
        mx = motion_Right;

    if (Keyboard[KbdDefs.button0])
        buttons += 1 << 0;
    if (Keyboard[KbdDefs.button1])
        buttons += 1 << 1;

	dx = mx * 127;
	dy = my * 127;

	info->x = dx;
	info->xaxis = mx;
	info->y = dy;
	info->yaxis = my;
	info->button0 = (buttons & (1 << 0)) != 0;
	info->button1 = (buttons & (1 << 1)) != 0;
	info->button2 = (buttons & (1 << 2)) != 0;
	info->button3 = (buttons & (1 << 3)) != 0;
	info->dir = DirTable[((my + 1) * 3) + (mx + 1)];
}
Exemple #10
0
///////////////////////////////////////////////////////////////////////////
//
//	IN_UserInput() - Waits for the specified delay time (in ticks) or the
//		user pressing a key or a mouse button. If the clear flag is set, it
//		then either clears the key or waits for the user to let the mouse
//		button up.
//
///////////////////////////////////////////////////////////////////////////
boolean IN_UserInput(longword delay)
{
	longword	lasttime;

	lasttime = GetTimeCount();
	IN_StartAck ();
	do
	{
        IN_ProcessEvents();
		if (IN_CheckAck())
			return true;
        SDL_Delay(5);
	} while (GetTimeCount() - lasttime < delay);
	return(false);
}
Exemple #11
0
/*
===============
IN_Frame
===============
*/
void IN_Frame( void )
{
	qboolean loading;

	//FIXME test, checking mouse grab
	if (in_checkForStolenMouseFocus->integer  &&  mouseActive  &&  !(SDL_GetAppState() & SDL_APPMOUSEFOCUS)) {
		Com_Printf("^3external application stole mouse focus\n");
	}

	IN_JoyMove( );

	// If not DISCONNECTED (main menu) or ACTIVE (in game), we're loading
	loading = ( cls.state != CA_DISCONNECTED && cls.state != CA_ACTIVE );

	if( !r_fullscreen->integer && ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) )
	{
		// Console is down in windowed mode
		IN_DeactivateMouse( );
	}
	else if( !r_fullscreen->integer && loading )
	{
		// Loading in windowed mode
		IN_DeactivateMouse( );
	}
	else if( !( SDL_GetAppState() & SDL_APPINPUTFOCUS ) )
	{
		// Window not got focus
		//Com_Printf("^3window lost focus\n");
		IN_DeactivateMouse( );
	}
	else {
		if (in_nograb->integer) {
			IN_DeactivateMouse();
		} else {
			IN_ActivateMouse( );
		}
	}

	IN_ProcessEvents( );

	// in case we had to delay actual restart of video system...
	if ( (vidRestartTime != 0) && (vidRestartTime < Sys_Milliseconds()) )
	{
		vidRestartTime = 0;
		Cbuf_AddText( "vid_restart\n" );
	}
}
/*
===============
IN_Frame
===============
*/
void IN_Frame( void )
{
	qboolean loading;
	qboolean cursorShowing;

	IN_JoyMove( );
	IN_ProcessEvents( );

	// If not DISCONNECTED (main menu) or ACTIVE (in game), we're loading
	loading = !!( cls.state != CA_DISCONNECTED && cls.state != CA_ACTIVE );
	cursorShowing = Key_GetCatcher( ) & KEYCATCH_UI;

	if( !r_fullscreen->integer && ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) )
	{
		// Console is down in windowed mode
		IN_DeactivateMouse( );
	}
	else if( !r_fullscreen->integer && loading )
	{
		// Loading in windowed mode
		IN_DeactivateMouse( );
	}
/*
	else if( !r_fullscreen->integer && cursorShowing )
	{
		// Use WM cursor when not fullscreen
		IN_DeactivateMouse( );
	}
*/
	else if( !( SDL_GetAppState() & SDL_APPINPUTFOCUS ) )
	{
		// Window not got focus
     	if( ( ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) && !r_fullscreen->integer ) || com_minimized->integer )
		IN_DeactivateMouse( );
	}
	else
		IN_ActivateMouse( );

/*
	if( !mouseActive )
	{
		SDL_GetMouseState( &x, &y );
		IN_SetUIMousePosition( x, y );
	}
*/
}
Exemple #13
0
void IN_Frame( void )
{
	qboolean loading;

	if ( in_xbox360ControllerAvailable->integer )
	{
		IN_Xbox360ControllerMove();
	}
	else
	{
		IN_JoyMove();
	}

	IN_ProcessEvents( dropInput );
	dropInput = qfalse;

	// If not DISCONNECTED (main menu) or ACTIVE (in game), we're loading
	loading = ( cls.state != CA_DISCONNECTED && cls.state != CA_ACTIVE );

	if ( ( !cls.glconfig.isFullscreen || SDL_VERSION_ATLEAST( 2, 0, 0 ) ) &&
	     ( cls.keyCatchers & KEYCATCH_CONSOLE || ( CL_UIOwnsMouse() && !in_uigrab->integer ) ) )
	{
		// Console is down, or UI is up, in windowed mode
		IN_DeactivateMouse( qfalse );
	}
	else if ( ( !cls.glconfig.isFullscreen || SDL_VERSION_ATLEAST( 2, 0, 0 ) ) && loading )
	{
		// Loading in windowed mode
		IN_DeactivateMouse( qtrue );
	}
	else if ( !( SDL_GetWindowFlags( window ) & SDL_WINDOW_INPUT_FOCUS ) )
	{
		// Window not got focus
		IN_DeactivateMouse( qfalse );
	}
	else if ( com_minimized->integer )
	{
		// Minimized
		IN_DeactivateMouse( qtrue );
	}
	else
	{
		IN_ActivateMouse();
	}
}
Exemple #14
0
void IN_StartAck(void)
{
    IN_ProcessEvents();
//
// get initial state of everything
//
	IN_ClearKeysDown();
	memset(btnstate, 0, sizeof(btnstate));

	int buttons = IN_JoyButtons() << 4;

	if(MousePresent)
		buttons |= IN_MouseButtons();

	for(int i = 0; i < NUMBUTTONS; i++, buttons >>= 1)
		if(buttons & 1)
			btnstate[i] = true;
}
Exemple #15
0
void IN_Frame(void)
{
	qboolean loading;

	//IN_JoyMove();

	// If not DISCONNECTED (main menu) or ACTIVE (in game), we're loading
	loading = (cls.state != CA_DISCONNECTED && cls.state != CA_ACTIVE);

	if (!cls.glconfig.isFullscreen && (Key_GetCatcher() & KEYCATCH_CONSOLE))
	{
		// Console is down in windowed mode
		IN_DeactivateMouse();
	}
	else if (!cls.glconfig.isFullscreen && loading)
	{
		// Loading in windowed mode
		IN_DeactivateMouse();
	}
	else if (com_minimized->integer || com_unfocused->integer)
	{
		// Window not got focus
		IN_DeactivateMouse();
	}
	else
	{
		if (loading)
		{
			// Just eat up all the mouse events that are not used anyway
			IN_GobbleMotionEvents();
		}

		IN_ActivateMouse();
	}

	// in case we had to delay actual restart of video system...
	if ((vidRestartTime != 0) && (vidRestartTime < Sys_Milliseconds()))
	{
		vidRestartTime = 0;
		Cbuf_AddText("vid_restart\n");
	}

	IN_ProcessEvents();
}
Exemple #16
0
boolean IN_CheckAck (void)
{
    IN_ProcessEvents();
//
// see if something has been pressed
//
	if(LastScan)
		return true;

	int buttons = IN_JoyButtons() << 4;

	if(MousePresent)
		buttons |= IN_MouseButtons();

	for(int i = 0; i < NUMBUTTONS; i++, buttons >>= 1)
	{
		if(buttons & 1)
		{
			if(!btnstate[i])
            {
                // Wait until button has been released
                do
                {
                    IN_WaitAndProcessEvents();
                    buttons = IN_JoyButtons() << 4;

                    if(MousePresent)
                        buttons |= IN_MouseButtons();
                }
                while(buttons & (1 << i));

				return true;
            }
		}
		else
			btnstate[i] = false;
	}

	return false;
}
Exemple #17
0
/*
==================
SCR_ModalMessage

Displays a text string in the center of the screen and waits for a Y or N
keypress.  
==================
*/
int SCR_ModalMessage (char *text, float timeout) //johnfitz -- timeout
{
	double time1, time2; //johnfitz -- timeout

	if (cls.state == ca_dedicated)
		return true;

	scr_notifystring = text;
 
// draw a fresh screen
	scr_drawdialog = true;
	SCR_UpdateScreen ();
	scr_drawdialog = false;
	
	S_ClearBuffer ();		// so dma doesn't loop current sound

	time1 = Sys_DoubleTime () + timeout; //johnfitz -- timeout
	time2 = 0.0f; //johnfitz -- timeout

	do
	{
		key_count = -1;		// wait for a key down and up
		IN_ProcessEvents ();
		if (timeout)
			time2 = Sys_DoubleTime (); //johnfitz -- zero timeout means wait forever.
	} while (key_lastpress != 'y' &&
		key_lastpress != 'n' &&
		key_lastpress != K_ESCAPE &&
		time2 <= time1);

	SCR_UpdateScreen ();

	//johnfitz -- timeout
	if (time2 > time1)
		return false;
	//johnfitz

	return key_lastpress == 'y';
}
static bool R_CastZoomer(const Frame *frame, CastIntermissionAction *cast)
{
	// This may appear to animate faster than vanilla, but I'm fairly sure
	// that's because while the time on screen is adaptive, the frame durations
	// were decremented by one each frame.
	TObjPtr<SpriteZoomer> zoomer = new SpriteZoomer(frame, 224);
	do
	{
		for(unsigned int t = tics;zoomer && t-- > 0;)
			zoomer->Tick();
		if(!zoomer)
			break;

		if(intermissionMapLoaded)
			ThreeDRefresh();
		else
		{
			// Unlike a 3D view, we will overwrite the whole screen here
			ShowImage(cast, true);
			DrawCastName(cast);
		}
		zoomer->Draw();
		VH_UpdateScreen();
		IN_ProcessEvents();
		if(Keyboard[sc_Space] || Keyboard[sc_Escape] || Keyboard[sc_Enter])
		{
			bool done = Keyboard[sc_Escape] || Keyboard[sc_Enter];
			Keyboard[sc_Space] = Keyboard[sc_Escape] = Keyboard[sc_Enter] = false;
			zoomer->Destroy();
			if(done)
				return true;
			break;
		}
		CalcTics();
	}
	while(true);
	return false;
}
Exemple #19
0
void IN_Frame (void) {
	IN_JoyMove( );
	IN_ProcessEvents( );

	if( !cls.glconfig.isFullscreen && ( Key_GetCatcher( ) & KEYCATCH_CONSOLE ) )
	{
		// Console is down in windowed mode
		IN_DeactivateMouse( );
	}
	else if( !( SDL_GetWindowFlags( SDL_window ) & SDL_WINDOW_INPUT_FOCUS ) )
	{
		// Window not got focus
		IN_DeactivateMouse( );
	}
	else
		IN_ActivateMouse( );

	// In case we had to delay actual restart of video system
	if( ( vidRestartTime != 0 ) && ( vidRestartTime < Sys_Milliseconds( ) ) )
	{
		vidRestartTime = 0;
		Cbuf_AddText( "vid_restart\n" );
	}
}
Exemple #20
0
static void InitGame()
{
#ifndef SPEARDEMO
    boolean didjukebox=false;
#endif

    // initialize SDL
#if defined _WIN32
    putenv("SDL_VIDEODRIVER=directx");
#endif
    if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0)
    {
        printf("Unable to init SDL: %s\n", SDL_GetError());
        exit(1);
    }
    atexit(SDL_Quit);

    int numJoysticks = SDL_NumJoysticks();
    if(param_joystickindex && (param_joystickindex < -1 || param_joystickindex >= numJoysticks))
    {
        if(!numJoysticks)
            printf("No joysticks are available to SDL!\n");
        else
            printf("The joystick index must be between -1 and %i!\n", numJoysticks - 1);
        exit(1);
    }

#if defined(GP2X_940)
    GP2X_MemoryInit();
#endif

    SignonScreen ();

#if defined _WIN32
    if(!fullscreen)
    {
        struct SDL_SysWMinfo wmInfo;
        SDL_VERSION(&wmInfo.version);

        if(SDL_GetWMInfo(&wmInfo) != -1)
        {
            HWND hwndSDL = wmInfo.window;
            DWORD style = GetWindowLong(hwndSDL, GWL_STYLE) & ~WS_SYSMENU;
            SetWindowLong(hwndSDL, GWL_STYLE, style);
            SetWindowPos(hwndSDL, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
        }
    }
#endif
	VW_UpdateScreen();

    VH_Startup ();
    IN_Startup ();
    PM_Startup ();
    SD_Startup ();
    CA_Startup ();
    US_Startup ();

    // TODO: Will any memory checking be needed someday??
#ifdef NOTYET
#ifndef SPEAR
    if (mminfo.mainmem < 235000L)
#else
    if (mminfo.mainmem < 257000L && !MS_CheckParm("debugmode"))
#endif
    {
        byte *screen;

        CA_CacheGrChunk (ERRORSCREEN);
        screen = grsegs[ERRORSCREEN];
        ShutdownId();
/*        memcpy((byte *)0xb8000,screen+7+7*160,17*160);
        gotoxy (1,23);*/
        exit(1);
    }
#endif


//
// build some tables
//
    InitDigiMap ();

    ReadConfig ();

    SetupSaveGames();

//
// HOLDING DOWN 'M' KEY?
//
	IN_ProcessEvents();

#ifndef SPEARDEMO
    if (Keyboard[sc_M])
    {
        DoJukebox();
        didjukebox=true;
    }
    else
#endif

//
// draw intro screen stuff
//
    IntroScreen ();

#ifdef _arch_dreamcast
    //TODO: VMU Selection Screen
#endif

//
// load in and lock down some basic chunks
//

    CA_CacheGrChunk(STARTFONT);
    CA_CacheGrChunk(STATUSBARPIC);

    LoadLatchMem ();
    BuildTables ();          // trig tables
    SetupWalls ();

    NewViewSize (viewsize);

//
// initialize variables
//
    InitRedShifts ();
#ifndef SPEARDEMO
    if(!didjukebox)
#endif
        FinishSignon();

#ifdef NOTYET
    vdisp = (byte *) (0xa0000+PAGE1START);
    vbuf = (byte *) (0xa0000+PAGE2START);
#endif
}
Exemple #21
0
void Sys_SendKeyEvents(void)
{
    IN_ProcessEvents();
}
Exemple #22
0
void PollControls (void)
{
    int max, min, i;
    byte buttonbits;

    IN_ProcessEvents();

//
// get timing info for last frame
//
    if (demoplayback || demorecord)   // demo recording and playback needs to be constant
    {
        // wait up to DEMOTICS Wolf tics
        uint32_t curtime = SDL_GetTicks();
        lasttimecount += DEMOTICS;
        int32_t timediff = (lasttimecount * 100) / 7 - curtime;
        if(timediff > 0)
            SDL_Delay(timediff);

        if(timediff < -2 * DEMOTICS)       // more than 2-times DEMOTICS behind?
            lasttimecount = (curtime * 7) / 100;    // yes, set to current timecount

        tics = DEMOTICS;
    }
    else
        CalcTics ();

    controlx = 0;
    controly = 0;
    memcpy (buttonheld, buttonstate, sizeof (buttonstate));
    memset (buttonstate, 0, sizeof (buttonstate));

    if (demoplayback)
    {
        //
        // read commands from demo buffer
        //
        buttonbits = *demoptr++;
        for (i = 0; i < NUMBUTTONS; i++)
        {
            buttonstate[i] = buttonbits & 1;
            buttonbits >>= 1;
        }

        controlx = *demoptr++;
        controly = *demoptr++;

        if (demoptr == lastdemoptr)
            playstate = ex_completed;   // demo is done

        controlx *= (int) tics;
        controly *= (int) tics;

        return;
    }


//
// get button states
//
    PollKeyboardButtons ();

    if (mouseenabled && IN_IsInputGrabbed())
        PollMouseButtons ();

    if (joystickenabled)
        PollJoystickButtons ();

//
// get movements
//
    PollKeyboardMove ();

    if (mouseenabled && IN_IsInputGrabbed())
        PollMouseMove ();

    if (joystickenabled)
        PollJoystickMove ();

//
// bound movement to a maximum
//
    max = 100 * tics;
    min = -max;
    if (controlx > max)
        controlx = max;
    else if (controlx < min)
        controlx = min;

    if (controly > max)
        controly = max;
    else if (controly < min)
        controly = min;

    if (demorecord)
    {
        //
        // save info out to demo buffer
        //
        controlx /= (int) tics;
        controly /= (int) tics;

        buttonbits = 0;

        // TODO: Support 32-bit buttonbits
        for (i = NUMBUTTONS - 1; i >= 0; i--)
        {
            buttonbits <<= 1;
            if (buttonstate[i])
                buttonbits |= 1;
        }

        *demoptr++ = buttonbits;
        *demoptr++ = controlx;
        *demoptr++ = controly;

        if (demoptr >= lastdemoptr - 8)
            playstate = ex_completed;
        else
        {
            controlx *= (int) tics;
            controly *= (int) tics;
        }
    }
}