|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * Win32 Drawing and DirectX interface
5: *
6: * Copyright 1997-1998 Mathias Ortmann
7: * Copyright 1997-2000 Brian King
8: */
9:
10: #include "config.h"
11: #include "sysconfig.h"
12:
13: #include <stdlib.h>
14: #include <stdarg.h>
15:
16: #include <signal.h>
17: #include <io.h>
18:
19: #include <windows.h>
20: #include <commctrl.h>
21: #include <stdio.h>
22:
23: #include "sysdeps.h"
24: #include "options.h"
25: #include "gensound.h"
26: #include "uae.h"
27: #include "memory.h"
28: #include "custom.h"
29: #include "events.h"
30: #include "xwin.h"
31: #include "keyboard.h"
32: #include "drawing.h"
33: #include "picasso96.h"
34: #include "osdep/win32.h"
35: #include "osdep/win32gui.h"
36: #include "osdep/win32gfx.h"
37: #include "sounddep/sound.h"
38:
39: /* Local globals */
40: static uae_u32 current_width, current_height, current_depth;
41: static int fullscreen = 0; /* fullscreen mode */
42: static int window_width = 900, window_height = 720, window_depth; /* target resolution */
43: static int usedirect = 0; /* direct to dx surface (fullscreen or overlay) */
1.1.1.2 ! root 44: static int overlay = 1; /* use overlay surface */
1.1 root 45: static int needs_direct; /* is overlay or fullscreen mode required */
46: static int display_change_requested = 0;
47: static int mapping_is_mainscreen = 0;
48: static BOOL bInitDone = FALSE; //?????JGI
49:
50: int screen_is_picasso = 0;
51:
52: static BOOL bJustClosedWithActiveMouse = FALSE;
53:
54: int WIN32GFX_IsPicassoScreen( void )
55: {
56: return screen_is_picasso;
57: }
58:
59: void WIN32GFX_DisablePicasso( void )
60: {
61: picasso_requested_on = 0;
62: picasso_on = 0;
63: }
64:
65: void WIN32GFX_EnablePicasso( void )
66: {
67: picasso_requested_on = 1;
68: }
69:
70: void WIN32GFX_DisplayChangeRequested( void )
71: {
72: display_change_requested = 1;
73: }
74:
75: int WIN32GFX_IsFullScreen( void )
76: {
77: return fullscreen;
78: }
79:
80: int WIN32GFX_GetWidth( void )
81: {
82: return current_width;
83: }
84:
85: int WIN32GFX_GetHeight( void )
86: {
87: return current_height;
88: }
89:
90: #ifdef _WIN32_WCE
91: int nr_joysticks = 1;
92:
93: void init_joystick( void )
94: {
95: }
96:
97: void read_joystick (int nr, unsigned int *dir, int *button)
98: {
99: *dir = *button = 0;
100:
101: if( nr < nr_joysticks )
102: {
103:
104: }
105: }
106:
107: void close_joystick( void )
108: {
109: }
110:
111: int check_prefs_changed_gfx (void)
112: {
113: return 0;
114: }
115:
116: int graphics_init( void )
117: {
118: return 1;
119: }
120:
121: int graphics_setup( void )
122: {
123: return 1;
124: }
125:
126: void graphics_leave( void )
127: {
128: }
129:
130: void unlockscr( void )
131: {
132: }
133:
134: int lockscr( void )
135: {
136: return 0;
137: }
138:
139: void flush_screen( int a, int b )
140: {
141: }
142:
143: void flush_block( int a, int b )
144: {
145: }
146:
147: void flush_line( int a )
148: {
149: }
150:
151: void WIN32GFX_PaletteChange( void )
152: {
153: }
154:
155: #else
156: #include "osdep/dxwrap.h"
157:
158: #ifdef __GNUC__
159: int __cdecl _fcloseall( void );
160: #endif
161:
162: /* Local Globals */
163: static UINT current_pixbytes;
164: static LPPALETTEENTRY current_palette = NULL;
165:
166: static BOOL doInit (void);
167: static void close_windows (void);
168:
169: uae_u32 default_freq = 0;
170:
171: HWND hStatusWnd = NULL;
172: HINSTANCE hDDraw = NULL;
173:
174: /* For the DX_Invalidate() and gfx_unlock_picasso() functions */
175: static int p96_double_buffer_first, p96_double_buffer_last, p96_double_buffer_needs_flushing = 0;
176:
177: static char scrlinebuf[4096]; /* this is too large, but let's rather play on the safe side here */
178:
179: static int rgbformat_bits (RGBFTYPE t)
180: {
181: unsigned long f = 1 << t;
182: return ((f & RGBMASK_8BIT) != 0 ? 8
183: : (f & RGBMASK_15BIT) != 0 ? 15
184: : (f & RGBMASK_16BIT) != 0 ? 16
185: : (f & RGBMASK_24BIT) != 0 ? 24
186: : (f & RGBMASK_32BIT) != 0 ? 32
187: : 0);
188: }
189:
190: static int set_ddraw (int width, int height, int wantfull, int wantoverlay, int bits, LPPALETTEENTRY pal)
191: {
192: HRESULT ddrval;
193:
194: bits = (bits + 7) & ~7;
195:
196: ddrval = DirectDraw_SetCooperativeLevel( hAmigaWnd, wantfull );
197: if (ddrval != DD_OK)
198: goto oops;
199:
200: if (wantfull)
201: {
202: write_log( "set_ddraw: Trying %dx%d, %d bits\n", width, height, bits );
203: ddrval = DirectDraw_SetDisplayMode( width, height, bits, 0 );
204: if (ddrval != DD_OK)
205: {
206: write_log( "set_ddraw: Couldn't SetDisplayMode()\n" );
207: goto oops;
208: }
209:
210: ddrval = DirectDraw_GetDisplayMode();
211: if (ddrval != DD_OK)
212: {
213: write_log( "set_ddraw: Couldn't GetDisplayMode()\n" );
214: goto oops;
215: }
216: }
217:
218: ddrval = DirectDraw_CreateClipper();
219: if (ddrval != DD_OK)
220: {
221: write_log( "set_ddraw: No clipping support\n" );
222: goto oops;
223: }
224:
225: ddrval = DirectDraw_CreateSurface( width, height );
226: if( ddrval != DD_OK )
227: {
228: write_log( "set_ddraw: Couldn't CreateSurface() for primary because %s.\n", DirectDraw_ErrorString( ddrval ) );
229: goto oops;
230: }
231:
1.1.1.2 ! root 232: if( wantoverlay )
! 233: {
! 234: if( !currprefs.win32_no_overlay && ( DirectDraw_GetPrimaryBitCount() != bits ) )
! 235: {
! 236: ddrval = DirectDraw_CreateOverlaySurface( width, height, bits );
! 237: if( ddrval != DD_OK )
! 238: {
! 239: write_log( "set_ddraw: Couldn't CreateOverlaySurface(%d,%d,%d) because %s.\n", width, height, bits, DirectDraw_ErrorString( ddrval ) );
! 240: overlay = 0;
! 241: }
! 242: }
! 243: else
! 244: {
! 245: overlay = 0;
! 246: }
! 247: }
! 248:
1.1 root 249: DirectDraw_ClearSurfaces();
250:
251: if( !DirectDraw_DetermineLocking( wantfull ) )
252: {
253: write_log( "set_ddraw: Couldn't determine locking.\n" );
254: goto oops;
255: }
256:
257: ddrval = DirectDraw_SetClipper( hAmigaWnd );
258:
259: if (ddrval != DD_OK)
260: {
261: write_log( "set_ddraw: Couldn't SetHWnd()\n" );
262: goto oops;
263: }
264:
265: current_pixbytes = DirectDraw_GetBytesPerPixel();
266:
267: write_log( "set_ddraw() called, and is %dx%d@%d-bytes\n", width, height, current_pixbytes );
268:
269: if (current_pixbytes == 1) {
270: current_palette = pal;
271: ddrval = DirectDraw_CreatePalette( pal );
272: if (ddrval != DD_OK)
273: {
274: write_log( "set_ddraw: Couldn't CreatePalette()\n" );
275: goto oops;
276: }
277: }
278:
279: return 1;
280:
281: oops:
282: if( wantfull )
283: DirectDraw_SetCooperativeLevel( hAmigaWnd, 0 ); /* No full-screen, so that people can see our gui_message() */
284: gui_message("set_ddraw(): DirectDraw initialization failed with %s/%d\n", DirectDraw_ErrorString( ddrval ), ddrval);
285: return 0;
286: }
287:
288: struct win32_displaymode *win32_displaymode_list;
289:
290: HRESULT CALLBACK modesCallback( LPDDSURFACEDESC2 modeDesc, LPVOID context )
291: {
292: struct win32_displaymode **dmpp;
293: RGBFTYPE colortype;
294:
295: colortype = DirectDraw_GetSurfacePixelFormat( modeDesc );
296: if (colortype == RGBFB_NONE || colortype == RGBFB_R8G8B8 || colortype == RGBFB_B8G8R8 )
297: return DDENUMRET_OK;
298:
299: dmpp = &win32_displaymode_list;
300: while (*dmpp != 0) {
301: if ((*dmpp)->width == modeDesc->dwWidth
302: && (*dmpp)->height == modeDesc->dwHeight
303: && (*dmpp)->refreshrate == modeDesc->dwRefreshRate)
304: break;
305: dmpp = &(*dmpp)->next;
306: }
307:
308: if (*dmpp == 0) {
309: *dmpp = (struct win32_displaymode *)xmalloc (sizeof **dmpp);
310: (*dmpp)->next = 0;
311: (*dmpp)->width = modeDesc->dwWidth;
312: (*dmpp)->height = modeDesc->dwHeight;
313: (*dmpp)->refreshrate = modeDesc->dwRefreshRate;
314: (*dmpp)->colormodes = 0;
315: }
316: (*dmpp)->colormodes |= 1 << colortype;
317: return DDENUMRET_OK;
318: }
319:
320: static void cleanup_modes( void )
321: {
322: struct win32_displaymode *temp = NULL, *dmpp = win32_displaymode_list;
323:
324: while( dmpp )
325: {
326: temp = dmpp;
327: dmpp = dmpp->next;
328: free( temp );
329: }
330: }
331:
332: static int our_possible_depths[] = { 8, 15, 16, 24, 32 };
333:
334: RGBFTYPE WIN32GFX_FigurePixelFormats( RGBFTYPE colortype )
335: {
336: HRESULT ddrval;
337: struct win32_displaymode *dm;
338: int got_16bit_mode = 0;
339: int window_created = 0;
340:
341: if( colortype == 0 ) /* Need to query a 16-bit display mode for its pixel-format. Do this by opening such a screen */
342: {
343: hAmigaWnd = CreateWindowEx (WS_EX_TOPMOST,
344: "AmigaPowah", VersionStr,
345: WS_VISIBLE | WS_POPUP,
346: CW_USEDEFAULT, CW_USEDEFAULT,
347: 1,//GetSystemMetrics (SM_CXSCREEN),
348: 1,//GetSystemMetrics (SM_CYSCREEN),
349: 0, NULL, 0, NULL);
350: if( hAmigaWnd )
351: {
352: window_created = 1;
353: ddrval = DirectDraw_SetCooperativeLevel( hAmigaWnd, TRUE ); /* TRUE indicates full-screen */
354: if( ddrval != DD_OK )
355: {
356: write_log( "WIN32GFX_FigurePixelFormats: ERROR - %s\n", DirectDraw_ErrorString(ddrval) );
357: gui_message( "WIN32GFX_FigurePixelFormats: ERROR - %s\n", DirectDraw_ErrorString(ddrval) );
358: goto out;
359: }
360: }
361: else
362: {
363: write_log( "WIN32GFX_FigurePixelFormats: ERROR - test-window could not be created.\n" );
364: gui_message( "WIN32GFX_FigurePixelFormats: ERROR - test-window could not be created.\n" );
365: }
366: }
367: else
368: {
369: got_16bit_mode = 1;
370: }
371:
372: for (dm = win32_displaymode_list; dm != 0; dm = dm->next)
373: {
374: if (!got_16bit_mode)
375: {
376: write_log ("figure_pixel_formats: Attempting %dx%d: ", dm->width, dm->height);
377:
378: ddrval = DirectDraw_SetDisplayMode( dm->width, dm->height, 16, 0 ); /* 0 for default freq */
379: if (ddrval != DD_OK)
380: continue;
381:
382: ddrval = DirectDraw_GetDisplayMode();
383: if (ddrval != DD_OK)
384: continue;
385:
386: colortype = DirectDraw_GetPixelFormat();
387: if (colortype != RGBFB_NONE)
388: {
389: write_log ("%d ", our_possible_depths[2]);
390:
391: /* Clear the 16-bit information, and get the real stuff! */
392: dm->colormodes &= ~(RGBFF_R5G6B5PC|RGBFF_R5G5B5PC|RGBFF_R5G6B5|RGBFF_R5G5B5|RGBFF_B5G6R5PC|RGBFF_B5G5R5PC);
393: dm->colormodes |= 1 << colortype;
394: got_16bit_mode = 1;
395: write_log( "Got real 16-bit colour-depth information: 0x%x\n", colortype );
396: }
397: }
398: else if (dm->colormodes & (RGBFF_R5G6B5PC|RGBFF_R5G5B5PC|RGBFF_R5G6B5|RGBFF_R5G5B5|RGBFF_B5G6R5PC|RGBFF_B5G5R5PC) )
399: {
400: /* Clear the 16-bit information, and set the real stuff! */
401: dm->colormodes &= ~(RGBFF_R5G6B5PC|RGBFF_R5G5B5PC|RGBFF_R5G6B5|RGBFF_R5G5B5|RGBFF_B5G6R5PC|RGBFF_B5G5R5PC);
402: dm->colormodes |= 1 << colortype;
403: }
404: }
405: out:
406: if( window_created )
407: {
408: Sleep( 2000 );
409: DestroyWindow( hAmigaWnd );
410: hAmigaWnd = NULL;
411: }
412: return colortype;
413: }
414:
415: /* DirectX will fail with "Mode not supported" if we try to switch to a full
416: * screen mode that doesn't match one of the dimensions we got during enumeration.
417: * So try to find a best match for the given resolution in our list. */
418: int WIN32GFX_AdjustScreenmode( uae_u32 *pwidth, uae_u32 *pheight, uae_u32 *ppixbits )
419: {
420: struct win32_displaymode *best;
421: uae_u32 selected_mask = (*ppixbits == 8 ? RGBMASK_8BIT
422: : *ppixbits == 15 ? RGBMASK_15BIT
423: : *ppixbits == 16 ? RGBMASK_16BIT
424: : *ppixbits == 24 ? RGBMASK_24BIT
425: : RGBMASK_32BIT);
426: int pass, i = 0, index = 0;
427:
428: for (pass = 0; pass < 2; pass++)
429: {
1.1.1.2 ! root 430: struct win32_displaymode *dm;
! 431: uae_u32 mask = (pass == 0
! 432: ? selected_mask
! 433: : RGBMASK_8BIT | RGBMASK_15BIT | RGBMASK_16BIT | RGBMASK_24BIT | RGBMASK_32BIT); /* %%% - BERND, were you missing 15-bit here??? */
1.1 root 434: i = 0;
435: index = 0;
436:
1.1.1.2 ! root 437: best = win32_displaymode_list;
! 438: dm = best->next;
1.1 root 439:
1.1.1.2 ! root 440: while (dm != 0)
1.1 root 441: {
1.1.1.2 ! root 442: if ((dm->colormodes & mask) != 0)
1.1 root 443: {
1.1.1.2 ! root 444: if (dm->width <= best->width && dm->height <= best->height
! 445: && dm->width >= *pwidth && dm->height >= *pheight)
1.1 root 446: {
1.1.1.2 ! root 447: best = dm;
1.1 root 448: index = i;
449: }
1.1.1.2 ! root 450: if (dm->width >= best->width && dm->height >= best->height
! 451: && dm->width <= *pwidth && dm->height <= *pheight)
1.1 root 452: {
1.1.1.2 ! root 453: best = dm;
1.1 root 454: index = i;
455: }
456: }
1.1.1.2 ! root 457: dm = dm->next;
! 458: i++;
! 459: }
! 460: if (best->width == *pwidth && best->height == *pheight)
1.1 root 461: {
462: selected_mask = mask; /* %%% - BERND, I added this - does it make sense? Otherwise, I'd specify a 16-bit display-mode for my
1.1.1.2 ! root 463: Workbench (using -H 2, but SHOULD have been -H 1), and end up with an 8-bit mode instead*/
! 464: break;
1.1 root 465: }
466: }
467: *pwidth = best->width;
468: *pheight = best->height;
469: if( best->colormodes & selected_mask )
470: return index;
471:
472: /* Ordering here is done such that 16-bit is preferred, followed by 15-bit, 8-bit, 32-bit and 24-bit */
473: if (best->colormodes & RGBMASK_16BIT)
474: *ppixbits = 16;
475: else if (best->colormodes & RGBMASK_15BIT) /* %%% - BERND, this possibility was missing? */
1.1.1.2 ! root 476: *ppixbits = 15;
1.1 root 477: else if (best->colormodes & RGBMASK_8BIT)
478: *ppixbits = 8;
479: else if (best->colormodes & RGBMASK_32BIT)
480: *ppixbits = 32;
481: else if (best->colormodes & RGBMASK_24BIT)
482: *ppixbits = 24;
483: else
484: index = -1;
485:
486: return index;
487: }
488:
489: void flush_line( int lineno )
490: {
491:
492: }
493:
494: void flush_block (int a, int b)
495: {
496:
497: }
498:
499: void flush_screen (int a, int b)
500: {
501: if( DirectDraw_GetLockableType() == secondary_surface )
502: {
503: if( fullscreen )
504: {
505: if( DX_Flip() == 0 )
506: {
507: DX_Blit( 0, a, 0, a, current_width, b - a + 1, BLIT_SRC );
508: }
509: }
510: else
511: {
512: DX_Blit( 0, a, 0, a, current_width, b - a + 1, BLIT_SRC );
513: }
514: }
515: }
516:
517: static uae_u8 *dolock (void)
518: {
519: char *surface = NULL, *oldsurface;
520:
521: if( !DirectDraw_SurfaceLock( lockable_surface ) )
522: return 0;
523:
524: surface = DirectDraw_GetSurfacePointer();
525: oldsurface = gfxvidinfo.bufmem;
526: gfxvidinfo.bufmem = surface;
527: if (surface != oldsurface && ! screen_is_picasso)
528: {
529: write_log ("Need to init_row_map\n");
530: init_row_map ();
531: }
532:
533: clear_inhibit_frame (IHF_WINDOWHIDDEN);
534: return surface;
535: }
536:
537: int lockscr( void )
538: {
539: return dolock() != 0;
540: }
541:
542: uae_u8 *gfx_lock_picasso (void)
543: {
544: return dolock ();
545: }
546:
547: void gfx_unlock_picasso (void)
548: {
549: DirectDraw_SurfaceUnlock();
550: if( p96_double_buffer_needs_flushing )
551: {
552: /* Here, our flush_block() will deal with a offscreen-plain (back-buffer) to visible-surface (front-buffer) */
553: if( DirectDraw_GetLockableType() == secondary_surface )
554: {
555: BOOL relock = FALSE;
556: if( DirectDraw_IsLocked() )
557: {
558: relock = TRUE;
559: unlockscr();
560: }
561: DX_Blit( 0, p96_double_buffer_first,
562: 0, p96_double_buffer_first,
563: current_width, p96_double_buffer_last - p96_double_buffer_first + 1,
564: BLIT_SRC );
565: if( relock )
566: {
567: lockscr();
568: }
569: }
570: p96_double_buffer_needs_flushing = 0;
571: }
572: }
573:
574: static void close_hwnds( void )
575: {
576: if (hStatusWnd)
577: {
578: ShowWindow( hStatusWnd, SW_HIDE );
579: DestroyWindow (hStatusWnd);
580: }
581: if (hAmigaWnd)
582: {
583: ShowWindow( hAmigaWnd, SW_HIDE );
584: DestroyWindow (hAmigaWnd);
585: }
586: if (hMainWnd)
587: {
588: ShowWindow( hMainWnd, SW_HIDE );
589: DestroyWindow (hMainWnd);
590: }
591:
592: hMainWnd = 0;
593: hStatusWnd = 0;
594: hAmigaWnd = 0;
595: }
596:
597: static int open_windows (void)
598: {
599: static BOOL bFirstTime = TRUE;
600: char tmpstr[300];
601:
602: char *fs_warning = 0;
603: RGBFTYPE colortype;
604:
605: current_pixbytes = 0;
606:
607: in_sizemove = 0;
608: fixup_prefs_dimensions (&currprefs);
609:
610: if( !DirectDraw_Start() )
611: return 0;
612: if( DirectDraw_GetDisplayMode() != DD_OK )
613: return 0;
614: colortype = DirectDraw_GetPixelFormat();
615: write_log ("Ct: %08lx, picasso_vidinfo.selected_rgbformat %08lx\n", (unsigned long)colortype,
616: picasso_vidinfo.selected_rgbformat);
617:
618: if (screen_is_picasso) {
619: fullscreen = currprefs.gfx_pfullscreen;
620: window_width = current_width = picasso_vidinfo.width;
621: window_height = current_height = picasso_vidinfo.height;
622: window_depth = current_depth = rgbformat_bits (picasso_vidinfo.selected_rgbformat);
623: } else {
624: fullscreen = currprefs.gfx_afullscreen;
625: window_width = current_width = currprefs.gfx_width;
626: window_height = current_height = currprefs.gfx_height;
627: window_depth = current_depth = (currprefs.color_mode == 0 ? 8
628: : currprefs.color_mode == 1 ? 15
629: : currprefs.color_mode == 2 ? 16
630: : currprefs.color_mode == 3 ? 8
631: : currprefs.color_mode == 4 ? 8 : 32);
632: }
633:
634: //If screen depth is equal to the desired window_depth then no overlay is needed.
635: if( DirectDraw_GetSurfaceBitCount() == window_depth )
636: overlay = 0;
637:
638: if (overlay) {
639: needs_direct = 1;
640: } else {
641: needs_direct = 0;
642: }
643:
644: if (colortype == RGBFB_NONE && !overlay) {
645: needs_direct = 1;
646: fs_warning = "the desktop is running in an unknown color mode.";
647: } else if (colortype == RGBFB_CLUT && !overlay) {
648: needs_direct = 1;
649: fs_warning = "the desktop is running in 8 bit color depth, which UAE can't use in windowed mode.";
650: } else if ( !fullscreen && ( current_width >= DirectDraw_CurrentWidth() || current_height >= DirectDraw_CurrentHeight() ) ) {
651: needs_direct = 1;
652: fs_warning = "the desktop is too small for the specified window size.";
653: overlay = 0; // we're going to go full-screen
654: } else if (screen_is_picasso && !fullscreen &&
655: ( picasso_vidinfo.selected_rgbformat != RGBFB_CHUNKY ) &&
656: ( picasso_vidinfo.selected_rgbformat != colortype ) &&
657: overlay )
658: {
659: needs_direct = 1;
660: fs_warning = "you selected a Picasso display with a color depth different from that of the desktop and an overlay was unavailable.";
661: if( !doInit() )
662: {
663: overlay = 0; // we're going to go full-screen
664: // doInit in windowed-mode modifies the width/height params, so
665: // restore our mucked-up width and height values for full-screen.
666: window_width = current_width = picasso_vidinfo.width;
667: window_height = current_height = picasso_vidinfo.height;
668: }
669: DirectDraw_Release();
670: close_hwnds();
671: if( !DirectDraw_Start() )
672: return 0;
673: }
674:
675: if( needs_direct && ! usedirect )
676: usedirect = needs_direct;
677:
678: if( fs_warning && !overlay )
679: {
680: // Temporarily drop the DirectDraw stuff
681: DirectDraw_Release();
682: sprintf (tmpstr, "The selected screen mode can't be displayed in a window, because %s\n"
683: "Switching to full-screen display.", fs_warning);
684: MessageBox (0, tmpstr, "WinUAE", MB_ICONEXCLAMATION | MB_OK);
685: DirectDraw_Start();
686: fullscreen = 1;
687: }
688:
689: if (! usedirect)
690: window_depth = rgbformat_bits (colortype);
691:
692: if( current_depth == 24 )
693: {
694: if( screen_is_picasso )
695: fs_warning = "you've selected a Picasso display with a 24-bit depth, which WinUAE no longer supports.";
696: else
697: fs_warning = "the desktop is running in 24-bit color depth, which WinUAE no longer supports.";
698: /* Temporarily drop the DirectDraw stuff. This is necessary, otherwise
699: * WinNT will just return 1 for the message box without ever displaying
700: * it on the screen. */
701: DirectDraw_Release();
702: sprintf (tmpstr, "WinUAE cannot run because %s", fs_warning);
703: MessageBox (0, tmpstr, "WinUAE", MB_ICONEXCLAMATION | MB_OK);
704: return 0;
705: }
706:
707: if (! doInit ())
708: return 0;
709:
710: if(!WIN32GFX_IsFullScreen() && ( bFirstTime || bJustClosedWithActiveMouse ) )
711: {
712: bFirstTime = FALSE;
713: bJustClosedWithActiveMouse = FALSE;
714: setmouseactive (1);
715: }
716:
717: return 1;
718: }
719:
720: int check_prefs_changed_gfx (void)
721: {
722: if (display_change_requested ||
723: ( currprefs.gfx_afullscreen != changed_prefs.gfx_afullscreen ) ||
724: ( currprefs.gfx_pfullscreen != changed_prefs.gfx_pfullscreen ) )
725: {
726: display_change_requested = 0;
727: currprefs.gfx_afullscreen = changed_prefs.gfx_afullscreen;
728: currprefs.gfx_pfullscreen = changed_prefs.gfx_pfullscreen;
729: close_windows ();
730: open_windows ();
731: return 1;
732: }
733: return 0;
734: }
735:
736: /* Color management */
737:
738: static xcolnr xcol8[4096];
739: static PALETTEENTRY colors256[256];
740: static int ncols256 = 0;
741:
742: static int red_bits, green_bits, blue_bits;
743: static int red_shift, green_shift, blue_shift;
744:
745: static int get_color (int r, int g, int b, xcolnr * cnp)
746: {
747: if (ncols256 == 256)
748: return 0;
749: colors256[ncols256].peRed = r * 0x11;
750: colors256[ncols256].peGreen = g * 0x11;
751: colors256[ncols256].peBlue = b * 0x11;
752: colors256[ncols256].peFlags = 0;
753: *cnp = ncols256;
754: ncols256++;
755: return 1;
756: }
757:
758: static void init_colors (void)
759: {
760: int i;
761: HRESULT ddrval;
762:
763: if (ncols256 == 0) {
764: alloc_colors256 (get_color);
765: memcpy (xcol8, xcolors, sizeof xcol8);
766: }
767:
768: /* init colors */
769:
770: switch( current_pixbytes )
771: {
772: case 1:
773: memcpy (xcolors, xcol8, sizeof xcolors);
774: ddrval = DirectDraw_SetPaletteEntries( 0, 256, colors256 );
775: if (ddrval != DD_OK)
776: gui_message ("DX_SetPalette() failed with %s/%d\n", DirectDraw_ErrorString (ddrval), ddrval);
777: break;
778:
779: case 2:
780: case 3:
781: case 4:
782: red_bits = bits_in_mask( DirectDraw_GetPixelFormatBitMask( red_mask ) );
783: green_bits = bits_in_mask( DirectDraw_GetPixelFormatBitMask( green_mask ) );
784: blue_bits = bits_in_mask( DirectDraw_GetPixelFormatBitMask( blue_mask ) );
785: red_shift = mask_shift( DirectDraw_GetPixelFormatBitMask( red_mask ) );
786: green_shift = mask_shift( DirectDraw_GetPixelFormatBitMask( green_mask ) );
787: blue_shift = mask_shift( DirectDraw_GetPixelFormatBitMask( blue_mask ) );
788:
789: alloc_colors64k (red_bits, green_bits, blue_bits, red_shift,
790: green_shift, blue_shift);
791: break;
792: }
793: switch (gfxvidinfo.pixbytes)
794: {
795: case 2:
796: for (i = 0; i < 4096; i++)
797: xcolors[i] = xcolors[i] * 0x00010001;
798: gfxvidinfo.can_double = 1;
799: break;
800: case 1:
801: for (i = 0; i < 4096; i++)
802: xcolors[i] = xcolors[i] * 0x01010101;
803: gfxvidinfo.can_double = 1;
804: break;
805: default:
806: gfxvidinfo.can_double = 0;
807: break;
808: }
809: }
810:
811: int DX_FillResolutions (uae_u16 * ppixel_format)
812: {
813: struct win32_displaymode *dm;
814: int count = 0;
815:
816: *ppixel_format = 0;
817: for (dm = win32_displaymode_list; dm != 0; dm = dm->next) {
818: *ppixel_format |= dm->colormodes;
819: if (dm->colormodes & RGBMASK_8BIT) {
820: DisplayModes[count].res.width = dm->width;
821: DisplayModes[count].res.height = dm->height;
822: DisplayModes[count].refresh = default_freq;
823: DisplayModes[count].depth = 1;
824: count++;
825: }
826: if (count >= MAX_PICASSO_MODES)
827: break;
828: if (dm->colormodes & (RGBMASK_16BIT | RGBMASK_15BIT)) {
829: DisplayModes[count].res.width = dm->width;
830: DisplayModes[count].res.height = dm->height;
831: DisplayModes[count].refresh = default_freq;
832: DisplayModes[count].depth = 2;
833: count++;
834: }
835: if (count >= MAX_PICASSO_MODES)
836: break;
837: if (dm->colormodes & RGBMASK_24BIT) {
838: DisplayModes[count].res.width = dm->width;
839: DisplayModes[count].res.height = dm->height;
840: DisplayModes[count].refresh = default_freq;
841: DisplayModes[count].depth = 3;
842: count++;
843: }
844: if (count >= MAX_PICASSO_MODES)
845: break;
846: if (dm->colormodes & RGBMASK_32BIT) {
847: DisplayModes[count].res.width = dm->width;
848: DisplayModes[count].res.height = dm->height;
849: DisplayModes[count].refresh = default_freq;
850: DisplayModes[count].depth = 4;
851: count++;
852: }
853: if (count >= MAX_PICASSO_MODES)
854: break;
855: }
856: return count;
857: }
858:
859: void DX_SetPalette (int start, int count)
860: {
861: HRESULT ddrval;
862:
863: if( !screen_is_picasso )
864: return;
865:
866: if( picasso96_state.RGBFormat != RGBFB_CHUNKY )
867: {
868: /* notice_screen_contents_lost(); */
869: return;
870: }
871:
872: if (picasso_vidinfo.pixbytes != 1)
873: {
874: /* write_log ("DX Setpalette emulation\n"); */
875: /* This is the case when we're emulating a 256 color display. */
876: while (count-- > 0)
877: {
878: int r = picasso96_state.CLUT[start].Red;
879: int g = picasso96_state.CLUT[start].Green;
880: int b = picasso96_state.CLUT[start].Blue;
881: picasso_vidinfo.clut[start++] = (doMask256 (r, red_bits, red_shift)
882: | doMask256 (g, green_bits, green_shift)
883: | doMask256 (b, blue_bits, blue_shift));
884: }
885: notice_screen_contents_lost();
886: return;
887: }
888:
889: /* Set our DirectX palette here */
890: if( current_pixbytes == 1 )
891: {
892: ddrval = DirectDraw_SetPaletteEntries( start, count, (LPPALETTEENTRY)&(picasso96_state.CLUT[start] ) );
893: if (ddrval != DD_OK)
894: gui_message("DX_SetPalette() failed with %s/%d\n", DirectDraw_ErrorString (ddrval), ddrval);
895: }
896: else
897: {
898: write_log ("ERROR - DX_SetPalette() pixbytes %d\n", current_pixbytes );
899: }
900: }
901:
902: void DX_Invalidate (int first, int last)
903: {
904: p96_double_buffer_first = first;
905: if( (unsigned)last >= picasso_vidinfo.height )
906: last = picasso_vidinfo.height - 1;
907: p96_double_buffer_last = last;
908: p96_double_buffer_needs_flushing = 1;
909: }
910:
911: int DX_BitsPerCannon (void)
912: {
913: return 8;
914: }
915:
916: static COLORREF BuildColorRef( int color, RGBFTYPE pixelformat )
917: {
918: COLORREF result;
919:
920: /* Do special case first */
921: if( pixelformat == RGBFB_CHUNKY )
922: result = color;
923: else
924: result = do_get_mem_long( &color );
925: return result;
926: #if 0
927: int r,g,b;
928: write_log( "DX_Blit() called to fill with color of 0x%x, rgbtype of 0x%x\n", color, pixelformat );
929:
930: switch( pixelformat )
931: {
932: case RGBFB_R5G6B5PC:
933: r = color & 0xF800 >> 11;
934: g = color & 0x07E0 >> 5;
935: b = color & 0x001F;
936: break;
937: case RGBFB_R5G5B5PC:
938: r = color & 0x7C00 >> 10;
939: g = color & 0x03E0 >> 5;
940: b = color & 0x001F;
941: break;
942: case RGBFB_B5G6R5PC:
943: r = color & 0x001F;
944: g = color & 0x07E0 >> 5;
945: b = color & 0xF800 >> 11;
946: break;
947: case RGBFB_B5G5R5PC:
948: r = color & 0x001F;
949: g = color & 0x03E0 >> 5;
950: b = color & 0x7C00 >> 10;
951: break;
952: case RGBFB_B8G8R8:
953: r = color & 0x00FF0000 >> 16;
954: g = color & 0x0000FF00 >> 8;
955: b = color & 0x000000FF;
956: break;
957: case RGBFB_A8B8G8R8:
958: r = color & 0xFF000000 >> 24;
959: g = color & 0x00FF0000 >> 16;
960: b = color & 0x0000FF00 >> 8;
961: break;
962: case RGBFB_R8G8B8:
963: r = color & 0x000000FF;
964: g = color & 0x0000FF00 >> 8;
965: b = color & 0x00FF0000 >> 16;
966: break;
967: case RGBFB_A8R8G8B8:
968: r = color & 0x0000FF00 >> 8;
969: g = color & 0x00FF0000 >> 16;
970: b = color & 0xFF000000 >> 24;
971: break;
972: default:
973: write_log( "Uknown 0x%x pixel-format\n", pixelformat );
974: break;
975: }
976: result = RGB(r,g,b);
977: write_log( "R = 0x%02x, G = 0x%02x, B = 0x%02x - result = 0x%08x\n", r, g, b, result );
978: return result;
979: #endif
980: }
981:
982: /* This is a general purpose DirectDrawSurface filling routine. It can fill within primary surface.
983: * Definitions:
984: * - primary is the displayed (visible) surface in VRAM, which may have an associated offscreen surface (or back-buffer)
985: */
986: int DX_Fill( int dstx, int dsty, int width, int height, uae_u32 color, RGBFTYPE rgbtype )
987: {
988: int result = 0;
989: RECT dstrect;
990: RECT srcrect;
991: DDBLTFX ddbltfx;
992: memset( &ddbltfx, 0, sizeof( ddbltfx ) );
993: ddbltfx.dwFillColor = BuildColorRef( color, rgbtype );
994: ddbltfx.dwSize = sizeof( ddbltfx );
995:
996: /* Set up our source rectangle. This NEVER needs to be adjusted for windowed display, since the
997: * source is ALWAYS in an offscreen buffer, or we're in full-screen mode. */
998: SetRect( &srcrect, dstx, dsty, dstx+width, dsty+height );
999:
1000: /* Set up our destination rectangle, and adjust for blit to windowed display (if necessary ) */
1001: SetRect( &dstrect, dstx, dsty, dstx+width, dsty+height );
1002: if( !fullscreen && !overlay )
1003: OffsetRect( &dstrect, amigawin_rect.left, amigawin_rect.top );
1004:
1005: /* Render our fill to the visible (primary) surface */
1006: if( ( result = DirectDraw_Blt( primary_surface, &dstrect, invalid_surface, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx ) ) )
1007: {
1008: if( DirectDraw_GetLockableType() == secondary_surface )
1009: {
1010: /* We've colour-filled the visible, but still need to colour-fill the offscreen */
1011: result = DirectDraw_Blt( secondary_surface, &srcrect, invalid_surface, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx );
1012: }
1013: }
1014: return result;
1015: }
1016:
1017: /* This is a general purpose DirectDrawSurface blitting routine. It can blit within primary surface
1018: * Definitions:
1019: * - primary is the displayed (visible) surface in VRAM, which may have an associated offscreen surface (or back-buffer)
1020: */
1021:
1022: DDBLTFX fx = { sizeof( DDBLTFX ) };
1023:
1024: DWORD BLIT_OPCODE_TRANSLATION[ BLIT_LAST ] =
1025: {
1026: BLACKNESS, /* BLIT_FALSE */
1027: NOTSRCERASE,/* BLIT_NOR */
1028: -1, /* BLIT_ONLYDST NOT SUPPORTED */
1029: NOTSRCCOPY, /* BLIT_NOTSRC */
1030: SRCERASE, /* BLIT_ONLYSRC */
1031: DSTINVERT, /* BLIT_NOTDST */
1032: SRCINVERT, /* BLIT_EOR */
1033: -1, /* BLIT_NAND NOT SUPPORTED */
1034: SRCAND, /* BLIT_AND */
1035: -1, /* BLIT_NEOR NOT SUPPORTED */
1036: -1, /* NO-OP */
1037: MERGEPAINT, /* BLIT_NOTONLYSRC */
1038: SRCCOPY, /* BLIT_SRC */
1039: -1, /* BLIT_NOTONLYDST NOT SUPPORTED */
1040: SRCPAINT, /* BLIT_OR */
1041: WHITENESS /* BLIT_TRUE */
1042: };
1043:
1044: // This function is only called for full-screen Amiga screen-modes, and simply flips
1045: // the front and back buffers. Additionally, because the emulation is not always drawing
1046: // complete frames, we also need to update the back-buffer with the new contents we just
1047: // flipped to. Thus, after our flip, we blit.
1048: int DX_Flip( void )
1049: {
1050: int result = 0;
1051:
1052: result = DirectDraw_Flip();
1053: if( result )
1054: {
1055: result = DirectDraw_BltFast( secondary_surface, 0, 0, primary_surface, NULL );
1056: }
1057: return result;
1058: }
1059:
1060: int DX_Blit( int srcx, int srcy, int dstx, int dsty, int width, int height, BLIT_OPCODE opcode )
1061: {
1062: int result = 0;
1063: RECT dstrect;
1064: RECT srcrect;
1065: DWORD dwROP = BLIT_OPCODE_TRANSLATION[ opcode ];
1066:
1067: /* Set up our source rectangle. This NEVER needs to be adjusted for windowed display, since the
1068: * source is ALWAYS in an offscreen buffer, or we're in full-screen mode. */
1069: SetRect( &srcrect, srcx, srcy, srcx+width, srcy+height );
1070:
1071: /* Set up our destination rectangle, and adjust for blit to windowed display (if necessary ) */
1072: SetRect( &dstrect, dstx, dsty, dstx+width, dsty+height );
1073:
1074: if( !fullscreen && !overlay )
1075: OffsetRect( &dstrect, amigawin_rect.left, amigawin_rect.top );
1076:
1077: if( dwROP == -1 )
1078: {
1079: /* Unsupported blit opcode! */
1080: return 0;
1081: }
1082: else
1083: {
1084: fx.dwROP = dwROP;
1085: }
1086:
1087: /* Render our blit within the primary surface */
1088: result = DirectDraw_Blt( primary_surface, &dstrect, DirectDraw_GetLockableType(), &srcrect, DDBLT_WAIT | DDBLT_ROP, &fx );
1089:
1090: if( !result )
1091: {
1092: BLIT_OPCODE_TRANSLATION[ opcode ] = -1;
1093: }
1094: else if( DirectDraw_GetLockableType() == secondary_surface )
1095: {
1096: /* We've just blitted from the offscreen to the visible, but still need to blit from offscreen to offscreen
1097: * NOTE: reset our destination rectangle again if its been modified above... */
1098: if( ( srcx != dstx ) || ( srcy != dsty ) )
1099: {
1100: if( !fullscreen )
1101: SetRect( &dstrect, dstx, dsty, dstx+width, dsty+height );
1102: result = DirectDraw_Blt( secondary_surface, &dstrect, secondary_surface, &srcrect, DDBLT_WAIT | DDBLT_ROP, &fx );
1103: }
1104: }
1105:
1106: return result;
1107: }
1108:
1109: void DX_WaitVerticalSync( void )
1110: {
1111: DirectDraw_WaitForVerticalBlank( DDWAITVB_BLOCKBEGIN );
1112: }
1113:
1114: uae_u32 DX_ShowCursor( uae_u32 activate )
1115: {
1116: uae_u32 result = 0;
1117: if( ShowCursor( activate ) > 0 )
1118: result = 1;
1119: return result;
1120: }
1121:
1122: uae_u32 DX_MoveCursor( uae_u32 x, uae_u32 y )
1123: {
1124: uae_u32 result = 0;
1125:
1126: // We may need to adjust the x,y values for our window-offset
1127: if( !fullscreen )
1128: {
1129: RECT rect;
1130: if( GetWindowRect( hAmigaWnd, &rect ) )
1131: {
1132: x = rect.left + x;
1133: y = rect.top + y;
1134: }
1135: }
1136: if( SetCursorPos( x, y ) )
1137: result = 1;
1138: return result;
1139: }
1140:
1141: static void open_screen( void )
1142: {
1143: close_windows ();
1144: if( open_windows() )
1145: DX_SetPalette (0, 256);
1146: else
1147: abort();
1148: }
1149:
1150: void gfx_set_picasso_state( int on )
1151: {
1152: if (screen_is_picasso == on)
1153: return;
1154:
1155: screen_is_picasso = on;
1156: open_screen();
1157: }
1158:
1159: void gfx_set_picasso_modeinfo( int w, int h, int depth, int rgbfmt )
1160: {
1161: depth >>= 3;
1162: if( ( picasso_vidinfo.width == w ) &&
1163: ( picasso_vidinfo.height == h ) &&
1164: ( picasso_vidinfo.depth == depth ) &&
1165: ( picasso_vidinfo.selected_rgbformat == rgbfmt) )
1166: return;
1167:
1168: picasso_vidinfo.selected_rgbformat = rgbfmt;
1169: picasso_vidinfo.width = w;
1170: picasso_vidinfo.height = h;
1171: picasso_vidinfo.depth = depth;
1172: picasso_vidinfo.extra_mem = 1;
1173:
1174: if( screen_is_picasso )
1175: {
1176: open_screen();
1177: }
1178: }
1179:
1180: int graphics_init (void)
1181: {
1182: return open_windows ();
1183: }
1184:
1185: int graphics_setup (void)
1186: {
1187: if( !DirectDraw_Start() )
1188: return 0;
1189:
1190: DirectDraw_Release();
1191:
1192: InitPicasso96();
1193:
1194: return 1;
1195: }
1196:
1197: void graphics_leave (void)
1198: {
1199: close_windows ();
1200: dumpcustom ();
1201: cleanup_modes ();
1202: }
1203:
1204: uae_u32 OSDEP_minimize_uae( void )
1205: {
1206: return ShowWindow( hAmigaWnd, SW_MINIMIZE );
1207: }
1208:
1209: static void close_windows (void)
1210: {
1211: gfxvidinfo.bufmem = 0;
1212:
1213: releasecapture ();
1214: setmouseactive (0);
1215: ClipCursor (NULL);
1216: DirectDraw_Release();
1217: close_hwnds();
1218: if( mouseactive )
1219: bJustClosedWithActiveMouse = TRUE;
1220: {
1221: int i;
1222: for( i=0;i<AK_CTRL+1;i++)my_kbd_handler (0,i,0);
1223: for( i=0;i<AK_CTRL+1;i++)my_kbd_handler (i,0,0);
1224: buttonstate[0] = 0;
1225: buttonstate[1] = 0;
1226: buttonstate[2] = 0;
1227: }
1228: bInitDone = FALSE; //?????JGI
1.1.1.2 ! root 1229: overlay = 1; // Go back to desiring overlay support
1.1 root 1230: }
1231:
1232: void WIN32GFX_ToggleFullScreen( void )
1233: {
1234: if (needs_direct && !overlay)
1235: return;
1236:
1237: display_change_requested = 1;
1238: if (screen_is_picasso)
1239: currprefs.gfx_pfullscreen ^= 1;
1240: else
1241: currprefs.gfx_afullscreen ^= 1;
1242: }
1243:
1244: static int create_windows (void)
1245: {
1246: if (!fullscreen)
1247: {
1248: RECT rc;
1249: LONG stored_x = 1, stored_y = GetSystemMetrics( SM_CYMENU ) + GetSystemMetrics( SM_CYBORDER );
1250: DWORD regkeytype;
1251: DWORD regkeysize = sizeof(LONG);
1252: HLOCAL hloc;
1253: LPINT lpParts;
1254:
1255: RegQueryValueEx( hWinUAEKey, "xPos", 0, ®keytype, (LPBYTE)&stored_x, ®keysize );
1256: RegQueryValueEx( hWinUAEKey, "yPos", 0, ®keytype, (LPBYTE)&stored_y, ®keysize );
1257: if( stored_x < 1 )
1258: stored_x = 1;
1259: if( stored_y < ( GetSystemMetrics( SM_CYMENU ) + GetSystemMetrics( SM_CYBORDER ) ) )
1260: stored_y = GetSystemMetrics( SM_CYMENU ) + GetSystemMetrics( SM_CYBORDER );
1261:
1262: if( stored_x > GetSystemMetrics( SM_CXFULLSCREEN ) )
1263: rc.left = 1;
1264: else
1265: rc.left = stored_x;
1266:
1267: if( stored_y > GetSystemMetrics( SM_CYFULLSCREEN ) )
1268: rc.top = 1;
1269: else
1270: rc.top = stored_y;
1271:
1272: rc.right = rc.left + current_width;
1273: rc.bottom = rc.top + current_height + GetSystemMetrics( SM_CYMENU ) + GetSystemMetrics( SM_CYBORDER )*3;
1274:
1275: AdjustWindowRect (&rc, NORMAL_WINDOW_STYLE, FALSE);
1276:
1277: hMainWnd = CreateWindowEx( picasso_on ? WS_EX_ACCEPTFILES : WS_EX_ACCEPTFILES | WS_EX_APPWINDOW, "PCsuxRox", "WinUAE",
1278: NORMAL_WINDOW_STYLE, rc.left, rc.top,
1279: rc.right - rc.left, rc.bottom - rc.top,
1280: NULL, NULL, 0, NULL);
1281:
1282: if (! hMainWnd)
1283: return 0;
1284: hStatusWnd = CreateStatusWindow (WS_CHILD | WS_VISIBLE, "", hMainWnd, 1);
1285: if (hStatusWnd)
1286: {
1287: GetClientRect (hMainWnd, &rc);
1288: /* Allocate an array for holding the right edge coordinates. */
1289: hloc = LocalAlloc (LHND, sizeof (int) * NUM_PARTS);
1290: if (hloc)
1291: {
1292: lpParts = LocalLock (hloc);
1293:
1294: /* Calculate the right edge coordinate for each part, and copy the coords
1295: * to the array. */
1296: lpParts[0] = rc.right - (DRIVE_WIDTH * 4) - LED_WIDTH - FPS_WIDTH - 2;
1297: lpParts[1] = lpParts[0] + FPS_WIDTH;
1298: lpParts[2] = lpParts[1] + LED_WIDTH;
1299: lpParts[3] = lpParts[2] + DRIVE_WIDTH;
1300: lpParts[4] = lpParts[3] + DRIVE_WIDTH;
1301: lpParts[5] = lpParts[4] + DRIVE_WIDTH;
1302: lpParts[6] = lpParts[5] + DRIVE_WIDTH;
1303:
1304: /* Create the seven parts */
1305: SendMessage (hStatusWnd, SB_SETPARTS, (WPARAM) NUM_PARTS, (LPARAM) lpParts);
1306:
1307: LocalUnlock (hloc);
1308: LocalFree (hloc);
1309: }
1310: }
1311: }
1312: else
1313: hMainWnd = NULL;
1314:
1315: hAmigaWnd = CreateWindowEx (fullscreen ? WS_EX_TOPMOST : WS_EX_ACCEPTFILES | WS_EX_APPWINDOW,
1316: "AmigaPowah", "WinUAE",
1317: hMainWnd ? WS_VISIBLE | WS_CHILD : WS_VISIBLE | WS_POPUP,
1318: hMainWnd ? 0 : CW_USEDEFAULT, hMainWnd ? 0 : CW_USEDEFAULT,
1319: fullscreen ? GetSystemMetrics (SM_CXSCREEN) : current_width,
1320: fullscreen ? GetSystemMetrics (SM_CYSCREEN) : current_height,
1321: hMainWnd, NULL, 0, NULL);
1322:
1323: if (! hAmigaWnd)
1324: {
1325: close_hwnds();
1326: return 0;
1327: }
1328:
1329:
1330: if (hMainWnd)
1331: UpdateWindow( hMainWnd );
1332: if (hAmigaWnd)
1333: UpdateWindow (hAmigaWnd);
1334:
1335: return 1;
1336: }
1337:
1338: static void setoverlay(void)
1339: {
1340: RECT sr, dr, statusr;
1341: POINT p = {0,0};
1342: int maxwidth, maxheight;
1343:
1344: GetClientRect(hMainWnd, &dr);
1345: // adjust the dest-rect to avoid the status-bar
1346: if( hStatusWnd )
1347: {
1348: if( GetWindowRect( hStatusWnd, &statusr ) )
1349: dr.bottom = dr.bottom - ( statusr.bottom - statusr.top );
1350: }
1351:
1352: ClientToScreen( hMainWnd, &p );
1353: dr.left = p.x;
1354: dr.top = p.y;
1355: dr.right += p.x;
1356: dr.bottom += p.y;
1357:
1358: sr.left = 0; sr.top = 0;
1359: sr.right = current_width; sr.bottom = current_height;
1360:
1361: // Adjust our dst-rect to match the dimensions of our src-rect
1362: if( dr.right - dr.left > sr.right - sr.left )
1363: {
1364: dr.right = dr.left + sr.right - sr.left;
1365: }
1366: if( dr.bottom - dr.top > sr.bottom - sr.top )
1367: {
1368: dr.bottom = dr.top + sr.bottom - sr.top;
1369: }
1370:
1371: maxwidth = GetSystemMetrics(SM_CXSCREEN);
1372: if (dr.right > maxwidth) {
1373: sr.right = current_width - (dr.right - maxwidth);
1374: dr.right = maxwidth;
1375: }
1376: maxheight = GetSystemMetrics(SM_CYSCREEN);
1377: if (dr.bottom > maxheight) {
1378: sr.bottom = current_height - (dr.bottom - maxheight);
1379: dr.bottom = maxheight;
1380: }
1381: if (dr.left < 0) {
1382: sr.left = -dr.left;
1383: dr.left = 0;
1384: }
1385: if (dr.top < 0) {
1386: sr.top = -dr.top;
1387: dr.top = 0;
1388: }
1389: DirectDraw_UpdateOverlay(sr, dr);
1390: }
1391:
1392: static BOOL doInit (void)
1393: {
1394: if (! create_windows ())
1395: goto oops;
1396:
1397: if( screen_is_picasso )
1398: {
1399: if (! set_ddraw (current_width, current_height, fullscreen, overlay, window_depth,
1400: (LPPALETTEENTRY) & picasso96_state.CLUT))
1401: goto oops;
1402: picasso_vidinfo.rowbytes = DirectDraw_GetSurfacePitch();
1403: picasso_vidinfo.pixbytes = DirectDraw_GetBytesPerPixel();
1404: picasso_vidinfo.rgbformat = DirectDraw_GetPixelFormat();
1405: }
1406: else
1407: {
1408: if (fullscreen)
1409: {
1410: #if 0
1411: write_log( "Calling adjust_screenmode with %d,%d,%d\n", window_width, window_height, window_depth );
1412: if( WIN32GFX_AdjustScreenmode( &window_width, &window_height, &window_depth ) < 0 )
1413: abort ();
1414: write_log( "Finished adjust_screenmode with %d,%d,%d\n", window_width, window_height, window_depth );
1415: #endif
1416: }
1417: if (! set_ddraw (current_width, current_height, fullscreen, overlay, window_depth, colors256))
1418: goto oops;
1419: gfxvidinfo.bufmem = 0;
1420: gfxvidinfo.linemem = 0;
1421: gfxvidinfo.emergmem = scrlinebuf; // memcpy from system-memory to video-memory
1422: gfxvidinfo.pixbytes = current_pixbytes;
1423: gfxvidinfo.width = current_width;
1424: gfxvidinfo.height = current_height;
1425: gfxvidinfo.maxblocklines = 0; // flush_screen actually does everything
1426: gfxvidinfo.rowbytes = DirectDraw_GetSurfacePitch();
1427: }
1428:
1429: if( fullscreen )
1430: {
1431: WIN32_MouseDefaults();
1432: }
1433: if( !DirectDraw_SurfaceLock( lockable_surface ) )
1434: goto oops;
1435: DirectDraw_SurfaceUnlock();
1436:
1437: if( ( DirectDraw_GetPixelFormatFlags() & (DDPF_RGB | DDPF_PALETTEINDEXED8 | DDPF_RGBTOYUV ) ) )
1438: {
1439: write_log( "%s mode (bits: %d, pixbytes: %d)\n", fullscreen ? "Full screen" : "Window",
1440: DirectDraw_GetSurfaceBitCount(), current_pixbytes );
1441: }
1442: else
1443: {
1444: char szMessage[ MAX_PATH ];
1445: WIN32GUI_LoadUIString( IDS_UNSUPPORTEDPIXELFORMAT, szMessage, MAX_PATH );
1446: gui_message( szMessage);
1447: goto oops;
1448: }
1449:
1450: init_colors ();
1451:
1452: if (overlay)
1453: setoverlay ();
1454:
1455: #if 0 // This crashes WinXP, because that last param should be an LPWINDOWPOS...
1456: if (! fullscreen)
1457: SendMessage( hMainWnd, WM_WINDOWPOSCHANGED, 0, 0);
1458: #endif
1459:
1460: bInitDone = TRUE;
1461: return 1;
1462:
1463: oops:
1464: DirectDraw_Release();
1465: close_hwnds();
1466: return 0;
1467: }
1468:
1469:
1470: void WIN32GFX_PaletteChange( void )
1471: {
1472: DirectDraw_SetPalette( 1 ); /* Remove current palette */
1473: DirectDraw_SetPalette( 0 ); /* Set our real palette */
1474: }
1475:
1476: void WIN32GFX_ClearPalette( void )
1477: {
1478: DirectDraw_SetPalette( 1 ); /* Remove palette */
1479: }
1480:
1481: void WIN32GFX_SetPalette( void )
1482: {
1483: DirectDraw_SetPalette( 0 ); /* Set palette */
1484: }
1485: #endif
1486: void WIN32GFX_WindowMove ( void )
1487: {
1488: if (overlay && hMainWnd && bInitDone) setoverlay();
1489: }
1490:
1491: void WIN32GFX_WindowSize ( void )
1492: {
1493: RECT r;
1494:
1495: //?????JGI (to delete): if (!overlay) return;
1496: if (!hMainWnd) return;
1497: if(!GetClientRect (hMainWnd, &r)) return;
1498: window_width = r.right - r.left;
1499: window_height = r.bottom - r.top;
1500: if (overlay && bInitDone) setoverlay();//????? JGI
1501: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.