| 1 | #include <windows.h>
 | 
|---|
| 2 | 
 | 
|---|
| 3 | #include "Daodan.h"
 | 
|---|
| 4 | #include "Daodan_Win32.h"
 | 
|---|
| 5 | 
 | 
|---|
| 6 | #include "BFW_Utility.h"
 | 
|---|
| 7 | #include "Oni.h"
 | 
|---|
| 8 | 
 | 
|---|
| 9 | 
 | 
|---|
| 10 | // LIrPlatform_Terminate wrapper. Removes any cursor clipping we've done. Doing
 | 
|---|
| 11 | // this is required for Windows 98 :-D
 | 
|---|
| 12 | void ONICALL DD_LIrPlatform_Terminate(void)
 | 
|---|
| 13 | {
 | 
|---|
| 14 |         ClipCursor(NULL);
 | 
|---|
| 15 |         LIrPlatform_Terminate();
 | 
|---|
| 16 | }
 | 
|---|
| 17 | 
 | 
|---|
| 18 | // LIrPlatform_Mode_Set wrapper. Clips cursor to window bounds to
 | 
|---|
| 19 | // prevent loosing focus (mostly on Linux).
 | 
|---|
| 20 | void ONICALL DD_LIrPlatform_Mode_Set(unsigned int active_mode)
 | 
|---|
| 21 | {
 | 
|---|
| 22 |         DDmAssert(ONgPlatformData.Window);
 | 
|---|
| 23 | 
 | 
|---|
| 24 |         if (active_mode)
 | 
|---|
| 25 |         {
 | 
|---|
| 26 |                 RECT rc;
 | 
|---|
| 27 |                 POINT pt;
 | 
|---|
| 28 | 
 | 
|---|
| 29 |                 pt.x = 0;
 | 
|---|
| 30 |                 pt.y = 0;
 | 
|---|
| 31 | 
 | 
|---|
| 32 |                 if (GetClientRect(ONgPlatformData.Window, &rc) &&
 | 
|---|
| 33 |                         ClientToScreen(ONgPlatformData.Window, &pt))
 | 
|---|
| 34 |                 {
 | 
|---|
| 35 |                         rc.left   += pt.x;
 | 
|---|
| 36 |                         rc.top    += pt.y;
 | 
|---|
| 37 |                         rc.right  += pt.x;
 | 
|---|
| 38 |                         rc.bottom += pt.y;
 | 
|---|
| 39 | 
 | 
|---|
| 40 |                         ClipCursor(&rc);
 | 
|---|
| 41 |                 }
 | 
|---|
| 42 |         }
 | 
|---|
| 43 |         else
 | 
|---|
| 44 |         {
 | 
|---|
| 45 |                 ClipCursor(NULL);
 | 
|---|
| 46 |         }
 | 
|---|
| 47 | 
 | 
|---|
| 48 |         LIrPlatform_Mode_Set(active_mode);
 | 
|---|
| 49 | }
 | 
|---|
| 50 | 
 | 
|---|
| 51 | BOOL WINAPI DD_GetCursorPos(LPPOINT lpPoint)
 | 
|---|
| 52 | {
 | 
|---|
| 53 |         DDmAssert(ONgPlatformData.Window);
 | 
|---|
| 54 |         
 | 
|---|
| 55 |         return GetCursorPos(lpPoint) && ScreenToClient(ONgPlatformData.Window, lpPoint);
 | 
|---|
| 56 | }
 | 
|---|
| 57 | 
 | 
|---|
| 58 | BOOL WINAPI DD_SetCursorPos(int X, int Y)
 | 
|---|
| 59 | {
 | 
|---|
| 60 |         POINT pt;
 | 
|---|
| 61 |         pt.x = X;
 | 
|---|
| 62 |         pt.y = Y;
 | 
|---|
| 63 |         
 | 
|---|
| 64 |         DDmAssert(ONgPlatformData.Window);
 | 
|---|
| 65 |         
 | 
|---|
| 66 |         return ClientToScreen(ONgPlatformData.Window, &pt) && SetCursorPos(pt.x, pt.y);
 | 
|---|
| 67 | }
 | 
