- file renaming and includes done
[genesis3d.git] / G3D / Drivers / SoftDrv / W32SAL.CPP
1 /****************************************************************************************/\r
2 /*  w32sal.cpp                                                                          */\r
3 /*                                                                                      */\r
4 /*  Description:  GDI dib handling code                                                 */\r
5 /*                                                                                      */\r
6 /*                Code fragments contributed by John Miles                              */\r
7 /*                                                                                      */\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
12 /*                                                                                      */\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
17 /*                                                                                      */\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
21 /*                                                                                      */\r
22 /****************************************************************************************/\r
23 \r
24 \r
25 // Mike's notes:\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
34 //\r
35 //\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
41 \r
42 \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
48 #include <Assert.h>\r
49 \r
50 #include "sal.h"\r
51 \r
52 #include <stdio.h>\r
53 #include <dos.h>\r
54 #include <malloc.h>\r
55 #include <direct.h>\r
56 #include <io.h>\r
57 \r
58 \r
59 //#ifdef SAL_USE_D3D\r
60 //      #include "d3dhal.h"\r
61 //#endif\r
62 \r
63 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
64 //ÛÛ                                                                        ÛÛ\r
65 //ÛÛ SAL statics and globals                                                ÛÛ\r
66 //ÛÛ                                                                        ÛÛ\r
67 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
68 \r
69 //\r
70 // Common variables\r
71 //\r
72 \r
73 static  S32        desktop_w;                 // Windows desktop width, height\r
74 static  S32        desktop_h;\r
75 \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
78 \r
79 static  char       debug_log_filename[256];\r
80 static  S32        log_to_file;               // TRUE if user wants debug log\r
81 \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
85 \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
91 \r
92 static  S32        mode_change_request;       // TRUE to toggle window/fullscreen\r
93 \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
99 \r
100 static  S32 SAL_preference[N_SAL_PREFS];      // Preferences array\r
101 \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
107 \r
108 static  LOGPALETTE       *pLogPal;            // LOGPALETTE structure\r
109 static  BITMAPINFO       *pbmi;               // BITMAPINFO structure\r
110 static  BITMAPINFOHEADER *pbmih;              // Pointer to pbmi header\r
111 \r
112 static  SAL_RGB32  palette_state[256];        // Current state of all DAC registers\r
113 \r
114 //\r
115 // CreateDIBSection() (windowed mode) variables and related data\r
116 //\r
117 \r
118 static  SAL_WINAREA area;                     // Location/size of window client area\r
119 \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
124 \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
128 \r
129 static  U32         DIB_R_Shift;\r
130 static  U32         DIB_G_Shift;\r
131 static  U32         DIB_B_Shift;\r
132 \r
133 static  S32         DIB_active;               // CreateDIBSection() active if TRUE\r
134 \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
138 \r
139 static  S32         palette_change_request;   // TRUE to signal palette update\r
140 \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
145 \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
149 \r
150 static  HDC Context;\r
151 static  HBITMAP DefaultBitmap;\r
152 \r
153 extern "C" long FAR PASCAL MyWndProc(HWND   hWindow, UINT   message,   //)\r
154                        WPARAM wParam,  LPARAM lParam);\r
155 \r
156 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
157 //ÛÛ                                                                        ÛÛ\r
158 //ÛÛ DLLMain() function to acquire DLL instance handle, etc.                ÛÛ\r
159 //ÛÛ                                                                        ÛÛ\r
160 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
161 \r
162 BOOL WINAPI DllMain(HINSTANCE hinstDLL,//)\r
163                     DWORD     fdwReason,\r
164                     LPVOID    lpvReserved)\r
165 {\r
166    if (fdwReason == DLL_PROCESS_ATTACH)\r
167       {\r
168       hDLLInstance = hinstDLL;\r
169       }\r
170 \r
171    return TRUE;\r
172 }\r
173 \r
174 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
175 //ÛÛ                                                                        ÛÛ\r
176 //ÛÛ Serve Windows message queue, returning 0 if WM_QUIT message received   ÛÛ\r
177 //ÛÛ                                                                        ÛÛ\r
178 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
179 \r
180 void serve_queue(void)\r
181 {\r
182         /*\r
183         MSG msg;\r
184 \r
185         if (app_terminated)\r
186         {\r
187                 return;\r
188         }\r
189 \r
190         //\r
191         //      Serve message queue\r
192         //\r
193 \r
194         while (PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE))\r
195         {\r
196                 if (!GetMessage(&msg, NULL, 0, 0 ))\r
197                 {\r
198                         app_active     = FALSE;\r
199                         app_terminated = TRUE;\r
200 \r
201                         (exit_callback)();\r
202 \r
203                         //\r
204                         // Return statement should not be reached\r
205                         //\r
206 \r
207                         return;\r
208                 }\r
209 \r
210                 TranslateMessage(&msg); \r
211                 DispatchMessage(&msg);\r
212         }\r
213         */\r
214 }\r
215 \r
216 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
217 //ÛÛ                                                                        ÛÛ\r
218 //ÛÛ Return rectangle containing client-area boundaries in screenspace      ÛÛ\r
219 //ÛÛ                                                                        ÛÛ\r
220 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
221 \r
222 RECT *client_screen_rect(void)\r
223 {\r
224    static RECT  rect;\r
225    POINT        ul,lr;\r
226 \r
227    GetClientRect(hWnd, &rect);\r
228 \r
229    ul.x = rect.left; \r
230    ul.y = rect.top; \r
231    lr.x = rect.right; \r
232    lr.y = rect.bottom; \r
233 \r
234    ClientToScreen(hWnd, &ul); \r
235    ClientToScreen(hWnd, &lr); \r
236 \r
237    SetRect(&rect, ul.x, ul.y, \r
238                   lr.x-1, lr.y-1); \r
239 \r
240    return &rect;\r
241 }\r
242 \r
243 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
244 //ÛÛ                                                                        ÛÛ\r
245 //ÛÛ Mouse/keyboard event management                                        ÛÛ\r
246 //ÛÛ                                                                        ÛÛ\r
247 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
248 \r
249 void MOUSE_event(unsigned long wParam, unsigned long lParam)\r
250 {\r
251 }\r
252 \r
253 void KEYDOWN_event(unsigned long wParam, unsigned long lParam)\r
254 {\r
255 }\r
256 \r
257 void KEYUP_event(unsigned long wParam, unsigned long lParam)\r
258 {\r
259 }\r
260 \r
261 void CHAR_event(unsigned long wParam, unsigned long lParam)\r
262 {\r
263 }\r
264 \r
265 \r
266 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
267 //ÛÛ                                                                        ÛÛ\r
268 //ÛÛ Shut down CreateDIBSection() services                                  ÛÛ\r
269 //ÛÛ                                                                        ÛÛ\r
270 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
271 \r
272 void DIB_shutdown(void)\r
273 {\r
274    if (constrain_state)\r
275       {\r
276       #ifndef DISABLED_BEHAVIOR\r
277                 ClipCursor(&unconstrained_rect);\r
278           #endif\r
279       constrain_request = 0;\r
280       }\r
281 \r
282    if (DIB_active && SAL_is_app_active())\r
283       {\r
284       SAL_wipe_surface(SAL_BACK_SURFACE, 0);\r
285       SAL_flip_surface();\r
286       }\r
287 \r
288    if (hDIB != NULL)\r
289       {\r
290       DeleteObject(hDIB);\r
291       hDIB = NULL;\r
292       }\r
293 \r
294    if (hPalette != NULL)\r
295       {\r
296       DeleteObject(hPalette);\r
297       hPalette = NULL;\r
298       }\r
299                 /*\r
300                 //\r
301                 //      Make sure we restore the old hWnd parms\r
302                 //\r
303                 SetWindowLong(hWnd, \r
304                              GWL_STYLE, \r
305                              OldWindowLong_GWL_STYLE);\r
306                 SetWindowLong(hWnd, \r
307                              GWL_EXSTYLE, \r
308                              OldWindowLong_GWL_EXSTYLE);\r
309                 SetWindowPos(hWnd, \r
310                             HWND_TOP, \r
311                             original_area.x,\r
312                             original_area.y,\r
313                                         original_area.width,\r
314                             original_area.height,\r
315                             SWP_NOCOPYBITS | SWP_NOZORDER);\r
316                 \r
317                 ShowWindow(hWnd, SW_SHOWNORMAL);\r
318                 */\r
319    DIB_active = 0;\r
320 }\r
321 \r
322 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
323 //ÛÛ                                                                        ÛÛ\r
324 //ÛÛ Start up CreateDIBSection() services for windowed display              ÛÛ\r
325 //ÛÛ                                                                        ÛÛ\r
326 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
327 \r
328 S32 DIB_startup(S32   display_size_X,//)\r
329                 S32   display_size_Y,\r
330                 S32   display_bpp)\r
331 {\r
332         HDC      hdc;\r
333         COLORREF color,save;\r
334         RECT     window_rect;\r
335 \r
336         area.x                  = 0;\r
337         area.y                  = 0;\r
338         area.width              = display_size_X;\r
339         area.height             = display_size_Y;\r
340         original_area   = area;\r
341         \r
342         GetWindowRect(hWnd, &window_rect);\r
343         original_window_rect = window_rect;\r
344         \r
345         OldWindowLong_GWL_STYLE = GetWindowLong(hWnd, GWL_STYLE);\r
346         OldWindowLong_GWL_EXSTYLE = GetWindowLong(hWnd, GWL_EXSTYLE);\r
347 \r
348         display_size_X = area.width;\r
349         display_size_Y = area.height;\r
350 \r
351         // Get desktop size\r
352         //\r
353         /*\r
354         desktop_w = GetSystemMetrics(SM_CXSCREEN);\r
355         desktop_h = GetSystemMetrics(SM_CYSCREEN);\r
356 \r
357         //\r
358         // Enable caption menu and user preferences\r
359         //\r
360 \r
361         SetWindowLong(hWnd, \r
362                  GWL_STYLE, \r
363                  GetWindowLong(hWnd, GWL_STYLE) & ~WS_POPUP);\r
364 \r
365         SetWindowLong(hWnd, \r
366                  GWL_STYLE, \r
367                  GetWindowLong(hWnd, GWL_STYLE) | (WS_OVERLAPPED  | \r
368                                                    WS_CAPTION     | \r
369                                                    WS_SYSMENU     | \r
370                                                    WS_MINIMIZEBOX));\r
371 \r
372         if (SAL_get_preference(SAL_ALLOW_WINDOW_RESIZE))\r
373         {\r
374                 SetWindowLong(hWnd, \r
375                     GWL_STYLE, \r
376                     GetWindowLong(hWnd, GWL_STYLE) | WS_THICKFRAME |\r
377                                                      WS_MAXIMIZEBOX);\r
378         }\r
379 \r
380         if (SAL_get_preference(SAL_ALWAYS_ON_TOP))\r
381         {\r
382                 SetWindowLong(hWnd, \r
383                     GWL_EXSTYLE, \r
384                     GetWindowLong(hWnd, GWL_EXSTYLE) | WS_EX_TOPMOST);\r
385         }\r
386         else\r
387         {\r
388                 SetWindowLong(hWnd, \r
389                     GWL_EXSTYLE, \r
390                     GetWindowLong(hWnd, GWL_EXSTYLE) & ~WS_EX_TOPMOST);\r
391         }\r
392 \r
393         //\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
397         //\r
398 \r
399         //if (area.width == -1)\r
400         {\r
401                 area.width  = display_size_X;\r
402                 area.height = display_size_Y;\r
403 \r
404                 area.x = ((desktop_w - area.width ) / 2);\r
405                 area.y = ((desktop_h - area.height) / 2);\r
406         }\r
407 \r
408         //\r
409         // Calculate adjusted position of window\r
410         //\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
413         //\r
414         // If window is offscreen (or almost entirely offscreen), center it\r
415         //\r
416 \r
417         do\r
418         {\r
419                 retry = 0;\r
420 \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
425 \r
426                 AdjustWindowRectEx(&window_rect,\r
427                           GetWindowLong(hWnd, GWL_STYLE),\r
428                          (GetMenu(hWnd) != NULL),\r
429                           GetWindowLong(hWnd, GWL_EXSTYLE));\r
430 \r
431                 if ((window_rect.right - window_rect.left + 1) > desktop_w)\r
432                 {\r
433                         area.width >>= 1;\r
434                         area.x = ((desktop_w - area.width ) / 2);\r
435                         retry = 1;\r
436                 }\r
437 \r
438                 if ((window_rect.bottom - window_rect.top + 1) > desktop_h)\r
439                 {\r
440                         area.height >>= 1;\r
441                         area.y = ((desktop_h - area.height) / 2);\r
442                         retry = 1;\r
443                 }\r
444 \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
449                 {\r
450                         area.x = ((desktop_w - area.width ) / 2);\r
451                         area.y = ((desktop_h - area.height) / 2);\r
452                         retry = 1;\r
453                 }\r
454         }\r
455    while (retry);\r
456 \r
457    //\r
458    // Save window and client areas for restoration if maximize button pressed\r
459    //\r
460 \r
461    original_window_rect = window_rect;\r
462    original_area        = area;\r
463 \r
464    //\r
465    // Set window size and position\r
466    //\r
467 \r
468    SetWindowPos(hWnd, \r
469                 HWND_TOP, \r
470                 window_rect.left,\r
471                 window_rect.top,\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
475 \r
476    GetClientRect(hWnd, \r
477                 &client_rect);\r
478 \r
479    SAL_debug_printf("SAL: Window at (%d,%d), client size = (%d,%d)\n",\r
480       window_rect.left,\r
481       window_rect.top,\r
482       client_rect.right,\r
483       client_rect.bottom);\r
484 \r
485    //\r
486    // Make window visible\r
487    //\r
488 \r
489    ShowWindow(hWnd, SW_SHOWNORMAL);\r
490 \r
491    //\r
492    // If mouse is constrained, limit its travel to the window area\r
493    //\r
494 \r
495    */\r
496 \r
497    if (constrain_state)    \r
498       {\r
499       constrain_request = 1;\r
500       }\r
501 \r
502    //\r
503    // Init DIB globals\r
504    //\r
505 \r
506    hDIB        = NULL;\r
507    lpDIBBuffer = NULL;\r
508    hPalette    = NULL;\r
509 \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
520 \r
521    //\r
522    // Get Windows desktop display format (and masks, in high-color modes)\r
523    //\r
524 \r
525    hdc = GetDC(hWnd);\r
526 \r
527    desktop_bpp = GetDeviceCaps(hdc, BITSPIXEL) * \r
528                  GetDeviceCaps(hdc, PLANES);\r
529 \r
530    SAL_debug_printf("SAL: Desktop = %dx%d, %d BPP\n",desktop_w, \r
531                                                      desktop_h, \r
532                                                      desktop_bpp);\r
533 \r
534    if(desktop_bpp > 8)\r
535    {\r
536            HBITMAP                      TempBmp;\r
537            BITMAPINFO           TempInfo;\r
538            OSVERSIONINFO        WinVer;\r
539 \r
540            memset(&WinVer, 0, sizeof(OSVERSIONINFO));\r
541            WinVer.dwOSVersionInfoSize   =sizeof(OSVERSIONINFO);\r
542 \r
543            GetVersionEx(&WinVer);\r
544            if(WinVer.dwPlatformId == VER_PLATFORM_WIN32_NT)\r
545            {\r
546                    TempBmp      =CreateCompatibleBitmap(hdc, 8, 8);\r
547                    if(TempBmp)\r
548                    {\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
553 \r
554                            if(GetDIBits(hdc, TempBmp, 0, 0, NULL, &TempInfo, DIB_RGB_COLORS))\r
555                            {\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
559 \r
560                                    SAL_debug_printf("(%x-%x-%x)\n", desktop_R_bitmask, desktop_G_bitmask, desktop_B_bitmask);\r
561                            }\r
562                            DeleteObject(TempBmp);\r
563                    }\r
564            }\r
565            else\r
566            {\r
567                    save = GetPixel(hdc,0,0);\r
568 \r
569                   SetPixel(hdc,0,0,RGB(0x08,0x08,0x08));\r
570 \r
571                   color = GetPixel(hdc,0,0) & 0xffffff;\r
572 \r
573                   SAL_debug_printf("SAL: Desktop pixel format = 0x%X ",color);\r
574 \r
575                   switch (color)\r
576                          {\r
577                          //\r
578                          // 0x000000 = 5-5-5\r
579                          //\r
580 \r
581                          case 0x000000:\r
582             \r
583                                 SAL_debug_printf("(5-5-5)\n");\r
584 \r
585                                 desktop_R_bitmask = 0x007c00;\r
586                                 desktop_G_bitmask = 0x0003e0;\r
587                                 desktop_B_bitmask = 0x00001f;\r
588                                 break;\r
589 \r
590                          //\r
591                          // 0x000800 = 5-6-5\r
592                          //\r
593 \r
594                          case 0x000800:\r
595             \r
596                                 SAL_debug_printf("(5-6-5)\n");\r
597 \r
598                                 desktop_R_bitmask = 0x00f800;\r
599                                 desktop_G_bitmask = 0x0007e0;\r
600                                 desktop_B_bitmask = 0x00001f;\r
601                                 break;\r
602 \r
603                          //\r
604                          // 0x080808 = 8-8-8\r
605                          //\r
606 \r
607                          case 0x080808:\r
608 \r
609                                 SAL_debug_printf("(8-8-8)\n");\r
610 \r
611                                 desktop_R_bitmask = 0xff0000;\r
612                                 desktop_G_bitmask = 0x00ff00;\r
613                                 desktop_B_bitmask = 0x0000ff;\r
614                                 break;\r
615 \r
616                          default:\r
617 \r
618                                 SAL_debug_printf("(Unsupported, using 5-6-5)\n");\r
619 \r
620                                 if ((desktop_bpp == 15) || (desktop_bpp == 16))\r
621                                    {\r
622                                    desktop_R_bitmask = 0x00f800;\r
623                                    desktop_G_bitmask = 0x0007e0;\r
624                                    desktop_B_bitmask = 0x00001f;\r
625                                    }\r
626                                 break;\r
627                          }\r
628 \r
629                   SetPixel(hdc,0,0,save);\r
630                   }\r
631    }\r
632    ReleaseDC(hWnd, hdc);\r
633 \r
634    //\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
637    // \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
640    //\r
641    // Finally, if 8BPP DIB requested, create GDI palette object based on \r
642    // current logical palette\r
643    //\r
644 \r
645    switch (display_bpp)\r
646       {\r
647       case 8:\r
648    \r
649          pbmih->biCompression = BI_RGB;\r
650 \r
651          hPalette = CreatePalette(pLogPal);\r
652          palette_change_request = TRUE;\r
653          break;\r
654 \r
655       case 16:\r
656 \r
657          pbmih->biCompression = BI_BITFIELDS;\r
658 \r
659          if ((desktop_bpp == 15) || (desktop_bpp == 16))\r
660             {\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
667 \r
668             }\r
669          else\r
670             {\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
677             }\r
678          break;\r
679 \r
680       case 24:\r
681 \r
682          pbmih->biCompression = BI_BITFIELDS;\r
683 \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
690          break;\r
691       }\r
692 \r
693    //\r
694    // Allocate the DIB section ("back buffer")\r
695    //\r
696 \r
697    hdc = GetDC(hWnd);\r
698 \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
703                            NULL,            // File\r
704                            0);              // Bitmap file offset\r
705 \r
706    ReleaseDC(hWnd, hdc);\r
707    \r
708    if (hDIB == NULL)\r
709       {\r
710       SAL_error_box(NULL,"CreateDIBSection() failed\n");\r
711       DIB_shutdown();\r
712       return FALSE;\r
713       }\r
714    \r
715    //\r
716    // Set global flag to indicate CreateDIBSection() is active\r
717    // \r
718 \r
719    DIB_active = 1;\r
720 \r
721    return TRUE;\r
722 }\r
723 \r
724 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
725 //ÛÛ                                                                        ÛÛ\r
726 //ÛÛ Copy current contents of DIB buffer to output window                   ÛÛ\r
727 //ÛÛ                                                                        ÛÛ\r
728 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
729 \r
730 void DIB_refresh_surface(void)\r
731 {\r
732    HDC hdc;\r
733 \r
734    hdc = GetDC(hWnd);\r
735 \r
736    //\r
737    // Select palette if desktop running in 8-bit mode\r
738    //\r
739    // If palette has changed, realize it\r
740    //\r
741 \r
742    if (desktop_bpp == 8)\r
743       {\r
744       SelectPalette(hdc, \r
745                     hPalette, \r
746                     0);\r
747 \r
748       if (palette_change_request)\r
749          {\r
750          palette_change_request = 0;\r
751          RealizePalette(hdc);\r
752          }\r
753       }\r
754 \r
755    //\r
756    // Disable Boolean operations during stretching\r
757    //\r
758 \r
759    SetStretchBltMode(hdc, COLORONCOLOR);\r
760 \r
761    //\r
762    // Stretch bitmap to conform to the size of the output window\r
763    //\r
764    /*\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
770                  0,              // Source X\r
771                  0,              // Source Y\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
778    */\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
784                  0,              // Source X\r
785                  0,              // Source Y\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
792    \r
793    ReleaseDC(hWnd, hdc);\r
794 }\r
795 \r
796 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
797 //ÛÛ                                                                        ÛÛ\r
798 //ÛÛ Flip CreateDIBSection() surface (simulated by StretchDIB())            ÛÛ\r
799 //ÛÛ                                                                        ÛÛ\r
800 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
801 \r
802 void DIB_flip_surface(void)\r
803 {\r
804         //while (1)\r
805         //{\r
806                 //serve_queue();\r
807 \r
808                 if (!SAL_is_app_active())\r
809                 {\r
810                         Sleep(10);\r
811                 }\r
812                 else\r
813                 {\r
814                         DIB_refresh_surface();\r
815                     //break;\r
816                 }\r
817         //} \r
818 }\r
819 \r
820 DXDEF void WINAPI SAL_blit_surface(void)\r
821 {\r
822         DIB_flip_surface();\r
823 }\r
824 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
825 //ÛÛ                                                                        ÛÛ\r
826 //ÛÛ Wipe CreateDIBSection() surface                                        ÛÛ\r
827 //ÛÛ                                                                        ÛÛ\r
828 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
829 \r
830 void DIB_wipe_surface           (S32        surface,//)\r
831                                  U32        color)\r
832 {\r
833    memset(lpDIBBuffer,\r
834           color,\r
835           current_size_X * current_size_Y * (current_bpp / 8));\r
836 }\r
837 \r
838 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
839 //ÛÛ                                                                        ÛÛ\r
840 //ÛÛ Return pointer to CreateDIBSection() surface                           ÛÛ\r
841 //ÛÛ                                                                        ÛÛ\r
842 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
843 \r
844 void DIB_lock_surface         (S32        surface,//)\r
845                                U8       **ptr,\r
846                                S32       *pitch)\r
847 {\r
848    if (ptr != NULL)\r
849       {\r
850       *ptr = lpDIBBuffer;\r
851       }\r
852 \r
853    if (pitch != NULL)\r
854       {\r
855       *pitch = current_size_X * (current_bpp / 8);\r
856       }\r
857 }\r
858 \r
859 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
860 //ÛÛ                                                                        ÛÛ\r
861 //ÛÛ Release pointer to CreateDIBSection() surface                          ÛÛ\r
862 //ÛÛ                                                                        ÛÛ\r
863 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
864 \r
865 void DIB_release_surface        (S32        surface,//)\r
866                                  S32        perform_flip)\r
867 {\r
868    if (perform_flip)\r
869       {\r
870       SAL_flip_surface();\r
871       }\r
872 }\r
873 \r
874 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
875 //ÛÛ                                                                        ÛÛ\r
876 //ÛÛ Start up SAL services                                                  ÛÛ\r
877 //ÛÛ                                                                        ÛÛ\r
878 //ÛÛ Initialize preferences                                                 ÛÛ\r
879 //ÛÛ                                                                        ÛÛ\r
880 //ÛÛ Non-zero: Success                                                      ÛÛ\r
881 //ÛÛ        0: Failure                                                      ÛÛ\r
882 //ÛÛ       -1: Attempt to launch multiple instances                         ÛÛ\r
883 //ÛÛ                                                                        ÛÛ\r
884 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
885 \r
886 DXDEF S32 WINAPI SAL_startup(BOOL FileLog)\r
887 {\r
888    log_to_file = FileLog;\r
889    strcpy(debug_log_filename, "debug.txt");\r
890 \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
894 \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
899 \r
900    area.width             = -1;\r
901 \r
902    focus_callback         =  NULL;\r
903    window_callback        =  NULL;\r
904    hWnd                   =  NULL;\r
905    hHook                  =  NULL;\r
906    mode_change_request    =  FALSE;\r
907    hSem                   =  NULL;\r
908 \r
909    DIB_active             =  FALSE;\r
910 \r
911    mode_change_allowed    =  FALSE;\r
912    current_window_mode    =  SAL_FULLSCREEN;\r
913    current_bpp            =  0;\r
914    current_size_X         =  0;\r
915    current_size_Y         =  0;\r
916 \r
917    palette_change_request = FALSE;\r
918 \r
919    //\r
920    // Get original mouse constraint area (normally entire screen)\r
921    //\r
922         #ifndef DISABLED_BEHAVIOR\r
923           GetClipCursor(&unconstrained_rect);\r
924         #endif\r
925    //\r
926    // Allocate palette and bitmap structures at startup time to avoid\r
927    // memory fragmentation during mode switches\r
928    //\r
929    // Clear palette structure to black to avoid screen flash when\r
930    // setting initial mode\r
931    //\r
932 \r
933    pLogPal = (LOGPALETTE *) \r
934              malloc (sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256));\r
935 \r
936    if (pLogPal == NULL)\r
937       {\r
938       return 0;\r
939       }\r
940 \r
941    memset(pLogPal,0, sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256));\r
942 \r
943    pLogPal->palVersion    = 0x300;\r
944    pLogPal->palNumEntries = 256;\r
945 \r
946    pbmi = (BITMAPINFO *) \r
947           malloc(sizeof (BITMAPINFOHEADER) + (sizeof (RGBQUAD) * 256));\r
948 \r
949    if (pbmi == NULL)\r
950       {\r
951       free(pLogPal);\r
952       return 0;\r
953       }\r
954  \r
955    memset(pbmi, 0, sizeof (BITMAPINFOHEADER) + (sizeof (RGBQUAD) * 256));\r
956 \r
957    pbmih = &(pbmi->bmiHeader);\r
958 \r
959    return TRUE;\r
960 }\r
961 \r
962 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
963 //ÛÛ                                                                        ÛÛ\r
964 //ÛÛ System Abstraction Layer exit function                                 ÛÛ\r
965 //ÛÛ                                                                        ÛÛ\r
966 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
967 \r
968 DXDEF void WINAPI SAL_shutdown(void)\r
969 {\r
970 //      if (OldWindowProc)\r
971 //      {\r
972 //              SetWindowLong( hWnd, GWL_WNDPROC, (LONG)OldWindowProc);\r
973 //              OldWindowProc = NULL;\r
974 //      }\r
975 \r
976    if (DIB_active)\r
977       {\r
978       DIB_shutdown();\r
979       }\r
980 \r
981    if (pbmi != NULL)\r
982       {\r
983       free(pbmi);\r
984       pbmi = NULL;\r
985       }\r
986 \r
987    if (pLogPal != NULL)\r
988       {\r
989       free(pLogPal);\r
990       pLogPal = NULL;\r
991       }\r
992 }\r
993 \r
994 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
995 //ÛÛ                                                                        ÛÛ\r
996 //ÛÛ Set SAL operational preferences and policies                           ÛÛ\r
997 //ÛÛ                                                                        ÛÛ\r
998 //ÛÛ May be called by applications which need to alter the default          ÛÛ\r
999 //ÛÛ behavior of the SAL system                                             ÛÛ\r
1000 //ÛÛ                                                                        ÛÛ\r
1001 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1002 \r
1003 DXDEF S32 WINAPI SAL_set_preference(U32 number, S32 value)\r
1004 {\r
1005    S32 old;\r
1006 \r
1007    old = SAL_preference[number];\r
1008 \r
1009    SAL_preference[number] = value;\r
1010 \r
1011    return old;\r
1012 }\r
1013 \r
1014 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1015 //ÛÛ                                                                        ÛÛ\r
1016 //ÛÛ Get SAL operational preferences and policies                           ÛÛ\r
1017 //ÛÛ                                                                        ÛÛ\r
1018 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1019 \r
1020 DXDEF S32 WINAPI SAL_get_preference(U32 number)\r
1021 {\r
1022    return SAL_preference[number];\r
1023 }\r
1024 \r
1025 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1026 //ÛÛ                                                                        ÛÛ\r
1027 //ÛÛ Monochrome debug printf() function                                     ÛÛ\r
1028 //ÛÛ                                                                        ÛÛ\r
1029 //ÛÛ Text written to logfile if WIN.INI / DOS environment option enabled    ÛÛ\r
1030 //ÛÛ                                                                        ÛÛ\r
1031 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1032 \r
1033 DXDEF void __cdecl SAL_debug_printf(char *fmt, ...)\r
1034 {\r
1035    static char work_string[4096];\r
1036    FILE       *log;\r
1037 \r
1038    if ((fmt == NULL) || (strlen(fmt) > sizeof(work_string)))\r
1039       {\r
1040       strcpy(work_string, "(String missing or too large)");\r
1041       }\r
1042    else\r
1043       {\r
1044       va_list ap;\r
1045 \r
1046       va_start(ap, \r
1047                fmt);\r
1048 \r
1049       vsprintf(work_string, \r
1050                fmt, \r
1051                ap);\r
1052 \r
1053       va_end  (ap);\r
1054       }\r
1055 \r
1056    if (log_to_file)\r
1057       {\r
1058       log = fopen(debug_log_filename,"a+t");\r
1059       \r
1060       if (log != NULL)\r
1061          {\r
1062          fprintf(log,"%s\n",work_string);\r
1063          fclose(log);\r
1064          }\r
1065       }\r
1066 \r
1067    OutputDebugString(work_string);\r
1068 }\r
1069 \r
1070 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1071 //ÛÛ                                                                        ÛÛ\r
1072 //ÛÛ Message box display function                                           ÛÛ\r
1073 //ÛÛ                                                                        ÛÛ\r
1074 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1075 \r
1076 DXDEF void __cdecl SAL_error_box(C8 *caption, C8 *fmt, ...)\r
1077 {\r
1078    static char work_string[4096];\r
1079    S32         restore_cursor;\r
1080 \r
1081    restore_cursor = cursor_state;\r
1082 \r
1083    if (!cursor_state)\r
1084       {\r
1085                 #ifndef DISABLED_BEHAVIOR\r
1086                         ShowCursor(1);\r
1087                 #endif\r
1088       }\r
1089 \r
1090    if ((fmt == NULL) || (strlen(fmt) > sizeof(work_string)))\r
1091       {\r
1092       strcpy(work_string, "(String missing or too large)");\r
1093       }\r
1094    else\r
1095       {\r
1096       va_list ap;\r
1097 \r
1098       va_start(ap, \r
1099                fmt);\r
1100 \r
1101       vsprintf(work_string, \r
1102                fmt, \r
1103                ap);\r
1104 \r
1105       va_end  (ap);\r
1106       }\r
1107 \r
1108    SAL_debug_printf("%s\n",work_string);\r
1109 \r
1110    //\r
1111    // If DirectDraw active, display GDI surface for dialog box\r
1112    // \r
1113 \r
1114    //\r
1115    // If in 8-bpp mode, save current palette and switch to standard palette\r
1116    // \r
1117 \r
1118    if (caption == NULL)\r
1119       {\r
1120       MessageBox(hWnd, \r
1121                  work_string,\r
1122                  "SAL Error", \r
1123                  MB_OK);\r
1124       }\r
1125    else\r
1126       {\r
1127       MessageBox(hWnd, \r
1128                  work_string,\r
1129                  caption,\r
1130                  MB_OK);\r
1131       }\r
1132 \r
1133    if (!restore_cursor)\r
1134       {\r
1135                 #ifndef DISABLED_BEHAVIOR\r
1136                         ShowCursor(0);\r
1137                 #endif\r
1138       }\r
1139 }\r
1140 \r
1141 DXDEF BOOL WINAPI SAL_set_main_window(HWND hWindow)\r
1142 {\r
1143         hWnd = hWindow;\r
1144 \r
1145         app_active = TRUE;\r
1146 \r
1147 //      OldWindowProc = (WNDPROC)SetWindowLong( hWnd, GWL_WNDPROC, (LONG)MyWndProc);\r
1148 \r
1149 //      if (!OldWindowProc)\r
1150 //              return FALSE;\r
1151 \r
1152         return TRUE;\r
1153 }\r
1154 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1155 //ÛÛ                                                                        ÛÛ\r
1156 //ÛÛ Set display mode and window size                                       ÛÛ\r
1157 //ÛÛ                                                                        ÛÛ\r
1158 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1159 \r
1160 DXDEF S32        WINAPI SAL_set_display_mode        (S32   display_size_X,//)\r
1161                                                      S32   display_size_Y,\r
1162                                                      S32   display_bpp,\r
1163                                                      S32   initial_window_mode,\r
1164                                                      S32   allow_mode_switch)\r
1165 {\r
1166    S32 result;\r
1167 \r
1168    //\r
1169    // Shut down current video mode\r
1170    //\r
1171 \r
1172    if (DIB_active)\r
1173    {\r
1174                   DIB_shutdown();\r
1175    }\r
1176 \r
1177    //\r
1178    // Hide or show mouse cursor, as appropriate\r
1179    //\r
1180 \r
1181    if (show_count < 1)\r
1182       {\r
1183       //\r
1184       // Hide mouse cursor if it's currently visible\r
1185       //\r
1186 \r
1187       if (cursor_state)\r
1188          {\r
1189          cursor_state = 0;\r
1190                         #ifndef DISABLED_BEHAVIOR\r
1191                                 ShowCursor(0);\r
1192                         #endif\r
1193                         \r
1194          }\r
1195       }\r
1196    else\r
1197       {\r
1198       //\r
1199       // Show mouse cursor if it's currently hidden\r
1200       //\r
1201 \r
1202       if (!cursor_state)\r
1203          {\r
1204          cursor_state = 1;\r
1205                         #ifndef DISABLED_BEHAVIOR\r
1206                                 ShowCursor(1);\r
1207                         #endif\r
1208          }\r
1209       }\r
1210 \r
1211    //\r
1212    // Start up new video mode\r
1213    //\r
1214 \r
1215    if (initial_window_mode == SAL_FULLSCREEN)\r
1216       {\r
1217       //\r
1218       // SAL_FULLSCREEN: Set up fullscreen video mode using DirectDraw\r
1219       //\r
1220 \r
1221       }\r
1222    else if (initial_window_mode == SAL_WINDOW)\r
1223       {\r
1224       //\r
1225       // SAL_WINDOW: Set up window using CreateDIBSection()\r
1226       //\r
1227 \r
1228       result = DIB_startup(display_size_X,\r
1229                            display_size_Y,\r
1230                            display_bpp);\r
1231         }\r
1232         else if (initial_window_mode == SAL_TRY_FULLSCREEN)\r
1233         {\r
1234                 assert(0);\r
1235 \r
1236       //\r
1237       // SAL_TRY_FULLSCREEN: Use DirectDraw if possible/available, otherwise\r
1238       //                     fall back automatically to CreateDIBSection()\r
1239       //\r
1240 \r
1241       }\r
1242    else\r
1243       {\r
1244       //\r
1245       // Unknown window mode, return failure\r
1246       //\r
1247 \r
1248       return FALSE;\r
1249       }\r
1250 \r
1251    //\r
1252    // If successful, update global variables to reflect new video mode\r
1253    //\r
1254 \r
1255    if (result)\r
1256       {\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
1262       }\r
1263 \r
1264    return result;\r
1265 }\r
1266 \r
1267 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1268 //ÛÛ                                                                        ÛÛ\r
1269 //ÛÛ Return current window mode                                             ÛÛ\r
1270 //ÛÛ                                                                        ÛÛ\r
1271 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1272 \r
1273 DXDEF S32 WINAPI  SAL_window_status           (void)\r
1274 {\r
1275    return current_window_mode;\r
1276 }\r
1277 \r
1278 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1279 //ÛÛ                                                                        ÛÛ\r
1280 //ÛÛ Return area of client window in screen coordinates                     ÛÛ\r
1281 //ÛÛ                                                                        ÛÛ\r
1282 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1283 \r
1284 DXDEF void WINAPI SAL_client_area             (SAL_WINAREA *area)\r
1285 {\r
1286    RECT *rect;\r
1287 \r
1288    if (DIB_active)\r
1289       {\r
1290       rect = client_screen_rect();\r
1291 \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
1296       }\r
1297 \r
1298 }\r
1299 \r
1300 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1301 //ÛÛ                                                                        ÛÛ\r
1302 //ÛÛ Return area of entire window in screen coordinates                     ÛÛ\r
1303 //ÛÛ                                                                        ÛÛ\r
1304 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1305 \r
1306 DXDEF void WINAPI SAL_window_area             (SAL_WINAREA *area)\r
1307 {\r
1308    RECT window_rect;\r
1309 \r
1310    if (DIB_active)\r
1311       {\r
1312       GetWindowRect(hWnd, &window_rect);\r
1313 \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
1318       }\r
1319 \r
1320 }\r
1321 \r
1322 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1323 //ÛÛ                                                                        ÛÛ\r
1324 //ÛÛ Return TRUE if app has input focus                                     ÛÛ\r
1325 //ÛÛ                                                                        ÛÛ\r
1326 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1327 \r
1328 DXDEF S32 WINAPI  SAL_is_app_active           (void)\r
1329 {\r
1330    return app_active;\r
1331 }\r
1332 \r
1333 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1334 //ÛÛ                                                                        ÛÛ\r
1335 //ÛÛ Register app function to be called when focus gained or lost           ÛÛ\r
1336 //ÛÛ                                                                        ÛÛ\r
1337 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1338 \r
1339 DXDEF SALFOCUSCB WINAPI SAL_register_focus_callback (SALFOCUSCB fn)\r
1340 {\r
1341    SALFOCUSCB old;\r
1342 \r
1343    old = focus_callback;\r
1344 \r
1345    focus_callback = fn;\r
1346 \r
1347    return old;\r
1348 }\r
1349 \r
1350 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1351 //ÛÛ                                                                        ÛÛ\r
1352 //ÛÛ Register application WNDPROC function                                  ÛÛ\r
1353 //ÛÛ                                                                        ÛÛ\r
1354 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1355 \r
1356 DXDEF WNDPROC WINAPI SAL_register_WNDPROC     (WNDPROC fn)\r
1357 {\r
1358    WNDPROC old;\r
1359 \r
1360    old = window_callback;\r
1361 \r
1362    window_callback = fn;\r
1363 \r
1364    return old;\r
1365 }\r
1366 \r
1367 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1368 //ÛÛ                                                                        ÛÛ\r
1369 //ÛÛ Service Windows message queue, handling any mode change request        ÛÛ\r
1370 //ÛÛ                                                                        ÛÛ\r
1371 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1372 \r
1373 DXDEF void WINAPI SAL_serve_message_queue(void)\r
1374 {\r
1375    S32 result;\r
1376 \r
1377    serve_queue();\r
1378 \r
1379    if (mode_change_request && mode_change_allowed)\r
1380       {\r
1381       mode_change_request = 0;   \r
1382 \r
1383       result = SAL_set_display_mode(\r
1384                   current_size_X,\r
1385                   current_size_Y,\r
1386                   current_bpp,\r
1387                   current_window_mode ^ (SAL_FULLSCREEN ^ SAL_WINDOW),\r
1388                   TRUE);\r
1389 \r
1390       //\r
1391       // If window mode toggle did not succeed, restore original mode\r
1392       //\r
1393 \r
1394       if (!result)\r
1395          {\r
1396          SAL_debug_printf("SAL: SAL_set_display_mode() failed, restoring old mode\n");\r
1397 \r
1398          SAL_set_display_mode(\r
1399             current_size_X,\r
1400             current_size_Y,\r
1401             current_bpp,\r
1402             current_window_mode,\r
1403             TRUE);\r
1404          }\r
1405       }\r
1406 }\r
1407 \r
1408 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1409 //ÛÛ                                                                        ÛÛ\r
1410 //ÛÛ Set a single palette entry                                             ÛÛ\r
1411 //ÛÛ                                                                        ÛÛ\r
1412 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1413 \r
1414 DXDEF void WINAPI SAL_set_palette_entry      (S32        index,//)\r
1415                                               SAL_RGB32 *entry,\r
1416                                               S32        wait_flag)\r
1417 {\r
1418    //\r
1419    // If we're not in 8BPP mode, bail out\r
1420    // \r
1421 \r
1422    if (current_bpp != 8)\r
1423       {\r
1424       return;\r
1425       }\r
1426 \r
1427    //\r
1428    // Update global palette state\r
1429    //\r
1430 \r
1431    palette_state[index] = *entry;\r
1432 \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
1437 \r
1438    //\r
1439    // Update DirectDraw palette, if appropriate\r
1440    //\r
1441 \r
1442 \r
1443    if (DIB_active)\r
1444       {\r
1445       if (hPalette != NULL)\r
1446          {\r
1447          DeleteObject(hPalette);\r
1448          }\r
1449 \r
1450       hPalette = CreatePalette(pLogPal);\r
1451 \r
1452       palette_change_request = TRUE;\r
1453       }\r
1454 }\r
1455 \r
1456 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1457 //ÛÛ                                                                        ÛÛ\r
1458 //ÛÛ Retrieve a single palette entry                                        ÛÛ\r
1459 //ÛÛ                                                                        ÛÛ\r
1460 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1461 \r
1462 DXDEF void WINAPI SAL_get_palette_entry      (S32        index,//)\r
1463                                               SAL_RGB32 *entry)\r
1464 {\r
1465    *entry = palette_state[index];\r
1466 }\r
1467 \r
1468 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1469 //ÛÛ                                                                        ÛÛ\r
1470 //ÛÛ Set a range of palette entries                                         ÛÛ\r
1471 //ÛÛ                                                                        ÛÛ\r
1472 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1473 \r
1474 DXDEF void WINAPI SAL_set_palette_range      (S32        index,//)\r
1475                                               S32        num_entries,\r
1476                                               SAL_RGB32 *entry_list,\r
1477                                               S32        wait_flag)\r
1478 {\r
1479    S32 i;\r
1480    S32 j;\r
1481 \r
1482    //\r
1483    // If we're not in 8BPP mode, bail out\r
1484    // \r
1485 \r
1486    if (current_bpp != 8)\r
1487       {\r
1488       return;\r
1489       }\r
1490 \r
1491    //\r
1492    // Update global palette state\r
1493    //\r
1494 \r
1495    for (i=0; i < num_entries; i++)\r
1496       {\r
1497       palette_state[index+i] = entry_list[i];\r
1498       }\r
1499 \r
1500    for (i=0, j=index; i < num_entries; i++, j++)\r
1501       {\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
1506       }\r
1507 \r
1508    //\r
1509    // Update DirectDraw palette, if appropriate\r
1510    //\r
1511 \r
1512 \r
1513    if (DIB_active)\r
1514       {\r
1515       if (hPalette != NULL)\r
1516          {\r
1517          DeleteObject(hPalette);\r
1518          }\r
1519 \r
1520       hPalette = CreatePalette(pLogPal);\r
1521 \r
1522       palette_change_request = TRUE;\r
1523       }\r
1524 }\r
1525                                    \r
1526 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1527 //ÛÛ                                                                        ÛÛ\r
1528 //ÛÛ Retrieve a range of palette entries                                    ÛÛ\r
1529 //ÛÛ                                                                        ÛÛ\r
1530 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1531 \r
1532 DXDEF void WINAPI SAL_get_palette_range      (S32        index,//)\r
1533                                               S32        num_entries,\r
1534                                               SAL_RGB32 *entry_list)\r
1535 {\r
1536    for (int i=0; i < num_entries; i++)\r
1537       {\r
1538       entry_list[i] = palette_state[index+i];\r
1539       }\r
1540 }\r
1541 \r
1542 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1543 //ÛÛ                                                                        ÛÛ\r
1544 //ÛÛ Make back surface visible                                              ÛÛ\r
1545 //ÛÛ                                                                        ÛÛ\r
1546 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1547 \r
1548 DXDEF void WINAPI SAL_flip_surface           (void)\r
1549 {\r
1550         if (DIB_active)\r
1551       {\r
1552       DIB_flip_surface();\r
1553       }\r
1554 }\r
1555 \r
1556 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1557 //ÛÛ                                                                        ÛÛ\r
1558 //ÛÛ Clear a surface to a desired color                                     ÛÛ\r
1559 //ÛÛ                                                                        ÛÛ\r
1560 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1561 \r
1562 DXDEF void WINAPI SAL_wipe_surface           (S32        surface,//)\r
1563                                               U32        color)\r
1564 {\r
1565         if (DIB_active)\r
1566       {\r
1567       DIB_wipe_surface(surface, color);\r
1568       }\r
1569 }\r
1570 \r
1571 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1572 //ÛÛ                                                                        ÛÛ\r
1573 //ÛÛ Request a pointer to a surface's memory block                          ÛÛ\r
1574 //ÛÛ                                                                        ÛÛ\r
1575 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1576 \r
1577 DXDEF void WINAPI SAL_lock_surface           (S32        surface,//)\r
1578                                               U8       **ptr,\r
1579                                               S32       *pitch)\r
1580 {\r
1581         if (DIB_active)\r
1582       {\r
1583       DIB_lock_surface(surface, ptr, pitch);\r
1584       }\r
1585 }\r
1586 \r
1587 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1588 //ÛÛ                                                                        ÛÛ\r
1589 //ÛÛ Release surface memory pointer, optionally performing page flip        ÛÛ\r
1590 //ÛÛ                                                                        ÛÛ\r
1591 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1592 \r
1593 DXDEF void WINAPI SAL_release_surface        (S32        surface,//)\r
1594                                               S32        perform_flip)\r
1595 {\r
1596         if (DIB_active)\r
1597       {\r
1598       DIB_release_surface(surface, perform_flip);\r
1599       }\r
1600 }\r
1601 \r
1602 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1603 //ÛÛ                                                                        ÛÛ\r
1604 //ÛÛ Request a pointer to a region of surface memory                        ÛÛ\r
1605 //ÛÛ                                                                        ÛÛ\r
1606 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1607 \r
1608 DXDEF void WINAPI SAL_lock_region            (S32        surface,//)\r
1609                                               SAL_REGION region,\r
1610                                               U8       **ptr,\r
1611                                               S32       *pitch)\r
1612 {\r
1613 \r
1614 }\r
1615 \r
1616 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1617 //ÛÛ                                                                        ÛÛ\r
1618 //ÛÛ Release surface region pointer                                         ÛÛ\r
1619 //ÛÛ                                                                        ÛÛ\r
1620 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1621 \r
1622 DXDEF void WINAPI SAL_release_region         (S32        surface,//)\r
1623                                               SAL_REGION region)\r
1624 {\r
1625 }\r
1626 \r
1627 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1628 //ÛÛ                                                                        ÛÛ\r
1629 //ÛÛ Show system mouse cursor                                               ÛÛ\r
1630 //ÛÛ                                                                        ÛÛ\r
1631 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1632 \r
1633 DXDEF void WINAPI SAL_show_system_mouse      (void)\r
1634 {\r
1635    ++show_count;\r
1636 \r
1637    if (show_count == 1)\r
1638       {\r
1639       //\r
1640       // Show count has become 1, so show mouse cursor if it's currently \r
1641       // hidden\r
1642       //\r
1643 \r
1644       if (!cursor_state)\r
1645          {\r
1646          cursor_state = 1;\r
1647                         #ifndef DISABLED_BEHAVIOR\r
1648                                 ShowCursor(1);\r
1649                         #endif\r
1650          }\r
1651       }\r
1652 }\r
1653 \r
1654 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1655 //ÛÛ                                                                        ÛÛ\r
1656 //ÛÛ Hide system mouse cursor                                               ÛÛ\r
1657 //ÛÛ                                                                        ÛÛ\r
1658 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1659 \r
1660 DXDEF void WINAPI SAL_hide_system_mouse      (void)\r
1661 {\r
1662    --show_count;\r
1663 \r
1664    if (show_count == 0)\r
1665       {\r
1666       //\r
1667       // Show count has become 0, so hide mouse cursor if it's currently\r
1668       // visible\r
1669       //\r
1670 \r
1671       if (cursor_state)\r
1672          {\r
1673          cursor_state = 0;\r
1674                         #ifndef DISABLED_BEHAVIOR\r
1675                                 ShowCursor(0);\r
1676                         #endif\r
1677          }\r
1678       }\r
1679 }\r
1680 \r
1681 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1682 //ÛÛ                                                                        ÛÛ\r
1683 //ÛÛ Constrain mouse to limits of client area window in DIB mode            ÛÛ\r
1684 //ÛÛ                                                                        ÛÛ\r
1685 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1686 \r
1687 DXDEF void WINAPI SAL_constrain_mouse(void)\r
1688 {\r
1689    constrain_state = 1;\r
1690 \r
1691    if (DIB_active)\r
1692       {\r
1693       constrain_request = 1;\r
1694       }\r
1695 }\r
1696 \r
1697 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1698 //ÛÛ                                                                        ÛÛ\r
1699 //ÛÛ Unconstrain mouse                                                      ÛÛ\r
1700 //ÛÛ                                                                        ÛÛ\r
1701 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1702 \r
1703 DXDEF void WINAPI SAL_unconstrain_mouse(void)\r
1704 {\r
1705    constrain_state = 0;\r
1706 \r
1707    if (DIB_active)\r
1708       {\r
1709       #ifndef DISABLED_BEHAVIOR\r
1710                 ClipCursor(&unconstrained_rect);\r
1711           #endif\r
1712       constrain_request = 0;\r
1713       }\r
1714 }\r
1715 \r
1716 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1717 //ÛÛ                                                                        ÛÛ\r
1718 //ÛÛ Get pixel format in current mode                                       ÛÛ\r
1719 //ÛÛ                                                                        ÛÛ\r
1720 //ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ\r
1721 \r
1722 DXDEF void WINAPI SAL_get_pixel_format(S32 *pixel_pitch, //)\r
1723                                        S32 *bytes_per_pixel,\r
1724                                        S32 *R_shift,\r
1725                                        U32 *R_mask,\r
1726                                        S32 *R_width,\r
1727                                        S32 *G_shift,\r
1728                                        U32 *G_mask,\r
1729                                        S32 *G_width,\r
1730                                        S32 *B_shift,\r
1731                                        U32 *B_mask,\r
1732                                        S32 *B_width)\r
1733 \r
1734 {\r
1735    S32 red_shift;\r
1736    U32 red_mask;\r
1737    S32 red_width;\r
1738    S32 grn_shift;\r
1739    U32 grn_mask;\r
1740    S32 grn_width;\r
1741    S32 blu_shift;\r
1742    U32 blu_mask;\r
1743    S32 blu_width;\r
1744    S32 i;\r
1745 \r
1746    //\r
1747    // Handle palettized (8 BPP) modes\r
1748    //\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
1751    //\r
1752 \r
1753    if (current_bpp == 8)\r
1754       {\r
1755       if (pixel_pitch     != NULL) *pixel_pitch     = 1;\r
1756       if (bytes_per_pixel != NULL) *bytes_per_pixel = 1;\r
1757 \r
1758       return;\r
1759       }\r
1760 \r
1761    //\r
1762    // Handle hi-color (16+ BPP) modes\r
1763    //\r
1764    // If using DirectDraw, do a GetPixelFormat() call\r
1765    // \r
1766    // If using CreateDIBSection(), return mask values used to create DIB\r
1767    // \r
1768 \r
1769    if (DIB_active)\r
1770       {\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
1773 \r
1774       red_mask = DIB_R_bitmask;\r
1775       grn_mask = DIB_G_bitmask;\r
1776       blu_mask = DIB_B_bitmask;\r
1777       }\r
1778 \r
1779    //\r
1780    // Derive shift, width values from masks\r
1781    //\r
1782 \r
1783    for (i=31; i >= 0; i--)\r
1784       {\r
1785       if (red_mask & (1 << i))\r
1786          {\r
1787          red_shift = i;\r
1788          }\r
1789 \r
1790       if (grn_mask & (1 << i))\r
1791          {\r
1792          grn_shift = i;\r
1793          }\r
1794 \r
1795       if (blu_mask & (1 << i))\r
1796          {\r
1797          blu_shift = i;\r
1798          }\r
1799       }\r
1800 \r
1801    for (i=0; i <= 31; i++)\r
1802       {\r
1803       if (red_mask & (1 << i))\r
1804          {\r
1805          red_width = i - red_shift + 1;\r
1806          }\r
1807 \r
1808       if (grn_mask & (1 << i))\r
1809          {\r
1810          grn_width = i - grn_shift + 1;\r
1811          }\r
1812 \r
1813       if (blu_mask & (1 << i))\r
1814          {\r
1815          blu_width = i - blu_shift + 1;\r
1816          }\r
1817       }\r
1818    //\r
1819    // Pass all requested values back to the caller\r
1820    //\r
1821 \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
1825 \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
1829 \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
1833 }\r
1834 \r
1835 DXDEF HBITMAP WINAPI GetDIBHandle(void)\r
1836 {\r
1837    return hDIB;\r
1838 }\r
1839 \r
1840 DXDEF void WINAPI SAL_GetBackBufferDC(HDC *dc)\r
1841 {\r
1842         if (DIB_active) \r
1843         {\r
1844                 *dc = CreateCompatibleDC ( 0 );\r
1845                 DefaultBitmap = SelectBitmap ( *dc, hDIB );\r
1846         }\r
1847 }\r
1848 \r
1849 DXDEF void WINAPI SAL_ReleaseBackBufferDC(HDC dc)\r
1850 {\r
1851 \r
1852         if (DIB_active) \r
1853         {\r
1854                 SelectBitmap ( dc, DefaultBitmap );\r
1855                 DeleteDC ( dc );\r
1856                 DeleteObject ( DefaultBitmap );\r
1857     }\r
1858 }\r