Annotation of uae/src/od-win32/win32gfx.c, revision 1.1.1.3

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 "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) */
1.1.1.2   root       43: static int overlay = 1; /* use overlay surface */
1.1       root       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: 
                     53: int WIN32GFX_IsPicassoScreen( void )
                     54: {
                     55:     return screen_is_picasso;
                     56: }
                     57: 
                     58: void WIN32GFX_DisablePicasso( void )
                     59: {
                     60:     picasso_requested_on = 0;
                     61:     picasso_on = 0;
                     62: }
                     63: 
                     64: void WIN32GFX_EnablePicasso( void )
                     65: {
                     66:     picasso_requested_on = 1;
                     67: }
                     68: 
                     69: void WIN32GFX_DisplayChangeRequested( void )
                     70: {
                     71:     display_change_requested = 1;
                     72: }
                     73: 
                     74: int WIN32GFX_IsFullScreen( void )
                     75: {
                     76:     return fullscreen;
                     77: }
                     78: 
                     79: int WIN32GFX_GetWidth( void )
                     80: {
                     81:     return current_width;
                     82: }
                     83: 
                     84: int WIN32GFX_GetHeight( void )
                     85: {
                     86:     return current_height;
                     87: }
                     88: 
                     89: #ifdef _WIN32_WCE
                     90: int nr_joysticks = 1;
                     91: 
                     92: void init_joystick( void )
                     93: {
                     94: }
                     95: 
                     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: 
                    106: void close_joystick( void )
                    107: {
                    108: }
                    109: 
                    110: int check_prefs_changed_gfx (void)
                    111: {
                    112:     return 0;
                    113: }
                    114: 
                    115: int graphics_init( void )
                    116: {
                    117:     return 1;
                    118: }
                    119: 
                    120: int graphics_setup( void )
                    121: {
                    122:     return 1;
                    123: }
                    124: 
                    125: void graphics_leave( void )
                    126: {
                    127: }
                    128: 
                    129: void unlockscr( void )
                    130: {
                    131: }
                    132: 
                    133: int lockscr( void )
                    134: {
                    135:     return 0;
                    136: }
                    137: 
                    138: void flush_screen( int a, int b )
                    139: {
                    140: }
                    141: 
                    142: void flush_block( int a, int b )
                    143: {
                    144: }
                    145: 
                    146: void flush_line( int a )
                    147: {
                    148: }
                    149: 
                    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: 
                    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: 
                    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:     {
1.1.1.3 ! root      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" );
1.1       root      206:            goto oops;
1.1.1.3 ! root      207:        }
1.1       root      208: 
                    209:        ddrval = DirectDraw_GetDisplayMode();
                    210:        if (ddrval != DD_OK)
1.1.1.3 ! root      211:        {
        !           212:            write_log( "set_ddraw: Couldn't GetDisplayMode()\n" );
1.1       root      213:            goto oops;
1.1.1.3 ! root      214:        }
1.1       root      215:     }
                    216: 
                    217:     ddrval = DirectDraw_CreateClipper();
                    218:     if (ddrval != DD_OK)
                    219:     {
1.1.1.3 ! root      220:        write_log( "set_ddraw: No clipping support\n" );
        !           221:        goto oops;
1.1       root      222:     }
                    223: 
                    224:     ddrval = DirectDraw_CreateSurface( width, height );
                    225:     if( ddrval != DD_OK )
                    226:     {
1.1.1.3 ! root      227:        write_log( "set_ddraw: Couldn't CreateSurface() for primary because %s.\n", DirectDraw_ErrorString( ddrval ) );
1.1       root      228:        goto oops;
                    229:     }
                    230: 
1.1.1.2   root      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: 
1.1       root      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:     {
1.1.1.3 ! root      260:        write_log( "set_ddraw: Couldn't SetHWnd()\n" );
1.1       root      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) {
1.1.1.3 ! root      269:        current_palette = pal;
        !           270:        ddrval = DirectDraw_CreatePalette( pal );
1.1       root      271:        if (ddrval != DD_OK)
1.1.1.3 ! root      272:        {
        !           273:            write_log( "set_ddraw: Couldn't CreatePalette()\n" );
        !           274:                goto oops;
        !           275:        }
1.1       root      276:     }
                    277: 
                    278:     return 1;
                    279: 
                    280:   oops:
                    281:     if( wantfull )
