void DoRBFDialog(const char *FileName)
{
	RBFName = FileName;

	Sys_GrabMouseCursor( false );

	DialogBox(0, MAKEINTRESOURCE(IDD_RENDERBUMPFLAT), 0, (DLGPROC)RBFProc); 

	Sys_GrabMouseCursor( true );
}
Example #2
0
/*
===============
idCommonLocal::UpdateScreen

This is an out-of-sequence screen update, not the normal game rendering
===============
*/
void idCommonLocal::UpdateScreen( bool captureToImage ) {
	if ( insideUpdateScreen ) {
		return;
	}
	insideUpdateScreen = true;

	// make sure the game / draw thread has completed
	gameThread.WaitForThread();

	// release the mouse capture back to the desktop
	Sys_GrabMouseCursor( false );

	// build all the draw commands without running a new game tic
	Draw();

	if ( captureToImage ) {
		renderSystem->CaptureRenderToImage( "_currentRender", false );
	}

	// this should exit right after vsync, with the GPU idle and ready to draw
	const emptyCommand_t * cmd = renderSystem->SwapCommandBuffers( &time_frontend, &time_backend, &time_shadows, &time_gpu );

	// get the GPU busy with new commands
	renderSystem->RenderCommandBuffers( cmd );

	insideUpdateScreen = false;
}
/**
* Initializes the material editor tool.
*/
void MaterialEditorInit( void ) {

	InitPropTree(win32.hInstance);

	com_editors = EDITOR_MATERIAL;

	Sys_GrabMouseCursor( false );

	InitAfx();

	InitCommonControls();

	// Initialize OLE libraries
	if (!AfxOleInit())
	{
		return;
	}
	AfxEnableControlContainer();

	NONCLIENTMETRICS info;
	info.cbSize = sizeof(info);

	::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(info), &info, 0);

	LOGFONT lf;
	memset(&lf, 0, sizeof (LOGFONT));

	CWindowDC dc(NULL);
	lf.lfCharSet = (BYTE)GetTextCharsetInfo(dc.GetSafeHdc(), NULL, 0);

	lf.lfHeight = info.lfMenuFont.lfHeight;
	lf.lfWeight = info.lfMenuFont.lfWeight;
	lf.lfItalic = info.lfMenuFont.lfItalic;

	// check if we should use system font
	_tcscpy(lf.lfFaceName, info.lfMenuFont.lfFaceName);

	materialEditorFont = new CFont;
	materialEditorFont->CreateFontIndirect(&lf);


	// To create the main window, this code creates a new frame window
	// object and then sets it as the application's main window object
	meMainFrame = new MEMainFrame;

	// create and load the frame with its resources
	meMainFrame->LoadFrame(IDR_ME_MAINFRAME, WS_OVERLAPPEDWINDOW | FWS_ADDTOTITLE, NULL, NULL);


	// hide the doom window by default
	::ShowWindow ( win32.hWnd, SW_HIDE );

	// The one and only window has been initialized, so show and update it
	meMainFrame->ShowWindow(SW_SHOW);
	meMainFrame->UpdateWindow();
}
Example #4
0
/*
===========
Sys_InitInput
===========
*/
void Sys_InitInput( void ) {
	common->Printf ("\n------- Input Initialization -------\n");
	IN_InitDirectInput();
	if ( win32.in_mouse.GetBool() ) {
		IN_InitDIMouse();
		// don't grab the mouse on initialization
		Sys_GrabMouseCursor( false );
	} else {
		common->Printf ("Mouse control not active.\n");
	}
	IN_StartupKeyboard();
	common->Printf ("------------------------------------\n");
	win32.in_mouse.ClearModified();
}
Example #5
0
/*
=================
RadiantInit

This is also called when you 'quit' in doom
=================
*/
void RadiantInit( void ) {

	// make sure the renderer is initialized
	if ( !renderSystem->IsOpenGLRunning() ) {
		common->Printf( "no OpenGL running\n" );
		return;
	}

	g_editorAlive = true;

	// allocate a renderWorld and a soundWorld
	if ( g_qeglobals.rw == NULL ) {
		g_qeglobals.rw = renderSystem->AllocRenderWorld();
		g_qeglobals.rw->InitFromMap( NULL );
	}
	if ( g_qeglobals.sw == NULL ) {
		g_qeglobals.sw = soundSystem->AllocSoundWorld( g_qeglobals.rw );
	}

	if ( g_DoomInstance ) {
		if ( ::IsWindowVisible( win32.hWnd ) ) {
			::ShowWindow( win32.hWnd, SW_HIDE );
			g_pParentWnd->ShowWindow( SW_SHOW );
			g_pParentWnd->SetFocus();
		}
	} else {
		Sys_GrabMouseCursor( false );

		g_DoomInstance = win32.hInstance;
		CWinApp* pApp = AfxGetApp();
		CWinThread *pThread = AfxGetThread();

		InitAfx();

		// App global initializations (rare)
		pApp->InitApplication();

		// Perform specific initializations
		pThread->InitInstance();

		qglFinish();
		//qwglMakeCurrent(0, 0);
		qwglMakeCurrent(win32.hDC, win32.hGLRC);

		// hide the doom window by default
		::ShowWindow( win32.hWnd, SW_HIDE );
	}
}
Example #6
0
/*
===============
GLX_Init
===============
*/
int GLX_Init(glimpParms_t a)
{
    int attrib[] =
    {
        GLX_RGBA,				// 0
        GLX_RED_SIZE, 8,		// 1, 2
        GLX_GREEN_SIZE, 8,		// 3, 4
        GLX_BLUE_SIZE, 8,		// 5, 6
        GLX_DOUBLEBUFFER,		// 7
        GLX_DEPTH_SIZE, 24,		// 8, 9
        GLX_STENCIL_SIZE, 8,	// 10, 11
        GLX_ALPHA_SIZE, 8, // 12, 13
        None
    };
    // these match in the array
#define ATTR_RED_IDX 2
#define ATTR_GREEN_IDX 4
#define ATTR_BLUE_IDX 6
#define ATTR_DEPTH_IDX 9
#define ATTR_STENCIL_IDX 11
#define ATTR_ALPHA_IDX 13
    Window root;
    XVisualInfo *visinfo;
    XSetWindowAttributes attr;
    XSizeHints sizehints;
    unsigned long mask;
    int colorbits, depthbits, stencilbits;
    int tcolorbits, tdepthbits, tstencilbits;
    int actualWidth, actualHeight;
    int i;
    const char *glstring;

    if ( !GLimp_OpenDisplay() )
    {
        return false;
    }

    common->Printf( "Initializing OpenGL display\n" );

    root = RootWindow( dpy, scrnum );

    actualWidth = glConfig.vidWidth;
    actualHeight = glConfig.vidHeight;

    // Get video mode list
    if ( !XF86VidModeQueryVersion( dpy, &vidmode_MajorVersion, &vidmode_MinorVersion ) )
    {
        vidmode_ext = false;
        common->Printf("XFree86-VidModeExtension not available\n");
    }
    else
    {
        vidmode_ext = true;
        common->Printf("Using XFree86-VidModeExtension Version %d.%d\n",
                       vidmode_MajorVersion, vidmode_MinorVersion);
    }

    GLX_TestDGA();

    if ( vidmode_ext )
    {
        int best_fit, best_dist, dist, x, y;

        XF86VidModeGetAllModeLines( dpy, scrnum, &num_vidmodes, &vidmodes );

        // Are we going fullscreen?  If so, let's change video mode
        if ( a.fullScreen )
        {
            best_dist = 9999999;
            best_fit = -1;

            for (i = 0; i < num_vidmodes; i++)
            {
                if (a.width > vidmodes[i]->hdisplay ||
                        a.height > vidmodes[i]->vdisplay)
                    continue;

                x = a.width - vidmodes[i]->hdisplay;
                y = a.height - vidmodes[i]->vdisplay;
                dist = (x * x) + (y * y);
                if (dist < best_dist)
                {
                    best_dist = dist;
                    best_fit = i;
                }
            }

            if (best_fit != -1)
            {
                actualWidth = vidmodes[best_fit]->hdisplay;
                actualHeight = vidmodes[best_fit]->vdisplay;

                // change to the mode
                XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]);
                vidmode_active = true;

                // Move the viewport to top left
                // FIXME: center?
                XF86VidModeSetViewPort(dpy, scrnum, 0, 0);

                common->Printf( "Free86-VidModeExtension Activated at %dx%d\n", actualWidth, actualHeight );

            }
            else
            {
                a.fullScreen = false;
                common->Printf( "Free86-VidModeExtension: No acceptable modes found\n" );
            }
        }
        else
        {
            common->Printf( "XFree86-VidModeExtension: not fullscreen, ignored\n" );
        }
    }
    // color, depth and stencil
    colorbits = 24;
    depthbits = 24;
    stencilbits = 8;

    for (i = 0; i < 16; i++)
    {
        // 0 - default
        // 1 - minus colorbits
        // 2 - minus depthbits
        // 3 - minus stencil
        if ((i % 4) == 0 && i)
        {
            // one pass, reduce
            switch (i / 4)
            {
            case 2:
                if (colorbits == 24)
                    colorbits = 16;
                break;
            case 1:
                if (depthbits == 24)
                    depthbits = 16;
                else if (depthbits == 16)
                    depthbits = 8;
            case 3:
                if (stencilbits == 24)
                    stencilbits = 16;
                else if (stencilbits == 16)
                    stencilbits = 8;
            }
        }

        tcolorbits = colorbits;
        tdepthbits = depthbits;
        tstencilbits = stencilbits;

        if ((i % 4) == 3)  		// reduce colorbits
        {
            if (tcolorbits == 24)
                tcolorbits = 16;
        }

        if ((i % 4) == 2)  		// reduce depthbits
        {
            if (tdepthbits == 24)
                tdepthbits = 16;
            else if (tdepthbits == 16)
                tdepthbits = 8;
        }

        if ((i % 4) == 1)  		// reduce stencilbits
        {
            if (tstencilbits == 24)
                tstencilbits = 16;
            else if (tstencilbits == 16)
                tstencilbits = 8;
            else
                tstencilbits = 0;
        }

        if (tcolorbits == 24)
        {
            attrib[ATTR_RED_IDX] = 8;
            attrib[ATTR_GREEN_IDX] = 8;
            attrib[ATTR_BLUE_IDX] = 8;
        }
        else
        {
            // must be 16 bit
            attrib[ATTR_RED_IDX] = 4;
            attrib[ATTR_GREEN_IDX] = 4;
            attrib[ATTR_BLUE_IDX] = 4;
        }

        attrib[ATTR_DEPTH_IDX] = tdepthbits;	// default to 24 depth
        attrib[ATTR_STENCIL_IDX] = tstencilbits;

        visinfo = qglXChooseVisual(dpy, scrnum, attrib);
        if (!visinfo)
        {
            continue;
        }

        common->Printf( "Using %d/%d/%d Color bits, %d Alpha bits, %d depth, %d stencil display.\n",
                        attrib[ATTR_RED_IDX], attrib[ATTR_GREEN_IDX],
                        attrib[ATTR_BLUE_IDX], attrib[ATTR_ALPHA_IDX],
                        attrib[ATTR_DEPTH_IDX],
                        attrib[ATTR_STENCIL_IDX]);

        glConfig.colorBits = tcolorbits;
        glConfig.depthBits = tdepthbits;
        glConfig.stencilBits = tstencilbits;
        break;
    }

    if (!visinfo)
    {
        common->Printf("Couldn't get a visual\n");
        return false;
    }
    // window attributes
    attr.background_pixel = BlackPixel(dpy, scrnum);
    attr.border_pixel = 0;
    attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
    attr.event_mask = X_MASK;
    if (vidmode_active)
    {
        mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore |
               CWEventMask | CWOverrideRedirect;
        attr.override_redirect = True;
        attr.backing_store = NotUseful;
        attr.save_under = False;
    }
    else
    {
        mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
    }

    win = XCreateWindow(dpy, root, 0, 0,
                        actualWidth, actualHeight,
                        0, visinfo->depth, InputOutput,
                        visinfo->visual, mask, &attr);

    XStoreName(dpy, win, GAME_NAME);

    // don't let the window be resized
    // FIXME: allow resize (win32 does)
    sizehints.flags = PMinSize | PMaxSize;
    sizehints.min_width = sizehints.max_width = actualWidth;
    sizehints.min_height = sizehints.max_height = actualHeight;

    XSetWMNormalHints(dpy, win, &sizehints);

    XMapWindow( dpy, win );

    if ( vidmode_active )
    {
        XMoveWindow( dpy, win, 0, 0 );
    }

    XFlush(dpy);
    XSync(dpy, False);
    ctx = qglXCreateContext(dpy, visinfo, NULL, True);
    XSync(dpy, False);

    // Free the visinfo after we're done with it
    XFree(visinfo);

    qglXMakeCurrent(dpy, win, ctx);

    glstring = (const char *) qglGetString(GL_RENDERER);
    common->Printf("GL_RENDERER: %s\n", glstring);

    glstring = (const char *) qglGetString(GL_EXTENSIONS);
    common->Printf("GL_EXTENSIONS: %s\n", glstring);

    // FIXME: here, software GL test

    glConfig.isFullscreen = a.fullScreen;

    if ( glConfig.isFullscreen )
    {
        Sys_GrabMouseCursor( true );
    }

    return true;
}
Example #7
0
/*
=================
idCommonLocal::Frame
=================
*/
void idCommonLocal::Frame() {
	try {
		SCOPED_PROFILE_EVENT( "Common::Frame" );

		// This is the only place this is incremented
		idLib::frameNumber++;

		// allow changing SIMD usage on the fly
		if ( com_forceGenericSIMD.IsModified() ) {
			idSIMD::InitProcessor( "doom", com_forceGenericSIMD.GetBool() );
			com_forceGenericSIMD.ClearModified();
		}

		// Do the actual switch between Doom 3 and the classics here so
		// that things don't get confused in the middle of the frame.
		PerformGameSwitch();

		// pump all the events
		Sys_GenerateEvents();

		// write config file if anything changed
		WriteConfiguration(); 

		eventLoop->RunEventLoop();

		// Activate the shell if it's been requested
		if ( showShellRequested && game ) {
			game->Shell_Show( true );
			showShellRequested = false;
		}

		// if the console or another gui is down, we don't need to hold the mouse cursor
		bool chatting = false;
		if ( console->Active() || Dialog().IsDialogActive() || session->IsSystemUIShowing() || ( game && game->InhibitControls() && !IsPlayingDoomClassic() ) ) {
			Sys_GrabMouseCursor( false );
			usercmdGen->InhibitUsercmd( INHIBIT_SESSION, true );
			chatting = true;
		} else {
			Sys_GrabMouseCursor( true );
			usercmdGen->InhibitUsercmd( INHIBIT_SESSION, false );
		}

		const bool pauseGame = ( !mapSpawned || ( !IsMultiplayer() && ( Dialog().IsDialogPausing() || session->IsSystemUIShowing() || ( game && game->Shell_IsActive() ) ) ) ) && !IsPlayingDoomClassic();

		// save the screenshot and audio from the last draw if needed
		if ( aviCaptureMode ) {
			idStr name = va("demos/%s/%s_%05i.tga", aviDemoShortName.c_str(), aviDemoShortName.c_str(), aviDemoFrameCount++ );
			renderSystem->TakeScreenshot( com_aviDemoWidth.GetInteger(), com_aviDemoHeight.GetInteger(), name, com_aviDemoSamples.GetInteger(), NULL );

			// remove any printed lines at the top before taking the screenshot
			console->ClearNotifyLines();

			// this will call Draw, possibly multiple times if com_aviDemoSamples is > 1
			renderSystem->TakeScreenshot( com_aviDemoWidth.GetInteger(), com_aviDemoHeight.GetInteger(), name, com_aviDemoSamples.GetInteger(), NULL );
		}

		//--------------------------------------------
		// wait for the GPU to finish drawing
		//
		// It is imporant to minimize the time spent between this
		// section and the call to renderSystem->RenderCommandBuffers(),
		// because the GPU is completely idle.
		//--------------------------------------------
		// this should exit right after vsync, with the GPU idle and ready to draw
		// This may block if the GPU isn't finished renderng the previous frame.
		frameTiming.startSyncTime = Sys_Microseconds();
		const emptyCommand_t * renderCommands = NULL;
		if ( com_smp.GetBool() ) {
			renderCommands = renderSystem->SwapCommandBuffers( &time_frontend, &time_backend, &time_shadows, &time_gpu );
		} else {
			// the GPU will stay idle through command generation for minimal
			// input latency
			renderSystem->SwapCommandBuffers_FinishRendering( &time_frontend, &time_backend, &time_shadows, &time_gpu );
		}
		frameTiming.finishSyncTime = Sys_Microseconds();

		//--------------------------------------------
		// Determine how many game tics we are going to run,
		// now that the previous frame is completely finished.
		//
		// It is important that any waiting on the GPU be done
		// before this, or there will be a bad stuttering when
		// dropping frames for performance management.
		//--------------------------------------------

		// input:
		// thisFrameTime
		// com_noSleep
		// com_engineHz
		// com_fixedTic
		// com_deltaTimeClamp
		// IsMultiplayer
		//
		// in/out state:
		// gameFrame
		// gameTimeResidual
		// lastFrameTime
		// syncNextFrame
		//
		// Output:
		// numGameFrames

		// How many game frames to run
		int numGameFrames = 0;

		for(;;) {
			const int thisFrameTime = Sys_Milliseconds();
			static int lastFrameTime = thisFrameTime;	// initialized only the first time
			const int deltaMilliseconds = thisFrameTime - lastFrameTime;
			lastFrameTime = thisFrameTime;

			// if there was a large gap in time since the last frame, or the frame
			// rate is very very low, limit the number of frames we will run
			const int clampedDeltaMilliseconds = Min( deltaMilliseconds, com_deltaTimeClamp.GetInteger() );

			gameTimeResidual += clampedDeltaMilliseconds * timescale.GetFloat();

			// don't run any frames when paused
			if ( pauseGame ) {
				gameFrame++;
				gameTimeResidual = 0;
				break;
			}

			// debug cvar to force multiple game tics
			if ( com_fixedTic.GetInteger() > 0 ) {
				numGameFrames = com_fixedTic.GetInteger();
				gameFrame += numGameFrames;
				gameTimeResidual = 0;
				break;
			}

			if ( syncNextGameFrame ) {
				// don't sleep at all
				syncNextGameFrame = false;
				gameFrame++;
				numGameFrames++;
				gameTimeResidual = 0;
				break;
			}

			for ( ;; ) {
				// How much time to wait before running the next frame,
				// based on com_engineHz
				const int frameDelay = FRAME_TO_MSEC( gameFrame + 1 ) - FRAME_TO_MSEC( gameFrame );
				if ( gameTimeResidual < frameDelay ) {
					break;
				}
				gameTimeResidual -= frameDelay;
				gameFrame++;
				numGameFrames++;
				// if there is enough residual left, we may run additional frames
			}

			if ( numGameFrames > 0 ) {
				// ready to actually run them
				break;
			}

			// if we are vsyncing, we always want to run at least one game
			// frame and never sleep, which might happen due to scheduling issues
			// if we were just looking at real time.
			if ( com_noSleep.GetBool() ) {
				numGameFrames = 1;
				gameFrame += numGameFrames;
				gameTimeResidual = 0;
				break;
			}

			// not enough time has passed to run a frame, as might happen if
			// we don't have vsync on, or the monitor is running at 120hz while
			// com_engineHz is 60, so sleep a bit and check again
			Sys_Sleep( 0 );
		}

		//--------------------------------------------
		// It would be better to push as much of this as possible
		// either before or after the renderSystem->SwapCommandBuffers(),
		// because the GPU is completely idle.
		//--------------------------------------------

		// Update session and syncronize to the new session state after sleeping
		session->UpdateSignInManager();
		session->Pump();
		session->ProcessSnapAckQueue();

		if ( session->GetState() == idSession::LOADING ) {
			// If the session reports we should be loading a map, load it!
			ExecuteMapChange();
			mapSpawnData.savegameFile = NULL;
			mapSpawnData.persistentPlayerInfo.Clear();
			return;
		} else if ( session->GetState() != idSession::INGAME && mapSpawned ) {
			// If the game is running, but the session reports we are not in a game, disconnect
			// This happens when a server disconnects us or we sign out
			LeaveGame();
			return;
		}

		if ( mapSpawned && !pauseGame ) {
			if ( IsClient() ) {
				RunNetworkSnapshotFrame();
			}
		}

		ExecuteReliableMessages();

		// send frame and mouse events to active guis
		GuiFrameEvents();

		//--------------------------------------------
		// Prepare usercmds and kick off the game processing
		// in a background thread
		//--------------------------------------------

		// get the previous usercmd for bypassed head tracking transform
		const usercmd_t	previousCmd = usercmdGen->GetCurrentUsercmd();

		// build a new usercmd
		int deviceNum = session->GetSignInManager().GetMasterInputDevice();
		usercmdGen->BuildCurrentUsercmd( deviceNum );
		if ( deviceNum == -1 ) {
			for ( int i = 0; i < MAX_INPUT_DEVICES; i++ ) {
				Sys_PollJoystickInputEvents( i );
				Sys_EndJoystickInputEvents();
			}
		}
		if ( pauseGame ) {
			usercmdGen->Clear();
		}

		usercmd_t newCmd = usercmdGen->GetCurrentUsercmd();

		// Store server game time - don't let time go past last SS time in case we are extrapolating
		if ( IsClient() ) {
			newCmd.serverGameMilliseconds = std::min( Game()->GetServerGameTimeMs(), Game()->GetSSEndTime() );
		} else {
			newCmd.serverGameMilliseconds = Game()->GetServerGameTimeMs();
		}

		userCmdMgr.MakeReadPtrCurrentForPlayer( Game()->GetLocalClientNum() );

		// Stuff a copy of this userCmd for each game frame we are going to run.
		// Ideally, the usercmds would be built in another thread so you could
		// still get 60hz control accuracy when the game is running slower.
		for ( int i = 0 ; i < numGameFrames ; i++ ) {
			newCmd.clientGameMilliseconds = FRAME_TO_MSEC( gameFrame-numGameFrames+i+1 );
			userCmdMgr.PutUserCmdForPlayer( game->GetLocalClientNum(), newCmd );
		}

		// If we're in Doom or Doom 2, run tics and upload the new texture.
		if ( ( GetCurrentGame() == DOOM_CLASSIC || GetCurrentGame() == DOOM2_CLASSIC ) && !( Dialog().IsDialogPausing() || session->IsSystemUIShowing() ) ) {
			RunDoomClassicFrame();
		}
		
		// start the game / draw command generation thread going in the background
		gameReturn_t ret = gameThread.RunGameAndDraw( numGameFrames, userCmdMgr, IsClient(), gameFrame - numGameFrames );

		if ( !com_smp.GetBool() ) {
			// in non-smp mode, run the commands we just generated, instead of
			// frame-delayed ones from a background thread
			renderCommands = renderSystem->SwapCommandBuffers_FinishCommandBuffers();
		}

		//----------------------------------------
		// Run the render back end, getting the GPU busy with new commands
		// ASAP to minimize the pipeline bubble.
		//----------------------------------------
		frameTiming.startRenderTime = Sys_Microseconds();
		renderSystem->RenderCommandBuffers( renderCommands );
		if ( com_sleepRender.GetInteger() > 0 ) {
			// debug tool to test frame adaption
			Sys_Sleep( com_sleepRender.GetInteger() );
		}
		frameTiming.finishRenderTime = Sys_Microseconds();

		// make sure the game / draw thread has completed
		// This may block if the game is taking longer than the render back end
		gameThread.WaitForThread();

		// Send local usermds to the server.
		// This happens after the game frame has run so that prediction data is up to date.
		SendUsercmds( Game()->GetLocalClientNum() );

		// Now that we have an updated game frame, we can send out new snapshots to our clients
		session->Pump(); // Pump to get updated usercmds to relay
		SendSnapshots();

		// Render the sound system using the latest commands from the game thread
		if ( pauseGame ) {
			soundWorld->Pause();
			soundSystem->SetPlayingSoundWorld( menuSoundWorld );
		} else {
			soundWorld->UnPause();
			soundSystem->SetPlayingSoundWorld( soundWorld );
		}
		soundSystem->Render();

		// process the game return for map changes, etc
		ProcessGameReturn( ret );

		idLobbyBase & lobby = session->GetActivePlatformLobbyBase();
		if ( lobby.HasActivePeers() ) {
			if ( net_drawDebugHud.GetInteger() == 1 ) {
				lobby.DrawDebugNetworkHUD();
			}
			if ( net_drawDebugHud.GetInteger() == 2 ) {
				lobby.DrawDebugNetworkHUD2();
			}
			lobby.DrawDebugNetworkHUD_ServerSnapshotMetrics( net_drawDebugHud.GetInteger() == 3 );
		}

		// report timing information
		if ( com_speeds.GetBool() ) {
			static int lastTime = Sys_Milliseconds();
			int	nowTime = Sys_Milliseconds();
			int	com_frameMsec = nowTime - lastTime;
			lastTime = nowTime;
			Printf( "frame:%d all:%3d gfr:%3d rf:%3lld bk:%3lld\n", idLib::frameNumber, com_frameMsec, time_gameFrame, time_frontend / 1000, time_backend / 1000 );
			time_gameFrame = 0;
			time_gameDraw = 0;
		}

		// the FPU stack better be empty at this point or some bad code or compiler bug left values on the stack
		if ( !Sys_FPU_StackIsEmpty() ) {
			Printf( Sys_FPU_GetState() );
			FatalError( "idCommon::Frame: the FPU stack is not empty at the end of the frame\n" );
		}

		mainFrameTiming = frameTiming;

		session->GetSaveGameManager().Pump();
	} catch( idException & ) {
		return;			// an ERP_DROP was thrown
	}
}
Example #8
0
/*
================
rvGEApp::Initialize

Initialize the gui editor application
================
*/
bool rvGEApp::Initialize ( void )
{
    mOptions.Init();

    // Mutually exclusive
    com_editors = EDITOR_GUI;

    Sys_GrabMouseCursor( false );

    // Load the options
    mOptions.Load ( );

    mInstance = win32.hInstance;

    // Create the accelerators
    mAccelerators = LoadAccelerators ( mInstance, MAKEINTRESOURCE(IDR_GUIED_ACCELERATORS) );

    // Register the window classes for the main frame and the mdi child window
    WNDCLASSEX wndClass;
    memset ( &wndClass, 0, sizeof(wndClass) );
    wndClass.cbSize = sizeof(WNDCLASSEX);
    wndClass.lpszClassName	= "QUAKE4_GUIEDITOR_CLASS";
    wndClass.lpfnWndProc	= FrameWndProc;
    wndClass.hbrBackground	= (HBRUSH) (COLOR_APPWORKSPACE + 1);
    wndClass.hCursor		= LoadCursor((HINSTANCE) NULL, IDC_ARROW);
    wndClass.lpszMenuName	= MAKEINTRESOURCE(IDR_GUIED_MAIN);
    wndClass.hInstance		= mInstance;
    RegisterClassEx ( &wndClass );

    wndClass.lpszMenuName	= NULL;
    wndClass.lpfnWndProc	= MDIChildProc;
    wndClass.lpszClassName	= "QUAKE4_GUIEDITOR_CHILD_CLASS";
    wndClass.style			= CS_OWNDC|CS_DBLCLKS|CS_BYTEALIGNWINDOW|CS_VREDRAW|CS_HREDRAW;
    wndClass.hbrBackground	= (HBRUSH)GetStockObject( LTGRAY_BRUSH );
    RegisterClassEx ( &wndClass );

    // Create the main window
    mMDIFrame = CreateWindow ( "QUAKE4_GUIEDITOR_CLASS",
                               "Quake IV GUI Editor",
                               WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS,
                               CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                               NULL, NULL, mInstance, (LPVOID)this );

    if ( !mMDIFrame )
    {
        return false;
    }

    SetClassLong( mMDIFrame, GCL_HICON, ( LONG )LoadIcon( win32.hInstance, MAKEINTRESOURCE( IDI_GUIED ) ) );

    // Create the MDI window
    CLIENTCREATESTRUCT ccs;
    ccs.hWindowMenu = GetSubMenu ( GetMenu ( mMDIFrame ), 5 );
    ccs.idFirstChild = IDM_WINDOWCHILD;
    mMDIClient = CreateWindow ( "MDICLIENT", NULL,
                                WS_CHILDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
                                0, 0, 1000, 1000,
                                mMDIFrame, NULL,
                                mInstance, &ccs );

    if ( !mMDIClient )
    {
        DestroyWindow ( mMDIFrame );
        return false;
    }

    // hide the doom window by default
    ::ShowWindow ( win32.hWnd, SW_HIDE );

    // Show both windows
    mOptions.GetWindowPlacement ( "mdiframe", mMDIFrame );
    ShowWindow ( mMDIFrame, SW_SHOW );
    UpdateWindow ( mMDIFrame );

    ShowWindow ( mMDIClient, SW_SHOW );
    UpdateWindow ( mMDIClient );

    return true;
}
/*
================
rvDebuggerServer::Break

Halt execution of the game threads and inform the debugger client that
the game has been halted
================
*/
void rvDebuggerServer::Break ( idInterpreter* interpreter, idProgram* program, int instructionPointer )
{
	msg_t				msg;
	byte				buffer[MAX_MSGLEN];
	const statement_t*	st;
	const char*			filename;

	// Clear all the break types
	mBreakStepOver = false;
	mBreakStepInto = false;
	mBreakNext     = false;
	
	// Grab the current statement and the filename that it came from
	st       = &program->GetStatement ( instructionPointer );
	filename = program->GetFilename ( st->file );

	idStr qpath;
	OSPathToRelativePath(filename, qpath);	
	qpath.BackSlashesToSlashes ( );

	// Give the mouse cursor back to the world
	Sys_GrabMouseCursor( false );	
	
	// Set the break variable so we know the main thread is stopped
	mBreak = true;
	mBreakProgram = program;
	mBreakInterpreter = interpreter;
	mBreakInstructionPointer = instructionPointer;
	
	// Inform the debugger of the breakpoint hit
	MSG_Init( &msg, buffer, sizeof( buffer ) );
	MSG_WriteShort ( &msg, (int)DBMSG_BREAK );
	MSG_WriteLong ( &msg, st->linenumber );
	MSG_WriteString ( &msg, qpath );
	SendPacket ( msg.data, msg.cursize );
		
	// Suspend the game thread.  Since this will be called from within the main game thread
	// execution wont return until after the thread is resumed
	SuspendThread ( mGameThread );						
	
	// Let the debugger client know that we have started back up again
	SendMessage ( DBMSG_RESUMED );

	// This is to give some time between the keypress that 
	// told us to resume and the setforeground window.  Otherwise the quake window
	// would just flash
	Sleep ( 150 );

	// Bring the window back to the foreground	
	SetForegroundWindow ( win32.hWnd );
	SetActiveWindow ( win32.hWnd );
	UpdateWindow ( win32.hWnd );
	SetFocus ( win32.hWnd );	
	
	// Give the mouse cursor back to the game
	Sys_GrabMouseCursor( true );	
	
	// Clear all commands that were generated before we went into suspended mode.  This is
	// to ensure we dont have mouse downs with no ups because the context was changed.
	idKeyInput::ClearStates();
}
Example #10
0
/*
===============
idCommonLocal::ExecuteMapChange

Performs the initialization of a game based on session match parameters, used for both single
player and multiplayer, but not for renderDemos, which don't create a game at all.
Exits with mapSpawned = true
===============
*/
void idCommonLocal::ExecuteMapChange() {
	if ( session->GetState() != idSession::LOADING ) {
		idLib::Warning( "Session state is not LOADING in ExecuteMapChange" );
		return;
	}

	// Clear all dialogs before beginning the load
	common->Dialog().ClearDialogs( true );
	
	// Remember the current load ID.
	// This is so we can tell if we had a new loadmap request from within an existing loadmap call
	const int cachedLoadingID = session->GetLoadingID();

	const idMatchParameters & matchParameters = session->GetActingGameStateLobbyBase().GetMatchParms();

	if ( matchParameters.numSlots <= 0 ) {
		idLib::Warning( "numSlots <= 0 in ExecuteMapChange" );
		return;
	}

	insideExecuteMapChange = true;

	common->Printf( "--------- Execute Map Change ---------\n" );
	common->Printf( "Map: %s\n", matchParameters.mapName.c_str() );

	// ensure that r_znear is reset to the default value
	// this fixes issues with the projection matrix getting messed up when switching maps or loading a saved game
	// while an in-game cinematic is playing.
	cvarSystem->SetCVarFloat( "r_znear", 1.0f );

	// reset all cheat cvars for a multiplayer game
	if ( IsMultiplayer() ) {
		cvarSystem->ResetFlaggedVariables( CVAR_CHEAT );
	}

	int start = Sys_Milliseconds();

	for ( int i = 0; i < MAX_INPUT_DEVICES; i++ ) {
		Sys_SetRumble( i, 0, 0 );
	}

	// close console and remove any prints from the notify lines
	console->Close();

	// clear all menu sounds
	soundWorld->Pause();
	menuSoundWorld->ClearAllSoundEmitters();
	soundSystem->SetPlayingSoundWorld( menuSoundWorld );
	soundSystem->Render();

	// extract the map name from serverinfo
	currentMapName = matchParameters.mapName;
	currentMapName.StripFileExtension();

	idStrStatic< MAX_OSPATH > fullMapName = "maps/";
	fullMapName += currentMapName;
	fullMapName.SetFileExtension( "map" );

	if ( mapSpawnData.savegameFile ) {
		fileSystem->BeginLevelLoad( currentMapName, NULL, 0 );
	} else {
		fileSystem->BeginLevelLoad( currentMapName, saveFile.GetDataPtr(), saveFile.GetAllocated() );
	}

	// capture the current screen and start a wipe
	// immediately complete the wipe to fade out the level transition
	// run the wipe to completion
	StartWipe( "wipeMaterial", true );
	CompleteWipe();

	int sm = Sys_Milliseconds();
	// shut down the existing game if it is running
	UnloadMap();
	int ms = Sys_Milliseconds() - sm;
	common->Printf( "%6d msec to unload map\n", ms );

	// Free media from previous level and
	// note which media we are going to need to load
	sm = Sys_Milliseconds();
	renderSystem->BeginLevelLoad();
	soundSystem->BeginLevelLoad();
	declManager->BeginLevelLoad();
	uiManager->BeginLevelLoad();
	ms = Sys_Milliseconds() - sm;
	common->Printf( "%6d msec to free assets\n", ms );

	//Sys_DumpMemory( true );

	// load / program a gui to stay up on the screen while loading
	// set the loading gui that we will wipe to
	bool hellMap = false;
	LoadLoadingGui( currentMapName, hellMap );

	// Stop rendering the wipe
	ClearWipe();


	if ( fileSystem->UsingResourceFiles() ) {
		idStrStatic< MAX_OSPATH > manifestName = currentMapName;
		manifestName.Replace( "game/", "maps/" );
		manifestName.Replace( "/mp/", "/" );
		manifestName += ".preload";
		idPreloadManifest manifest;
		manifest.LoadManifest( manifestName );
		renderSystem->Preload( manifest, currentMapName );
		soundSystem->Preload( manifest );
		game->Preload( manifest );
	}

	if ( common->IsMultiplayer() ) {
		// In multiplayer, make sure the player is either 60Hz or 120Hz
		// to avoid potential issues.
		const float mpEngineHz = ( com_engineHz.GetFloat() < 90.0f ) ? 60.0f : 120.0f;
		com_engineHz_denominator = 100LL * mpEngineHz;
		com_engineHz_latched = mpEngineHz;
	} else {
		// allow com_engineHz to be changed between map loads
		com_engineHz_denominator = 100LL * com_engineHz.GetFloat();
		com_engineHz_latched = com_engineHz.GetFloat();
	}

	// note any warning prints that happen during the load process
	common->ClearWarnings( currentMapName );

	// release the mouse cursor
	// before we do this potentially long operation
	Sys_GrabMouseCursor( false );

	// let the renderSystem load all the geometry
	if ( !renderWorld->InitFromMap( fullMapName ) ) {
		common->Error( "couldn't load %s", fullMapName.c_str() );
	}

	// for the synchronous networking we needed to roll the angles over from
	// level to level, but now we can just clear everything
	usercmdGen->InitForNewMap();

	// load and spawn all other entities ( from a savegame possibly )
	if ( mapSpawnData.savegameFile ) {
		if ( !game->InitFromSaveGame( fullMapName, renderWorld, soundWorld, mapSpawnData.savegameFile, mapSpawnData.stringTableFile, mapSpawnData.savegameVersion ) ) {
			// If the loadgame failed, end the session, which will force us to go back to the main menu
			session->QuitMatchToTitle();
		}
	} else {
		if ( !IsMultiplayer() ) {
			assert( game->GetLocalClientNum() == 0 );
			assert( matchParameters.gameMode == GAME_MODE_SINGLEPLAYER );
			assert( matchParameters.gameMap == GAME_MAP_SINGLEPLAYER );
			game->SetPersistentPlayerInfo( 0, mapSpawnData.persistentPlayerInfo );
		}
		game->SetServerInfo( matchParameters.serverInfo );
		game->InitFromNewMap( fullMapName, renderWorld, soundWorld, matchParameters.gameMode, Sys_Milliseconds() );
	}

	game->Shell_CreateMenu( true );

	// Reset some values important to multiplayer
	ResetNetworkingState();

	// If the session state is not loading here, something went wrong.
	if ( session->GetState() == idSession::LOADING && session->GetLoadingID() == cachedLoadingID ) {
		// Notify session we are done loading
		session->LoadingFinished();

		while ( session->GetState() == idSession::LOADING ) {
			Sys_GenerateEvents();
			session->UpdateSignInManager();
			session->Pump();
			Sys_Sleep( 10 );
		}
	}

	if ( !mapSpawnData.savegameFile ) {
		// run a single frame to catch any resources that are referenced by events posted in spawn
		idUserCmdMgr emptyCommandManager;
		gameReturn_t emptyGameReturn;
		for ( int playerIndex = 0; playerIndex < MAX_PLAYERS; ++playerIndex ) {
			emptyCommandManager.PutUserCmdForPlayer( playerIndex, usercmd_t() );
		}
		if ( IsClient() ) {
			game->ClientRunFrame( emptyCommandManager, false, emptyGameReturn );
		} else {
			game->RunFrame( emptyCommandManager, emptyGameReturn );
		}
	}

	renderSystem->EndLevelLoad();
	soundSystem->EndLevelLoad();
	declManager->EndLevelLoad();
	uiManager->EndLevelLoad( currentMapName );
	fileSystem->EndLevelLoad();

	if ( !mapSpawnData.savegameFile && !IsMultiplayer() ) {
		common->Printf( "----- Running initial game frames -----\n" );

		// In single player, run a bunch of frames to make sure ragdolls are settled
		idUserCmdMgr emptyCommandManager;
		gameReturn_t emptyGameReturn;
		for ( int i = 0; i < 100; i++ ) {
			for ( int playerIndex = 0; playerIndex < MAX_PLAYERS; ++playerIndex ) {
				emptyCommandManager.PutUserCmdForPlayer( playerIndex, usercmd_t() );
			}
			game->RunFrame( emptyCommandManager, emptyGameReturn );
		}

		// kick off an auto-save of the game (so we can always continue in this map if we die before hitting an autosave)
		common->Printf( "----- Saving Game -----\n" );
		SaveGame( "autosave" );
	}

	common->Printf( "----- Generating Interactions -----\n" );

	// let the renderSystem generate interactions now that everything is spawned
	renderWorld->GenerateAllInteractions();

	{
		int vertexMemUsedKB = vertexCache.staticData.vertexMemUsed.GetValue() / 1024;
		int indexMemUsedKB = vertexCache.staticData.indexMemUsed.GetValue() / 1024;
		idLib::Printf( "Used %dkb of static vertex memory (%d%%)\n", vertexMemUsedKB, vertexMemUsedKB * 100 / ( STATIC_VERTEX_MEMORY / 1024 ) );
		idLib::Printf( "Used %dkb of static index memory (%d%%)\n", indexMemUsedKB, indexMemUsedKB * 100 / ( STATIC_INDEX_MEMORY / 1024 ) );
	}

	if ( common->JapaneseCensorship() ) {
		if ( currentMapName.Icmp( "game/mp/d3xpdm3" ) == 0 ) {
			const idMaterial * gizpool2 = declManager->FindMaterial( "textures/hell/gizpool2" );
			idMaterial * chiglass1bluex = const_cast<idMaterial *>( declManager->FindMaterial( "textures/sfx/chiglass1bluex" ) );
			idTempArray<char> text( gizpool2->GetTextLength() );
			gizpool2->GetText( text.Ptr() );
			chiglass1bluex->Parse( text.Ptr(), text.Num(), false );
		}
	}

	common->PrintWarnings();

	session->Pump();

	if ( session->GetState() != idSession::INGAME ) {
		// Something went wrong, don't process stale reliables that have been queued up.
		reliableQueue.Clear();
	}

	usercmdGen->Clear();

	// remove any prints from the notify lines
	console->ClearNotifyLines();

	Sys_SetPhysicalWorkMemory( -1, -1 );

	// at this point we should be done with the loading gui so we kill it
	delete loadGUI;
	loadGUI = NULL;


	// capture the current screen and start a wipe
	StartWipe( "wipe2Material" );

	// we are valid for game draws now
	insideExecuteMapChange = false;
	mapSpawned = true;
	Sys_ClearEvents();


	int	msec = Sys_Milliseconds() - start;
	common->Printf( "%6d msec to load %s\n", msec, currentMapName.c_str() );
	//Sys_DumpMemory( false );	

	// Issue a render at the very end of the load process to update soundTime before the first frame
	soundSystem->Render();
}
Example #11
0
bool Console::ProcessEvent( const sysEvent_t* event, bool forceAccept )
{
	if( isInitialized() )
	{
		const bool consoleKey = event->evType == SE_KEY && event->evValue == K_GRAVE && com_allowConsole.GetBool();
		
		const bool tabKey = event->evType == SE_KEY && event->evValue == K_TAB;
		
		// we always catch the console key event
		if( !forceAccept && consoleKey )
		{
			// ignore up events
			if( event->evValue2 == 0 )
			{
				return true;
			}
			
			// if window is Active we close it with consoleKey
			if( Active() )
			{
				Close();
				Sys_GrabMouseCursor( true );
			}
			else
			{
				Open();
				Sys_GrabMouseCursor( false );
			}
			return true;
		}
		
		// return event as processed when console open
		// aka don't pass the input further
		if( Active() )
		{
			if( tabKey )
			{
				// ignore up events
				if( event->evValue2 == 0 )
				{
					return true;
				}
				TabComplete();
			}
			return true;
		}
		
		// if we aren't Active, dump all the other events
		if( !forceAccept && !Active() )
		{
			return false;
		}
		
		if( forceAccept )
		{
			// a dummy here
			return true;
		}
		
		// we don't handle things like mouse, joystick, and network packets
		return false;
	}
	return false;
}
Example #12
0
/*
==============
ProcessEvent
==============
*/
bool	idConsoleLocal::ProcessEvent( const sysEvent_t* event, bool forceAccept )
{
	const bool consoleKey = event->evType == SE_KEY && event->evValue == K_GRAVE && com_allowConsole.GetBool();
	
	// we always catch the console key event
	if( !forceAccept && consoleKey )
	{
		// ignore up events
		if( event->evValue2 == 0 )
		{
			return true;
		}
		
		consoleField.ClearAutoComplete();
		
		// a down event will toggle the destination lines
		if( keyCatching )
		{
			Close();
			Sys_GrabMouseCursor( true );
		}
		else
		{
			consoleField.Clear();
			keyCatching = true;
			if( idKeyInput::IsDown( K_LSHIFT ) || idKeyInput::IsDown( K_RSHIFT ) )
			{
				// if the shift key is down, don't open the console as much
				SetDisplayFraction( 0.2f );
			}
			else
			{
				SetDisplayFraction( 0.5f );
			}
		}
		return true;
	}
	
	// if we aren't key catching, dump all the other events
	if( !forceAccept && !keyCatching )
	{
		return false;
	}
	
	// handle key and character events
	if( event->evType == SE_CHAR )
	{
		// never send the console key as a character
		if( event->evValue != '`' && event->evValue != '~' )
		{
			consoleField.CharEvent( event->evValue );
		}
		return true;
	}
	
	if( event->evType == SE_KEY )
	{
		// ignore up key events
		if( event->evValue2 == 0 )
		{
			return true;
		}
		
		KeyDownEvent( event->evValue );
		return true;
	}
	
	// we don't handle things like mouse, joystick, and network packets
	return false;
}