/*virtual*/ void EldritchFramework::HandleEvent(const WBEvent& Event) { XTRACE_FUNCTION; Framework3D::HandleEvent(Event); STATIC_HASHED_STRING(ToggleInvertY); STATIC_HASHED_STRING(ToggleFullscreen); STATIC_HASHED_STRING(OnSliderChanged); STATIC_HASHED_STRING(WritePrefsConfig); STATIC_HASHED_STRING(CheckForUpdates); const HashedString EventName = Event.GetEventName(); if (EventName == sToggleInvertY) { XTRACE_NAMED(ToggleInvertY); // TODO: Also invert controller? Or on a separate button? STATIC_HASHED_STRING(TurnY); const bool InvertY = !m_InputSystem->GetMouseInvert(sTurnY); m_InputSystem->SetMouseInvert(sTurnY, InvertY); m_InputSystem->SetControllerInvert(sTurnY, InvertY); // Publish config var so UI can reflect the change. // I could make input system publish config vars for each adjustment, but // that seems wasteful since most inputs currently have no adjustment. STATICHASH(InvertY); ConfigManager::SetBool(sInvertY, InvertY); } else if (EventName == sToggleFullscreen) { XTRACE_NAMED(ToggleFullscreen); ToggleFullscreen(); } else if (EventName == sOnSliderChanged) { XTRACE_NAMED(OnSliderChanged); STATIC_HASHED_STRING(SliderName); const HashedString SliderName = Event.GetHash(sSliderName); STATIC_HASHED_STRING(SliderValue); const float SliderValue = Event.GetFloat(sSliderValue); HandleUISliderEvent(SliderName, SliderValue); } else if (EventName == sWritePrefsConfig) { XTRACE_NAMED(WritePrefsConfig); WritePrefsConfig(); } else if (EventName == sCheckForUpdates) { #if BUILD_WINDOWS && !BUILD_STEAM XTRACE_NAMED(CheckForUpdates); // So I can compile updating out of certain builds. STATICHASH(Framework); STATICHASH(CheckForUpdates); const bool CheckForUpdates = ConfigManager::GetBool(sCheckForUpdates, true, sFramework); if (CheckForUpdates) { m_CheckForUpdates->Check(false, true); } #endif } }
/*virtual*/ void Framework3D::HandleEvent(const WBEvent& Event) { XTRACE_FUNCTION; STATIC_HASHED_STRING(QuitGame); STATIC_HASHED_STRING(ResetRenderer); STATIC_HASHED_STRING(ConditionalRefreshDisplay); STATIC_HASHED_STRING(RefreshDisplay); const HashedString EventName = Event.GetEventName(); if (EventName == sQuitGame) { #if BUILD_WINDOWS_NO_SDL XTRACE_NAMED(PostQuitMessage); PostQuitMessage(0); #endif #if BUILD_SDL SDL_Event QuitEvent; QuitEvent.type = SDL_QUIT; const int Success = SDL_PushEvent(&QuitEvent); ASSERT(Success); Unused(Success); #endif } else if (EventName == sResetRenderer) { ResetRenderer(); } else if (EventName == sConditionalRefreshDisplay) { ConditionalRefreshDisplay(); } else if (EventName == sRefreshDisplay) { RefreshDisplay(m_Display->m_Fullscreen, m_Display->m_Width, m_Display->m_Height); } }
/*virtual*/ bool Framework3D::Tick() { XTRACE_FUNCTION; PROFILE_FUNCTION; bool DoNextTick = true; if( HasRequestedExit() ) { DoNextTick = false; } m_HasFocus = m_Window->HasFocus(); StringManager::FlushStrings( StringManager::ESL_Transient ); m_Clock->Tick( m_UIManager->GetUIStack()->PausesGame(), false ); m_EventManager->Tick(); if( m_DoVideoCapture ) { // One sim tick, one render tick DoNextTick &= TickSim( m_VideoCaptureFixedFrameTime ); TickRender(); } else if( m_UseFixedFrameTime ) { m_FrameTimeAccumulator += m_Clock->GetMachineDeltaTime(); if( m_FrameTimeAccumulator > m_FrameTimeLimit ) { // We've hit a very long frame, maybe we were sitting in the debugger. // Don't bother simming for this duration, it will just cause more hitches. m_FrameTimeAccumulator = 0.0f; } const int NumSimTicks = static_cast<int>( m_FrameTimeAccumulator / m_FixedFrameTime ); const int LastSimTick = NumSimTicks - 1; for( int SimTickIndex = 0; SimTickIndex <= LastSimTick && DoNextTick; ++SimTickIndex ) { ASSERT( m_FrameTimeAccumulator >= m_FixedFrameTime ); m_FrameTimeAccumulator -= m_FixedFrameTime; DoNextTick &= TickSim( m_FixedFrameTime ); if( SimTickIndex == LastSimTick ) { TickRender(); } else { DropRender(); } } } else { // One sim tick, one render tick DoNextTick &= TickSim( m_Clock->GetMachineDeltaTime() ); TickRender(); } #if BUILD_WINDOWS_NO_SDL { XTRACE_NAMED( SwitchToThread ); // Crashing within this trace name would typically indicate a crash in another thread. const BOOL SwitchedToThread = SwitchToThread(); if( 0 == SwitchedToThread ) { // Prevent hogging the CPU, maybe? Sleep( 0 ); } } #endif #if BUILD_SDL { SDL_Delay( 0 ); } #endif return DoNextTick; }
/*virtual*/ void D3D9Renderer::RenderBucket( Bucket* pBucket, const ViewportPass* const pViewportPass) { XTRACE_FUNCTION; PROFILE_FUNCTION; if (pBucket->m_RenderTarget) { SetRenderTarget(pBucket->m_RenderTarget); if (pViewportPass) { SetViewport(pViewportPass); } } if (pBucket->m_ClearFlags != CLEAR_NONE) { Clear(pBucket->m_ClearFlags, pBucket->m_ClearColor, pBucket->m_ClearDepth); } if (pBucket->m_View) { View* const pView = pViewportPass ? pViewportPass->GetView(pBucket->m_View) : pBucket->m_View; m_View = *pView; m_View.ApplyToRenderer(*this); } if (pBucket->m_Flags & MAT_ALPHA) { pBucket->Sort(m_View); } else if (m_DoMaterialSort && pBucket->m_SortByMaterial) { pBucket->SortByMaterials(); } Mesh* pMesh = NULL; D3D9VertexBuffer* VertexBuffer = NULL; D3D9IndexBuffer* IndexBuffer = NULL; IVertexDeclaration* pVertexDeclaration = NULL; uint NumMeshes = pBucket->m_Meshes.Size(); Frustum ViewFrustum(GetViewMatrix() * GetProjectionMatrix()); #if BUILD_DEBUG if (pBucket->m_DEBUGUseFrustum) { pBucket->m_DEBUGFrustumView.ApplyToFrustum(ViewFrustum); } #endif for (uint MeshIndex = 0; MeshIndex < NumMeshes; ++MeshIndex) { XTRACE_NAMED(RenderBucketMesh); pMesh = pBucket->m_Meshes[MeshIndex]; DEVASSERT(pMesh); DEVASSERT(pMesh->m_VertexBuffer->GetNumVertices() > 0); const uint MaterialFlags = pMesh->GetMaterialFlags(); // Frustum culling--I can't do this earlier, when a mesh is added, because // it might be visible in one view (e.g., shadow map depth) and not to // player. if (!m_DoFrustumCulling || pBucket->m_Flags & MAT_HUD || pBucket->m_Flags & MAT_INWORLDHUD || #if BUILD_DEV pBucket->m_Flags & MAT_DEBUG_ALWAYS || MaterialFlags & MAT_DEBUG_ALWAYS || #endif pBucket->m_Flags & MAT_ALWAYS || MaterialFlags & MAT_ALWAYS || ViewFrustum.Intersects(pMesh->m_AABB)) { VertexBuffer = (D3D9VertexBuffer*)pMesh->m_VertexBuffer; IndexBuffer = (D3D9IndexBuffer*)pMesh->m_IndexBuffer; // RENDERTODO: It might be useful to adapt this for material overrides in // the future // Shader = (D3D9Shader*)( pBucket->m_OverrideShader ? // pBucket->m_OverrideShader : pMesh->m_OLDMaterial.m_Shader ); if (pMesh->m_VertexDeclaration != pVertexDeclaration) { XTRACE_NAMED(SetVertexDeclaration); m_D3DDevice->SetVertexDeclaration( (IDirect3DVertexDeclaration9*) pMesh->m_VertexDeclaration->GetDeclaration()); } pVertexDeclaration = pMesh->m_VertexDeclaration; DEVASSERT(VertexBuffer); DEVASSERT(pVertexDeclaration); DEVASSERT(IndexBuffer); SetWorldMatrix(pMesh->GetConcatenatedTransforms()); { XTRACE_NAMED(SetStreams); uint VertexSignature = pVertexDeclaration->GetSignature(); uint Index = 0; #define SETSTREAM(STREAM, SIGNATURE, TYPE) \ if (SIGNATURE == (VertexSignature & SIGNATURE)) { \ IDirect3DVertexBuffer9* const pBuffer = \ static_cast<IDirect3DVertexBuffer9*>(VertexBuffer->Get##STREAM()); \ DEVASSERT(pBuffer); \ m_D3DDevice->SetStreamSource(Index++, pBuffer, 0, sizeof(TYPE)); \ } SETSTREAM(Positions, VD_POSITIONS, Vector); SETSTREAM(Colors, VD_COLORS, uint); #if USE_HDR SETSTREAM(FloatColors1, VD_FLOATCOLORS, Vector4); SETSTREAM(FloatColors2, VD_BASISCOLORS, Vector4); SETSTREAM(FloatColors3, VD_BASISCOLORS, Vector4); // For SM2 cards, an alternative way to do HDR colors SETSTREAM(FloatColors1, VD_FLOATCOLORS_SM2, Vector4); SETSTREAM(FloatColors2, VD_BASISCOLORS_SM2, Vector4); SETSTREAM(FloatColors3, VD_BASISCOLORS_SM2, Vector4); #endif SETSTREAM(UVs, VD_UVS, Vector2); SETSTREAM(Normals, VD_NORMALS, Vector); SETSTREAM(Tangents, VD_TANGENTS, Vector4); SETSTREAM(BoneIndices, VD_BONEINDICES, SBoneData); SETSTREAM(BoneWeights, VD_BONEWEIGHTS, SBoneData); #undef SETSTREAM m_D3DDevice->SetIndices( (IDirect3DIndexBuffer9*)IndexBuffer->GetIndices()); } ApplyMaterial(pMesh->m_Material, pMesh, m_View); if (VertexBuffer->GetNumVertices() > 0) { XTRACE_NAMED(DrawIndexedPrimitive); m_D3DDevice->DrawIndexedPrimitive(IndexBuffer->GetPrimitiveType(), 0, 0, VertexBuffer->GetNumVertices(), 0, IndexBuffer->GetNumPrimitives()); } #if BUILD_DEBUG ++m_DEBUGRenderStats.NumMeshes; m_DEBUGRenderStats.NumPrimitives += IndexBuffer->GetNumPrimitives(); #endif } #if BUILD_DEV // WARNING: This assumes the mesh is only in one bucket, which could be bad if (pMesh->m_IsDebugMesh) { m_DeferredDeleteDebugMeshes.PushBackUnique(pMesh); } #endif } }