|---|
| 68 | 
 | 
|---|
| 69 | static LRESULT CALLBACK DD_ONrPlatform_WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 70 | {
 | 
|---|
| 71 |         switch (uMsg)
 | 
|---|
| 72 |         {
 | 
|---|
| 73 |                 case WM_SYSCOMMAND:
 | 
|---|
| 74 |                         if (wParam == SC_SCREENSAVE)
 | 
|---|
| 75 |                         {
 | 
|---|
| 76 |                                 // Prevent screen saver from starting when Oni has focus.
 | 
|---|
| 77 |                                 return 0;
 | 
|---|
| 78 |                         }
 | 
|---|
| 79 |                         break;
 | 
|---|
| 80 |                 
 | 
|---|
| 81 |                 case WM_PAINT:
 | 
|---|
| 82 |                 {
 | 
|---|
| 83 |                         PAINTSTRUCT ps;
 | 
|---|
| 84 |                         BeginPaint(hWnd, &ps);
 | 
|---|
| 85 |                         // Oni does a useless PatBlt here.
 | 
|---|
| 86 |                         EndPaint(hWnd, &ps);
 | 
|---|
| 87 |                         return 0;
 | 
|---|
| 88 |                 }
 | 
|---|
| 89 |                 
 | 
|---|
| 90 |                 case WM_CLOSE:
 | 
|---|
| 91 |                         // There's no way to reliably terminate a modal dialog.
 | 
|---|
| 92 |                         // The following condition is (almost) always true.
 | 
|---|
| 93 |                         if (WMgActive)
 | 
|---|
| 94 |                                 exit(0);
 | 
|---|
| 95 | 
 | 
|---|
| 96 |                         ONgTerminateGame = UUcTrue;
 | 
|---|
| 97 |                         return 0;
 | 
|---|
| 98 |                         
 | 
|---|
| 99 |                 case WM_SETCURSOR:
 | 
|---|
| 100 |                         // If a mouse is inside our client area, we hide cursor (always),
 | 
|---|
| 101 |                         // otherwise we ask DefWindowProc to set an appropriate arrow for us.
 | 
|---|
| 102 |                         if (LOWORD(lParam) == HTCLIENT)
 | 
|---|
| 103 |                         {
 | 
|---|
| 104 |                                 SetCursor(NULL);
 | 
|---|
| 105 |                                 return TRUE;
 | 
|---|
| 106 |                         }
 | 
|---|
| 107 |                         
 | 
|---|
| 108 |                         break;
 | 
|---|
| 109 |         }
 | 
|---|
| 110 |         
 | 
|---|
| 111 |         return ONrPlatform_WindowProc(hWnd, uMsg, wParam, lParam);
 | 
|---|
| 112 | }
 | 
|---|
| 113 | 
 | 
|---|
| 114 | 
 | 
|---|
| 115 | UUtError ONICALL DD_ONrPlatform_Initialize(ONtPlatformData *PlatformData)
 | 
