source: Daodan/src/Patches/Win32.c@ 1165

Last change on this file since 1165 was 1163, checked in by rossy, 3 years ago

Daodan: Add new local input system based on Raw Input

File size: 4.7 KB
Line 
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
13void 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).
21void 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
52BOOL WINAPI DD_GetCursorPos(LPPOINT lpPoint)
53{
54 DDmAssert(ONgPlatformData.Window);
55
56 return GetCursorPos(lpPoint) && ScreenToClient(ONgPlatformData.Window, lpPoint);
57}
58
59BOOL 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
70static 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
120UUtError 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
Note: See TracBrowser for help on using the repository browser.