1.1.1.3 ! root      282:        DirectDraw_SetCooperativeLevel( hAmigaWnd, 0 ); /* No full-screen, so that people can see our gui_message() */
1.1       root      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: 
                    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: 
                    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: 
                    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:     {
1.1.1.3 ! root      342:        hAmigaWnd = CreateWindowEx (WS_EX_TOPMOST,
1.1       root      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);
1.1.1.3 ! root      349:        if( hAmigaWnd )
        !           350:        {
        !           351:            window_created = 1;
        !           352:            ddrval = DirectDraw_SetCooperativeLevel( hAmigaWnd, TRUE ); /* TRUE indicates full-screen */
        !           353:            if( ddrval != DD_OK )
        !           354:            {
1.1       root      355:                write_log( "WIN32GFX_FigurePixelFormats: ERROR -  %s\n", DirectDraw_ErrorString(ddrval) );
1.1.1.3 ! root      356:                gui_message( "WIN32GFX_FigurePixelFormats: ERROR - %s\n", DirectDraw_ErrorString(ddrval) );
        !           357:                goto out;
        !           358:            }
        !           359:        }
        !           360:        else
        !           361:        {
1.1       root      362:            write_log( "WIN32GFX_FigurePixelFormats: ERROR - test-window could not be created.\n" );
1.1.1.3 ! root      363:            gui_message( "WIN32GFX_FigurePixelFormats: ERROR - test-window could not be created.\n" );
        !           364:        }
1.1       root      365:     }
                    366:     else
                    367:     {
1.1.1.3 ! root      368:        got_16bit_mode = 1;
1.1       root      369:     }
                    370: 
                    371:     for (dm = win32_displaymode_list; dm != 0; dm = dm->next) 
                    372:     {
1.1.1.3 ! root      373:        if (!got_16bit_mode)
        !           374:        {
        !           375:            write_log ("figure_pixel_formats: Attempting %dx%d: ", dm->width, dm->height);
1.1       root      376: 
1.1.1.3 ! root      377:            ddrval = DirectDraw_SetDisplayMode( dm->width, dm->height, 16, 0 ); /* 0 for default freq */
1.1       root      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) 
1.1.1.3 ! root      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:        }
1.1       root      403:     }
                    404:     out:
                    405:     if( window_created )
                    406:     {
1.1.1.3 ! root      407:        Sleep( 2000 );
        !           408:        DestroyWindow( hAmigaWnd );
1.1       root      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.  */
                    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:     {
1.1.1.2   root      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??? */
1.1.1.3 ! root      433:        i = 0;
        !           434:        index = 0;
1.1       root      435: 
1.1.1.2   root      436:        best = win32_displaymode_list;
                    437:        dm = best->next;
1.1       root      438: 
1.1.1.2   root      439:        while (dm != 0) 
1.1.1.3 ! root      440:        {
1.1.1.2   root      441:            if ((dm->colormodes & mask) != 0) 
1.1.1.3 ! root      442:            {
1.1.1.2   root      443:                if (dm->width <= best->width && dm->height <= best->height
                    444:                    && dm->width >= *pwidth && dm->height >= *pheight)
1.1.1.3 ! root      445:                {
1.1.1.2   root      446:                    best = dm;
1.1.1.3 ! root      447:                    index = i;
        !           448:                }
1.1.1.2   root      449:                if (dm->width >= best->width && dm->height >= best->height
                    450:                    && dm->width <= *pwidth && dm->height <= *pheight)
1.1.1.3 ! root      451:                {
1.1.1.2   root      452:                    best = dm;
1.1.1.3 ! root      453:                    index = i;
        !           454:                }
1.1       root      455:            }
1.1.1.2   root      456:            dm = dm->next;
1.1.1.3 ! root      457:            i++;
1.1.1.2   root      458:        }
                    459:        if (best->width == *pwidth && best->height == *pheight)
1.1.1.3 ! root      460:        {
        !           461:            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      462:                                     Workbench (using -H 2, but SHOULD have been -H 1), and end up with an 8-bit mode instead*/
                    463:            break;
1.1.1.3 ! root      464:        }
1.1       root      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? */
1.1.1.2   root      475:        *ppixbits = 15;
1.1       root      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
1.1.1.3 ! root      483:        index = -1;
1.1       root      484: 
                    485:     return index;
                    486: }
                    487: 
                    488: void flush_line( int lineno )
                    489: {
                    490: 
                    491: }
                    492: 
                    493: void flush_block (int a, int b)
                    494: {
                    495: 
                    496: }
                    497: 
                    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: 
                    516: static uae_u8 *dolock (void)
                    517: {
                    518:     char *surface = NULL, *oldsurface;
                    519: 
                    520:     if( !DirectDraw_SurfaceLock( lockable_surface ) )
1.1.1.3 ! root      521:        return 0;
1.1       root      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: 
                    536: int lockscr( void )
                    537: {
                    538:     return dolock() != 0;
                    539: }
                    540: 
                    541: uae_u8 *gfx_lock_picasso (void)
                    542: {
                    543:     return dolock ();
                    544: }
                    545: 
                    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) */
1.1.1.3 ! root      552:        if( DirectDraw_GetLockableType() == secondary_surface )
1.1       root      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:        }
1.1.1.3 ! root      569:        p96_double_buffer_needs_flushing = 0;
1.1       root      570:     }
                    571: }
                    572: 
                    573: static void close_hwnds( void )
                    574: {
                    575:     if (hStatusWnd)
                    576:     {
1.1.1.3 ! root      577:        ShowWindow( hStatusWnd, SW_HIDE );
        !           578:        DestroyWindow (hStatusWnd);
1.1       root      579:     }
                    580:     if (hAmigaWnd)
                    581:     {
1.1.1.3 ! root      582:        ShowWindow( hAmigaWnd, SW_HIDE );
1.1       root      583:        DestroyWindow (hAmigaWnd);
                    584:     }
                    585:     if (hMainWnd)
                    586:     {
1.1.1.3 ! root      587:        ShowWindow( hMainWnd, SW_HIDE );
1.1       root      588:        DestroyWindow (hMainWnd);
                    589:     }
                    590: 
                    591:     hMainWnd = 0;
                    592:     hStatusWnd = 0;
                    593:     hAmigaWnd = 0;
                    594: }
                    595: 
                    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 )
