1 /****************************************************************************************/
\r
4 /* Description: GDI dib handling code */
\r
6 /* Code fragments contributed by John Miles */
\r
8 /* The contents of this file are subject to the Genesis3D Public License */
\r
9 /* Version 1.01 (the "License"); you may not use this file except in */
\r
10 /* compliance with the License. You may obtain a copy of the License at */
\r
11 /* http://www.genesis3d.com */
\r
13 /* Software distributed under the License is distributed on an "AS IS" */
\r
14 /* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See */
\r
15 /* the License for the specific language governing rights and limitations */
\r
16 /* under the License. */
\r
18 /* The Original Code is Genesis3D, released March 25, 1999. */
\r
19 /*Genesis3D Version 1.1 released November 15, 1999 */
\r
20 /* Copyright (C) 1999 WildTangent, Inc. All Rights Reserved */
\r
22 /****************************************************************************************/
\r
26 // not very much of this module is being used, and what is being used is only
\r
27 // being used by the software rasterizer. This needs to be trimmed. it would be
\r
28 // best to take out the superclassing system and replace it with some basic utility
\r
29 // functions called from the client.
\r
30 // I think these would do it:
\r
31 // paint() to repaint
\r
32 // activate() to inform the engine about activation/deactivation
\r
33 // fullscreen_toggle()
\r
36 // for the moment, I've disabled most of the superclassing behavior, so that it
\r
37 // does not interfere with the application's window (if it is in windowed mode)
\r
38 // I think this will work (there may be problems with full-screen software
\r
39 // rasterization mode)
\r
40 #define DISABLED_BEHAVIOR
\r
43 #define WIN32_LEAN_AND_MEAN
\r
44 #include <windows.h>
\r
45 #include <windowsx.h>
\r
46 #include <winuser.h>
\r
47 #include <mmsystem.h>
\r
59 //#ifdef SAL_USE_D3D
\r
60 // #include "d3dhal.h"
\r
63 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
65 //ÛÛ SAL statics and globals ÛÛ
\r
67 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
73 static S32 desktop_w; // Windows desktop width, height
\r
74 static S32 desktop_h;
\r
76 static S32 cursor_state; // Copy of Windows mouse hide/show state
\r
77 static S32 show_count; // System mouse cursor show count
\r
79 static char debug_log_filename[256];
\r
80 static S32 log_to_file; // TRUE if user wants debug log
\r
82 static S32 app_minimized; // TRUE if this SAL app has been minimized
\r
83 static S32 app_active; // TRUE if this SAL app has input focus
\r
84 static S32 app_terminated; // TRUE if app has received its quit message
\r
86 static SALEXITCB exit_callback; // Address of mandatory exit callback
\r
87 static SALFOCUSCB focus_callback; // Address of focus callback, if any
\r
88 static WNDPROC window_callback; // Address of WNDPROC, if any
\r
89 static WNDPROC OldWindowProc;
\r
90 static HANDLE hSem; // Semaphore to limit instances
\r
92 static S32 mode_change_request; // TRUE to toggle window/fullscreen
\r
94 static HINSTANCE hAppInstance; // Application instance handle
\r
95 static HINSTANCE hDLLInstance; // DLL instance handle
\r
96 static char szMyAppName[512]; // Application name
\r
97 static HWND hWnd; // Handle to application window
\r
98 static HANDLE hHook; // Handle to Windows hook object
\r
100 static S32 SAL_preference[N_SAL_PREFS]; // Preferences array
\r
102 static S32 mode_change_allowed; // TRUE if window/fullscreen toggle allowed
\r
103 static S32 current_window_mode; // SAL_FULLSCREEN / SAL_WINDOW
\r
104 static S32 current_bpp; // Mode info set by last call to
\r
105 static S32 current_size_X; // SAL_set_display_mode
\r
106 static S32 current_size_Y;
\r
108 static LOGPALETTE *pLogPal; // LOGPALETTE structure
\r
109 static BITMAPINFO *pbmi; // BITMAPINFO structure
\r
110 static BITMAPINFOHEADER *pbmih; // Pointer to pbmi header
\r
112 static SAL_RGB32 palette_state[256]; // Current state of all DAC registers
\r
115 // CreateDIBSection() (windowed mode) variables and related data
\r
118 static SAL_WINAREA area; // Location/size of window client area
\r
120 static S32 desktop_bpp; // Windows video mode BPP
\r
121 static U32 desktop_R_bitmask; // Desktop high-color pixel format
\r
122 static U32 desktop_G_bitmask;
\r
123 static U32 desktop_B_bitmask;
\r
125 static U32 DIB_R_bitmask; // DIB high-color pixel format
\r
126 static U32 DIB_G_bitmask;
\r
127 static U32 DIB_B_bitmask;
\r
129 static U32 DIB_R_Shift;
\r
130 static U32 DIB_G_Shift;
\r
131 static U32 DIB_B_Shift;
\r
133 static S32 DIB_active; // CreateDIBSection() active if TRUE
\r
135 static U8 *lpDIBBuffer; // DIB image buffer
\r
136 static HBITMAP hDIB; // Handle returned from CreateDIBSection
\r
137 static HPALETTE hPalette; // Handle to palette if 8-bit mode in use
\r
139 static S32 palette_change_request; // TRUE to signal palette update
\r
141 static RECT original_window_rect; // Default size of DIB window
\r
142 static SAL_WINAREA original_area; // Default size of client area
\r
143 static LONG OldWindowLong_GWL_STYLE; // Old Window GWL_STYLE
\r
144 static LONG OldWindowLong_GWL_EXSTYLE; // Old Window GWL_STYLE
\r
146 static RECT unconstrained_rect; // Default area of mouse constraint
\r
147 static S32 constrain_state; // 1 if mouse limited to window area
\r
148 static S32 constrain_request; // 1 if mouse should be constrained at next movement
\r
150 static HDC Context;
\r
151 static HBITMAP DefaultBitmap;
\r
153 extern "C" long FAR PASCAL MyWndProc(HWND hWindow, UINT message, //)
\r
154 WPARAM wParam, LPARAM lParam);
\r
156 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
158 //ÛÛ DLLMain() function to acquire DLL instance handle, etc. ÛÛ
\r
160 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
162 BOOL WINAPI DllMain(HINSTANCE hinstDLL,//)
\r
164 LPVOID lpvReserved)
\r
166 if (fdwReason == DLL_PROCESS_ATTACH)
\r
168 hDLLInstance = hinstDLL;
\r
174 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
176 //ÛÛ Serve Windows message queue, returning 0 if WM_QUIT message received ÛÛ
\r
178 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
180 void serve_queue(void)
\r
185 if (app_terminated)
\r
191 // Serve message queue
\r
194 while (PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE))
\r
196 if (!GetMessage(&msg, NULL, 0, 0 ))
\r
198 app_active = FALSE;
\r
199 app_terminated = TRUE;
\r
204 // Return statement should not be reached
\r
210 TranslateMessage(&msg);
\r
211 DispatchMessage(&msg);
\r
216 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
218 //ÛÛ Return rectangle containing client-area boundaries in screenspace ÛÛ
\r
220 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
222 RECT *client_screen_rect(void)
\r
227 GetClientRect(hWnd, &rect);
\r
231 lr.x = rect.right;
\r
232 lr.y = rect.bottom;
\r
234 ClientToScreen(hWnd, &ul);
\r
235 ClientToScreen(hWnd, &lr);
\r
237 SetRect(&rect, ul.x, ul.y,
\r
243 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
245 //ÛÛ Mouse/keyboard event management ÛÛ
\r
247 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
249 void MOUSE_event(unsigned long wParam, unsigned long lParam)
\r
253 void KEYDOWN_event(unsigned long wParam, unsigned long lParam)
\r
257 void KEYUP_event(unsigned long wParam, unsigned long lParam)
\r
261 void CHAR_event(unsigned long wParam, unsigned long lParam)
\r
266 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
268 //ÛÛ Shut down CreateDIBSection() services ÛÛ
\r
270 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
272 void DIB_shutdown(void)
\r
274 if (constrain_state)
\r
276 #ifndef DISABLED_BEHAVIOR
\r
277 ClipCursor(&unconstrained_rect);
\r
279 constrain_request = 0;
\r
282 if (DIB_active && SAL_is_app_active())
\r
284 SAL_wipe_surface(SAL_BACK_SURFACE, 0);
\r
285 SAL_flip_surface();
\r
290 DeleteObject(hDIB);
\r
294 if (hPalette != NULL)
\r
296 DeleteObject(hPalette);
\r
301 // Make sure we restore the old hWnd parms
\r
303 SetWindowLong(hWnd,
\r
305 OldWindowLong_GWL_STYLE);
\r
306 SetWindowLong(hWnd,
\r
308 OldWindowLong_GWL_EXSTYLE);
\r
309 SetWindowPos(hWnd,
\r
313 original_area.width,
\r
314 original_area.height,
\r
315 SWP_NOCOPYBITS | SWP_NOZORDER);
\r
317 ShowWindow(hWnd, SW_SHOWNORMAL);
\r
322 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
324 //ÛÛ Start up CreateDIBSection() services for windowed display ÛÛ
\r
326 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
328 S32 DIB_startup(S32 display_size_X,//)
\r
329 S32 display_size_Y,
\r
333 COLORREF color,save;
\r
338 area.width = display_size_X;
\r
339 area.height = display_size_Y;
\r
340 original_area = area;
\r
342 GetWindowRect(hWnd, &window_rect);
\r
343 original_window_rect = window_rect;
\r
345 OldWindowLong_GWL_STYLE = GetWindowLong(hWnd, GWL_STYLE);
\r
346 OldWindowLong_GWL_EXSTYLE = GetWindowLong(hWnd, GWL_EXSTYLE);
\r
348 display_size_X = area.width;
\r
349 display_size_Y = area.height;
\r
351 // Get desktop size
\r
354 desktop_w = GetSystemMetrics(SM_CXSCREEN);
\r
355 desktop_h = GetSystemMetrics(SM_CYSCREEN);
\r
358 // Enable caption menu and user preferences
\r
361 SetWindowLong(hWnd,
\r
363 GetWindowLong(hWnd, GWL_STYLE) & ~WS_POPUP);
\r
365 SetWindowLong(hWnd,
\r
367 GetWindowLong(hWnd, GWL_STYLE) | (WS_OVERLAPPED |
\r
372 if (SAL_get_preference(SAL_ALLOW_WINDOW_RESIZE))
\r
374 SetWindowLong(hWnd,
\r
376 GetWindowLong(hWnd, GWL_STYLE) | WS_THICKFRAME |
\r
380 if (SAL_get_preference(SAL_ALWAYS_ON_TOP))
\r
382 SetWindowLong(hWnd,
\r
384 GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_TOPMOST);
\r
388 SetWindowLong(hWnd,
\r
390 GetWindowLong(hWnd, GWL_EXSTYLE) & ~WS_EX_TOPMOST);
\r
394 // If area not already established, center window's client area on
\r
395 // desktop, and size it to correspond to the display size for optimum
\r
396 // performance (no stretching needed)
\r
399 //if (area.width == -1)
\r
401 area.width = display_size_X;
\r
402 area.height = display_size_Y;
\r
404 area.x = ((desktop_w - area.width ) / 2);
\r
405 area.y = ((desktop_h - area.height) / 2);
\r
409 // Calculate adjusted position of window
\r
411 // Do not allow overall window size to exceed desktop size; keep
\r
412 // dividing height and width by 2 until entire window fits
\r
414 // If window is offscreen (or almost entirely offscreen), center it
\r
421 window_rect.left = area.x;
\r
422 window_rect.right = area.x + area.width - 1;
\r
423 window_rect.top = area.y;
\r
424 window_rect.bottom = area.y + area.height - 1;
\r
426 AdjustWindowRectEx(&window_rect,
\r
427 GetWindowLong(hWnd, GWL_STYLE),
\r
428 (GetMenu(hWnd) != NULL),
\r
429 GetWindowLong(hWnd, GWL_EXSTYLE));
\r
431 if ((window_rect.right - window_rect.left + 1) > desktop_w)
\r
434 area.x = ((desktop_w - area.width ) / 2);
\r
438 if ((window_rect.bottom - window_rect.top + 1) > desktop_h)
\r
441 area.y = ((desktop_h - area.height) / 2);
\r
445 if ((window_rect.left >= (desktop_w-16)) ||
\r
446 (window_rect.top >= (desktop_h-16)) ||
\r
447 (window_rect.right <= 16) ||
\r
448 (window_rect.bottom <= 16))
\r
450 area.x = ((desktop_w - area.width ) / 2);
\r
451 area.y = ((desktop_h - area.height) / 2);
\r
458 // Save window and client areas for restoration if maximize button pressed
\r
461 original_window_rect = window_rect;
\r
462 original_area = area;
\r
465 // Set window size and position
\r
468 SetWindowPos(hWnd,
\r
472 window_rect.right - window_rect.left + 1,
\r
473 window_rect.bottom - window_rect.top + 1,
\r
474 SWP_NOCOPYBITS | SWP_NOZORDER);
\r
476 GetClientRect(hWnd,
\r
479 SAL_debug_printf("SAL: Window at (%d,%d), client size = (%d,%d)\n",
\r
483 client_rect.bottom);
\r
486 // Make window visible
\r
489 ShowWindow(hWnd, SW_SHOWNORMAL);
\r
492 // If mouse is constrained, limit its travel to the window area
\r
497 if (constrain_state)
\r
499 constrain_request = 1;
\r
503 // Init DIB globals
\r
507 lpDIBBuffer = NULL;
\r
510 pbmih->biSize = sizeof(BITMAPINFOHEADER);
\r
511 pbmih->biWidth = (display_size_X);
\r
512 pbmih->biHeight = -(display_size_Y);
\r
513 pbmih->biPlanes = 1;
\r
514 pbmih->biBitCount = (U16) display_bpp;
\r
515 pbmih->biSizeImage = 0;
\r
516 pbmih->biXPelsPerMeter = 0;
\r
517 pbmih->biYPelsPerMeter = 0;
\r
518 pbmih->biClrUsed = 0;
\r
519 pbmih->biClrImportant = 0;
\r
522 // Get Windows desktop display format (and masks, in high-color modes)
\r
527 desktop_bpp = GetDeviceCaps(hdc, BITSPIXEL) *
\r
528 GetDeviceCaps(hdc, PLANES);
\r
530 SAL_debug_printf("SAL: Desktop = %dx%d, %d BPP\n",desktop_w,
\r
534 if(desktop_bpp > 8)
\r
537 BITMAPINFO TempInfo;
\r
538 OSVERSIONINFO WinVer;
\r
540 memset(&WinVer, 0, sizeof(OSVERSIONINFO));
\r
541 WinVer.dwOSVersionInfoSize =sizeof(OSVERSIONINFO);
\r
543 GetVersionEx(&WinVer);
\r
544 if(WinVer.dwPlatformId == VER_PLATFORM_WIN32_NT)
\r
546 TempBmp =CreateCompatibleBitmap(hdc, 8, 8);
\r
549 memset(&TempInfo, 0, sizeof(BITMAPINFO));
\r
550 TempInfo.bmiHeader.biSize =sizeof(BITMAPINFO);
\r
551 TempInfo.bmiHeader.biBitCount =(U16)desktop_bpp;
\r
552 TempInfo.bmiHeader.biCompression =BI_BITFIELDS;
\r
554 if(GetDIBits(hdc, TempBmp, 0, 0, NULL, &TempInfo, DIB_RGB_COLORS))
\r
556 desktop_R_bitmask =*((U32 *)&TempInfo.bmiColors[0]);
\r
557 desktop_G_bitmask =*((U32 *)&TempInfo.bmiColors[1]);
\r
558 desktop_B_bitmask =*((U32 *)&TempInfo.bmiColors[2]);
\r
560 SAL_debug_printf("(%x-%x-%x)\n", desktop_R_bitmask, desktop_G_bitmask, desktop_B_bitmask);
\r
562 DeleteObject(TempBmp);
\r
567 save = GetPixel(hdc,0,0);
\r
569 SetPixel(hdc,0,0,RGB(0x08,0x08,0x08));
\r
571 color = GetPixel(hdc,0,0) & 0xffffff;
\r
573 SAL_debug_printf("SAL: Desktop pixel format = 0x%X ",color);
\r
578 // 0x000000 = 5-5-5
\r
583 SAL_debug_printf("(5-5-5)\n");
\r
585 desktop_R_bitmask = 0x007c00;
\r
586 desktop_G_bitmask = 0x0003e0;
\r
587 desktop_B_bitmask = 0x00001f;
\r
591 // 0x000800 = 5-6-5
\r
596 SAL_debug_printf("(5-6-5)\n");
\r
598 desktop_R_bitmask = 0x00f800;
\r
599 desktop_G_bitmask = 0x0007e0;
\r
600 desktop_B_bitmask = 0x00001f;
\r
604 // 0x080808 = 8-8-8
\r
609 SAL_debug_printf("(8-8-8)\n");
\r
611 desktop_R_bitmask = 0xff0000;
\r
612 desktop_G_bitmask = 0x00ff00;
\r
613 desktop_B_bitmask = 0x0000ff;
\r
618 SAL_debug_printf("(Unsupported, using 5-6-5)\n");
\r
620 if ((desktop_bpp == 15) || (desktop_bpp == 16))
\r
622 desktop_R_bitmask = 0x00f800;
\r
623 desktop_G_bitmask = 0x0007e0;
\r
624 desktop_B_bitmask = 0x00001f;
\r
629 SetPixel(hdc,0,0,save);
\r
632 ReleaseDC(hWnd, hdc);
\r
635 // If DIB and desktop are both in 15/16-BPP mode, set DIB to desktop
\r
636 // pixel format for maximum throughput
\r
638 // Otherwise, set DIB to 5-6-5 mode if 16BPP DIB requested, or 8-8-8 mode
\r
639 // if 24BPP DIB requested
\r
641 // Finally, if 8BPP DIB requested, create GDI palette object based on
\r
642 // current logical palette
\r
645 switch (display_bpp)
\r
649 pbmih->biCompression = BI_RGB;
\r
651 hPalette = CreatePalette(pLogPal);
\r
652 palette_change_request = TRUE;
\r
657 pbmih->biCompression = BI_BITFIELDS;
\r
659 if ((desktop_bpp == 15) || (desktop_bpp == 16))
\r
661 *(U32 *) (&(pbmi->bmiColors[0])) = desktop_R_bitmask;
\r
662 *(U32 *) (&(pbmi->bmiColors[1])) = desktop_G_bitmask;
\r
663 *(U32 *) (&(pbmi->bmiColors[2])) = desktop_B_bitmask;
\r
664 DIB_R_bitmask = desktop_R_bitmask;
\r
665 DIB_G_bitmask = desktop_G_bitmask;
\r
666 DIB_B_bitmask = desktop_B_bitmask;
\r
671 *(U32 *) (&(pbmi->bmiColors[0])) = 0x00f800;
\r
672 *(U32 *) (&(pbmi->bmiColors[1])) = 0x0007e0;
\r
673 *(U32 *) (&(pbmi->bmiColors[2])) = 0x00001f;
\r
674 DIB_R_bitmask = 0x00f800;
\r
675 DIB_G_bitmask = 0x0007e0;
\r
676 DIB_B_bitmask = 0x00001f;
\r
682 pbmih->biCompression = BI_BITFIELDS;
\r
684 *(U32 *) (&(pbmi->bmiColors[0])) = 0xff0000;
\r
685 *(U32 *) (&(pbmi->bmiColors[1])) = 0x00ff00;
\r
686 *(U32 *) (&(pbmi->bmiColors[2])) = 0x0000ff;
\r
687 DIB_R_bitmask = 0xff0000;
\r
688 DIB_G_bitmask = 0x00ff00;
\r
689 DIB_B_bitmask = 0x0000ff;
\r
694 // Allocate the DIB section ("back buffer")
\r
699 hDIB = CreateDIBSection(hdc, // Device context
\r
700 pbmi, // BITMAPINFO structure
\r
701 DIB_RGB_COLORS, // Color data type
\r
702 (void **) &lpDIBBuffer, // Address of image map pointer
\r
704 0); // Bitmap file offset
\r
706 ReleaseDC(hWnd, hdc);
\r
710 SAL_error_box(NULL,"CreateDIBSection() failed\n");
\r
716 // Set global flag to indicate CreateDIBSection() is active
\r
724 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
726 //ÛÛ Copy current contents of DIB buffer to output window ÛÛ
\r
728 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
730 void DIB_refresh_surface(void)
\r
737 // Select palette if desktop running in 8-bit mode
\r
739 // If palette has changed, realize it
\r
742 if (desktop_bpp == 8)
\r
744 SelectPalette(hdc,
\r
748 if (palette_change_request)
\r
750 palette_change_request = 0;
\r
751 RealizePalette(hdc);
\r
756 // Disable Boolean operations during stretching
\r
759 SetStretchBltMode(hdc, COLORONCOLOR);
\r
762 // Stretch bitmap to conform to the size of the output window
\r
765 StretchDIBits(hdc, // Destination DC
\r
766 0, // Destination X
\r
767 0, // Destination Y
\r
768 area.width, // Destination (client area) width
\r
769 area.height, // Destination (client area) height
\r
772 current_size_X, // Source (back buffer) width
\r
773 current_size_Y, // Source (back buffer) height
\r
774 lpDIBBuffer, // Pointer to source (back buffer)
\r
775 pbmi, // Bitmap info for back buffer
\r
776 DIB_RGB_COLORS, // Bitmap contains index values
\r
777 SRCCOPY); // Do normal copy with stretching
\r
779 StretchDIBits(hdc, // Destination DC
\r
780 0, // Destination X
\r
781 0, // Destination Y
\r
782 current_size_X, // Destination (client area) width
\r
783 current_size_Y, // Destination (client area) height
\r
786 current_size_X, // Source (back buffer) width
\r
787 current_size_Y, // Source (back buffer) height
\r
788 lpDIBBuffer, // Pointer to source (back buffer)
\r
789 pbmi, // Bitmap info for back buffer
\r
790 DIB_RGB_COLORS, // Bitmap contains index values
\r
791 SRCCOPY); // Do normal copy with stretching
\r
793 ReleaseDC(hWnd, hdc);
\r
796 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
798 //ÛÛ Flip CreateDIBSection() surface (simulated by StretchDIB()) ÛÛ
\r
800 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
802 void DIB_flip_surface(void)
\r
808 if (!SAL_is_app_active())
\r
814 DIB_refresh_surface();
\r
820 DXDEF void WINAPI SAL_blit_surface(void)
\r
822 DIB_flip_surface();
\r
824 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
826 //ÛÛ Wipe CreateDIBSection() surface ÛÛ
\r
828 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
830 void DIB_wipe_surface (S32 surface,//)
\r
833 memset(lpDIBBuffer,
\r
835 current_size_X * current_size_Y * (current_bpp / 8));
\r
838 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
840 //ÛÛ Return pointer to CreateDIBSection() surface ÛÛ
\r
842 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
844 void DIB_lock_surface (S32 surface,//)
\r
850 *ptr = lpDIBBuffer;
\r
855 *pitch = current_size_X * (current_bpp / 8);
\r
859 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
861 //ÛÛ Release pointer to CreateDIBSection() surface ÛÛ
\r
863 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
865 void DIB_release_surface (S32 surface,//)
\r
870 SAL_flip_surface();
\r
874 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
876 //ÛÛ Start up SAL services ÛÛ
\r
878 //ÛÛ Initialize preferences ÛÛ
\r
880 //ÛÛ Non-zero: Success ÛÛ
\r
882 //ÛÛ -1: Attempt to launch multiple instances ÛÛ
\r
884 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
886 DXDEF S32 WINAPI SAL_startup(BOOL FileLog)
\r
888 log_to_file = FileLog;
\r
889 strcpy(debug_log_filename, "debug.txt");
\r
891 app_active = FALSE; // App not activated yet
\r
892 app_terminated = FALSE; // App not terminated yet
\r
893 app_minimized = FALSE; // App not minimized by default
\r
895 show_count = 0; // Mouse cursor show count
\r
896 cursor_state = 1; // (Windows cursor is on by default)
\r
897 constrain_state = 0; // Mouse is not constrained to window
\r
898 constrain_request = 0; // Mouse should not be constrained at next movement
\r
902 focus_callback = NULL;
\r
903 window_callback = NULL;
\r
906 mode_change_request = FALSE;
\r
909 DIB_active = FALSE;
\r
911 mode_change_allowed = FALSE;
\r
912 current_window_mode = SAL_FULLSCREEN;
\r
914 current_size_X = 0;
\r
915 current_size_Y = 0;
\r
917 palette_change_request = FALSE;
\r
920 // Get original mouse constraint area (normally entire screen)
\r
922 #ifndef DISABLED_BEHAVIOR
\r
923 GetClipCursor(&unconstrained_rect);
\r
926 // Allocate palette and bitmap structures at startup time to avoid
\r
927 // memory fragmentation during mode switches
\r
929 // Clear palette structure to black to avoid screen flash when
\r
930 // setting initial mode
\r
933 pLogPal = (LOGPALETTE *)
\r
934 malloc (sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256));
\r
936 if (pLogPal == NULL)
\r
941 memset(pLogPal,0, sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256));
\r
943 pLogPal->palVersion = 0x300;
\r
944 pLogPal->palNumEntries = 256;
\r
946 pbmi = (BITMAPINFO *)
\r
947 malloc(sizeof (BITMAPINFOHEADER) + (sizeof (RGBQUAD) * 256));
\r
955 memset(pbmi, 0, sizeof (BITMAPINFOHEADER) + (sizeof (RGBQUAD) * 256));
\r
957 pbmih = &(pbmi->bmiHeader);
\r
962 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
964 //ÛÛ System Abstraction Layer exit function ÛÛ
\r
966 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
968 DXDEF void WINAPI SAL_shutdown(void)
\r
970 // if (OldWindowProc)
\r
972 // SetWindowLong( hWnd, GWL_WNDPROC, (LONG)OldWindowProc);
\r
973 // OldWindowProc = NULL;
\r
987 if (pLogPal != NULL)
\r
994 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
996 //ÛÛ Set SAL operational preferences and policies ÛÛ
\r
998 //ÛÛ May be called by applications which need to alter the default ÛÛ
\r
999 //ÛÛ behavior of the SAL system ÛÛ
\r
1001 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1003 DXDEF S32 WINAPI SAL_set_preference(U32 number, S32 value)
\r
1007 old = SAL_preference[number];
\r
1009 SAL_preference[number] = value;
\r
1014 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1016 //ÛÛ Get SAL operational preferences and policies ÛÛ
\r
1018 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1020 DXDEF S32 WINAPI SAL_get_preference(U32 number)
\r
1022 return SAL_preference[number];
\r
1025 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1027 //ÛÛ Monochrome debug printf() function ÛÛ
\r
1029 //ÛÛ Text written to logfile if WIN.INI / DOS environment option enabled ÛÛ
\r
1031 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1033 DXDEF void __cdecl SAL_debug_printf(char *fmt, ...)
\r
1035 static char work_string[4096];
\r
1038 if ((fmt == NULL) || (strlen(fmt) > sizeof(work_string)))
\r
1040 strcpy(work_string, "(String missing or too large)");
\r
1049 vsprintf(work_string,
\r
1058 log = fopen(debug_log_filename,"a+t");
\r
1062 fprintf(log,"%s\n",work_string);
\r
1067 OutputDebugString(work_string);
\r
1070 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1072 //ÛÛ Message box display function ÛÛ
\r
1074 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1076 DXDEF void __cdecl SAL_error_box(C8 *caption, C8 *fmt, ...)
\r
1078 static char work_string[4096];
\r
1079 S32 restore_cursor;
\r
1081 restore_cursor = cursor_state;
\r
1083 if (!cursor_state)
\r
1085 #ifndef DISABLED_BEHAVIOR
\r
1090 if ((fmt == NULL) || (strlen(fmt) > sizeof(work_string)))
\r
1092 strcpy(work_string, "(String missing or too large)");
\r
1101 vsprintf(work_string,
\r
1108 SAL_debug_printf("%s\n",work_string);
\r
1111 // If DirectDraw active, display GDI surface for dialog box
\r
1115 // If in 8-bpp mode, save current palette and switch to standard palette
\r
1118 if (caption == NULL)
\r
1133 if (!restore_cursor)
\r
1135 #ifndef DISABLED_BEHAVIOR
\r
1141 DXDEF BOOL WINAPI SAL_set_main_window(HWND hWindow)
\r
1145 app_active = TRUE;
\r
1147 // OldWindowProc = (WNDPROC)SetWindowLong( hWnd, GWL_WNDPROC, (LONG)MyWndProc);
\r
1149 // if (!OldWindowProc)
\r
1154 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1156 //ÛÛ Set display mode and window size ÛÛ
\r
1158 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1160 DXDEF S32 WINAPI SAL_set_display_mode (S32 display_size_X,//)
\r
1161 S32 display_size_Y,
\r
1163 S32 initial_window_mode,
\r
1164 S32 allow_mode_switch)
\r
1169 // Shut down current video mode
\r
1178 // Hide or show mouse cursor, as appropriate
\r
1181 if (show_count < 1)
\r
1184 // Hide mouse cursor if it's currently visible
\r
1190 #ifndef DISABLED_BEHAVIOR
\r
1199 // Show mouse cursor if it's currently hidden
\r
1202 if (!cursor_state)
\r
1205 #ifndef DISABLED_BEHAVIOR
\r
1212 // Start up new video mode
\r
1215 if (initial_window_mode == SAL_FULLSCREEN)
\r
1218 // SAL_FULLSCREEN: Set up fullscreen video mode using DirectDraw
\r
1222 else if (initial_window_mode == SAL_WINDOW)
\r
1225 // SAL_WINDOW: Set up window using CreateDIBSection()
\r
1228 result = DIB_startup(display_size_X,
\r
1232 else if (initial_window_mode == SAL_TRY_FULLSCREEN)
\r
1237 // SAL_TRY_FULLSCREEN: Use DirectDraw if possible/available, otherwise
\r
1238 // fall back automatically to CreateDIBSection()
\r
1245 // Unknown window mode, return failure
\r
1252 // If successful, update global variables to reflect new video mode
\r
1257 mode_change_allowed = allow_mode_switch;
\r
1258 current_window_mode = initial_window_mode;
\r
1259 current_bpp = display_bpp;
\r
1260 current_size_X = display_size_X;
\r
1261 current_size_Y = display_size_Y;
\r
1267 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1269 //ÛÛ Return current window mode ÛÛ
\r
1271 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1273 DXDEF S32 WINAPI SAL_window_status (void)
\r
1275 return current_window_mode;
\r
1278 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1280 //ÛÛ Return area of client window in screen coordinates ÛÛ
\r
1282 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1284 DXDEF void WINAPI SAL_client_area (SAL_WINAREA *area)
\r
1290 rect = client_screen_rect();
\r
1292 area->x = rect->left;
\r
1293 area->y = rect->top;
\r
1294 area->width = rect->right - rect->left + 1;
\r
1295 area->height = rect->bottom - rect->top + 1;
\r
1300 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1302 //ÛÛ Return area of entire window in screen coordinates ÛÛ
\r
1304 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1306 DXDEF void WINAPI SAL_window_area (SAL_WINAREA *area)
\r
1312 GetWindowRect(hWnd, &window_rect);
\r
1314 area->x = window_rect.left;
\r
1315 area->y = window_rect.top;
\r
1316 area->width = window_rect.right - window_rect.left + 1;
\r
1317 area->height = window_rect.bottom - window_rect.top + 1;
\r
1322 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1324 //ÛÛ Return TRUE if app has input focus ÛÛ
\r
1326 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1328 DXDEF S32 WINAPI SAL_is_app_active (void)
\r
1330 return app_active;
\r
1333 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1335 //ÛÛ Register app function to be called when focus gained or lost ÛÛ
\r
1337 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1339 DXDEF SALFOCUSCB WINAPI SAL_register_focus_callback (SALFOCUSCB fn)
\r
1343 old = focus_callback;
\r
1345 focus_callback = fn;
\r
1350 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1352 //ÛÛ Register application WNDPROC function ÛÛ
\r
1354 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1356 DXDEF WNDPROC WINAPI SAL_register_WNDPROC (WNDPROC fn)
\r
1360 old = window_callback;
\r
1362 window_callback = fn;
\r
1367 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1369 //ÛÛ Service Windows message queue, handling any mode change request ÛÛ
\r
1371 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1373 DXDEF void WINAPI SAL_serve_message_queue(void)
\r
1379 if (mode_change_request && mode_change_allowed)
\r
1381 mode_change_request = 0;
\r
1383 result = SAL_set_display_mode(
\r
1387 current_window_mode ^ (SAL_FULLSCREEN ^ SAL_WINDOW),
\r
1391 // If window mode toggle did not succeed, restore original mode
\r
1396 SAL_debug_printf("SAL: SAL_set_display_mode() failed, restoring old mode\n");
\r
1398 SAL_set_display_mode(
\r
1402 current_window_mode,
\r
1408 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1410 //ÛÛ Set a single palette entry ÛÛ
\r
1412 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1414 DXDEF void WINAPI SAL_set_palette_entry (S32 index,//)
\r
1419 // If we're not in 8BPP mode, bail out
\r
1422 if (current_bpp != 8)
\r
1428 // Update global palette state
\r
1431 palette_state[index] = *entry;
\r
1433 pLogPal->palPalEntry[index].peRed = pbmi->bmiColors[index].rgbRed = (unsigned char) entry->r;
\r
1434 pLogPal->palPalEntry[index].peGreen = pbmi->bmiColors[index].rgbGreen = (unsigned char) entry->g;
\r
1435 pLogPal->palPalEntry[index].peBlue = pbmi->bmiColors[index].rgbBlue = (unsigned char) entry->b;
\r
1436 pLogPal->palPalEntry[index].peFlags = NULL;
\r
1439 // Update DirectDraw palette, if appropriate
\r
1445 if (hPalette != NULL)
\r
1447 DeleteObject(hPalette);
\r
1450 hPalette = CreatePalette(pLogPal);
\r
1452 palette_change_request = TRUE;
\r
1456 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1458 //ÛÛ Retrieve a single palette entry ÛÛ
\r
1460 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1462 DXDEF void WINAPI SAL_get_palette_entry (S32 index,//)
\r
1465 *entry = palette_state[index];
\r
1468 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1470 //ÛÛ Set a range of palette entries ÛÛ
\r
1472 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1474 DXDEF void WINAPI SAL_set_palette_range (S32 index,//)
\r
1476 SAL_RGB32 *entry_list,
\r
1483 // If we're not in 8BPP mode, bail out
\r
1486 if (current_bpp != 8)
\r
1492 // Update global palette state
\r
1495 for (i=0; i < num_entries; i++)
\r
1497 palette_state[index+i] = entry_list[i];
\r
1500 for (i=0, j=index; i < num_entries; i++, j++)
\r
1502 pLogPal->palPalEntry[j].peRed = pbmi->bmiColors[j].rgbRed = (unsigned char) entry_list[i].r;
\r
1503 pLogPal->palPalEntry[j].peGreen = pbmi->bmiColors[j].rgbGreen = (unsigned char) entry_list[i].g;
\r
1504 pLogPal->palPalEntry[j].peBlue = pbmi->bmiColors[j].rgbBlue = (unsigned char) entry_list[i].b;
\r
1505 pLogPal->palPalEntry[j].peFlags = NULL;
\r
1509 // Update DirectDraw palette, if appropriate
\r
1515 if (hPalette != NULL)
\r
1517 DeleteObject(hPalette);
\r
1520 hPalette = CreatePalette(pLogPal);
\r
1522 palette_change_request = TRUE;
\r
1526 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1528 //ÛÛ Retrieve a range of palette entries ÛÛ
\r
1530 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1532 DXDEF void WINAPI SAL_get_palette_range (S32 index,//)
\r
1534 SAL_RGB32 *entry_list)
\r
1536 for (int i=0; i < num_entries; i++)
\r
1538 entry_list[i] = palette_state[index+i];
\r
1542 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1544 //ÛÛ Make back surface visible ÛÛ
\r
1546 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1548 DXDEF void WINAPI SAL_flip_surface (void)
\r
1552 DIB_flip_surface();
\r
1556 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1558 //ÛÛ Clear a surface to a desired color ÛÛ
\r
1560 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1562 DXDEF void WINAPI SAL_wipe_surface (S32 surface,//)
\r
1567 DIB_wipe_surface(surface, color);
\r
1571 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1573 //ÛÛ Request a pointer to a surface's memory block ÛÛ
\r
1575 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1577 DXDEF void WINAPI SAL_lock_surface (S32 surface,//)
\r
1583 DIB_lock_surface(surface, ptr, pitch);
\r
1587 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1589 //ÛÛ Release surface memory pointer, optionally performing page flip ÛÛ
\r
1591 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1593 DXDEF void WINAPI SAL_release_surface (S32 surface,//)
\r
1598 DIB_release_surface(surface, perform_flip);
\r
1602 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1604 //ÛÛ Request a pointer to a region of surface memory ÛÛ
\r
1606 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1608 DXDEF void WINAPI SAL_lock_region (S32 surface,//)
\r
1609 SAL_REGION region,
\r
1616 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1618 //ÛÛ Release surface region pointer ÛÛ
\r
1620 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1622 DXDEF void WINAPI SAL_release_region (S32 surface,//)
\r
1623 SAL_REGION region)
\r
1627 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1629 //ÛÛ Show system mouse cursor ÛÛ
\r
1631 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1633 DXDEF void WINAPI SAL_show_system_mouse (void)
\r
1637 if (show_count == 1)
\r
1640 // Show count has become 1, so show mouse cursor if it's currently
\r
1644 if (!cursor_state)
\r
1647 #ifndef DISABLED_BEHAVIOR
\r
1654 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1656 //ÛÛ Hide system mouse cursor ÛÛ
\r
1658 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1660 DXDEF void WINAPI SAL_hide_system_mouse (void)
\r
1664 if (show_count == 0)
\r
1667 // Show count has become 0, so hide mouse cursor if it's currently
\r
1674 #ifndef DISABLED_BEHAVIOR
\r
1681 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1683 //ÛÛ Constrain mouse to limits of client area window in DIB mode ÛÛ
\r
1685 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1687 DXDEF void WINAPI SAL_constrain_mouse(void)
\r
1689 constrain_state = 1;
\r
1693 constrain_request = 1;
\r
1697 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1699 //ÛÛ Unconstrain mouse ÛÛ
\r
1701 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1703 DXDEF void WINAPI SAL_unconstrain_mouse(void)
\r
1705 constrain_state = 0;
\r
1709 #ifndef DISABLED_BEHAVIOR
\r
1710 ClipCursor(&unconstrained_rect);
\r
1712 constrain_request = 0;
\r
1716 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1718 //ÛÛ Get pixel format in current mode ÛÛ
\r
1720 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
\r
1722 DXDEF void WINAPI SAL_get_pixel_format(S32 *pixel_pitch, //)
\r
1723 S32 *bytes_per_pixel,
\r
1747 // Handle palettized (8 BPP) modes
\r
1749 // Write 8-bit pixel pitch and visible bytes/pixel fields
\r
1750 // If we're in 8BPP mode, exit without altering RGB fields
\r
1753 if (current_bpp == 8)
\r
1755 if (pixel_pitch != NULL) *pixel_pitch = 1;
\r
1756 if (bytes_per_pixel != NULL) *bytes_per_pixel = 1;
\r
1762 // Handle hi-color (16+ BPP) modes
\r
1764 // If using DirectDraw, do a GetPixelFormat() call
\r
1766 // If using CreateDIBSection(), return mask values used to create DIB
\r
1771 if (pixel_pitch != NULL) *pixel_pitch = (current_bpp / 8);
\r
1772 if (bytes_per_pixel != NULL) *bytes_per_pixel = (current_bpp / 8);
\r
1774 red_mask = DIB_R_bitmask;
\r
1775 grn_mask = DIB_G_bitmask;
\r
1776 blu_mask = DIB_B_bitmask;
\r
1780 // Derive shift, width values from masks
\r
1783 for (i=31; i >= 0; i--)
\r
1785 if (red_mask & (1 << i))
\r
1790 if (grn_mask & (1 << i))
\r
1795 if (blu_mask & (1 << i))
\r
1801 for (i=0; i <= 31; i++)
\r
1803 if (red_mask & (1 << i))
\r
1805 red_width = i - red_shift + 1;
\r
1808 if (grn_mask & (1 << i))
\r
1810 grn_width = i - grn_shift + 1;
\r
1813 if (blu_mask & (1 << i))
\r
1815 blu_width = i - blu_shift + 1;
\r
1819 // Pass all requested values back to the caller
\r
1822 if (R_shift != NULL) *R_shift = red_shift;
\r
1823 if (G_shift != NULL) *G_shift = grn_shift;
\r
1824 if (B_shift != NULL) *B_shift = blu_shift;
\r
1826 if (R_mask != NULL) *R_mask = red_mask;
\r
1827 if (G_mask != NULL) *G_mask = grn_mask;
\r
1828 if (B_mask != NULL) *B_mask = blu_mask;
\r
1830 if (R_width != NULL) *R_width = red_width;
\r
1831 if (G_width != NULL) *G_width = grn_width;
\r
1832 if (B_width != NULL) *B_width = blu_width;
\r
1835 DXDEF HBITMAP WINAPI GetDIBHandle(void)
\r
1840 DXDEF void WINAPI SAL_GetBackBufferDC(HDC *dc)
\r
1844 *dc = CreateCompatibleDC ( 0 );
\r
1845 DefaultBitmap = SelectBitmap ( *dc, hDIB );
\r
1849 DXDEF void WINAPI SAL_ReleaseBackBufferDC(HDC dc)
\r
1854 SelectBitmap ( dc, DefaultBitmap );
\r
1856 DeleteObject ( DefaultBitmap );
\r