Fichier source en cours : FW - System.cpp






Voici le code source cpp :




	#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;
}