|---|
| 116 | {
 | 
|---|
| 117 |         WNDCLASSEX WndClass;
 | 
|---|
| 118 |         RECT Rect;
 | 
|---|
| 119 |         const int Width = 640, Height = 480;
 | 
|---|
| 120 |         DWORD window_style, window_style_ex;
 | 
|---|
| 121 |  
 | 
|---|
| 122 |         PlatformData->Instance = ONgInstance;
 | 
|---|
| 123 |         PlatformData->Window   = NULL;
 | 
|---|
| 124 |         
 | 
|---|
| 125 |         if (FindWindow("ONI ", "ONI "))
 | 
|---|
| 126 |         {
 | 
|---|
| 127 |                 AUrMessageBox(1, "Daodan: There is already an instance of the game running.");
 | 
|---|
| 128 |                 exit(0);
 | 
|---|
| 129 |         }
 | 
|---|
| 130 |         
 | 
|---|
| 131 |         WndClass.cbSize        = sizeof(WndClass);
 | 
|---|
| 132 |         WndClass.style         = CS_VREDRAW | CS_HREDRAW | CS_OWNDC;
 | 
|---|
| 133 |         WndClass.cbClsExtra    = 0;
 | 
|---|
| 134 |         WndClass.cbWndExtra    = 0;
 | 
|---|
| 135 |         WndClass.hInstance     = PlatformData->Instance;
 | 
|---|
| 136 |         WndClass.hCursor       = NULL; // To debug: LoadCursor(NULL, IDC_ARROW);
 | 
|---|
| 137 |         WndClass.hIcon         = LoadIcon(ONgInstance, MAKEINTRESOURCE(103));
 | 
|---|
| 138 |         WndClass.hIconSm       = LoadIcon(ONgInstance, MAKEINTRESOURCE(103));
 | 
|---|
| 139 |         WndClass.hbrBackground = GetStockObject(BLACK_BRUSH);
 | 
|---|
| 140 |         WndClass.lpszMenuName = NULL;
 | 
|---|
| 141 |         WndClass.lpszMenuName  = NULL;
 | 
|---|
| 142 |         WndClass.lpszClassName = "ONI ";
 | 
|---|
| 143 |         WndClass.lpfnWndProc   = DD_ONrPlatform_WindowProc;
 | 
|---|
| 144 |  
 | 
|---|
| 145 |         RegisterClassEx(&WndClass);
 | 
|---|
| 146 |         
 | 
|---|
| 147 |         if (M3gResolutionSwitch)
 | 
|---|
| 148 |         {
 | 
|---|
| 149 |                 // Do not allow border and topmost flag for a fullscreen window.
 | 
|---|
| 150 |                 window_style    = WS_POPUP;
 | 
|---|
| 151 |                 window_style_ex = 0;
 | 
|---|
| 152 |         }
 | 
|---|
| 153 |         else
 | 
|---|
| 154 |         {
 | 
|---|
| 155 |                 window_style    = (opt_border) ? WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_DLGFRAME | WS_MINIMIZEBOX : WS_POPUP;
 | 
|---|
| 156 |                 window_style_ex = (opt_topmost) ? WS_EX_TOPMOST : 0;
 | 
|---|
| 157 |         }
 | 
|---|
| 158 |         
 | 
|---|
| 159 |         Rect.left = (GetSystemMetrics(SM_CXSCREEN) / 2) - (Width / 2);
 | 
|---|
| 160 |         Rect.top = (GetSystemMetrics(SM_CYSCREEN) / 2) - (Height / 2);
 | 
|---|
| 161 |         Rect.right = Rect.left + Width;
 | 
|---|
| 162 |         Rect.bottom = Rect.top + Height;
 | 
|---|
| 163 |         AdjustWindowRectEx(&Rect, window_style, FALSE, window_style_ex);
 | 
|---|
| 164 |         
 | 
|---|
| 165 |         PlatformData->Window = CreateWindowEx(window_style_ex, WndClass.lpszClassName, "ONI ", window_style,
 | 
|---|
| 166 |                 Rect.left, Rect.top, Rect.right - Rect.left, Rect.bottom - Rect.top,
 | 
|---|
| 167 |                 NULL, NULL, PlatformData->Instance, NULL);
 | 
|---|
| 168 |         
 | 
|---|
| 169 |         ShowWindow(PlatformData->Window, SW_SHOWNORMAL);
 | 
|---|
| 170 |         UpdateWindow(PlatformData->Window);
 | 
|---|
| 171 |  
 | 
|---|
| 172 |         return UUcError_None;
 | 
|---|
| 173 |  }
 | 
|---|
| 174 | 
 | 
|---|