1.1.1.3 ! root      635:        overlay = 0;
1.1       root      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: 
                    719: int check_prefs_changed_gfx (void)
                    720: {
                    721:     if (display_change_requested || 
1.1.1.3 ! root      722:        ( currprefs.gfx_afullscreen != changed_prefs.gfx_afullscreen ) ||
        !           723:        ( currprefs.gfx_pfullscreen != changed_prefs.gfx_pfullscreen ) )
1.1       root      724:     {
                    725:        display_change_requested = 0;
1.1.1.3 ! root      726:        currprefs.gfx_afullscreen = changed_prefs.gfx_afullscreen;
        !           727:        currprefs.gfx_pfullscreen = changed_prefs.gfx_pfullscreen;
        !           728:        close_windows ();
1.1       root      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: 
                    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: 
                    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:     {
1.1.1.3 ! root      771:        case 1:
1.1       root      772:            memcpy (xcolors, xcol8, sizeof xcolors);
                    773:            ddrval = DirectDraw_SetPaletteEntries( 0, 256, colors256 );
                    774:            if (ddrval != DD_OK)
1.1.1.3 ! root      775:                gui_message ("DX_SetPalette() failed with %s/%d\n", DirectDraw_ErrorString (ddrval), ddrval);
1.1       root      776:        break;
                    777: 
1.1.1.3 ! root      778:        case 2:
        !           779:        case 3:
        !           780:        case 4:
1.1       root      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: 
                    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: 
                    858: void DX_SetPalette (int start, int count)
                    859: {
                    860:     HRESULT ddrval;
                    861: 
                    862:     if( !screen_is_picasso )
1.1.1.3 ! root      863:        return;
1.1       root      864: 
                    865:     if( picasso96_state.RGBFormat != RGBFB_CHUNKY )
                    866:     {
1.1.1.3 ! root      867:        /* notice_screen_contents_lost(); */
        !           868:        return;
1.1       root      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) 
1.1.1.3 ! root      876:        {
1.1       root      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)
1.1.1.3 ! root      893:                gui_message("DX_SetPalette() failed with %s/%d\n", DirectDraw_ErrorString (ddrval), ddrval);
1.1       root      894:     }
                    895:     else
                    896:     {
                    897:            write_log ("ERROR - DX_SetPalette() pixbytes %d\n", current_pixbytes );
                    898:     }
                    899: }
                    900: 
                    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: 
                    910: int DX_BitsPerCannon (void)
                    911: {
                    912:     return 8;
                    913: }
                    914: 
                    915: static COLORREF BuildColorRef( int color, RGBFTYPE pixelformat )
                    916: {
                    917:     COLORREF result;
                    918: 
                    919:     /* Do special case first */
                    920:     if( pixelformat == RGBFB_CHUNKY )
1.1.1.3 ! root      921:        result = color;
1.1       root      922:     else
1.1.1.3 ! root      923:        result = do_get_mem_long( &color );
1.1       root      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:     {
1.1.1.3 ! root      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;
1.1       root      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:  */
                    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.
                   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: 
                   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 )
1.1.1.3 ! root     1074:        OffsetRect( &dstrect, amigawin_rect.left, amigawin_rect.top );
1.1       root     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 )
1.1.1.3 ! root     1100:                SetRect( &dstrect, dstx, dsty, dstx+width, dsty+height );
        !          1101:            result = DirectDraw_Blt( secondary_surface, &dstrect, secondary_surface, &srcrect, DDBLT_WAIT | DDBLT_ROP, &fx );
1.1       root     1102:        }
                   1103:     }
                   1104: 
                   1105:     return result;
                   1106: }
                   1107: 
                   1108: void DX_WaitVerticalSync( void )
                   1109: {
                   1110:     DirectDraw_WaitForVerticalBlank( DDWAITVB_BLOCKBEGIN );
                   1111: }
                   1112: 
                   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: 
                   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: 
                   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: 
                   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: 
                   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: 
                   1179: int graphics_init (void)
                   1180: {
                   1181:     return open_windows ();
                   1182: }
                   1183: 
                   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: 
                   1196: void graphics_leave (void)
                   1197: {
                   1198:     close_windows ();
                   1199:     dumpcustom ();
                   1200:     cleanup_modes ();
                   1201: }
                   1202: 
                   1203: uae_u32 OSDEP_minimize_uae( void )
                   1204: {
                   1205:     return ShowWindow( hAmigaWnd, SW_MINIMIZE );
                   1206: }
                   1207: 
                   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
