ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/Daodan/src/Patches/Win32.c
Revision: 1163
Committed: Sun Oct 24 02:50:48 2021 UTC (3 years, 11 months ago) by rossy
Content type: text/x-csrc
File size: 4830 byte(s)
Log Message:
Daodan: Add new local input system based on Raw Input

File Contents

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