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