#include #include "Daodan.h" #include "Daodan_Win32.h" #include "BFW_Utility.h" #include "Oni.h" // LIrPlatform_Terminate wrapper. Removes any cursor clipping we've done. Doing // this is required for Windows 98 :-D void ONICALL DD_LIrPlatform_Terminate(void) { ClipCursor(NULL); LIrPlatform_Terminate(); } // LIrPlatform_Mode_Set wrapper. Clips cursor to window bounds to // prevent loosing focus (mostly on Linux). void ONICALL DD_LIrPlatform_Mode_Set(unsigned int active_mode) { DDmAssert(ONgPlatformData.Window); if (active_mode) { RECT rc; POINT pt; pt.x = 0; pt.y = 0; if (GetClientRect(ONgPlatformData.Window, &rc) && ClientToScreen(ONgPlatformData.Window, &pt)) { rc.left += pt.x; rc.top += pt.y; rc.right += pt.x; rc.bottom += pt.y; ClipCursor(&rc); } } else { ClipCursor(NULL); } LIrPlatform_Mode_Set(active_mode); } BOOL WINAPI DD_GetCursorPos(LPPOINT lpPoint) { DDmAssert(ONgPlatformData.Window); return GetCursorPos(lpPoint) && ScreenToClient(ONgPlatformData.Window, lpPoint); } BOOL WINAPI DD_SetCursorPos(int X, int Y) { POINT pt; pt.x = X; pt.y = Y; DDmAssert(ONgPlatformData.Window); return ClientToScreen(ONgPlatformData.Window, &pt) && SetCursorPos(pt.x, pt.y); } static LRESULT CALLBACK DD_ONrPlatform_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_SYSCOMMAND: if (wParam == SC_SCREENSAVE) { // Prevent screen saver from starting when Oni has focus. return 0; } break; case WM_PAINT: { PAINTSTRUCT ps; BeginPaint(hWnd, &ps); // Oni does a useless PatBlt here. EndPaint(hWnd, &ps); return 0; } case WM_CLOSE: // There's no way to reliably terminate a modal dialog. // The following condition is (almost) always true. if (WMgActive) exit(0); ONgTerminateGame = UUcTrue; return 0; case WM_SETCURSOR: // If a mouse is inside our client area, we hide cursor (always), // otherwise we ask DefWindowProc to set an appropriate arrow for us. if (LOWORD(lParam) == HTCLIENT) { SetCursor(NULL); return TRUE; } break; } return ONrPlatform_WindowProc(hWnd, uMsg, wParam, lParam); } UUtError ONICALL DD_ONrPlatform_Initialize(ONtPlatformData *PlatformData) { WNDCLASSEX WndClass; RECT Rect; const int Width = 640, Height = 480; DWORD window_style, window_style_ex; PlatformData->Instance = ONgInstance; PlatformData->Window = NULL; if (FindWindow("ONI ", "ONI ")) { AUrMessageBox(1, "There is already an instance of the game running."); exit(0); } WndClass.cbSize = sizeof(WndClass); WndClass.style = CS_VREDRAW | CS_HREDRAW | CS_OWNDC; WndClass.cbClsExtra = 0; WndClass.cbWndExtra = 0; WndClass.hInstance = PlatformData->Instance; WndClass.hCursor = NULL; // To debug: LoadCursor(NULL, IDC_ARROW); WndClass.hIcon = LoadIcon(ONgInstance, MAKEINTRESOURCE(103)); WndClass.hIconSm = LoadIcon(ONgInstance, MAKEINTRESOURCE(103)); WndClass.hbrBackground = GetStockObject(BLACK_BRUSH); WndClass.lpszMenuName = NULL; WndClass.lpszMenuName = NULL; WndClass.lpszClassName = "ONI "; WndClass.lpfnWndProc = DD_ONrPlatform_WindowProc; RegisterClassEx(&WndClass); if (M3gResolutionSwitch) { // Do not allow border and topmost flag for a fullscreen window. window_style = WS_POPUP; window_style_ex = 0; } else { window_style = (opt_border) ? WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_DLGFRAME | WS_MINIMIZEBOX : WS_POPUP; window_style_ex = (opt_topmost) ? WS_EX_TOPMOST : 0; } Rect.left = (GetSystemMetrics(SM_CXSCREEN) / 2) - (Width / 2); Rect.top = (GetSystemMetrics(SM_CYSCREEN) / 2) - (Height / 2); Rect.right = Rect.left + Width; Rect.bottom = Rect.top + Height; AdjustWindowRectEx(&Rect, window_style, FALSE, window_style_ex); PlatformData->Window = CreateWindowEx(window_style_ex, WndClass.lpszClassName, "ONI ", window_style, Rect.left, Rect.top, Rect.right - Rect.left, Rect.bottom - Rect.top, NULL, NULL, PlatformData->Instance, NULL); ShowWindow(PlatformData->Window, SW_SHOWNORMAL); UpdateWindow(PlatformData->Window); return UUcError_None; }