1.1.1.2   root     1228:     overlay = 1; // Go back to desiring overlay support
1.1       root     1229: }
                   1230: 
                   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: 
                   1243: static int create_windows (void)
                   1244: {
                   1245:     if (!fullscreen) 
                   1246:     {
1.1.1.3 ! root     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;
1.1       root     1252:            LPINT lpParts;
                   1253: 
1.1.1.3 ! root     1254:        RegQueryValueEx( hWinUAEKey, "xPos", 0, &regkeytype, (LPBYTE)&stored_x, &regkeysize );
        !          1255:        RegQueryValueEx( hWinUAEKey, "yPos", 0, &regkeytype, (LPBYTE)&stored_y, &regkeysize );
        !          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;
1.1       root     1270: 
1.1.1.3 ! root     1271:        rc.right = rc.left + current_width;
        !          1272:        rc.bottom = rc.top + current_height + GetSystemMetrics( SM_CYMENU ) + GetSystemMetrics( SM_CYBORDER )*3;
1.1       root     1273: 
                   1274:        AdjustWindowRect (&rc, NORMAL_WINDOW_STYLE, FALSE);
                   1275: 
1.1.1.3 ! root     1276:        hMainWnd = CreateWindowEx( picasso_on ? WS_EX_ACCEPTFILES : WS_EX_ACCEPTFILES | WS_EX_APPWINDOW, "PCsuxRox", "WinUAE",
1.1       root     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) 
1.1.1.3 ! root     1285:        {
1.1       root     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) 
1.1.1.3 ! root     1290:            {
1.1       root     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;
1.1.1.3 ! root     1296:                lpParts[1] = lpParts[0] + FPS_WIDTH;
1.1       root     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:     {
1.1.1.3 ! root     1324:        close_hwnds();
1.1       root     1325:        return 0;
                   1326:     }
                   1327: 
                   1328: 
                   1329:     if (hMainWnd)
1.1.1.3 ! root     1330:        UpdateWindow( hMainWnd );
1.1       root     1331:     if (hAmigaWnd)
1.1.1.3 ! root     1332:        UpdateWindow (hAmigaWnd);
1.1       root     1333: 
                   1334:     return 1;
                   1335: }
                   1336: 
                   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: 
                   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;
1.1.1.3 ! root     1401:        picasso_vidinfo.rowbytes = DirectDraw_GetSurfacePitch();
1.1       root     1402:        picasso_vidinfo.pixbytes = DirectDraw_GetBytesPerPixel();
                   1403:        picasso_vidinfo.rgbformat = DirectDraw_GetPixelFormat();
                   1404:     }
                   1405:     else
                   1406:     {
                   1407:        if (fullscreen)
1.1.1.3 ! root     1408:        {
1.1       root     1409: #if 0
1.1.1.3 ! root     1410:            write_log( "Calling adjust_screenmode with %d,%d,%d\n", window_width, window_height, window_depth );
1.1       root     1411:            if( WIN32GFX_AdjustScreenmode( &window_width, &window_height, &window_depth ) < 0 )
                   1412:                abort ();
1.1.1.3 ! root     1413:            write_log( "Finished adjust_screenmode with %d,%d,%d\n", window_width, window_height, window_depth );
1.1       root     1414: #endif
1.1.1.3 ! root     1415:        }
1.1       root     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;
1.1.1.3 ! root     1424:        gfxvidinfo.maxblocklines = 0; // flush_screen actually does everything
1.1       root     1425:        gfxvidinfo.rowbytes = DirectDraw_GetSurfacePitch();
                   1426:     }
                   1427: 
                   1428:     if( fullscreen ) 
                   1429:     {
1.1.1.3 ! root     1430:        WIN32_MouseDefaults();
1.1       root     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:     {
1.1.1.3 ! root     1438:        write_log( "%s mode (bits: %d, pixbytes: %d)\n", fullscreen ? "Full screen" : "Window",
1.1       root     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)
1.1.1.3 ! root     1456:        SendMessage( hMainWnd, WM_WINDOWPOSCHANGED, 0, 0);
1.1       root     1457: #endif
                   1458: 
                   1459:     bInitDone = TRUE;
                   1460:     return 1;
                   1461: 
                   1462: oops:
                   1463:     DirectDraw_Release();
                   1464:     close_hwnds();
                   1465:     return 0;
                   1466: }
                   1467: 
                   1468: 
                   1469: void WIN32GFX_PaletteChange( void )
                   1470: {
                   1471:     DirectDraw_SetPalette( 1 ); /* Remove current palette */
                   1472:     DirectDraw_SetPalette( 0 ); /* Set our real palette */
                   1473: }
                   1474: 
                   1475: void WIN32GFX_ClearPalette( void )
                   1476: {
                   1477:     DirectDraw_SetPalette( 1 ); /* Remove palette */
                   1478: }
                   1479: 
                   1480: void WIN32GFX_SetPalette( void )
                   1481: {
                   1482:     DirectDraw_SetPalette( 0 ); /* Set palette */
                   1483: }
                   1484: #endif
                   1485: void WIN32GFX_WindowMove ( void )
                   1486: {
                   1487:     if (overlay && hMainWnd && bInitDone) setoverlay();
                   1488: }
                   1489: 
                   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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.