Avoid non-alpha characters in _qdgdfv_alnum in win32.
[qdgdf.git] / qdgdf_video_win32gdi.c
blob26b8b155ab9ddf3ec22d206318b645e63b3db4d3
1 /*
3 Quick and Dirty Game Development Framework (QDGDF)
5 Copyright (C) 2001/2011 Angel Ortega <angel@triptico.com>
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 http://www.triptico.com
25 #include "config.h"
26 #include <stdio.h>
27 #include "qdgdf_video.h"
29 #ifdef CONFOPT_WIN32GDI
31 #include <stdlib.h>
32 #include <string.h>
33 #include <math.h>
34 #include <time.h>
35 #include <ctype.h>
36 #include <windows.h>
38 HINSTANCE hinst = NULL;
39 HWND hwnd;
40 HDC hdc;
42 #ifdef CONFOPT_OPENGL
43 HGLRC hrc;
44 #endif
46 /* keyboard scancodes */
47 static int _scan_codes[128];
49 /* the double screen */
50 static unsigned char *_double_screen;
52 /* the bitmap info */
53 BITMAPINFO bmi;
55 /* opengl in use */
56 static int opengl_flag = 0;
59 /** code **/
61 static void draw(HWND hwnd)
63 PAINTSTRUCT ps;
65 if (opengl_flag) {
66 SwapBuffers(hdc);
68 else {
69 hdc = BeginPaint(hwnd, &ps);
71 SetDIBitsToDevice(hdc, 0, 0,
72 _qdgdfv_screen_x_size * _qdgdfv_scale,
73 _qdgdfv_screen_y_size * _qdgdfv_scale,
77 _qdgdfv_screen_y_size * _qdgdfv_scale,
78 _double_screen, &bmi, 0);
80 EndPaint(hwnd, &ps);
85 long STDCALL WndProc_GDI(HWND hwnd, UINT msg, UINT wparam, LONG lparam)
86 /* main window Proc */
88 int k;
90 switch (msg) {
91 case WM_PAINT:
92 draw(hwnd);
93 break;
95 case WM_CHAR:
97 if (isalnum(wparam)) {
98 _qdgdfv_key_alnum = 1;
99 _qdgdfv_alnum = wparam;
102 return 0;
104 case WM_SYSKEYDOWN:
105 case WM_KEYDOWN:
106 k = (lparam >> 16) & 0xff;
107 _scan_codes[k] = 1;
109 return 0;
111 case WM_SYSKEYUP:
112 case WM_KEYUP:
113 k = (lparam >> 16) & 0xff;
114 _scan_codes[k] = 0;
116 _qdgdfv_key_alnum = 0;
118 return 0;
120 case WM_CLOSE:
121 DestroyWindow(hwnd);
122 return 0;
124 case WM_DESTROY:
125 PostQuitMessage(0);
126 return 0;
128 case WM_SETCURSOR:
130 SetCursor(NULL);
131 return 0;
134 return DefWindowProcW(hwnd, msg, wparam, lparam);
138 static int _qdgdfv_timer(int reset)
140 static int prev = 0;
141 int c, r;
143 c = GetTickCount();
144 r = c - prev;
146 /* avoid timer wraps */
147 if (r < 0)
148 r = 0;
150 if (reset)
151 prev = c;
153 return r;
157 static void _qdgdfv_set_palette(void)
162 static void _qdgdfv_dump_virtual_screen(void)
164 if (_qdgdfv_scale2x) {
165 switch (_qdgdfv_scale) {
166 case 1:
167 _qdgdfv_dump4_screen(_qdgdfv_virtual_screen,
168 (int *) _double_screen);
169 break;
171 case 2:
172 _qdgdfv_s2x_dump4_screen(_qdgdfv_virtual_screen,
173 (int *) _double_screen);
174 break;
176 case 3:
177 _qdgdfv_s3x_dump4_screen(_qdgdfv_virtual_screen,
178 (int *) _double_screen);
179 break;
182 else {
183 switch (_qdgdfv_scale) {
184 case 1:
185 _qdgdfv_dump4_screen(_qdgdfv_virtual_screen,
186 (int *) _double_screen);
187 break;
189 case 2:
190 _qdgdfv_double_dump4_screen(_qdgdfv_virtual_screen,
191 (int *) _double_screen);
192 break;
194 case 3:
195 _qdgdfv_triple_dump4_screen(_qdgdfv_virtual_screen,
196 (int *) _double_screen);
197 break;
201 InvalidateRect(hwnd, NULL, FALSE);
205 static void _qdgdfv_input_poll(void)
207 MSG msg;
209 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
210 TranslateMessage(&msg);
211 DispatchMessage(&msg);
214 _qdgdfv_key_up = _scan_codes[0x48];
215 _qdgdfv_key_down = _scan_codes[0x50];
216 _qdgdfv_key_left = _scan_codes[0x4b];
217 _qdgdfv_key_right = _scan_codes[0x4d];
218 _qdgdfv_key_escape = _scan_codes[0x01];
219 _qdgdfv_key_space = _scan_codes[0x39];
220 _qdgdfv_key_enter = _scan_codes[0x1c];
221 _qdgdfv_key_control = _scan_codes[0x1d];
222 _qdgdfv_key_pgup = _scan_codes[0x49];
223 _qdgdfv_key_pgdn = _scan_codes[0x51];
224 _qdgdfv_key_home = _scan_codes[0x47];
225 _qdgdfv_key_end = _scan_codes[0x4f];
226 /* _qdgdfv_key_control_r = _scan_codes[0x1d];
227 _qdgdfv_key_control_r=_scan_codes[0x36];
228 0x36 is right shift, windows does not differ between left and right control keys, both are 0x1d
230 _qdgdfv_key_shift_l = _scan_codes[0x2a];
231 _qdgdfv_key_shift_r = _scan_codes[0x36];
233 _qdgdfv_key_f1 = _scan_codes[0x3b];
234 _qdgdfv_key_f2 = _scan_codes[0x3c];
235 _qdgdfv_key_f3 = _scan_codes[0x3d];
236 _qdgdfv_key_f4 = _scan_codes[0x3e];
237 _qdgdfv_key_f5 = _scan_codes[0x3f];
238 _qdgdfv_key_f6 = _scan_codes[0x40];
239 _qdgdfv_key_f7 = _scan_codes[0x41];
240 _qdgdfv_key_f8 = _scan_codes[0x42];
241 _qdgdfv_key_f9 = _scan_codes[0x43];
242 _qdgdfv_key_f10 = _scan_codes[0x44];
246 static int _qdgdfv_opengl(int onoff)
248 int ret = 0;
250 #ifdef CONFOPT_OPENGL
252 if (onoff) {
253 PIXELFORMATDESCRIPTOR pfd;
254 int i;
256 /* get the device context (DC) */
257 hdc = GetDC(hwnd);
259 /* set the pixel format for the DC */
260 ZeroMemory(&pfd, sizeof(pfd));
261 pfd.nSize = sizeof(pfd);
262 pfd.nVersion = 1;
263 pfd.dwFlags =
264 PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
265 pfd.iPixelType = PFD_TYPE_RGBA;
266 pfd.cColorBits = 24;
267 pfd.cDepthBits = 16;
268 pfd.iLayerType = PFD_MAIN_PLANE;
269 i = ChoosePixelFormat(hdc, &pfd);
270 SetPixelFormat(hdc, i, &pfd);
272 /* create and enable the render context (RC) */
273 hrc = wglCreateContext(hdc);
274 wglMakeCurrent(hdc, hrc);
276 else {
277 wglMakeCurrent(NULL, NULL);
278 wglDeleteContext(hrc);
279 ReleaseDC(hwnd, hdc);
282 opengl_flag = onoff;
283 ret = 1;
285 #endif
287 return ret;
291 static int _qdgdfv_startup(void)
293 WNDCLASSW wc;
294 BITMAPINFOHEADER *h;
295 RECT cr;
296 RECT wr;
298 if (_qdgdfv_full_screen == -1)
299 _qdgdfv_full_screen = 0;
301 /* reject full screen mode */
302 if (_qdgdfv_full_screen == 1)
303 return 0;
305 if (_qdgdfv_scale > 3)
306 _qdgdfv_scale = 3;
308 _qdgdfv_pixel_size = 4;
310 _qdgdfv_red_mask = 0xff000000;
311 _qdgdfv_red_shift = 8;
313 _qdgdfv_green_mask = 0xff000000;
314 _qdgdfv_green_shift = 16;
316 _qdgdfv_blue_mask = 0xff000000;
317 _qdgdfv_blue_shift = 24;
319 hinst = (HINSTANCE) _qdgdfv_additional_int_info;
321 /* register the window */
322 wc.style = CS_HREDRAW | CS_VREDRAW;
323 wc.lpfnWndProc = WndProc_GDI;
324 wc.cbClsExtra = 0;
325 wc.cbWndExtra = 0;
326 wc.hInstance = hinst;
327 wc.hIcon = NULL;
328 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
329 wc.hbrBackground = NULL;
330 wc.lpszMenuName = NULL;
331 wc.lpszClassName = L"qdgdf_gdi";
333 if (!RegisterClassW(&wc)) {
334 qdgdfv_logger("qdgdfv_startup", "RegisterClass error");
335 return 0;
338 /* create the window */
339 hwnd = CreateWindowW(L"qdgdf_gdi", L"",
340 WS_OVERLAPPED | WS_CLIPCHILDREN,
341 CW_USEDEFAULT, CW_USEDEFAULT,
342 CW_USEDEFAULT, CW_USEDEFAULT,
343 NULL, NULL, hinst, NULL);
345 if (hwnd == NULL) {
346 qdgdfv_logger("qdgdfv_startup", "WIN32 GDI CreateWindow error");
347 return 0;
350 _qdgdfv_virtual_screen = (unsigned char *)
351 qdgdfv_malloc(_qdgdfv_screen_x_size * _qdgdfv_screen_y_size);
353 _double_screen = (unsigned char *)
354 qdgdfv_malloc(_qdgdfv_screen_x_size * _qdgdfv_screen_y_size *
355 _qdgdfv_scale * _qdgdfv_scale * _qdgdfv_pixel_size);
357 GetClientRect(hwnd, &cr);
358 GetWindowRect(hwnd, &wr);
360 MoveWindow(hwnd,
361 _qdgdfv_window_x,
362 _qdgdfv_window_y,
363 _qdgdfv_screen_x_size * _qdgdfv_scale + (wr.right -
364 wr.left) -
365 cr.right,
366 _qdgdfv_screen_y_size * _qdgdfv_scale + (wr.bottom -
367 wr.top) -
368 cr.bottom, FALSE);
370 qdgdfv_clear_virtual_screen();
372 ShowWindow(hwnd, SW_SHOW);
373 UpdateWindow(hwnd);
374 SetCursor(NULL);
376 /* fill the bitmap information */
377 memset(&bmi, '\0', sizeof(bmi));
378 h = &bmi.bmiHeader;
380 h->biSize = sizeof(BITMAPINFOHEADER);
381 h->biWidth = _qdgdfv_screen_x_size * _qdgdfv_scale;
382 h->biHeight = -_qdgdfv_screen_y_size * _qdgdfv_scale;
383 h->biPlanes = 1;
384 h->biBitCount = 32;
385 h->biCompression = BI_RGB;
386 h->biSizeImage = 0;
387 h->biClrUsed = 0;
388 h->biClrImportant = 0;
390 SetWindowText(hwnd, _qdgdfv_window_title);
392 qdgdfv_logger("qdgdfv_startup", "Win32 GDI driver startup");
394 return 1;
398 static void _qdgdfv_shutdown(void)
400 SendMessage(hwnd, WM_CLOSE, 0, 0);
402 qdgdfv_logger("qdgdfv_startup", "Win32 GDI driver shutdown");
406 /** driver information **/
408 static struct _qdgdfv_driver drv = {
409 "win32_gdi",
410 _qdgdfv_set_palette,
411 _qdgdfv_dump_virtual_screen,
412 _qdgdfv_input_poll,
413 _qdgdfv_timer,
414 _qdgdfv_opengl,
415 _qdgdfv_startup,
416 _qdgdfv_shutdown
420 struct _qdgdfv_driver *win32gdi_drv_detect(void)
421 /* detection function */
423 if (_qdgdfv_startup())
424 return &drv;
426 return NULL;
429 #endif /* CONFOPT_WIN32GDI */