#include #include "../test_utils.h" using namespace dxvk; struct Extent2D { uint32_t w, h; }; class ClearApp { public: ClearApp(HINSTANCE instance, HWND window) : m_window(window) { HRESULT status = Direct3DCreate9Ex(D3D_SDK_VERSION, &m_d3d); if (FAILED(status)) throw DxvkError("Failed to create D3D9 interface"); D3DPRESENT_PARAMETERS params; getPresentParams(params); status = m_d3d->CreateDeviceEx( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, m_window, D3DCREATE_HARDWARE_VERTEXPROCESSING, ¶ms, nullptr, &m_device); if (FAILED(status)) throw DxvkError("Failed to create D3D9 device"); } void run() { this->adjustBackBuffer(); m_device->BeginScene(); m_device->Clear( 0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_RGBA(255, 0, 0, 0), 0.0f, 0); m_device->EndScene(); m_device->PresentEx( nullptr, nullptr, nullptr, nullptr, 0); } void adjustBackBuffer() { RECT windowRect = { 0, 0, 1024, 600 }; GetClientRect(m_window, &windowRect); Extent2D newSize = { static_cast(windowRect.right - windowRect.left), static_cast(windowRect.bottom - windowRect.top), }; if (m_windowSize.w != newSize.w || m_windowSize.h != newSize.h) { m_windowSize = newSize; D3DPRESENT_PARAMETERS params; getPresentParams(params); HRESULT status = m_device->ResetEx(¶ms, nullptr); if (FAILED(status)) throw DxvkError("Device reset failed"); } } void getPresentParams(D3DPRESENT_PARAMETERS& params) { params.AutoDepthStencilFormat = D3DFMT_UNKNOWN; params.BackBufferCount = 1; params.BackBufferFormat = D3DFMT_X8R8G8B8; params.BackBufferWidth = m_windowSize.w; params.BackBufferHeight = m_windowSize.h; params.EnableAutoDepthStencil = FALSE; params.Flags = 0; params.FullScreen_RefreshRateInHz = 0; params.hDeviceWindow = m_window; params.MultiSampleQuality = 0; params.MultiSampleType = D3DMULTISAMPLE_NONE; params.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; params.SwapEffect = D3DSWAPEFFECT_DISCARD; params.Windowed = TRUE; } private: HWND m_window; Extent2D m_windowSize = { 1024, 600 }; Com m_d3d; Com m_device; }; LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { HWND hWnd; WNDCLASSEXW wc; ZeroMemory(&wc, sizeof(WNDCLASSEX)); wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.hInstance = hInstance; wc.hCursor = LoadCursor(nullptr, IDC_ARROW); wc.hbrBackground = (HBRUSH)COLOR_WINDOW; wc.lpszClassName = L"WindowClass1"; RegisterClassExW(&wc); hWnd = CreateWindowExW(0, L"WindowClass1", L"Our First Windowed Program", WS_OVERLAPPEDWINDOW, 300, 300, 640, 480, nullptr, nullptr, hInstance, nullptr); ShowWindow(hWnd, nCmdShow); MSG msg; try { ClearApp app(hInstance, hWnd); while (true) { if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) { TranslateMessage(&msg); DispatchMessage(&msg); if (msg.message == WM_QUIT) return msg.wParam; } else { app.run(); } } } catch (const dxvk::DxvkError& e) { std::cerr << e.message() << std::endl; return msg.wParam; } } LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CLOSE: PostQuitMessage(0); return 0; } return DefWindowProc(hWnd, message, wParam, lParam); }