MegaSteve/MegaEngine.cpp

183 lines
3.6 KiB
C++
Raw Normal View History

module;
#include <Windows.h>
#include <windowsx.h>
#include <wincodec.h>
#include <iostream>
#include <chrono>
#include <thread>
module MegaEngine;
import Input;
using namespace std;
using namespace std::chrono;
void Game::Run()
{
StartUp();
while (PeekMsg() && !Done())
{
Update();
Render();
LaterUpdate();
}
CleanUp();
}
void Game::StartUp()
{
last = steady_clock::now();
CreateWnd();
Graphics::Init(hwnd);
steve.OnStartUp();
}
void Game::Update()
{
auto now = steady_clock::now();
delta = duration_cast<duration<float>>(now - last).count();
last = now;
steve.OnUpdate(delta);
}
void Game::Render()
{
Graphics::BeginDraw();
Graphics::Clear();
steve.OnRender();
Graphics::Present();
}
void Game::LaterUpdate()
{
steve.OnLaterUpdate(delta);
}
void Game::CleanUp()
{
steve.OnCleanUp();
Graphics::Finalize();
if (hwnd) DestroyWindow(hwnd);
auto hInst = GetModuleHandleW(nullptr);
UnregisterClassW(L"1mGameWnd", hInst);
}
void Game::CreateWnd()
{
auto hInst = GetModuleHandleW(nullptr);
WNDCLASSEXW wc =
{
sizeof(WNDCLASSEXW),
CS_CLASSDC,
WndProcSetUp,
0,
0,
hInst,
LoadIconW(nullptr, IDI_APPLICATION),
LoadCursorW(nullptr, IDC_ARROW),
CreateSolidBrush(0x808080),
nullptr,
wndClassName,
nullptr
};
wc.lpszClassName = L"1mGameWnd";
RegisterClassExW(&wc);
auto wnd_style = WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME;//WS_CAPTION | WS_SYSMENU;
RECT client_rect{ 0, 0, wndWidth, wndHeight };
AdjustWindowRectEx(&client_rect, wnd_style, FALSE, 0u);
hwnd = CreateWindowExW
(
0L,
L"1mGameWnd",
L"1mGame",
wnd_style,
CW_USEDEFAULT,
CW_USEDEFAULT,
client_rect.right - client_rect.left,
client_rect.bottom - client_rect.top,
nullptr, nullptr, hInst, (LPVOID)this
);
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
}
bool Game::PeekMsg()
{
MSG msg;
while (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT) return false;
DispatchMessageW(&msg);
}
return true;
}
bool Game::Done()
{
return done;
}
LRESULT CALLBACK Game::WndProcSetUp(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
if (msg == WM_NCCREATE)
{
ImmDisableIME(GetCurrentThreadId());
auto CreateData = reinterpret_cast<CREATESTRUCTW*>(lParam);
auto wnd_ptr = reinterpret_cast<Game*>(CreateData->lpCreateParams);
SetWindowLongPtrW(hWnd, GWLP_WNDPROC, reinterpret_cast<LONG_PTR>(&Game::WndProcThunk));
SetWindowLongPtrW(hWnd, GWLP_USERDATA, reinterpret_cast<LONG_PTR>(wnd_ptr));
return wnd_ptr->WndProc(hWnd, msg, wParam, lParam);
}
return DefWindowProcW(hWnd, msg, wParam, lParam);
}
LRESULT CALLBACK Game::WndProcThunk(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
auto wnd_ptr = reinterpret_cast<Game*>(GetWindowLongPtrW(hWnd, GWLP_USERDATA));
return wnd_ptr->WndProc(hWnd, msg, wParam, lParam);
}
LRESULT Game::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_KEYDOWN:
KeyBoard::Update((char)wParam, true);
break;
case WM_KEYUP:
KeyBoard::Update((char)wParam, false);
break;
case WM_CLOSE:
done = true;
DestroyWindow(hwnd);
hwnd = nullptr;
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProcW(hWnd, msg, wParam, lParam);
}
return 0;
}