#include "Framework.h" using namespace fw; template<> System* Singleton<System>::ms_instance = nullptr; LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { if (!InputManager::IsCreated() || !SYSTEM->IsReady()) { return DefWindowProc(hWnd, message, wParam, lParam); } switch (message) { case WM_DESTROY: PostQuitMessage(0); break; case WM_KEYDOWN: { INPUT_MANAGER->InjectKeyDown(wParam, HIWORD(lParam)); if (wParam == VK_SHIFT) { INPUT_MANAGER->InjectKeyModifierDown(InputManager::KeyModifier::SHIFT); } if (wParam == VK_CONTROL) { INPUT_MANAGER->InjectKeyModifierDown(InputManager::KeyModifier::CTRL); } if (wParam == VK_MENU) { INPUT_MANAGER->InjectKeyModifierDown(InputManager::KeyModifier::ALT); } break; } case WM_KEYUP: { INPUT_MANAGER->InjectKeyUp(wParam, HIWORD(lParam)); if (wParam == VK_SHIFT) { INPUT_MANAGER->InjectKeyModifierUp(InputManager::KeyModifier::SHIFT); } if (wParam == VK_CONTROL) { INPUT_MANAGER->InjectKeyModifierUp(InputManager::KeyModifier::CTRL); } if (wParam == VK_MENU) { INPUT_MANAGER->InjectKeyModifierUp(InputManager::KeyModifier::ALT); } break; } case WM_MOUSEMOVE: { int iMouseX = (int)LOWORD(lParam); int iMouseY = (int)HIWORD(lParam); INPUT_MANAGER->InjectMousePosition(iMouseX, iMouseY); break; } case WM_LBUTTONDOWN: { INPUT_MANAGER->InjectMouseButtonDown(InputManager::MouseButton::MouseButtonLeft); break; } case WM_RBUTTONDOWN: { INPUT_MANAGER->InjectMouseButtonDown(InputManager::MouseButton::MouseButtonRight); break; } case WM_MBUTTONDOWN: { INPUT_MANAGER->InjectMouseButtonDown(InputManager::MouseButton::MouseButtonMiddle); break; } case WM_MBUTTONUP: case WM_LBUTTONUP: case WM_RBUTTONUP: { INPUT_MANAGER->InjectMouseButtonUp(); break; } case WM_MOUSEWHEEL: { uint32 zDelta = GET_WHEEL_DELTA_WPARAM(wParam); INPUT_MANAGER->InjectMouseWheel(zDelta); break; } case WM_SETFOCUS: { INPUT_MANAGER->InjectWindowHasFocus(true); INPUT_MANAGER->RestoreMousePosition(); break; } case WM_KILLFOCUS: { INPUT_MANAGER->InjectWindowHasFocus(false); INPUT_MANAGER->ReleaseAllKeys(); INPUT_MANAGER->SaveMousePosition(); INPUT_MANAGER->CenterMouseCursor(); break; } case WM_WINDOWPOSCHANGED: { SYSTEM->GetCurrentRenderer()->SetFullScreenWindowChange(true); break; } case WM_ERASEBKGND: { /* if (SYSTEM->GetRenderer()->FullScreenWindowChanged()) { SYSTEM->GetRenderer()->SetFullScreenPaint(true); if (!SYSTEM->GetRenderer()->GetIgnoreTimeFrame()) { SYSTEM->GetRenderer()->HandleFullScreenModeAltEnter(); } } */ break; } case WM_DISPLAYCHANGE: { SYSTEM->GetCurrentRenderer()->RestoreFrameStopped(); break; } default: { return DefWindowProc(hWnd, message, wParam, lParam); } } return 0; } System::System(RenderMode mode) : m_pRenderer(nullptr), m_bFullScreen(mode == RenderMode::Fullscreen ? 1 : 0), m_bRunning(true), m_pFrameListener(nullptr), m_bD3DInitSuccess(false), m_bCenterMouse(false) { m_hInstance = GetModuleHandle(nullptr); // Nom de l'application m_sApplicationName = APPLICATION_NAME_WIDE; m_pSingletonManager = new SingletonObjectsManager; } System::~System() { DestroyTheWindow(); SAFE_DELETE(m_pRenderer); // à déplacer m_pSingletonManager->DestroyAllObjects(); SAFE_DELETE(m_pSingletonManager); } void System::Shutdown() { } bool System::Run(FrameListener* pFrameListener) { MSG msg; // Initialise la structure de message ZeroMemory (&msg, sizeof(MSG)); // Boucler jusqu'à obtenir un message de sortie de la fenêtre ou de l'utilisateur while (m_bRunning) { // Gérer les messages de la fenêtre if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); } // Si la fenêtre demande à fermer l'application, alors on sort if (msg.message == WM_QUIT) { m_bRunning = false; } else { // Autrement, effectuer le traitement de la trame if (pFrameListener != nullptr) { pFrameListener->UpdateFrame(); } } } return true; } bool System::Initialize(DXVersion version, const SplashScreen::SplashScreenInfo& splashInfo) { m_version = version; m_pSingletonManager->CreateSystemPass(); if (splashInfo.GetInitialized() == OptionalParam::Initialized) { LaunchSplashScreen(splashInfo); } if (!SetupTheWindow()) { MessageBoxA(nullptr, "Erreur d'initialisation de la fenêtre !", "Erreur", MB_ICONHAND | MB_OK); return false; } if (m_version == DXVersion::D3D_10) { m_pSingletonManager->CreateAllObjects_D3D10Pass(); m_pRenderer = new D3D10Renderer(m_Hwnd); } else if(m_version == DXVersion::D3D_11) { m_pSingletonManager->CreateAllObjects_D3D11Pass(); m_pRenderer = new D3D11Renderer(m_Hwnd); } m_bD3DInitSuccess = m_pRenderer->Initialize(m_bFullScreen); INPUT_MANAGER->CenterMouseCursor(); INPUT_MANAGER->SaveMousePosition(); if (!m_bD3DInitSuccess) { MessageBoxA(nullptr, "Erreur d'initialisation du D3DRenderer !", "Erreur", MB_ICONHAND | MB_OK); return false; } PrintSystemInformations(); return true; } bool System::HasFocus() { return GetFocus() == m_Hwnd; } bool System::SetupTheWindow() { // Détermine la résolution de l'écran. uint32 iScreenWidth = GetSystemMetrics(SM_CXSCREEN); uint32 iScreenHeight = GetSystemMetrics(SM_CYSCREEN); // Structure de la classe à configurer WNDCLASSEX wcex; // Taille de la structure WNDCLASSEX wcex.cbSize = sizeof( WNDCLASSEX ); // Style de la classe wcex.style = CS_HREDRAW | CS_VREDRAW; // Pointeur de la fonction de boucle de fenêtre (Callback) wcex.lpfnWndProc = WndProc; // Inutile à comprendre wcex.cbClsExtra = 0; // Inutile à comprendre wcex.cbWndExtra = 0; // Obtention de l'instance de cette application wcex.hInstance = m_hInstance; // Icone de la fenêtre wcex.hIcon = LoadIcon(nullptr, IDI_WINLOGO); // Icone du pointeur de la souris wcex.hCursor = LoadCursor(nullptr, IDC_ARROW); // Inutile à comprendre wcex.hbrBackground = ( HBRUSH )( COLOR_WINDOW + 1 ); // Inutile à comprendre wcex.lpszMenuName = nullptr; // Nom de la classe enregistrée wcex.lpszClassName = m_sApplicationName; wcex.hIconSm = wcex.hIcon; DEVMODE dmScreenSettings; // Cas plein écran if (m_bFullScreen) { ZeroMemory(&dmScreenSettings, sizeof(dmScreenSettings)); dmScreenSettings.dmSize = sizeof (dmScreenSettings); dmScreenSettings.dmPelsWidth = (uint64) iScreenWidth; dmScreenSettings.dmPelsHeight = (uint64) iScreenHeight; dmScreenSettings.dmBitsPerPel = 32; dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN); } if (!RegisterClassEx(&wcex)) { return false; } // Créée la fenêtre RECT rc = { 0, 0, 1200, 800 }; AdjustWindowRect( &rc, WS_OVERLAPPEDWINDOW, FALSE ); m_Hwnd = CreateWindow(m_sApplicationName, m_sApplicationName, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, nullptr, nullptr, m_hInstance, nullptr); if (!m_Hwnd) { return false; } ShowWindow(m_Hwnd, SW_SHOW); SetForegroundWindow(m_Hwnd); SetFocus(m_Hwnd); return true; } void System::DestroyTheWindow() { // Change les paramètres d'affichage si l'on quitte le mode plein écran if (m_bFullScreen) { ChangeDisplaySettings(nullptr, 0); } // Détruit la fenêtre. DestroyWindow(m_Hwnd); m_Hwnd = nullptr; // Détruit l'instance de l'application UnregisterClass(m_sApplicationName, m_hInstance); m_hInstance = nullptr; } bool System::IsQuitting() { return m_bRunning == false; } void System::Quit() { /* if (Logger::IsCreated()) { //SYSTEM_LOG->SetEndingState(Logger::FatalError); Logger::Destroy(); } */ //PostQuitMessage(1); m_bRunning = false; } std::string System::GetVersion() { return ENGINE_VERSION; } HWND System::GetHwnd() { return m_Hwnd; } void System::ChangeWindowTitle(const std::string& sWindowTitle) { SetWindowTextA(m_Hwnd, sWindowTitle.c_str()); } D3DRenderer* System::GetCurrentRenderer() { return m_pRenderer; } D3DRenderer* System::GetRenderer(DXVersion version) { if (version == DXVersion::D3D_10) { return GetSpecificRenderer<D3D10>(); } else if (version == DXVersion::D3D_11) { return GetSpecificRenderer<D3D11>(); } return nullptr; } void System::UpdateWindowTitle() { static char buffer[256]; D3DXVECTOR3 camPos = SCENE_MANAGER->GetActiveCamera()->GetPosition(); sprintf_s(buffer, "Position de la caméra : X = %.2f Y = %.2f Z = %.2f", camPos.x, camPos.y, camPos.z); // On met à jour le titre de la fenêtre ChangeWindowTitle(buffer); } void System::PrintSystemInformations() { new ComputerInfo(); LogMessage(std::endl); LogMessage("Voici le nom de votre processeur : " << COMPUTER_INFO->GetCpuName().c_str() << std::endl); LogMessage("Voici la vitesse de votre processeur : " << COMPUTER_INFO->GetCpuSpeed().c_str() << std::endl); LogMessage("Voici la capacité total de votre mémoire centrale : " << COMPUTER_INFO->GetTotalMemory().c_str() << std::endl); LogMessage("Voici la capacité restante de votre mémoire centrale : " << COMPUTER_INFO->GetAvailableMemory().c_str() << std::endl); LogMessage("Voici la capacité restante de votre volume de disque principal : " << COMPUTER_INFO->GetHDSpace().c_str() << std::endl); LogMessage("Voici le nom de votre système d'exploitation : " << COMPUTER_INFO->GetOsName().c_str() << std::endl); LogMessage(std::endl); CPUInfo* pCPUInfo = new CPUInfo(); pCPUInfo->Initialize(); LogMessage("Voici le nombre de coeurs de votre processeur : " << pCPUInfo->GetSystemProcessorCount() << " coeurs" << std::endl); LogMessage("Voici le nombre de coeurs physiques de votre processeur : " << pCPUInfo->GetPhysicalProcessorCount() << " coeurs" << std::endl); uint32 L1CacheSize = pCPUInfo->GetL1CacheSize(); uint32 L2CacheSize = pCPUInfo->GetL2CacheSize(); uint32 L3CacheSize = pCPUInfo->GetL3CacheSize(); std::string sizeL1CacheFormat = " KB"; std::string sizeL2CacheFormat = " KB"; std::string sizeL3CacheFormat = " KB"; if (MATHS->GetDigitsCount(L1CacheSize) > 6) { L1CacheSize /= 1000000; sizeL1CacheFormat = " MB"; } if (MATHS->GetDigitsCount(L2CacheSize) > 6) { L2CacheSize /= 1000000; sizeL2CacheFormat = " MB"; } if (MATHS->GetDigitsCount(L3CacheSize) > 6) { L3CacheSize /= 1000000; sizeL3CacheFormat = " MB"; } LogMessage("Voici la taille du cache L1 de votre processeur : " << L1CacheSize << sizeL1CacheFormat.c_str() << std::endl); LogMessage("Voici la taille du cache L2 de votre processeur : " << L2CacheSize << sizeL2CacheFormat.c_str() << std::endl); LogMessage("Voici la taille du cache L3 de votre processeur : " << L3CacheSize << sizeL3CacheFormat.c_str() << std::endl); LogMessage(std::endl); const CPUInfo::CPUExtensionsSupport& extensions = pCPUInfo->GetExtensionsSupport(); LogMessage("Voici les extensions de CPU supportées : " << std::endl); std::cout << std::endl; if (extensions.HW_SSE) { LogMessage("\tSSE supporté" << std::endl); } if (extensions.HW_SSE2) { LogMessage("\tSSE2 supporté" << std::endl); } if (extensions.HW_SSE3) { LogMessage("\tSSE3 supporté" << std::endl); } if (extensions.HW_SSE41) { LogMessage("\tSSE41 supporté" << std::endl); } if (extensions.HW_SSE42) { LogMessage("\tSSE42 supporté" << std::endl); } if (extensions.HW_SSE4a) { LogMessage("\tSSE4a supporté" << std::endl); } if (extensions.HW_MMX) { LogMessage("\tMMX supporté" << std::endl); } if (extensions.HW_ABM) { LogMessage("\tABM supporté" << std::endl); } if (extensions.HW_AES) { LogMessage("\tAES supporté" << std::endl); } if (extensions.HW_AVX) { LogMessage("\tAVX supporté" << std::endl); } if (extensions.HW_AVX2) { LogMessage("\tAVX2 supporté" << std::endl); } if (extensions.HW_FMA3) { LogMessage("\tFMA3 supporté" << std::endl); } if (extensions.HW_FMA4) { LogMessage("\tFMA4 supporté" << std::endl); } if (extensions.HW_RDRAND) { LogMessage("\tRDRAND supporté" << std::endl); } if (extensions.HW_SHA) { LogMessage("\tSHA supporté" << std::endl); } if (extensions.HW_x64) { LogMessage("\tx64 supporté" << std::endl); } if (extensions.HW_XOP) { LogMessage("\tXOP supporté" << std::endl); } LogMessage(std::endl); delete pCPUInfo; COMPUTER_INFO->Destroy(); } DXVersion System::GetDirectXVersion() { return m_version; } bool System::IsReady() { return m_bD3DInitSuccess; } void System::LaunchSplashScreen(const SplashScreen::SplashScreenInfo& splashInfo) { GAME_RESOURCES_MANAGER->LoadZipFile(); bool bImageExist = GAME_RESOURCES_MANAGER->FileExist(splashInfo.m_sImageFileName); SKIP_IF_FAILED_AssertMsg(bImageExist, "Problème chargement d'image de l'écran de démarrage") { ThreadsWrapper::Thread* pT = nullptr; std::function<void(void)> function = [splashInfo]() { SplashScreen splash(splashInfo); splash.Show(GetModuleHandle(NULL)); }; pT = THREADS_WRAPPER->CreateThreadLambda("SplashScreen", function); if (pT) { std::thread::id id = THREADS_WRAPPER->LaunchThread(pT); } } } void System::LoadCustomCursor(const std::string& sCursorName) { PointerHolder<CursorFileBuffer> cursorBuffer = GAME_RESOURCES_MANAGER->LoadWindowCursor_ZIP(sCursorName); if (cursorBuffer->IsEmpty()) { return; } HWND hwnd = GetHwnd(); HICON hIcon = nullptr; size_t32 iWidth = cursorBuffer->GetCursorWidth(); size_t32 iHeight = cursorBuffer->GetCursorHeight(); char* pBuffer = cursorBuffer->GetBuffer(); uint16 offset = LookupIconIdFromDirectoryEx((PBYTE)pBuffer, TRUE, iWidth, iHeight, LR_DEFAULTCOLOR); if (offset != 0) { hIcon = CreateIconFromResourceEx((PBYTE)pBuffer + offset, 0, TRUE, 0x30000, iWidth, iHeight, LR_DEFAULTCOLOR); } cursorBuffer->Done(); cursorBuffer.ToDelete(); GAME_RESOURCES_MANAGER->RemoveFileBuffer(cursorBuffer); SetClassLong((HWND)hwnd, GCL_HCURSOR, (LONG)hIcon); } void System::ToggleCenteredMouseCursor() { m_bCenterMouse = !m_bCenterMouse; ShowCursor(!m_bCenterMouse); } char* System::GetTime(const char* sFormat) { time_t CurrentTime = time(NULL); static char sTime[24]; strftime(sTime, sizeof(sTime), sFormat, localtime(&CurrentTime)); return sTime; }