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