Display::Display() : m_Width( 0 ) , m_Height( 0 ) , m_ScreenWidth( 0 ) , m_ScreenHeight( 0 ) , m_AspectRatio( 0.0f ) , m_Fullscreen( false ) , m_DisplayModes() { STATICHASH( DisplayWidth ); STATICHASH( DisplayHeight ); STATICHASH( FOV ); STATICHASH( Fullscreen ); m_Width = ConfigManager::GetInt( sDisplayWidth ); m_Height = ConfigManager::GetInt( sDisplayHeight ); m_AspectRatio = ( float )m_Width / ( float )m_Height; m_Fullscreen = ConfigManager::GetBool( sFullscreen ); // Get the stored resolution #if BUILD_WINDOWS_NO_SDL DEVMODE DevMode; XTRACE_BEGIN( EnumDisplaySettings ); EnumDisplaySettings( NULL, ENUM_REGISTRY_SETTINGS, &DevMode ); XTRACE_END; m_ScreenWidth = DevMode.dmPelsWidth; m_ScreenHeight = DevMode.dmPelsHeight; #endif #if BUILD_SDL SDL_DisplayMode DisplayMode; SDL_GetDesktopDisplayMode( 0, &DisplayMode ); m_ScreenWidth = DisplayMode.w; m_ScreenHeight = DisplayMode.h; #endif UpdateDisplay(); }
// Recover from a lost device bool D3D9Renderer::Reset() { XTRACE_FUNCTION; if (!CanReset()) { return false; } PreReset(); D3DPRESENT_PARAMETERS Params; GetPresentParams(Params); XTRACE_BEGIN(ResetDevice); const HRESULT hr = m_D3DDevice->Reset(&Params); if (hr != D3D_OK) { return false; } XTRACE_END; m_DeviceLost = false; PostReset(); return true; }
/*virtual*/ bool Framework3D::TickSim( float DeltaTime ) { XTRACE_FUNCTION; const bool WasPaused = m_UIManager->GetUIStack()->PausesGame(); m_Clock->GameTick( WasPaused, DeltaTime ); #if BUILD_SDL if( !TickSDLEvents() ) { return false; } #endif TickDevices(); #if !BUILD_STEAM // Bit of a hack... And would conflict with Steam's F12 key function. if( m_Keyboard->OnRise( Keyboard::EB_F12 ) ) { TakeScreenshot(); } #endif // Man I'm really ruining the notion of "TickInput" huh. if( ( m_Keyboard->IsHigh( Keyboard::EB_LeftAlt ) || m_Keyboard->IsHigh( Keyboard::EB_RightAlt ) ) && m_Keyboard->OnRise( Keyboard::EB_Enter ) ) { ToggleFullscreen(); } #if !BUILD_MAC // This causes problems on Mac, but is essential on Linux and maybe Windows. if( m_Mouse->IsActive() && m_Window->HasFocus() ) { // Fix invisible cursor from affecting other windows m_Mouse->SetPosition( m_Display->m_Width / 2, m_Display->m_Height / 2, m_Window ); } #endif XTRACE_BEGIN( TickUI ); m_UIManager->ProcessEvents(); m_UIManager->GetUIStack()->Tick( DeltaTime, DeltaTime, false ); XTRACE_END; const bool Unpaused = WasPaused && !m_UIManager->GetUIStack()->PausesGame(); if( Unpaused ) { OnUnpaused(); m_Clock->GameTick( false, DeltaTime ); } if( m_HasFocus ) { if( WasPaused ) { TickPausedInput(); } else { if( !TickInput( DeltaTime ) ) { return false; } } } if( !WasPaused ) { TickGame( DeltaTime ); } XTRACE_BEGIN( TickAudio ); m_AudioSystem->Tick( DeltaTime, WasPaused ); XTRACE_END; return true; }
/*virtual*/ void Framework3D::Initialize() { XTRACE_FUNCTION; m_IsInitializing = true; #if BUILD_SDL const int Error = SDL_Init( SDL_INIT_TIMER | SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER | SDL_INIT_EVENTS | SDL_INIT_NOPARACHUTE ); ASSERT( 0 == Error ); Unused( Error ); if( 0 != Error ) { PRINTF( "SDL_Init: %s\n", SDL_GetError() ); } SDL_DisableScreenSaver(); #endif STATICHASH( Framework ); #if BUILD_WINDOWS #if BUILD_FINAL STATICHASH( ShowConsole ); const bool ShowConsole = ConfigManager::GetBool( sShowConsole, false, sFramework ); if( ShowConsole ) #endif { Console::GetInstance()->SetPos( 0, 0 ); } #endif STATICHASH( UseRandomSeed ); const bool UseRandomSeed = ConfigManager::GetBool( sUseRandomSeed, false, sFramework ); STATICHASH( RandomSeed ); const int RandomSeed = ConfigManager::GetInt( sRandomSeed, 0, sFramework ); if( UseRandomSeed ) { Math::SeedGenerator( RandomSeed ); } else { Math::SeedGenerator(); } STATICHASH( UseFixedFrameTime ); m_UseFixedFrameTime = ConfigManager::GetBool( sUseFixedFrameTime, true, sFramework ); STATICHASH( FixedFrameTime ); m_FixedFrameTime = ConfigManager::GetFloat( sFixedFrameTime, 1.0f / 60.0f, sFramework ); STATICHASH( FramesLimit ); const int FramesLimit = ConfigManager::GetInt( sFramesLimit, 5, sFramework ); m_FrameTimeLimit = m_FixedFrameTime * static_cast<float>( FramesLimit ); STATICHASH( DoVideoCapture ); m_DoVideoCapture = ConfigManager::GetBool( sDoVideoCapture, false, sFramework ); STATICHASH( VideoCaptureFixedFrameTime ); m_VideoCaptureFixedFrameTime = ConfigManager::GetFloat( sVideoCaptureFixedFrameTime, 1.0f / 30.0f, sFramework ); uint DisplayWidth = 0; uint DisplayHeight = 0; SimpleString WindowTitle; // Loads display parameters from config, so GetInitialDisplaySize can use that. m_Display = new Display; // Make sure that we use a supported resolution regardless of what the config file said. const SDisplayMode BestDisplayMode = m_Display->GetBestDisplayMode( m_Display->m_Width, m_Display->m_Height ); m_Display->SetResolution( BestDisplayMode.Width, BestDisplayMode.Height ); uint WindowIcon = 0; GetInitialWindowIcon( WindowIcon ); GetInitialDisplaySize( DisplayWidth, DisplayHeight ); GetInitialWindowTitle( WindowTitle ); CreateSplashWindow( WindowIcon, WindowTitle.CStr() ); m_Window = new Window; #if BUILD_WINDOWS_NO_SDL DWORD WindowStyle = 0; if( m_Display->m_Fullscreen || ( m_Display->m_ScreenWidth == m_Display->m_Width && m_Display->m_ScreenHeight == m_Display->m_Height ) ) { WindowStyle = WS_POPUP; } else { WindowStyle = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; } m_Window->Init( WindowTitle.CStr(), "Class1", WindowStyle, 0, DisplayWidth, DisplayHeight, m_hInstance, WindowProc, WindowIcon, m_Display->m_ScreenWidth, m_Display->m_ScreenHeight ); #elif BUILD_SDL uint WindowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN; if( m_Display->m_Fullscreen || ( m_Display->m_ScreenWidth == m_Display->m_Width && m_Display->m_ScreenHeight == m_Display->m_Height ) ) { WindowFlags |= SDL_WINDOW_BORDERLESS; } // TODO SDL: Unify interface? m_Window->Init( WindowTitle.CStr(), WindowFlags, DisplayWidth, DisplayHeight ); STATICHASH( IconImage ); const char* const pIconImage = ConfigManager::GetString( sIconImage, NULL, sFramework ); ASSERT( pIconImage ); const Surface IconSurface = Surface( PackStream( pIconImage ), Surface::ESFT_BMP ); SDL_SetWindowIcon( m_Window->GetSDLWindow(), IconSurface.GetSDLSurface() ); #endif m_Window->SetFullscreen( m_Display->m_Fullscreen ); if( m_Display->m_Fullscreen ) { m_Window->SetPosition( 0, 0 ); } m_Clock = new Clock; XTRACE_BEGIN( InitializeDevices ); m_Keyboard = new Keyboard; #if BUILD_WINDOWS_NO_SDL m_Mouse = new Mouse( m_hInstance, m_Window->GetHWnd() ); #elif BUILD_SDL m_Mouse = new Mouse( m_Window ); #endif XTRACE_END; InitializeUIInputMap(); XTRACE_BEGIN( InitializeAudioSystem ); InitializeAudioSystem(); XTRACE_END; XTRACE_BEGIN( InitializeRenderer ); #if BUILD_WINDOWS_NO_SDL STATICHASH( OpenGL ); const bool OpenGL = ConfigManager::GetBool( sOpenGL ); if( OpenGL ) #endif { PRINTF( "Using OpenGL renderer.\n" ); m_Renderer = CreateGL2Renderer( m_Window ); } #if BUILD_WINDOWS_NO_SDL else { PRINTF( "Using Direct3D renderer.\n" ); m_Renderer = CreateD3D9Renderer( m_Window->GetHWnd(), m_Display->m_Fullscreen ); } #endif IRenderer::SRestoreDeviceCallback Callback; Callback.m_Callback = &Framework3D::RendererRestoreDeviceCallback; Callback.m_Void = this; m_Renderer->SetRestoreDeviceCallback( Callback ); InitializeRender(); m_Renderer->Initialize(); m_Renderer->SetDisplay( m_Display ); m_Renderer->SetClock( m_Clock ); XTRACE_END; if( ShowWindowASAP() ) { SafeDelete( m_SplashWindow ); #if BUILD_WINDOWS_NO_SDL m_Window->Show( m_CmdShow ); #elif BUILD_SDL m_Window->Show(); #endif // Reattach GL context if needed. m_Renderer->Refresh(); } if( UseClassicTargetManager() ) { m_TargetManager = new TargetManager( m_Renderer, DisplayWidth, DisplayHeight ); } XTRACE_BEGIN( InitializeUI ); SimpleString UIManagerDefinitionName; GetUIManagerDefinitionName( UIManagerDefinitionName ); m_UIManager = new UIManagerFramework( this ); m_UIManager->InitializeFromDefinition( UIManagerDefinitionName ); m_UIManager->GetUIStack()->SetFadeOverlay( m_UIManager->GetScreen( "Fade" ) ); UIScreen::UpdateMouseButtonsSwapped(); XTRACE_END; m_IsInitializing = false; }
/*virtual*/ void EldritchFramework::Initialize() { XTRACE_FUNCTION; XTRACE_BEGIN(PreFramework3D); ReverseHash::Initialize(); PackStream::StaticAddPackageFile("eldritch-base.cpk"); FrameworkUtil::MinimalLoadConfigFiles("Config/default.ccf"); InitializePackages(); InitializeDLC(); // Load prefs over anything in the defaults. LoadPrefsConfig(); LOADPRINTLEVELS; STATICHASH(Version); STATICHASH(ContentSyncer); SimpleString LocalVersion = ConfigManager::GetString(sVersion, "", sContentSyncer); PRINTF("Version: %s\n", LocalVersion.CStr()); XTRACE_BEGIN(InitializeFactories); PRINTF("Initializing factories...\n"); PRINTF("Initializing SDP factories.\n"); SDPFactory::InitializeBaseFactories(); #define ADDSDPFACTORY(type) \ SDPFactory::RegisterSDPFactory(#type, SDP##type::Factory); #include "eldritchsdps.h" #undef ADDSDPFACTORY PRINTF("Initializing UI factories.\n"); UIFactory::InitializeBaseFactories(); #define ADDUISCREENFACTORY(type) \ UIFactory::RegisterUIScreenFactory(#type, UIScreen##type::Factory); #include "eldritchuiscreens.h" #undef ADDUISCREENFACTORY PRINTF("Initializing anim event factories.\n"); #define ADDANIMEVENTFACTORY(type) \ AnimEventFactory::GetInstance()->Register(#type, AnimEvent##type::Factory); #include "eldritchanimevents.h" #undef ADDANIMEVENTFACTORY PRINTF("Initializing PE factories.\n"); WBParamEvaluatorFactory::InitializeBaseFactories(); #define ADDWBPEFACTORY(type) \ WBParamEvaluatorFactory::RegisterFactory(#type, WBPE##type::Factory); #include "rodinwbpes.h" #include "eldritchwbpes.h" #undef ADDWBPEFACTORY PRINTF("Initializing action factories.\n"); WBActionFactory::InitializeBaseFactories(); #define ADDWBACTIONFACTORY(type) \ WBActionFactory::RegisterFactory(#type, WBAction##type::Factory); #include "uiwbactions.h" #include "rodinwbactions.h" #include "eldritchwbactions.h" #undef ADDWBPEFACTORY PRINTF("Initializing BT factories.\n"); RodinBTNodeFactory::InitializeBaseFactories(); #define ADDRODINBTNODEFACTORY(type) \ RodinBTNodeFactory::RegisterFactory(#type, RodinBTNode##type::Factory); #include "eldritchrodinbtnodes.h" #undef ADDRODINBTNODEFACTORY // Initialize core and Eldritch Workbench component factories. PRINTF("Initializing component factories.\n"); WBComponent::InitializeBaseFactories(); #define ADDWBCOMPONENT(type) \ WBComponent::RegisterWBCompFactory(#type, WBComp##type::Factory); #include "rodinwbcomponents.h" #include "eldritchwbcomponents.h" #undef ADDWBCOMPONENT XTRACE_END; PRINTF("Factories initialized.\n"); // Create input system before framework so it will exist for UI. But don't // attach devices yet, as they don't exist. PRINTF("Initializing input system.\n"); m_InputSystem = new InputSystem; m_InputSystem->Initialize("EldritchInput"); XTRACE_END; Framework3D::Initialize(); STATICHASH(DisplayWidth); STATICHASH(DisplayHeight); m_DisplayWidth = ConfigManager::GetInt(sDisplayWidth); m_DisplayHeight = ConfigManager::GetInt(sDisplayHeight); #if BUILD_WINDOWS m_CheckForUpdates = new CheckForUpdates(m_UIManager); #endif m_Controller = new XInputController; m_TargetManager = new EldritchTargetManager(m_Renderer); m_TargetManager->CreateTargets(m_Display->m_Width, m_Display->m_Height); m_Audio3DListener = new EldritchSound3DListener; m_Audio3DListener->Initialize(); ASSERT(m_AudioSystem); m_AudioSystem->Set3DListener(m_Audio3DListener); STATICHASH(FOV); const float FOV = ConfigManager::GetFloat(sFOV, 90.0f); STATICHASH(ForegroundFOV); const float FGFOV = ConfigManager::GetFloat(sForegroundFOV, 60.0f); STATICHASH(NearClip); const float NearClip = ConfigManager::GetFloat(sNearClip, 0.1f); STATICHASH(FarClip); const float FarClip = ConfigManager::GetFloat(sFarClip, 0.1f); const float fDisplayWidth = static_cast<float>(m_DisplayWidth); const float fDisplayHeight = static_cast<float>(m_DisplayHeight); const float AspectRatio = fDisplayWidth / fDisplayHeight; m_MainView = new View(Vector(), Angles(), FOV, AspectRatio, NearClip, FarClip); m_FGView = new View(Vector(), Angles(), FGFOV, AspectRatio, NearClip, FarClip); CreateHUDView(); CreateMirrorView(); CreateMinimapView(); CreateBuckets(); m_InputSystem->SetKeyboard(m_Keyboard); m_InputSystem->SetMouse(m_Mouse); m_InputSystem->SetController(m_Controller); m_InputSystem->SetClock(m_Clock); WBActionStack::Initialize(); PRINTF("Initializing Eldritch.\n"); InitializeWorld(HashedString(), false); m_Game = new EldritchGame; m_Game->RefreshRTDependentSystems(); m_Game->Initialize(); // Initialize config stuff { STATICHASH(InvertY); const bool InvertY = ConfigManager::GetBool(sInvertY); STATIC_HASHED_STRING(TurnY); m_InputSystem->SetMouseInvert(sTurnY, InvertY); m_InputSystem->SetControllerInvert(sTurnY, InvertY); STATICHASH(ControllerPower); const float ControllerPower = ConfigManager::GetFloat(sControllerPower); STATIC_HASHED_STRING(MoveX); m_InputSystem->SetControllerPower(sMoveX, ControllerPower); STATIC_HASHED_STRING(MoveY); m_InputSystem->SetControllerPower(sMoveY, ControllerPower); STATIC_HASHED_STRING(TurnX); m_InputSystem->SetControllerPower(sTurnX, ControllerPower); m_InputSystem->SetControllerPower(sTurnY, ControllerPower); } // Initialize UI sliders. This could be neater. // This also pushes the initial values to their respective systems, which is // pret-ty terrible design. { WBEventManager* pEventManager = WBWorld::GetInstance()->GetEventManager(); { STATICHASH(MouseSpeed); const float MouseSpeed = ConfigManager::GetFloat(sMouseSpeed, 1.0f); STATIC_HASHED_STRING(ControlsOptionsScreen); STATIC_HASHED_STRING(MouseSpeedSlider); WB_MAKE_EVENT(SetUISliderValue, NULL); WB_SET_AUTO(SetUISliderValue, Hash, Screen, sControlsOptionsScreen); WB_SET_AUTO(SetUISliderValue, Hash, Widget, sMouseSpeedSlider); WB_SET_AUTO(SetUISliderValue, Float, SliderValue, GetSliderValueFromMouseSpeed(MouseSpeed)); WB_DISPATCH_EVENT(pEventManager, SetUISliderValue, NULL); } { STATICHASH(ControllerSpeed); const float ControllerSpeed = ConfigManager::GetFloat(sControllerSpeed, 1.0f); STATIC_HASHED_STRING(ControlsOptionsScreen); STATIC_HASHED_STRING(ControllerSpeedSlider); WB_MAKE_EVENT(SetUISliderValue, NULL); WB_SET_AUTO(SetUISliderValue, Hash, Screen, sControlsOptionsScreen); WB_SET_AUTO(SetUISliderValue, Hash, Widget, sControllerSpeedSlider); WB_SET_AUTO(SetUISliderValue, Float, SliderValue, GetSliderValueFromControllerSpeed(ControllerSpeed)); WB_DISPATCH_EVENT(pEventManager, SetUISliderValue, NULL); } { STATICHASH(Brightness); const float Brightness = ConfigManager::GetFloat(sBrightness, 1.0f); STATIC_HASHED_STRING(BrightnessScreen); STATIC_HASHED_STRING(BrightnessSlider); WB_MAKE_EVENT(SetUISliderValue, NULL); WB_SET_AUTO(SetUISliderValue, Hash, Screen, sBrightnessScreen); WB_SET_AUTO(SetUISliderValue, Hash, Widget, sBrightnessSlider); WB_SET_AUTO(SetUISliderValue, Float, SliderValue, GetSliderValueFromBrightness(Brightness)); WB_DISPATCH_EVENT(pEventManager, SetUISliderValue, NULL); } { STATIC_HASHED_STRING(DisplayOptionsScreen); STATIC_HASHED_STRING(FOVSlider); WB_MAKE_EVENT(SetUISliderValue, NULL); WB_SET_AUTO(SetUISliderValue, Hash, Screen, sDisplayOptionsScreen); WB_SET_AUTO(SetUISliderValue, Hash, Widget, sFOVSlider); WB_SET_AUTO(SetUISliderValue, Float, SliderValue, GetSliderValueFromFOV(FOV)); WB_DISPATCH_EVENT(pEventManager, SetUISliderValue, NULL); } { STATICHASH(MasterVolume); const float MasterVolume = ConfigManager::GetFloat(sMasterVolume); STATIC_HASHED_STRING(AudioOptionsScreen); STATIC_HASHED_STRING(VolumeSlider); WB_MAKE_EVENT(SetUISliderValue, NULL); WB_SET_AUTO(SetUISliderValue, Hash, Screen, sAudioOptionsScreen); WB_SET_AUTO(SetUISliderValue, Hash, Widget, sVolumeSlider); WB_SET_AUTO(SetUISliderValue, Float, SliderValue, MasterVolume); WB_DISPATCH_EVENT(pEventManager, SetUISliderValue, NULL); } { STATICHASH(MusicVolume); const float MusicVolume = ConfigManager::GetFloat(sMusicVolume); STATIC_HASHED_STRING(AudioOptionsScreen); STATIC_HASHED_STRING(MusicVolumeSlider); WB_MAKE_EVENT(SetUISliderValue, NULL); WB_SET_AUTO(SetUISliderValue, Hash, Screen, sAudioOptionsScreen); WB_SET_AUTO(SetUISliderValue, Hash, Widget, sMusicVolumeSlider); WB_SET_AUTO(SetUISliderValue, Float, SliderValue, MusicVolume); WB_DISPATCH_EVENT(pEventManager, SetUISliderValue, NULL); } } // Initialize UI callbacks { UIScreenEldSetRes* pSetRes = m_UIManager->GetScreen<UIScreenEldSetRes>("SetResScreen"); pSetRes->SetUICallback(SUICallback(EldritchFramework::OnSetRes, nullptr)); UIScreenFade* pFade = m_UIManager->GetScreen<UIScreenFade>("Fade"); pFade->SetFadeCallback( SUICallback(EldritchFramework::OnFadeFinished, nullptr)); } WB_MAKE_EVENT(ResetToInitialScreens, NULL); WB_DISPATCH_EVENT(WBWorld::GetInstance()->GetEventManager(), ResetToInitialScreens, NULL); { // HACK: Too content aware STATIC_HASHED_STRING(MKGLogoScreen); WB_MAKE_EVENT(PushUIScreen, NULL); WB_SET_AUTO(PushUIScreen, Hash, Screen, sMKGLogoScreen); WB_DISPATCH_EVENT(WBWorld::GetInstance()->GetEventManager(), PushUIScreen, NULL); } // Tick world once to pump the event queue. Fixes title screen bugs. m_World->Tick(0.0f); // All done, show the window finally. SafeDelete(m_SplashWindow); #if BUILD_WINDOWS_NO_SDL m_Window->Show(m_CmdShow); #elif BUILD_SDL m_Window->Show(); #endif // Reattach GL context if needed. m_Renderer->Refresh(); PRINTF("Eldritch initialization complete.\n"); }