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

1.1       root        1: /*
                      2:  * UAE - The Un*x Amiga Emulator
                      3:  *
                      4:  * Win32 interface
                      5:  *
                      6:  * Copyright 1997 Mathias Ortmann
                      7:  */
                      8: 
1.1.1.2 ! root        9: #include "config.h"
        !            10: #include "sysconfig.h"
        !            11: 
1.1       root       12: #include <stdlib.h>
                     13: #include <stdarg.h>
1.1.1.2 ! root       14: #include <signal.h>
        !            15: 
        !            16: /* No idea what this is for, but it doesn't link without it if we use
        !            17:    QueryInterface.  */
        !            18: #define INITGUID
        !            19: 
        !            20: #include <windows.h>
        !            21: #include <ddraw.h>
1.1       root       22: #include <commctrl.h>
                     23: #include <commdlg.h>
                     24: #include <io.h>
                     25: 
                     26: #include "sysdeps.h"
                     27: #include "options.h"
                     28: #include "gensound.h"
                     29: #include "sounddep/sound.h"
                     30: #include "uae.h"
                     31: #include "memory.h"
                     32: #include "custom.h"
                     33: #include "events.h"
                     34: #include "xwin.h"
                     35: #include "keyboard.h"
                     36: #include "picasso96.h"
                     37: 
1.1.1.2 ! root       38: #include "osdep/win32.h"
1.1       root       39: #include "osdep/win32gui.h"
                     40: #include "resource.h"
                     41: 
1.1.1.2 ! root       42: #define IHF_WINDOWHIDDEN 6
1.1       root       43: 
                     44: HINSTANCE hInst;
1.1.1.2 ! root       45: 
        !            46: static BOOL (WINAPI * pGetOpenFileNameA) (LPOPENFILENAME);
        !            47: static HRESULT (WINAPI * pDirectDrawCreate) (GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *);
        !            48: static HRESULT CALLBACK modesCallback (LPDDSURFACEDESC modeDesc, LPVOID context);
        !            49: 
        !            50: static int display_change_requested = 0;
        !            51: 
        !            52: int julian_mode;
        !            53: int debug_logging = 3;
        !            54: 
        !            55: HWND hAmigaWnd, hMainWnd, hStatusWnd;
        !            56: /*DWORD Keys; */
1.1       root       57: static RECT amigawin_rect;
                     58: 
                     59: char *start_path = NULL;
                     60: 
                     61: static LPDIRECTDRAW lpDD;
1.1.1.2 ! root       62: static LPDIRECTDRAW2 lpDD2;
1.1       root       63: static LPDIRECTDRAWSURFACE lpDDS;
                     64: static LPDIRECTDRAWCLIPPER lpDDC;
                     65: static LPDIRECTDRAWPALETTE lpDDP;
1.1.1.2 ! root       66: static DDSURFACEDESC current_surface;
1.1       root       67: static DDSURFACEDESC ddsd;
                     68: 
                     69: #define TITLETEXT PROGNAME " -- Amiga Display"
                     70: 
1.1.1.2 ! root       71: char VersionStr[256];
1.1       root       72: 
1.1.1.2 ! root       73: static int current_width, current_height, current_depth;
        !            74: static int fullscreen, needs_fullscreen;
1.1       root       75: static int current_pixbytes;
                     76: 
1.1.1.2 ! root       77: static int in_sizemove;
1.1       root       78: 
                     79: static int screen_is_picasso = 0;
1.1.1.2 ! root       80: 
        !            81: int customsize = 0;
1.1       root       82: 
                     83: int bActive;
                     84: int toggle_sound;
                     85: 
                     86: int process_desired_pri;
                     87: 
                     88: BOOL viewing_child = FALSE;
1.1.1.2 ! root       89: BOOL running_winnt = FALSE;
1.1       root       90: 
                     91: static char scrlinebuf[8192];  /* this is too large, but let's rather play on the safe side here */
                     92: static int scrindirect;
                     93: 
                     94: static void set_linemem (void)
                     95: {
                     96:     if (scrindirect)
                     97:        gfxvidinfo.linemem = scrlinebuf;
                     98:     else
                     99:        gfxvidinfo.linemem = 0;
                    100: }
                    101: 
                    102: /* Keyboard emulation, Win32 helper routines. */
                    103: static LPARAM keysdown[256];
                    104: static short numkeysdown;
                    105: 
                    106: int checkkey (int vkey, LPARAM lParam)
                    107: {
                    108:     switch (vkey) {
1.1.1.2 ! root      109:      case VK_SHIFT:
        !           110:      case VK_LSHIFT:
        !           111:      case VK_RSHIFT:
        !           112:      case VK_CONTROL:
        !           113:      case VK_LCONTROL:
        !           114:      case VK_RCONTROL:
        !           115:      case VK_MENU:
        !           116:      case VK_LMENU:
        !           117:      case VK_RMENU:
1.1       root      118:        return GetKeyState (vkey) & 0x8000;
                    119:     }
                    120:     return GetAsyncKeyState (vkey) & 0x8000;
                    121: }
                    122: 
                    123: /* Mouse emulation, Win32 interface */
                    124: static int mousecx = 160, mousecy = 100, mousedx = 160, mousedy = 100;
                    125: static int mousecl = MAKELONG (160, 100);
                    126: int mouseactive;
                    127: 
                    128: void setmouseactive (int active)
                    129: {
                    130:     mousedx = (amigawin_rect.right - amigawin_rect.left) / 2;
                    131:     mousedy = (amigawin_rect.bottom - amigawin_rect.top) / 2;
                    132:     mousecl = MAKELONG (mousedx, mousedy);
                    133:     mousecx = amigawin_rect.left + mousedx;
                    134:     mousecy = amigawin_rect.top + mousedy;
                    135: 
                    136:     if (active == mouseactive)
                    137:        return;
                    138:     mouseactive = active;
                    139: 
                    140:     if (active) {
                    141:        ShowCursor (FALSE);
                    142:        SetCursorPos (mousecx, mousecy);
                    143:        SetWindowText (hMainWnd ? hMainWnd : hAmigaWnd, TITLETEXT " [Mouse active - press Alt-Tab to cancel]");
                    144:        ClipCursor (&amigawin_rect);
                    145:     } else {
                    146:        ShowCursor (TRUE);
                    147:        SetWindowText (hMainWnd ? hMainWnd : hAmigaWnd, TITLETEXT);
                    148:        ClipCursor (NULL);
                    149:     }
                    150: }
                    151: 
                    152: static int hascapture = 0;
                    153: 
1.1.1.2 ! root      154: static void setcapture (void)
1.1       root      155: {
                    156:     if (hascapture)
                    157:        return;
                    158:     hascapture++;
                    159:     SetCapture (hAmigaWnd);
                    160: }
                    161: 
                    162: static __inline__ void releasecapture (void)
                    163: {
                    164:     if (!hascapture)
                    165:        return;
                    166:     hascapture--;
                    167:     ReleaseCapture ();
                    168: }
                    169: 
1.1.1.2 ! root      170: static void illhandler(int foo)
        !           171: {
        !           172:     rpt_available = 0;
        !           173: }
        !           174: 
1.1       root      175: static void figure_processor_speed (void)
                    176: {
1.1.1.2 ! root      177:     frame_time_t best_time;
        !           178:     int i;
1.1       root      179: 
1.1.1.2 ! root      180:     rpt_available = 1;
        !           181:     signal (SIGILL, illhandler);
        !           182:     read_processor_time ();
        !           183:     signal (SIGILL, SIG_DFL);
        !           184:     if (! rpt_available) {
        !           185:        fprintf (stderr, "Your processor does not support the RDTSC instruction.\n");
1.1       root      186:        return;
                    187:     }
1.1.1.2 ! root      188:     fprintf (stderr, "Calibrating delay loop.. ");
        !           189:     fflush (stderr);
        !           190:     best_time = (frame_time_t)-1;
        !           191:     for (i = 0; i < 5; i++) {
        !           192:        frame_time_t t = read_processor_time ();
        !           193:        Sleep (1001);
        !           194:        t = 2 * read_processor_time () - t;
        !           195:        Sleep (1);
        !           196:        t -= read_processor_time ();
        !           197:        if (t < best_time)
        !           198:            best_time = t;
1.1       root      199:     }
1.1.1.2 ! root      200:     fprintf (stderr, "ok - %.2f BogoMIPS\n",
        !           201:             ((double)best_time / 1000000), best_time);
        !           202:     vsynctime = best_time / 50;
1.1       root      203: }
                    204: 
1.1.1.2 ! root      205: /* DirectDraw stuff */
        !           206: static char *getddrname (HRESULT ddrval)
1.1       root      207: {
                    208:     switch (ddrval) {
                    209:     case DDERR_ALREADYINITIALIZED:
                    210:        return "This object is already initialized.";
                    211:     case DDERR_BLTFASTCANTCLIP:
                    212:        return "Cannot use BLTFAST with Clipper attached to surface.";
                    213:     case DDERR_CANNOTATTACHSURFACE:
                    214:        return "Cannot attach surface.";
                    215:     case DDERR_CANNOTDETACHSURFACE:
                    216:        return "Cannot detach surface.";
                    217:     case DDERR_CANTCREATEDC:
                    218:        return "Cannot create DC Device Context.";
                    219:     case DDERR_CANTDUPLICATE:
                    220:        return "Cannot duplicate.";
                    221:     case DDERR_CANTLOCKSURFACE:
                    222:        return "Access to surface refused (no DCI provider).";
                    223:     case DDERR_CANTPAGELOCK:
                    224:        return "PageLock failure.";
                    225:     case DDERR_CANTPAGEUNLOCK:
                    226:        return "PageUnlock failure.";
                    227:     case DDERR_CLIPPERISUSINGHWND:
                    228:        return "Can't set a clip-list for a Clipper which is attached to an HWND.";
                    229:     case DDERR_COLORKEYNOTSET:
                    230:        return "No source colour-key provided.";
                    231:     case DDERR_CURRENTLYNOTAVAIL:
                    232:        return "Support unavailable.";
                    233:     case DDERR_DCALREADYCREATED:
                    234:        return "Surface already has a Device Context.";
                    235:     case DDERR_DIRECTDRAWALREADYCREATED:
                    236:        return "DirectDraw already bound to this process.";
                    237:     case DDERR_EXCEPTION:
                    238:        return "Unexpected exception.";
                    239:     case DDERR_EXCLUSIVEMODEALREADYSET:
                    240:        return "Already in exclusive mode.";
                    241:     case DDERR_GENERIC:
                    242:        return "Undefined";     /* THIS MAKES SENSE!  FUCKING M$ */
                    243: 
                    244:     case DDERR_HEIGHTALIGN:
                    245:        return "Height needs to be aligned.";
                    246:     case DDERR_HWNDALREADYSET:
                    247:        return "HWND already set for cooperative level.";
                    248:     case DDERR_HWNDSUBCLASSED:
                    249:        return "HWND has been subclassed.";
                    250:     case DDERR_IMPLICITLYCREATED:
                    251:        return "Can't restore an implicitly created surface.";
                    252:     case DDERR_INCOMPATIBLEPRIMARY:
                    253:        return "New params doesn't match existing primary surface.";
                    254:     case DDERR_INVALIDCAPS:
                    255:        return "Device doesn't have requested capabilities.";
                    256:     case DDERR_INVALIDCLIPLIST:
                    257:        return "Provided clip-list not supported.";
                    258:     case DDERR_INVALIDDIRECTDRAWGUID:
                    259:        return "Invalid GUID.";
                    260:     case DDERR_INVALIDMODE:
                    261:        return "Mode not supported.";
                    262:     case DDERR_INVALIDOBJECT:
                    263:        return "Invalid object.";
                    264:     case DDERR_INVALIDPARAMS:
                    265:        return "Invalid params.";
                    266:     case DDERR_INVALIDPIXELFORMAT:
                    267:        return "Device doesn't support requested pixel format.";
                    268:     case DDERR_INVALIDPOSITION:
                    269:        return "Overlay position illegal.";
                    270:     case DDERR_INVALIDRECT:
                    271:        return "Invalid RECT.";
                    272:     case DDERR_INVALIDSURFACETYPE:
                    273:        return "Wrong type of surface.";
                    274:     case DDERR_LOCKEDSURFACES:
                    275:        return "Surface locked.";
                    276:     case DDERR_NO3D:
                    277:        return "No 3d capabilities.";
                    278:     case DDERR_NOALPHAHW:
                    279:        return "No alpha h/w.";
                    280:     case DDERR_NOBLTHW:
                    281:        return "No blit h/w.";
                    282:     case DDERR_NOCLIPLIST:
                    283:        return "No clip-list.";
                    284:     case DDERR_NOCLIPPERATTACHED:
                    285:        return "No Clipper attached.";
                    286:     case DDERR_NOCOLORCONVHW:
                    287:        return "No colour-conversion h/w.";
                    288:     case DDERR_NOCOLORKEY:
                    289:        return "No colour-key.";
                    290: 
                    291:     case DDERR_NOTLOCKED:
                    292:        return "Not locked.";
                    293:     case DDERR_NOTPAGELOCKED:
                    294:        return "Not page-locked.";
                    295:     case DDERR_NOTPALETTIZED:
                    296:        return "Not palette-based.";
                    297: 
                    298:     case DDERR_OUTOFCAPS:
                    299:        return "out of caps";
                    300:     case DDERR_OUTOFMEMORY:
                    301:        return "Out of memory.";
                    302:     case DDERR_OUTOFVIDEOMEMORY:
                    303:        return "out of video memory.";
                    304:     case DDERR_PALETTEBUSY:
                    305:        return "Palette busy.";
                    306:     case DDERR_PRIMARYSURFACEALREADYEXISTS:
                    307:        return "Already a primary surface.";
                    308: 
                    309:     case DDERR_SURFACEBUSY:
                    310:        return "Surface busy.";
1.1.1.2 ! root      311:        /*case DDERR_SURFACEOBSCURED:     return "Surface is obscured."; */
1.1       root      312:     case DDERR_SURFACELOST:
                    313:        return "Surface lost.";
                    314: 
                    315:     case DDERR_UNSUPPORTED:
                    316:        return "Unsupported.";
                    317:     case DDERR_UNSUPPORTEDFORMAT:
                    318:        return "Unsupported format.";
                    319: 
                    320:     case DDERR_WASSTILLDRAWING:
                    321:        return "Was still drawing.";
                    322:     }
                    323:     return "";
                    324: }
                    325: 
                    326: static int lockcnt = 0;
                    327: 
                    328: static int do_surfacelock (void)
                    329: {
                    330:     HRESULT ddrval = IDirectDrawSurface_Lock (lpDDS, NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
                    331:     if (ddrval != DD_OK) {
                    332:        if (ddrval == DDERR_SURFACELOST)
                    333:            ddrval = IDirectDrawSurface_Restore (lpDDS);
                    334:        else if (ddrval != DDERR_SURFACEBUSY)
1.1.1.2 ! root      335:            write_log ("lpDDS->Lock() failed - %s (%d)\n", getddrname (ddrval), (unsigned short) ddrval);
1.1       root      336:        return 0;
                    337:     }
                    338:     lockcnt++;
                    339:     return 1;
                    340: }
                    341: 
                    342: void unlockscr (void)
                    343: {
                    344:     lockcnt--;
                    345:     IDirectDrawSurface_Unlock (lpDDS, ddsd.lpSurface);
                    346: }
                    347: 
1.1.1.2 ! root      348: /* Return one of the pixel formats declared in picasso96.h if the surface
        !           349:  * is usable for us, or RGBFB_NONE if it is not usable.  */
        !           350: static RGBFTYPE surface_pixelformat (DDSURFACEDESC *surface)
        !           351: {
        !           352:     DDPIXELFORMAT *pfp = &surface->ddpfPixelFormat;
        !           353:     DWORD r, g, b;
        !           354: 
        !           355:     if ((surface->dwFlags & (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_REFRESHRATE)) 
        !           356:        != (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_REFRESHRATE))
        !           357:        return RGBFB_NONE;
        !           358: 
        !           359:     if ((pfp->dwFlags & DDPF_RGB) == 0)
        !           360:        return RGBFB_NONE;
        !           361: 
        !           362:     r = pfp->dwRBitMask;
        !           363:     g = pfp->dwGBitMask;
        !           364:     b = pfp->dwBBitMask;
        !           365:     switch (pfp->dwRGBBitCount) {
        !           366:      case 8:
        !           367:        if ((pfp->dwFlags & DDPF_PALETTEINDEXED8) != 0)
        !           368:            return RGBFB_CHUNKY;
        !           369:        break;
        !           370: 
        !           371:      case 16:
        !           372:        if (r == 0xF800 && g == 0x07E0 && b == 0x001F)
        !           373:            return RGBFB_R5G6B5PC;
        !           374:        if (r == 0x7C00 && g == 0x03E0 && b == 0x001F)
        !           375:            return RGBFB_R5G5B5PC;
        !           376:        if (b == 0xF800 && g == 0x07E0 && r == 0x001F)
        !           377:            return RGBFB_B5G6R5PC;
        !           378:        if (b == 0x7C00 && g == 0x03E0 && r == 0x001F)
        !           379:            return RGBFB_B5G5R5PC;
        !           380:        /* This happens under NT - with r == b == g == 0 !!! */
        !           381:        printf ("Unknown 16 bit format %d %d %d\n", r, g, b);
        !           382:        break;
        !           383: 
        !           384:      case 24:
        !           385:        if (r == 0xFF0000 && g == 0x00FF00 && b == 0x0000FF)
        !           386:            return RGBFB_B8G8R8;
        !           387:        if (r == 0x0000FF && g == 0x00FF00 && b == 0xFF0000)
        !           388:            return RGBFB_R8G8B8;
        !           389:        break;
        !           390: 
        !           391:      case 32:
        !           392:        if (r == 0x00FF0000 && g == 0x0000FF00 && b == 0x000000FF)
        !           393:            return RGBFB_B8G8R8A8;
        !           394:        if (r == 0x000000FF && g == 0x0000FF00 && b == 0x00FF0000)
        !           395:            return RGBFB_R8G8B8A8;
        !           396:        if (r == 0xFF000000 && g == 0x00FF0000 && b == 0x0000FF00)
        !           397:            return RGBFB_A8B8G8R8;
        !           398:        if (r == 0x0000FF00 && g == 0x00FF0000 && b == 0xFF000000)
        !           399:            return RGBFB_A8R8G8B8;
        !           400:        break;
        !           401:        
        !           402:      default:
        !           403:        printf ("Unknown %d bit format %d %d %d\n", pfp->dwRGBBitCount, r, g, b);
        !           404:        break;
        !           405:     }
        !           406:     return RGBFB_NONE;
        !           407: }
        !           408: 
        !           409: static int rgbformat_bits (RGBFTYPE t)
        !           410: {
        !           411:     unsigned long f = 1 << t;
        !           412:     return ((f & RGBMASK_8BIT) != 0 ? 8
        !           413:            : (f & RGBMASK_15BIT) != 0 ? 15
        !           414:            : (f & RGBMASK_16BIT) != 0 ? 16
        !           415:            : (f & RGBMASK_24BIT) != 0 ? 24
        !           416:            : (f & RGBMASK_32BIT) != 0 ? 32
        !           417:            : 0);
        !           418: }
        !           419: 
        !           420: static void release_ddraw (void)
1.1       root      421: {
1.1.1.2 ! root      422: #if 0
        !           423:     if (lpDD2) {
        !           424:        IDirectDraw2_RestoreDisplayMode (lpDD2);
        !           425:        IDirectDraw2_SetCooperativeLevel (lpDD2, hAmigaWnd, DDSCL_NORMAL);
        !           426:     }
        !           427: #else
1.1       root      428:     if (lpDD) {
                    429:        IDirectDraw_RestoreDisplayMode (lpDD);
                    430:        IDirectDraw_SetCooperativeLevel (lpDD, hAmigaWnd, DDSCL_NORMAL);
                    431:     }
1.1.1.2 ! root      432: #endif
        !           433: 
1.1       root      434:     if (lpDDC)
                    435:        IDirectDrawClipper_Release (lpDDC);
                    436:     if (lpDDS)
                    437:        IDirectDrawSurface_Release (lpDDS);
                    438:     if (lpDDP)
                    439:        IDirectDrawPalette_Release (lpDDP);
1.1.1.2 ! root      440:     if (lpDD2)
        !           441:        IDirectDraw2_Release (lpDD2);
1.1       root      442:     if (lpDD)
                    443:        IDirectDraw_Release (lpDD);
                    444:     lpDDC = 0;
                    445:     lpDDS = 0;
                    446:     lpDDP = 0;
1.1.1.2 ! root      447:     lpDD2 = 0;
1.1       root      448:     lpDD = 0;
                    449: }
                    450: 
1.1.1.2 ! root      451: 
        !           452: static int start_ddraw (void)
1.1       root      453: {
                    454:     HRESULT ddrval;
                    455: 
                    456:     ddrval = (*pDirectDrawCreate) (NULL, &lpDD, NULL);
1.1.1.2 ! root      457:     if (ddrval != DD_OK)
        !           458:        goto oops;
        !           459: 
        !           460: #if 0
        !           461:     ddrval = IDirectDraw_QueryInterface (lpDD, &IID_IDirectDraw2, (LPVOID *)&lpDD2);
        !           462:     if (ddrval != DD_OK)
        !           463:        goto oops;
1.1       root      464: #endif
1.1.1.2 ! root      465: 
        !           466:     current_surface.dwSize = sizeof current_surface;
        !           467:     ddrval = IDirectDraw_GetDisplayMode (lpDD, &current_surface);
1.1       root      468:     if (ddrval != DD_OK)
                    469:        goto oops;
                    470: 
1.1.1.2 ! root      471:     return 1;
        !           472: 
        !           473:   oops:
        !           474:     write_log ("DirectDraw initialization failed with %s/%d\n", getddrname (ddrval), ddrval);
        !           475:     release_ddraw ();
        !           476:     return 0;
        !           477: }
        !           478: 
        !           479: static int set_ddraw (int width, int height, int wantfull, int bits,
        !           480:                      LPPALETTEENTRY pal)
        !           481: {
        !           482:     HRESULT ddrval;
        !           483: 
        !           484:     bits = (bits + 7) & ~7;
        !           485:     
1.1       root      486:     ddrval = IDirectDraw_SetCooperativeLevel (lpDD, hAmigaWnd,
1.1.1.2 ! root      487:                                              (wantfull
        !           488:                                               ? DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN
        !           489:                                               : DDSCL_NORMAL));
1.1       root      490:     if (ddrval != DD_OK)
                    491:        goto oops;
                    492: 
                    493:     ddrval = IDirectDraw_CreateClipper (lpDD, 0, &lpDDC, NULL);
1.1.1.2 ! root      494:     if (ddrval != DD_OK)
        !           495:        goto oops;
        !           496: 
        !           497:     ddrval = IDirectDrawClipper_SetHWnd (lpDDC, 0, hAmigaWnd);
        !           498:     if (ddrval != DD_OK)
        !           499:        goto oops;
1.1       root      500: 
                    501:     if (wantfull) {
1.1.1.2 ! root      502:        /* Hmmm...
        !           503:         * The "bits" parameter is somewhat suspicious.  What if a graphics
        !           504:         * card supports A8R8G8B8 and A8B8G8R8 modes? */
        !           505:        printf ("Trying %dx%d, %d\n", width, height, bits);
1.1       root      506:        ddrval = IDirectDraw_SetDisplayMode (lpDD, width, height, bits);
                    507:        if (ddrval != DD_OK)
                    508:            goto oops;
1.1.1.2 ! root      509:        printf ("ok\n");
        !           510: 
        !           511:        current_surface.dwSize = sizeof current_surface;
        !           512:        ddrval = IDirectDraw_GetDisplayMode (lpDD, &current_surface);
        !           513:        if (ddrval != DD_OK)
        !           514:            goto oops;
1.1       root      515:     }
1.1.1.2 ! root      516: 
1.1       root      517:     ddsd.dwSize = sizeof (ddsd);
                    518:     ddsd.dwFlags = DDSD_CAPS;
                    519:     ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
                    520: 
                    521:     ddrval = IDirectDraw_CreateSurface (lpDD, &ddsd, &lpDDS, NULL);
                    522:     if (ddrval != DD_OK)
                    523:        goto oops;
                    524: 
                    525:     if (! do_surfacelock ())
                    526:        return 0;
                    527:     unlockscr ();
                    528: 
1.1.1.2 ! root      529:     current_pixbytes = (ddsd.ddpfPixelFormat.dwRGBBitCount + 7) >> 3;
1.1       root      530: 
1.1.1.2 ! root      531:     if (current_pixbytes == 1) {
1.1       root      532:        ddrval = IDirectDraw_CreatePalette (lpDD, DDPCAPS_8BIT | DDPCAPS_ALLOW256,
1.1.1.2 ! root      533:                                            pal,
        !           534:                                            &lpDDP, NULL);
1.1       root      535:        if (ddrval != DD_OK)
                    536:            goto oops;
                    537: 
                    538:        ddrval = IDirectDrawSurface2_SetPalette (lpDDS, lpDDP);
                    539:        if (ddrval != DD_OK)
                    540:            goto oops;
1.1.1.2 ! root      541:     }
1.1       root      542: 
                    543:     return 1;
                    544: 
1.1.1.2 ! root      545:   oops:
        !           546:     write_log ("DirectDraw initialization failed with %s/%d\n", getddrname (ddrval), ddrval);
1.1       root      547:     return 0;
                    548: }
                    549: 
                    550: /* Color management */
                    551: 
                    552: static xcolnr xcol8[4096];
                    553: static PALETTEENTRY colors256[256];
                    554: static int ncols256 = 0;
                    555: 
1.1.1.2 ! root      556: static int red_bits, green_bits, blue_bits;
        !           557: static int red_shift, green_shift, blue_shift;
        !           558: 
        !           559: static int get_color (int r, int g, int b, xcolnr * cnp)
1.1       root      560: {
                    561:     if (ncols256 == 256)
                    562:        return 0;
                    563:     colors256[ncols256].peRed = r * 0x11;
                    564:     colors256[ncols256].peGreen = g * 0x11;
                    565:     colors256[ncols256].peBlue = b * 0x11;
                    566:     colors256[ncols256].peFlags = 0;
                    567:     *cnp = ncols256;
                    568:     ncols256++;
                    569:     return 1;
                    570: }
                    571: 
                    572: static void init_colors (void)
                    573: {
1.1.1.2 ! root      574:     int i;
        !           575: 
        !           576:     if (ncols256 == 0) {
1.1       root      577:        alloc_colors256 (get_color);
1.1.1.2 ! root      578:        memcpy (xcol8, xcolors, sizeof xcol8);
        !           579:     }
1.1       root      580: 
                    581:     /* init colors */
                    582: 
                    583:     switch (current_pixbytes) {
1.1.1.2 ! root      584:     case 1:
1.1       root      585:        memcpy (xcolors, xcol8, sizeof xcolors);
                    586:        if (lpDDP != 0) {
                    587:            HRESULT ddrval = IDirectDrawPalette_SetEntries (lpDDP, 0, 0, 256, colors256);
                    588:            if (ddrval != DD_OK)
1.1.1.2 ! root      589:                write_log ("DX_SetPalette() failed with %s/%d\n", getddrname (ddrval), ddrval);
1.1       root      590:        }
                    591:        break;
                    592: 
1.1.1.2 ! root      593:     case 2:
        !           594:     case 3:
        !           595:     case 4:
        !           596:        red_bits = bits_in_mask (ddsd.ddpfPixelFormat.dwRBitMask);
        !           597:        green_bits = bits_in_mask (ddsd.ddpfPixelFormat.dwGBitMask);
        !           598:        blue_bits = bits_in_mask (ddsd.ddpfPixelFormat.dwBBitMask);
        !           599:        red_shift = mask_shift (ddsd.ddpfPixelFormat.dwRBitMask);
        !           600:        green_shift = mask_shift (ddsd.ddpfPixelFormat.dwGBitMask);
        !           601:        blue_shift = mask_shift (ddsd.ddpfPixelFormat.dwBBitMask);
1.1       root      602: 
1.1.1.2 ! root      603:        alloc_colors64k (red_bits, green_bits, blue_bits, red_shift,
        !           604:                         green_shift, blue_shift);
        !           605:        break;
        !           606:     }
        !           607:     switch (gfxvidinfo.pixbytes) {
        !           608:      case 2:
        !           609:        for (i = 0; i < 4096; i++)
        !           610:            xcolors[i] = xcolors[i] * 0x00010001;
        !           611:        gfxvidinfo.can_double = 1;
        !           612:        break;
        !           613:      case 1:
        !           614:        for (i = 0; i < 4096; i++)
        !           615:            xcolors[i] = xcolors[i] * 0x01010101;
        !           616:        gfxvidinfo.can_double = 1;
        !           617:        break;
        !           618:      default:
        !           619:        gfxvidinfo.can_double = 0;
1.1       root      620:        break;
                    621:     }
                    622: }
                    623: 
                    624: static void close_windows (void)
                    625: {
                    626:     gfxvidinfo.bufmem = 0;
                    627:     gfxvidinfo.linemem = 0;
                    628: 
                    629:     releasecapture ();
                    630:     setmouseactive (0);
                    631:     ClipCursor (NULL);
1.1.1.2 ! root      632:     release_ddraw ();
        !           633:     dsound_newwindow (0);
1.1       root      634: 
                    635:     if (hAmigaWnd)
                    636:        DestroyWindow (hAmigaWnd);
1.1.1.2 ! root      637:     if (hStatusWnd)
        !           638:        DestroyWindow (hStatusWnd);
1.1       root      639:     if (hMainWnd)
                    640:        DestroyWindow (hMainWnd);
1.1.1.2 ! root      641: 
1.1       root      642:     hMainWnd = 0;
1.1.1.2 ! root      643:     hStatusWnd = 0;
1.1       root      644:     hAmigaWnd = 0;
                    645: }
                    646: 
                    647: void toggle_fullscreen (void)
                    648: {
1.1.1.2 ! root      649:     if (needs_fullscreen)
        !           650:        return;
        !           651: 
        !           652:     display_change_requested = 1;
1.1       root      653:     if (screen_is_picasso)
1.1.1.2 ! root      654:        currprefs.gfx_pfullscreen ^= 1;
1.1       root      655:     else
1.1.1.2 ! root      656:        currprefs.gfx_afullscreen ^= 1;    
1.1       root      657: }
                    658: 
1.1.1.2 ! root      659: static long FAR PASCAL AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1.1       root      660: {
                    661:     PAINTSTRUCT ps;
                    662:     HDC hDC;
                    663: 
                    664:     switch (message) {
1.1.1.2 ! root      665:      case WM_ACTIVATEAPP:
1.1       root      666:        if (bActive = wParam) {
                    667:            if (fullscreen) {
                    668:                SetCursor (NULL);
1.1.1.2 ! root      669:                SetCursorPos (mousecx, mousecy);
1.1       root      670:            }
                    671:            my_kbd_handler (VK_CAPITAL, 0x3a, TRUE);
                    672:        } else {
                    673:            if (!fullscreen)
                    674:                setmouseactive (0);
                    675:        }
                    676:        break;
                    677: 
1.1.1.2 ! root      678:      case WM_ACTIVATE:
1.1       root      679:        if (LOWORD (wParam) != WA_INACTIVE) {
                    680:            ShowWindow (hWnd, SW_RESTORE);
                    681:        }
                    682:        break;
                    683: 
1.1.1.2 ! root      684:      case WM_SETCURSOR:
1.1       root      685:        if (fullscreen) {
                    686:            SetCursor (NULL);
                    687:            return TRUE;
                    688:        }
                    689:        break;
                    690: 
1.1.1.2 ! root      691:      case WM_SYSCOMMAND:
1.1       root      692:        if (wParam == SC_ZOOM) {
                    693:            toggle_fullscreen ();
                    694:            return 0;
                    695:        }
                    696:        break;
                    697: 
1.1.1.2 ! root      698:      case WM_KEYUP:
        !           699:      case WM_SYSKEYUP:
1.1       root      700:        numkeysdown--;
                    701:        keysdown[wParam] = 0;
                    702:        my_kbd_handler (wParam, (lParam >> 16) & 0x1ff, FALSE);
                    703:        break;
                    704: 
1.1.1.2 ! root      705:      case WM_KEYDOWN:
        !           706:      case WM_SYSKEYDOWN:
1.1       root      707:        if (LOWORD (lParam) == 1) {
                    708:            if (numkeysdown) {
                    709:                int key;
                    710:                numkeysdown = 0;
                    711: 
                    712:                for (key = 256; key--;) {
                    713:                    if (keysdown[key]) {
                    714:                        if (checkkey (key, lParam))
                    715:                            numkeysdown++;
                    716:                        else {
                    717:                            my_kbd_handler (key, (keysdown[key] >> 16) & 0x1ff, FALSE);
                    718:                            keysdown[key] = 0;
                    719:                        }
                    720:                    }
                    721:                }
                    722:            }
                    723:            if (!keysdown[wParam]) {
                    724:                keysdown[wParam] = lParam;
                    725:                numkeysdown++;
                    726:            }
                    727:            numkeysdown++;
                    728:            my_kbd_handler (wParam, (lParam >> 16) & 0x1ff, TRUE);
                    729:        }
                    730:        break;
                    731: 
1.1.1.2 ! root      732:      case WM_LBUTTONDOWN:
1.1       root      733:        if (ievent_alive) {
                    734:            setcapture ();
                    735:            buttonstate[0] = 1;
                    736:        } else if (!fullscreen && !mouseactive)
                    737:            setmouseactive (1);
                    738:        else
                    739:            buttonstate[0] = 1;
                    740:        break;
                    741: 
1.1.1.2 ! root      742:      case WM_LBUTTONUP:
1.1       root      743:        releasecapture ();
                    744:        buttonstate[0] = 0;
                    745:        break;
                    746: 
1.1.1.2 ! root      747:      case WM_MBUTTONDOWN:
1.1       root      748:        if (ievent_alive)
                    749:            setcapture ();
                    750:        buttonstate[1] = 1;
                    751:        break;
                    752: 
1.1.1.2 ! root      753:      case WM_MBUTTONUP:
1.1       root      754:        releasecapture ();
                    755:        buttonstate[1] = 0;
                    756:        break;
                    757: 
1.1.1.2 ! root      758:      case WM_RBUTTONDOWN:
1.1       root      759:        if (ievent_alive)
                    760:            setcapture ();
                    761:        buttonstate[2] = 1;
                    762:        break;
                    763: 
1.1.1.2 ! root      764:      case WM_RBUTTONUP:
1.1       root      765:        releasecapture ();
                    766:        buttonstate[2] = 0;
                    767:        break;
                    768: 
1.1.1.2 ! root      769:      case WM_MOUSEMOVE:
1.1       root      770:        if ((mouseactive && !ievent_alive) || fullscreen) {
                    771:            /*
                    772:             * In this mode, the mouse pointer is always centered in the window,
                    773:             * this is ensured by the SetCursorPos call below.
                    774:             * We don't want to handle messages that result from such a SetCursorPos
                    775:             * call (recursion!), so exit early if we see one.
                    776:             */
                    777:            if (lParam == mousecl)
                    778:                break;
                    779:            lastmx += (signed short) LOWORD (lParam) - mousedx;
                    780:            lastmy += (signed short) HIWORD (lParam) - mousedy;
                    781:            if (ievent_alive) {
                    782:                if (lastmx < 0)
                    783:                    lastmx = 0;
                    784:                if (lastmx > current_width)
                    785:                    lastmx = current_width;
                    786:                if (lastmy < 0)
                    787:                    lastmy = 0;
                    788:                if (lastmy > current_height)
                    789:                    lastmy = current_height;
                    790: 
                    791:            }
                    792:            SetCursorPos (mousecx, mousecy);
                    793:            break;
                    794:        }
                    795:        lastmx = (signed short) LOWORD (lParam);
                    796:        lastmy = (signed short) HIWORD (lParam);
                    797:        break;
                    798: 
1.1.1.2 ! root      799:      case WM_PAINT:
1.1       root      800:        clear_inhibit_frame (IHF_WINDOWHIDDEN);
1.1.1.2 ! root      801:        hDC = BeginPaint (hWnd, &ps);
1.1       root      802:        EndPaint (hWnd, &ps);
1.1.1.2 ! root      803:        notice_screen_contents_lost ();
1.1       root      804:        break;
                    805: 
1.1.1.2 ! root      806:      case WM_DROPFILES:
1.1       root      807:        if (DragQueryFile ((HDROP) wParam, (UINT) - 1, NULL, 0)) {
                    808:            if (DragQueryFile ((HDROP) wParam, 0, NULL, 0) < 255)
                    809:                DragQueryFile ((HDROP) wParam, 0, changed_prefs.df[0], sizeof (changed_prefs.df[0]));
                    810:        }
                    811:        DragFinish ((HDROP) wParam);
                    812:        break;
                    813: 
1.1.1.2 ! root      814:      case WM_CAPTURECHANGED:
        !           815:        if ((HWND)lParam != hAmigaWnd)
1.1       root      816:            buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
                    817:        break;
                    818: 
1.1.1.2 ! root      819:      case WM_TIMER:
        !           820:        finishjob ();
1.1       root      821:        break;
                    822: 
1.1.1.2 ! root      823:      case WM_USER + 0x200:
        !           824:        DoSomeWeirdPrintingStuff (wParam);
1.1       root      825:        break;
                    826: 
1.1.1.2 ! root      827:      case WM_CREATE:
1.1       root      828:        DragAcceptFiles (hWnd, TRUE);
                    829:        break;
                    830: 
1.1.1.2 ! root      831:      case WM_CLOSE:
        !           832:        uae_quit ();
        !           833:        return 0;
        !           834: 
        !           835:      case WM_WINDOWPOSCHANGED:
        !           836:        GetWindowRect (hAmigaWnd, &amigawin_rect);
1.1       root      837:        break;
                    838:     }
                    839: 
                    840:     return DefWindowProc (hWnd, message, wParam, lParam);
                    841: }
                    842: 
1.1.1.2 ! root      843: static long FAR PASCAL MainWindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
1.1       root      844: {
                    845:     PAINTSTRUCT ps;
1.1.1.2 ! root      846:     RECT rc;
1.1       root      847:     HDC hDC;
                    848: 
                    849:     switch (message) {
                    850:      case WM_LBUTTONDOWN:
                    851:      case WM_MOUSEMOVE:
                    852:      case WM_ACTIVATEAPP:
                    853:      case WM_ACTIVATE:
                    854:      case WM_SETCURSOR:
                    855:      case WM_SYSCOMMAND:
                    856:      case WM_KEYUP:
                    857:      case WM_SYSKEYUP:
                    858:      case WM_KEYDOWN:
                    859:      case WM_SYSKEYDOWN:
                    860:      case WM_LBUTTONUP:
                    861:      case WM_MBUTTONDOWN:
                    862:      case WM_MBUTTONUP:
                    863:      case WM_RBUTTONDOWN:
                    864:      case WM_RBUTTONUP:
                    865:      case WM_DROPFILES:
                    866:      case WM_CREATE:
                    867:      case WM_DESTROY:
                    868:      case WM_USER + 0x200:
1.1.1.2 ! root      869:      case WM_CLOSE:
1.1       root      870:        return AmigaWindowProc (hWnd, message, wParam, lParam);
                    871: 
                    872:      case WM_DISPLAYCHANGE:
1.1.1.2 ! root      873:        if (!fullscreen && (wParam + 7) / 8 != current_pixbytes)
        !           874:            display_change_requested = 1;
1.1       root      875:        break;
1.1.1.2 ! root      876:        
1.1       root      877:      case WM_ENTERSIZEMOVE:
1.1.1.2 ! root      878:        in_sizemove++;
1.1       root      879:        break;
                    880: 
                    881:      case WM_EXITSIZEMOVE:
1.1.1.2 ! root      882:        in_sizemove--;
        !           883: 
1.1       root      884:        /* fall through */
                    885: 
                    886:      case WM_WINDOWPOSCHANGED:
                    887:        GetWindowRect (hAmigaWnd, &amigawin_rect);
                    888: 
1.1.1.2 ! root      889:        if (in_sizemove > 0)
        !           890:            break;
        !           891: 
1.1       root      892:        if (!fullscreen && hAmigaWnd) {
1.1.1.2 ! root      893:            if (amigawin_rect.left & 3) {
        !           894:                RECT rc2;
        !           895:                GetWindowRect (hMainWnd, &rc2);
        !           896:                if (1 /*!mon || rc2.left + 4 < GetSystemMetrics (SM_CXSCREEN) */ ) {
        !           897:                    MoveWindow (hMainWnd, rc2.left + 4 - amigawin_rect.left % 4, rc2.top,
        !           898:                                rc2.right - rc2.left, rc2.bottom - rc2.top, TRUE);
1.1       root      899:                }
                    900:            }
1.1.1.2 ! root      901: 
1.1       root      902:            setmouseactive (0);
                    903:            return 0;
                    904:        }
1.1.1.2 ! root      905: 
1.1       root      906:        break;
                    907: 
                    908:      case WM_PAINT:
                    909:        hDC = BeginPaint (hWnd, &ps);
                    910:        GetClientRect (hWnd, &rc);
                    911:        DrawEdge (hDC, &rc, EDGE_SUNKEN, BF_RECT);
                    912: 
                    913:        EndPaint (hWnd, &ps);
                    914:        break;
                    915: 
                    916:      case WM_NCLBUTTONDBLCLK:
                    917:        if (wParam == HTCAPTION) {
                    918:            toggle_fullscreen ();
                    919:            return 0;
                    920:        }
1.1.1.2 ! root      921:        break;
1.1       root      922:     }
                    923: 
                    924:     return DefWindowProc (hWnd, message, wParam, lParam);
                    925: }
                    926: 
                    927: static HANDLE debugfile;
                    928: 
                    929: /* Console Win32 helper routines */
                    930: void activate_debugger ();
                    931: 
                    932: static BOOL __stdcall ctrlchandler (DWORD type)
                    933: {
                    934:     SetConsoleCtrlHandler ((PHANDLER_ROUTINE) ctrlchandler, FALSE);
                    935: 
                    936:     if (type == CTRL_C_EVENT) {
                    937:        activate_debugger ();
                    938:        return TRUE;
                    939:     }
                    940:     return FALSE;
                    941: }
                    942: 
                    943: void setup_brkhandler (void)
                    944: {
                    945:     SetConsoleCtrlHandler ((PHANDLER_ROUTINE) ctrlchandler, TRUE);
                    946: }
                    947: 
                    948: void remove_brkhandler (void)
                    949: {
                    950:     SetConsoleCtrlHandler ((PHANDLER_ROUTINE) ctrlchandler, FALSE);
                    951: }
                    952: 
                    953: static int register_classes (void)
                    954: {
                    955:     WNDCLASS wc;
                    956: 
                    957:     wc.style = 0;
                    958:     wc.lpfnWndProc = AmigaWindowProc;
                    959:     wc.cbClsExtra = 0;
                    960:     wc.cbWndExtra = 0;
                    961:     wc.hInstance = 0;
                    962:     wc.hIcon = LoadIcon (GetModuleHandle (NULL), IDI_APPICON);
                    963:     wc.hCursor = LoadCursor (NULL, IDC_ARROW);
                    964:     wc.hbrBackground = GetStockObject (BLACK_BRUSH);
1.1.1.2 ! root      965:     wc.lpszMenuName = 0;
1.1       root      966:     wc.lpszClassName = "AmigaPowah";
                    967:     if (!RegisterClass (&wc))
                    968:        return 0;
                    969: 
                    970:     wc.style = 0;
                    971:     wc.lpfnWndProc = MainWindowProc;
                    972:     wc.cbClsExtra = 0;
                    973:     wc.cbWndExtra = 0;
                    974:     wc.hInstance = 0;
                    975:     wc.hIcon = LoadIcon (GetModuleHandle (NULL), IDI_APPICON);
                    976:     wc.hCursor = LoadCursor (NULL, IDC_ARROW);
                    977:     wc.hbrBackground = GetStockObject (BLACK_BRUSH);
1.1.1.2 ! root      978:     wc.lpszMenuName = 0;
1.1       root      979:     wc.lpszClassName = "PCsuxRox";
                    980:     if (!RegisterClass (&wc))
                    981:        return 0;
                    982:     return 1;
                    983: }
                    984: 
1.1.1.2 ! root      985: struct win32_displaymode *win32_displaymode_list;
        !           986: 
        !           987: static HRESULT CALLBACK modesCallback (LPDDSURFACEDESC modeDesc, LPVOID context)
1.1       root      988: {
1.1.1.2 ! root      989:     struct win32_displaymode **dmpp;
        !           990:     RGBFTYPE colortype;
1.1       root      991: 
1.1.1.2 ! root      992:     colortype = surface_pixelformat (modeDesc);
        !           993:     if (colortype == RGBFB_NONE)
        !           994:        return DDENUMRET_OK;
        !           995: 
        !           996:     dmpp = &win32_displaymode_list;
        !           997:     while (*dmpp != 0) {
        !           998:        if ((*dmpp)->width == modeDesc->dwWidth
        !           999:            && (*dmpp)->height == modeDesc->dwHeight
        !          1000:            && (*dmpp)->refreshrate == modeDesc->dwRefreshRate)
        !          1001:            break;
        !          1002:        dmpp = &(*dmpp)->next;
        !          1003:     }
1.1       root     1004: 
1.1.1.2 ! root     1005:     if (*dmpp == 0) {
        !          1006:        *dmpp = (struct win32_displaymode *)malloc (sizeof **dmpp);
        !          1007:        (*dmpp)->next = 0;
        !          1008:        (*dmpp)->width = modeDesc->dwWidth;
        !          1009:        (*dmpp)->height = modeDesc->dwHeight;
        !          1010:        (*dmpp)->refreshrate = modeDesc->dwRefreshRate;
        !          1011:        (*dmpp)->colormodes = 0;
        !          1012:     }
        !          1013:     (*dmpp)->colormodes |= 1 << colortype;
        !          1014:     return DDENUMRET_OK;
1.1       root     1015: }
                   1016: 
1.1.1.2 ! root     1017: static int our_possible_depths[] = { 8, 15, 16, 24, 32 };
1.1       root     1018: 
1.1.1.2 ! root     1019: static void figure_pixel_formats (void)
1.1       root     1020: {
1.1.1.2 ! root     1021:     HWND tmpw;
        !          1022:     HRESULT ddrval;
        !          1023:     struct win32_displaymode *dm;
        !          1024: 
        !          1025:     tmpw = CreateWindowEx (WS_EX_TOPMOST,
        !          1026:                           "AmigaPowah", PROGNAME,
        !          1027:                           WS_VISIBLE | WS_POPUP,
        !          1028:                           CW_USEDEFAULT, CW_USEDEFAULT,
        !          1029:                           GetSystemMetrics (SM_CXSCREEN),
        !          1030:                           GetSystemMetrics (SM_CYSCREEN),
        !          1031:                           0, NULL, 0, NULL);
        !          1032: 
        !          1033:     ddrval = IDirectDraw_SetCooperativeLevel (lpDD, tmpw,
        !          1034:                                              DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
        !          1035:     if (ddrval != DD_OK) {
        !          1036:        printf ("error %s\n", getddrname (ddrval));
        !          1037:        goto out;
        !          1038:     }
        !          1039: 
        !          1040:     for (dm = win32_displaymode_list; dm != 0; dm = dm->next) {
        !          1041:        int i;
        !          1042: 
        !          1043:        printf ("Attempting %dx%d: ", dm->width, dm->height);
        !          1044:        dm->colormodes = 0;
        !          1045: 
        !          1046:        for (i = 0; i < 5; i++) {
        !          1047:            RGBFTYPE colortype;
        !          1048:            ddrval = IDirectDraw_SetDisplayMode (lpDD, dm->width, dm->height, our_possible_depths[i]);
        !          1049:            if (ddrval != DD_OK)
        !          1050:                continue;
        !          1051: 
        !          1052:            current_surface.dwSize = sizeof current_surface;
        !          1053:            ddrval = IDirectDraw_GetDisplayMode (lpDD, &current_surface);
        !          1054:            if (ddrval != DD_OK)
        !          1055:                continue;
        !          1056:            colortype = surface_pixelformat (&current_surface);
        !          1057:            if (colortype != RGBFB_NONE) {
        !          1058:                printf ("%d ", our_possible_depths[i]);
        !          1059:                dm->colormodes |= 1 << colortype;
        !          1060:            }
        !          1061:        }
        !          1062:        printf ("(%08lx)\n", dm->colormodes);
        !          1063:     }
        !          1064:     out:
        !          1065:     DestroyWindow (tmpw);
        !          1066: }
        !          1067: 
        !          1068: #define NORMAL_WINDOW_STYLE (WS_VISIBLE | WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX)
1.1       root     1069: 
1.1.1.2 ! root     1070: #define NUM_PARTS 6
        !          1071: #define LED_WIDTH 50
        !          1072: #define DRIVE_WIDTH 16
        !          1073: 
        !          1074: static int create_windows (void)
        !          1075: {
1.1       root     1076:     if (!fullscreen) {
                   1077:        RECT rc;
1.1.1.2 ! root     1078:        HLOCAL hloc;
        !          1079:        LPINT lpParts;
1.1       root     1080: 
                   1081:        rc.left = 0;
                   1082:        rc.top = 0;
                   1083:        rc.right = current_width;
1.1.1.2 ! root     1084:        rc.bottom = current_height + GetSystemMetrics (SM_CYMENU);
1.1       root     1085:        rc.right += 4;
                   1086:        rc.bottom += 4;
                   1087:        AdjustWindowRect (&rc, NORMAL_WINDOW_STYLE, FALSE);
1.1.1.2 ! root     1088:        printf ("(%d %d) (%d %d)\n", rc.left, rc.top, rc.right, rc.bottom);
1.1       root     1089: 
1.1.1.2 ! root     1090:        hMainWnd = CreateWindowEx (WS_EX_ACCEPTFILES, "PCsuxRox", TITLETEXT,
        !          1091:                                   NORMAL_WINDOW_STYLE, CW_USEDEFAULT, CW_USEDEFAULT,
1.1       root     1092:                                   rc.right - rc.left, rc.bottom - rc.top,
1.1.1.2 ! root     1093:                                   NULL, NULL, 0, NULL);
1.1       root     1094: 
                   1095:        if (! hMainWnd)
                   1096:            return 0;
1.1.1.2 ! root     1097:        hStatusWnd = CreateStatusWindow (WS_CHILD | WS_VISIBLE, "", hMainWnd, 1);
        !          1098:        if (hStatusWnd) {
        !          1099:            GetClientRect (hMainWnd, &rc);
        !          1100:            /* Allocate an array for holding the right edge coordinates. */
        !          1101:            hloc = LocalAlloc (LHND, sizeof (int) * NUM_PARTS);
        !          1102:            if (hloc) {
        !          1103:                lpParts = LocalLock (hloc);
        !          1104: 
        !          1105:                /* Calculate the right edge coordinate for each part, and copy the coords
        !          1106:                 * to the array.  */
        !          1107:                lpParts[0] = rc.right - (DRIVE_WIDTH * 4) - LED_WIDTH - 2;
        !          1108:                lpParts[1] = lpParts[0] + LED_WIDTH;
        !          1109:                lpParts[2] = lpParts[1] + DRIVE_WIDTH;
        !          1110:                lpParts[3] = lpParts[2] + DRIVE_WIDTH;
        !          1111:                lpParts[4] = lpParts[3] + DRIVE_WIDTH;
        !          1112:                lpParts[5] = lpParts[4] + DRIVE_WIDTH;
        !          1113: 
        !          1114:                /* Create the six parts */
        !          1115:                SendMessage (hStatusWnd, SB_SETPARTS, (WPARAM) NUM_PARTS, (LPARAM) lpParts);
        !          1116: 
        !          1117:                LocalUnlock (hloc);
        !          1118:                LocalFree (hloc);
        !          1119:            }
        !          1120:        }
1.1       root     1121:     } else
                   1122:        hMainWnd = NULL;
                   1123: 
                   1124:     hAmigaWnd = CreateWindowEx (fullscreen ? WS_EX_TOPMOST : WS_EX_ACCEPTFILES,
1.1.1.2 ! root     1125:                                "AmigaPowah", PROGNAME,
1.1       root     1126:                                hMainWnd ? WS_VISIBLE | WS_CHILD : WS_VISIBLE | WS_POPUP,
                   1127:                                hMainWnd ? 2 : CW_USEDEFAULT, hMainWnd ? 2 : CW_USEDEFAULT,
                   1128:                                fullscreen ? GetSystemMetrics (SM_CXSCREEN) : current_width,
                   1129:                                fullscreen ? GetSystemMetrics (SM_CYSCREEN) : current_height,
1.1.1.2 ! root     1130:                                hMainWnd, NULL, 0, NULL);
1.1       root     1131: 
1.1.1.2 ! root     1132:     
        !          1133:     if (! hAmigaWnd) {
1.1       root     1134:        if (hMainWnd)
                   1135:            DestroyWindow (hMainWnd);
                   1136:        return 0;
                   1137:     }
                   1138: 
                   1139:     if (hMainWnd)
                   1140:        UpdateWindow (hMainWnd);
                   1141:     if (hAmigaWnd)
                   1142:        UpdateWindow (hAmigaWnd);
                   1143: 
                   1144:     return 1;
                   1145: }
                   1146: 
1.1.1.2 ! root     1147: /* DirectX will fail with "Mode not supported" if we try to switch to a full
        !          1148:  * screen mode that doesn't match one of the dimensions we got during enumeration.
        !          1149:  * So try to find a best match for the given resolution in our list.  */
        !          1150: static int adjust_screenmode (int *pwidth, int *pheight, int *ppixbits)
        !          1151: {
        !          1152:     struct win32_displaymode *best;
        !          1153:     uae_u32 selected_mask = (*ppixbits == 8 ? RGBMASK_8BIT
        !          1154:                             : *ppixbits == 15 ? RGBMASK_15BIT
        !          1155:                             : *ppixbits == 16 ? RGBMASK_16BIT
        !          1156:                             : *ppixbits == 24 ? RGBMASK_24BIT
        !          1157:                             : RGBMASK_32BIT);
        !          1158:     int pass;
        !          1159:     
        !          1160:     for (pass = 0; pass < 2; pass++) {
        !          1161:        struct win32_displaymode *dm;
        !          1162:        uae_u32 mask = (pass == 0
        !          1163:                        ? selected_mask
        !          1164:                        : RGBMASK_8BIT | RGBMASK_16BIT | RGBMASK_24BIT | RGBMASK_32BIT);
        !          1165: 
        !          1166:        best = win32_displaymode_list;
        !          1167:        dm = best->next;
        !          1168: 
        !          1169:        while (dm != 0) {
        !          1170:            if ((dm->colormodes & mask) != 0) {
        !          1171:                if (dm->width <= best->width && dm->height <= best->height
        !          1172:                    && dm->width >= *pwidth && dm->height >= *pheight)
        !          1173:                    best = dm;
        !          1174:                if (dm->width >= best->width && dm->height >= best->height
        !          1175:                    && dm->width <= *pwidth && dm->height <= *pheight)
        !          1176:                    best = dm;
        !          1177:            }
        !          1178:            dm = dm->next;
        !          1179:        }
        !          1180:        if (best->width == *pwidth && best->height == *pheight)
        !          1181:            break;
        !          1182:     }
        !          1183:     *pwidth = best->width;
        !          1184:     *pheight = best->height;
        !          1185:     if ((best->colormodes & selected_mask) != 0)
        !          1186:        return 1;
        !          1187:     if (best->colormodes & RGBMASK_8BIT)
        !          1188:        *ppixbits = 8;
        !          1189:     else if (best->colormodes & RGBMASK_16BIT)
        !          1190:        *ppixbits = 16;
        !          1191:     else if (best->colormodes & RGBMASK_32BIT)
        !          1192:        *ppixbits = 32;
        !          1193:     else if (best->colormodes & RGBMASK_24BIT)
        !          1194:        *ppixbits = 24;
        !          1195: 
        !          1196:     return 1;
        !          1197: }
        !          1198: 
        !          1199: static BOOL doInit (void)
1.1       root     1200: {
                   1201:     if (! create_windows ())
1.1.1.2 ! root     1202:        goto oops;
        !          1203: 
1.1       root     1204:     if (screen_is_picasso) {
1.1.1.2 ! root     1205:        if (! set_ddraw (current_width, current_height, fullscreen, current_depth,
        !          1206:                        (LPPALETTEENTRY) & picasso96_state.CLUT))
1.1       root     1207:            goto oops;
                   1208:        picasso_vidinfo.rowbytes = ddsd.lPitch;
1.1.1.2 ! root     1209:        picasso_vidinfo.pixbytes = current_pixbytes;
        !          1210:        picasso_vidinfo.rgbformat = surface_pixelformat (&current_surface);
        !          1211:     } else {
        !          1212:        if (fullscreen)
        !          1213:            if (! adjust_screenmode (&current_width, &current_height, &current_depth))
        !          1214:                abort ();
        !          1215: 
        !          1216:        if (! set_ddraw (current_width, current_height, fullscreen, current_depth, colors256))
1.1       root     1217:            goto oops;
                   1218:        gfxvidinfo.bufmem = 0;
                   1219:        gfxvidinfo.linemem = 0;
                   1220:        gfxvidinfo.maxblocklines = 0;
1.1.1.2 ! root     1221:        gfxvidinfo.pixbytes = current_pixbytes;
1.1       root     1222:        gfxvidinfo.width = current_width;
                   1223:        gfxvidinfo.height = current_height;
                   1224:        gfxvidinfo.rowbytes = ddsd.lPitch;
                   1225:     }
                   1226: 
                   1227:     if (fullscreen) {
                   1228:        scrindirect = 0;
                   1229:        gfxvidinfo.linemem = 0;
                   1230:        mousecx = 160, mousecy = 100, mousedx = 160, mousedy = 100, mousecl = MAKELONG (160, 100);
                   1231:     }
                   1232:     if (! do_surfacelock ())
                   1233:        goto oops;
                   1234:     unlockscr ();
                   1235: 
1.1.1.2 ! root     1236:     if ((ddsd.ddpfPixelFormat.dwFlags & (DDPF_RGB | DDPF_PALETTEINDEXED8 | DDPF_RGBTOYUV)) != 0) {
        !          1237:        write_log ("%s mode (bits: %d, pixbytes: %d)\n", fullscreen ? "Full screen" : "Window",
        !          1238:                   ddsd.ddpfPixelFormat.dwRGBBitCount, current_pixbytes);
1.1       root     1239:     } else {
1.1.1.2 ! root     1240:        write_log ("Error: Unsupported pixel format - use a different screen mode\n");
1.1       root     1241:        goto oops;
                   1242:     }
                   1243: 
1.1.1.2 ! root     1244:     init_colors ();
        !          1245: 
        !          1246:     if (! fullscreen)
1.1       root     1247:        MainWindowProc (0, WM_WINDOWPOSCHANGED, 0, 0);
1.1.1.2 ! root     1248:     dsound_newwindow (hAmigaWnd);
1.1       root     1249:     return 1;
                   1250: 
1.1.1.2 ! root     1251:   oops:
        !          1252:     release_ddraw ();
1.1       root     1253:     if (hMainWnd)
                   1254:        DestroyWindow (hMainWnd);
                   1255:     if (hAmigaWnd)
                   1256:        DestroyWindow (hAmigaWnd);
                   1257:     return 0;
                   1258: }
                   1259: 
                   1260: struct myRGNDATA {
                   1261:     RGNDATAHEADER rdh;
1.1.1.2 ! root     1262:     RECT rects[640];           /* fixed buffers suck, but this is _very_ unlikely to overflow */
        !          1263: } ClipList = { { sizeof (ClipList), RDH_RECTANGLES, 0, 640 * sizeof (RECT) } };
1.1       root     1264: 
                   1265: /* this is the way the display line is put to screen
                   1266:  * if the display is not 16 bits deep or the window is not fully visible */
                   1267: static void clipped_linetoscr (char *dst, char *src, int y)
                   1268: {
                   1269:     LPRECT lpRect = ClipList.rects;
                   1270:     int i;
                   1271: 
                   1272:     switch (current_pixbytes) {
1.1.1.2 ! root     1273:      case 1:
1.1       root     1274:        for (i = ClipList.rdh.nCount; i--; lpRect++) {
1.1.1.2 ! root     1275:            if (y >= lpRect->top && y < lpRect->bottom)
1.1       root     1276:                memcpy (dst + lpRect->left, src + lpRect->left, lpRect->right);
                   1277:        }
                   1278:        break;
                   1279: 
1.1.1.2 ! root     1280:      case 2:
1.1       root     1281:        for (i = ClipList.rdh.nCount; i--; lpRect++) {
1.1.1.2 ! root     1282:            if (y >= lpRect->top && y < lpRect->bottom)
        !          1283:                memcpy (dst + lpRect->left * 2, src + lpRect->left * 2, lpRect->right * 2);
1.1       root     1284:        }
                   1285:        break;
                   1286: 
1.1.1.2 ! root     1287:      case 3:
1.1       root     1288:        for (i = ClipList.rdh.nCount; i--; lpRect++) {
1.1.1.2 ! root     1289:            if (y >= lpRect->top && y < lpRect->bottom)
        !          1290:                memcpy (dst + lpRect->left * 3, src + lpRect->left * 3, lpRect->right * 3);
1.1       root     1291:        }
                   1292:        break;
                   1293: 
                   1294:      case 4:
                   1295:        for (i = ClipList.rdh.nCount; i--; lpRect++) {
1.1.1.2 ! root     1296:            if (y >= lpRect->top && y < lpRect->bottom)
        !          1297:                memcpy (dst + lpRect->left * 4, src + lpRect->left * 4, lpRect->right * 4);
1.1       root     1298:        }
                   1299:        break;
                   1300:     }
                   1301: }
                   1302: 
1.1.1.2 ! root     1303: void flush_line (int lineno)
1.1       root     1304: {
                   1305:     if (scrindirect)
1.1.1.2 ! root     1306:        clipped_linetoscr (gfxvidinfo.bufmem + lineno * gfxvidinfo.rowbytes,
        !          1307:                           scrlinebuf, lineno);
1.1       root     1308: }
                   1309: 
1.1.1.2 ! root     1310: void flush_block (int a, int b)
1.1       root     1311: {
                   1312: }
                   1313: 
1.1.1.2 ! root     1314: void flush_screen (int a, int b)
1.1       root     1315: {
                   1316: }
                   1317: 
1.1.1.2 ! root     1318: static uae_u8 *dolock (void)
1.1       root     1319: {
1.1.1.2 ! root     1320:     char *surface = NULL, *oldsurface;
1.1       root     1321:     DWORD tmp;
                   1322:     LPRECT lpRect;
                   1323: 
1.1.1.2 ! root     1324:     if (! do_surfacelock ())
        !          1325:        return 0;
1.1       root     1326: 
                   1327:     surface = ddsd.lpSurface;
                   1328:     oldsurface = gfxvidinfo.bufmem;
1.1.1.2 ! root     1329:     if (! fullscreen) {
1.1       root     1330:        surface += amigawin_rect.top * ddsd.lPitch + current_pixbytes * amigawin_rect.left;
                   1331:     }
                   1332:     gfxvidinfo.bufmem = surface;
                   1333:     if (surface != oldsurface && ! screen_is_picasso) {
                   1334:        write_log ("Need to init_row_map\n");
                   1335:        init_row_map ();
                   1336:     }
                   1337:     scrindirect = 0;
                   1338: 
                   1339:     if (fullscreen) {
                   1340:        set_linemem ();
                   1341:        clear_inhibit_frame (IHF_WINDOWHIDDEN);
                   1342:        return surface;
                   1343:     }
                   1344:     tmp = sizeof (ClipList.rects);
                   1345: 
                   1346:     /* This is the VERY instruction that drags other threads (input/file system) down when in windowed
                   1347:      * mode - WHY can't Microsoft implement the IsClipListChanged() method as documented? ARGH! */
                   1348:     if (IDirectDrawClipper_GetClipList (lpDDC, NULL, (LPRGNDATA) & ClipList, &tmp) == DD_OK) {
                   1349:        lpRect = ClipList.rects;
                   1350: 
                   1351:        if (!ClipList.rdh.nCount) {
                   1352:            set_inhibit_frame (IHF_WINDOWHIDDEN);
                   1353:            unlockscr ();
                   1354:            return 0;
                   1355:        }
                   1356:        if (ClipList.rdh.nCount != 1
                   1357:            || lpRect->right - lpRect->left != current_width
                   1358:            || lpRect->bottom - lpRect->top != current_height)
                   1359:        {
                   1360:            scrindirect = 1;
                   1361:            for (tmp = ClipList.rdh.nCount; tmp--; lpRect++) {
                   1362:                lpRect->left -= amigawin_rect.left;
                   1363:                lpRect->right -= amigawin_rect.left;
                   1364:                lpRect->top -= amigawin_rect.top;
                   1365:                lpRect->bottom -= amigawin_rect.top;
                   1366: 
                   1367:                lpRect->right -= lpRect->left;
                   1368:            }
                   1369:        }
                   1370:     }
                   1371:     set_linemem ();
                   1372:     clear_inhibit_frame (IHF_WINDOWHIDDEN);
                   1373:     return surface;
                   1374: }
                   1375: 
1.1.1.2 ! root     1376: int lockscr (void)
1.1       root     1377: {
1.1.1.2 ! root     1378:     return dolock () != 0;
1.1       root     1379: }
                   1380: 
1.1.1.2 ! root     1381: uae_u8 *gfx_lock_picasso (void)
1.1       root     1382: {
1.1.1.2 ! root     1383:     return dolock ();
1.1       root     1384: }
                   1385: 
1.1.1.2 ! root     1386: void gfx_unlock_picasso (void)
1.1       root     1387: {
1.1.1.2 ! root     1388:     unlockscr ();
1.1       root     1389: }
                   1390: 
1.1.1.2 ! root     1391: static int open_windows (void)
1.1       root     1392: {
1.1.1.2 ! root     1393:     char *fs_warning = 0;
        !          1394:     RGBFTYPE colortype;
1.1       root     1395: 
1.1.1.2 ! root     1396:     current_pixbytes = 0;
1.1       root     1397: 
1.1.1.2 ! root     1398:     in_sizemove = 0;
        !          1399:     fixup_prefs_dimensions (&currprefs);
1.1       root     1400: 
1.1.1.2 ! root     1401:     if (! start_ddraw ())
        !          1402:        return 0;
1.1       root     1403: 
1.1.1.2 ! root     1404:     colortype = surface_pixelformat (&current_surface);
        !          1405:     printf ("Ct: %08lx, picasso_vidinfo.selected_rgbformat %08lx\n", (unsigned long)colortype,
        !          1406:            picasso_vidinfo.selected_rgbformat);
1.1       root     1407: 
1.1.1.2 ! root     1408:     if (screen_is_picasso) {
        !          1409:        fullscreen = currprefs.gfx_pfullscreen;
        !          1410:        current_width = picasso_vidinfo.width;
        !          1411:        current_height = picasso_vidinfo.height;
        !          1412:        current_depth = rgbformat_bits (picasso_vidinfo.selected_rgbformat);
        !          1413:     } else {
        !          1414:        fullscreen = currprefs.gfx_afullscreen;
        !          1415:        current_width = currprefs.gfx_width;
        !          1416:        current_height = currprefs.gfx_height;
        !          1417:        current_depth = (currprefs.color_mode == 0 ? 8
        !          1418:                         : currprefs.color_mode == 1 ? 15
        !          1419:                         : currprefs.color_mode == 2 ? 16
        !          1420:                         : currprefs.color_mode == 3 ? 8
        !          1421:                         : currprefs.color_mode == 4 ? 8 : 32);
        !          1422:     }
        !          1423: 
        !          1424:     needs_fullscreen = 0;
        !          1425:     if (colortype == RGBFB_NONE) {
        !          1426:        needs_fullscreen = 1;
        !          1427:        fs_warning = "the desktop is running in an unknown color mode.";
        !          1428:     } else if (colortype == RGBFB_CLUT) {
        !          1429:        needs_fullscreen = 1;
        !          1430:        fs_warning = "the desktop is running in 8 bit color depth, which UAE can't use in windowed mode.";
        !          1431:     } else if (current_width > current_surface.dwWidth || current_height > current_surface.dwHeight) {
        !          1432:        needs_fullscreen = 1;
        !          1433:        fs_warning = "the desktop is too small for the specified window size.";
        !          1434:     } else if (screen_is_picasso
        !          1435:               && picasso_vidinfo.selected_rgbformat != RGBFB_CHUNKY
        !          1436:               && picasso_vidinfo.selected_rgbformat != colortype)
        !          1437:     {
        !          1438:        needs_fullscreen = 1;
        !          1439:        fs_warning = "you selected a Picasso display with a color depth different from that of the desktop.";
1.1       root     1440:     }
                   1441: 
1.1.1.2 ! root     1442:     if (needs_fullscreen && ! fullscreen) {
        !          1443:        char tmpstr[300];
        !          1444:        fullscreen = needs_fullscreen;
        !          1445:        /* Temporarily drop the DirectDraw stuff.  This is necessary, otherwise
        !          1446:         * WinNT will just return 1 for the message box without ever displaying 
        !          1447:         * it on the screen.  */
        !          1448:        release_ddraw ();
        !          1449:        sprintf (tmpstr, "The selected screen mode can't be displayed in a window, because %s\n"
        !          1450:                 "Switching to full-screen display.", fs_warning);
        !          1451:        MessageBox (0, tmpstr, "UAE", MB_ICONEXCLAMATION | MB_OK);
        !          1452:        start_ddraw ();
        !          1453:     }
        !          1454:     
        !          1455:     if (! fullscreen)
        !          1456:        current_depth = rgbformat_bits (colortype);
        !          1457:     
        !          1458:     if (! doInit ())
        !          1459:        return 0;
1.1       root     1460: 
1.1.1.2 ! root     1461:     return 1;
1.1       root     1462: }
                   1463: 
1.1.1.2 ! root     1464: void handle_events (void)
1.1       root     1465: {
1.1.1.2 ! root     1466:     MSG msg;
1.1       root     1467: 
1.1.1.2 ! root     1468:     while (PeekMessage (&msg, 0, 0, 0, PM_REMOVE)) {
        !          1469:        TranslateMessage (&msg);
        !          1470:        DispatchMessage (&msg);
        !          1471:     }
1.1       root     1472: }
                   1473: 
1.1.1.2 ! root     1474: int check_prefs_changed_gfx (void)
1.1       root     1475: {
1.1.1.2 ! root     1476:     if (display_change_requested) {
        !          1477:        display_change_requested = 0;
        !          1478:        close_windows ();
        !          1479:        open_windows ();
        !          1480:        return 1;
        !          1481:     }
        !          1482:     return 0;
1.1       root     1483: }
                   1484: 
                   1485: /* this truly sucks, I'll include a native gunzip() routine soon */
                   1486: int gunzip_hack (const char *src, const char *dst)
                   1487: {
                   1488:     char buf[1024];
                   1489:     STARTUPINFO si =
                   1490:     {sizeof si};
                   1491:     PROCESS_INFORMATION pi;
                   1492: 
                   1493:     strcpy (buf, dst);
                   1494:     strcat (buf, ".gz");
                   1495: 
                   1496:     if (CopyFile (src, buf, FALSE)) {
                   1497:        sprintf (buf, "gzip -f -d \"%s.gz\"", dst);
                   1498:        si.dwFlags = STARTF_USESTDHANDLES;
                   1499:        if (CreateProcess (NULL, buf, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
                   1500:            WaitForSingleObject (pi.hProcess, INFINITE);
                   1501:            return -1;
                   1502:        } else {
1.1.1.2 ! root     1503:            write_log ("Error: You need gzip.exe (32 bit) to use .adz/.roz files!\n");
1.1       root     1504:        }
                   1505:     }
                   1506:     return 0;
                   1507: }
                   1508: 
1.1.1.2 ! root     1509: static OPENFILENAME ofn =
        !          1510: {
1.1       root     1511:     sizeof (OPENFILENAME),
                   1512:     NULL, NULL, "Amiga Disk Files\000*.adf;*.adz\000",
                   1513:     NULL, 0, 0, 0, 256, NULL, 0, "",
                   1514:     0,
                   1515:     OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,
                   1516:     0,
                   1517:     0,
                   1518:     "adf",
                   1519:     0,
                   1520:     NULL,
                   1521:     NULL
                   1522: };
                   1523: 
                   1524: int requestfname (char *title, char *name)
                   1525: {
                   1526:     char *result;
                   1527: 
                   1528:     ofn.hwndOwner = hAmigaWnd;
                   1529:     ofn.lpstrTitle = title;
                   1530:     ofn.lpstrFile = name;
                   1531: 
                   1532:     if (pGetOpenFileNameA == 0)
                   1533:        return 0;
                   1534: 
                   1535:     if (!fullscreen)
                   1536:        setmouseactive (0);
                   1537: 
                   1538:     if (title)
1.1.1.2 ! root     1539:        result = (char *) ((*pGetOpenFileNameA) (&ofn));
1.1       root     1540:     else {
1.1.1.2 ! root     1541:        GetSettings (0);
1.1       root     1542:     }
                   1543: 
                   1544:     if (!fullscreen || !mouseactive)
                   1545:        SetCursor (NULL);
                   1546: 
                   1547:     notice_screen_contents_lost ();
                   1548: 
                   1549:     if (result)
                   1550:        return 1;
                   1551: 
                   1552:     return 0;
                   1553: }
1.1.1.2 ! root     1554: 
        !          1555: int DisplayGUI (void)
        !          1556: {
        !          1557: #ifdef PICASSO96
        !          1558:     BITMAPINFO bminfo =
        !          1559:     {
        !          1560:        {
        !          1561:            sizeof (BITMAPINFOHEADER),
        !          1562:            0, 0,
        !          1563:            1, 8, BI_RGB, 0, 0, 0, 0, 0,
        !          1564:        },
        !          1565:        0
        !          1566:     };
        !          1567: #endif
        !          1568: 
        !          1569:     bminfo.bmiHeader.biWidth = current_width;
        !          1570:     bminfo.bmiHeader.biHeight = -current_height;
        !          1571: #if 0
        !          1572:     /* ??????? */
        !          1573:     bminfo.bmiColors[0] = &picasso96_state.CLUT;
        !          1574: #endif
        !          1575:     if (pGetOpenFileNameA) {
        !          1576:        if (lpDDP)
        !          1577:            IDirectDrawSurface_SetPalette (lpDDS, NULL);
        !          1578: 
        !          1579:        if (!fullscreen)
        !          1580:            setmouseactive (FALSE);
        !          1581:        GetSettings (0);
        !          1582: 
        !          1583:        if (lpDDP)
        !          1584:            IDirectDrawSurface2_SetPalette (lpDDS, lpDDP);
        !          1585: 
        !          1586:        if (!fullscreen || !mouseactive)
        !          1587:            SetCursor (NULL);
        !          1588:     }
        !          1589:     return 0;
        !          1590: }
1.1       root     1591: 
                   1592: #ifdef __GNUC__
                   1593: #undef WINAPI
                   1594: #define WINAPI
                   1595: #endif
                   1596: 
                   1597: static HINSTANCE hDDraw = NULL, hComDlg32 = NULL, hRichEdit = NULL;
                   1598: 
1.1.1.2 ! root     1599: static int cleanuplibs (void)
1.1       root     1600: {
                   1601:     if (hRichEdit)
1.1.1.2 ! root     1602:        FreeLibrary (hRichEdit);
1.1       root     1603:     if (hDDraw)
1.1.1.2 ! root     1604:        FreeLibrary (hDDraw);
1.1       root     1605:     if (hComDlg32)
1.1.1.2 ! root     1606:        FreeLibrary (hComDlg32);
1.1       root     1607:     return 1;
                   1608: }
                   1609: 
                   1610: /* try to load COMDLG32 and DDRAW, initialize csDraw, try to obtain the system clock frequency
                   1611:  * from the registry, try to find out if we are running on a Pentium */
1.1.1.2 ! root     1612: static int initlibs (void)
1.1       root     1613: {
1.1.1.2 ! root     1614:     OSVERSIONINFO osinfo;
        !          1615:     /* Figure out which Win32 OS we're running under */
        !          1616:     osinfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
        !          1617:     if (GetVersionEx (&osinfo)) {
        !          1618:        if (osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT)
        !          1619:            running_winnt = TRUE;
        !          1620:        else
        !          1621:            running_winnt = FALSE;
        !          1622:     }
        !          1623:     figure_processor_speed ();
1.1       root     1624:     /* Make sure we do an InitCommonControls() to get some advanced controls */
                   1625:     InitCommonControls ();
                   1626: 
                   1627:     if (hComDlg32 = LoadLibrary ("COMDLG32.DLL")) {
                   1628:        pGetOpenFileNameA = (BOOL (WINAPI *) (LPOPENFILENAME)) GetProcAddress (hComDlg32, "GetOpenFileNameA");
                   1629:     } else
                   1630:        /* System administrator? ROFL! -- Bernd */
1.1.1.2 ! root     1631:        write_log ("COMDLG32.DLL not available. Please contact your system administrator.\n");
1.1       root     1632: 
                   1633:     /* LoadLibrary the richedit control stuff */
                   1634:     if ((hRichEdit = LoadLibrary ("RICHED32.DLL")) == NULL) {
1.1.1.2 ! root     1635:        write_log ("RICHED32.DLL not available. Please contact your system administrator.\n");
1.1       root     1636:     }
1.1.1.2 ! root     1637:     hDDraw = LoadLibrary ("DDRAW.DLL");
        !          1638:     if (hDDraw == 0) {
        !          1639:        write_log ("You have to install DirectX on your system before you can use UAE.\n"
        !          1640:                   "Refer to the documentation for further details.\n");
        !          1641:        return 0;
        !          1642:     }
        !          1643:     pDirectDrawCreate = (HRESULT (WINAPI *) (GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *)) GetProcAddress (hDDraw, "DirectDrawCreate");
1.1       root     1644: 
1.1.1.2 ! root     1645:     process_desired_pri = IDLE_PRIORITY_CLASS;
1.1       root     1646: 
1.1.1.2 ! root     1647:     return 1;
1.1       root     1648: }
                   1649: 
1.1.1.2 ! root     1650: void write_log (const char *format,...)
1.1       root     1651: {
1.1.1.2 ! root     1652:     DWORD numwritten;
1.1       root     1653:     char buffer[512];
                   1654:     va_list parms;
                   1655: 
                   1656:     va_start (parms, format);
                   1657:     vsprintf (buffer, format, parms);
                   1658:     va_end (parms);
                   1659: 
1.1.1.2 ! root     1660:     fprintf (stderr, "%s", buffer);
        !          1661: 
        !          1662:     WriteFile (debugfile, buffer, strlen (buffer), &numwritten, NULL);
1.1       root     1663: }
                   1664: 
                   1665: int debuggable (void)
                   1666: {
                   1667:     return 1;
                   1668: }
                   1669: 
                   1670: int needmousehack (void)
                   1671: {
                   1672:     return 1;
                   1673: }
                   1674: 
1.1.1.2 ! root     1675: void LED (int a)
1.1       root     1676: {
                   1677: }
                   1678: 
1.1.1.2 ! root     1679: int DX_FillResolutions (uae_u16 * ppixel_format)
1.1       root     1680: {
1.1.1.2 ! root     1681:     struct win32_displaymode *dm;
        !          1682:     int count = 0;
1.1       root     1683: 
1.1.1.2 ! root     1684:     *ppixel_format = 0;
        !          1685:     for (dm = win32_displaymode_list; dm != 0; dm = dm->next) {
        !          1686:        *ppixel_format |= dm->colormodes;
        !          1687:        if (dm->colormodes & RGBMASK_8BIT) {
        !          1688:            DisplayModes[count].res.width = dm->width;
        !          1689:            DisplayModes[count].res.height = dm->height;
        !          1690:            DisplayModes[count].refresh = 75;
        !          1691:            DisplayModes[count].depth = 1;
        !          1692:            count++;
        !          1693:        }
        !          1694:        if (count >= MAX_PICASSO_MODES)
1.1       root     1695:            break;
1.1.1.2 ! root     1696:        if (dm->colormodes & (RGBMASK_16BIT | RGBMASK_15BIT)) {
        !          1697:            DisplayModes[count].res.width = dm->width;
        !          1698:            DisplayModes[count].res.height = dm->height;
        !          1699:            DisplayModes[count].refresh = 75;
        !          1700:            DisplayModes[count].depth = 2;
        !          1701:            count++;
        !          1702:        }
        !          1703:        if (count >= MAX_PICASSO_MODES)
1.1       root     1704:            break;
1.1.1.2 ! root     1705:        if (dm->colormodes & RGBMASK_24BIT) {
        !          1706:            DisplayModes[count].res.width = dm->width;
        !          1707:            DisplayModes[count].res.height = dm->height;
        !          1708:            DisplayModes[count].refresh = 75;
        !          1709:            DisplayModes[count].depth = 3;
        !          1710:            count++;
        !          1711:        }
        !          1712:        if (count >= MAX_PICASSO_MODES)
1.1       root     1713:            break;
1.1.1.2 ! root     1714:        if (dm->colormodes & RGBMASK_32BIT) {
        !          1715:            DisplayModes[count].res.width = dm->width;
        !          1716:            DisplayModes[count].res.height = dm->height;
        !          1717:            DisplayModes[count].refresh = 75;
        !          1718:            DisplayModes[count].depth = 4;
        !          1719:            count++;
        !          1720:        }
        !          1721:        if (count >= MAX_PICASSO_MODES)
1.1       root     1722:            break;
                   1723:     }
1.1.1.2 ! root     1724:     return count;
1.1       root     1725: }
1.1.1.2 ! root     1726: 
1.1       root     1727: void DX_SetPalette (int start, int count)
                   1728: {
                   1729:     HRESULT ddrval;
                   1730: 
1.1.1.2 ! root     1731:     if (! screen_is_picasso || picasso96_state.RGBFormat != RGBFB_CHUNKY)
        !          1732:        return;
        !          1733: 
        !          1734:     if (picasso_vidinfo.pixbytes != 1) {
        !          1735:        printf ("DX Setpalette emulation\n");
        !          1736:        /* This is the case when we're emulating a 256 color display.  */
        !          1737:        while (count-- > 0) {
        !          1738:            int r = picasso96_state.CLUT[start].Red;
        !          1739:            int g = picasso96_state.CLUT[start].Green;
        !          1740:            int b = picasso96_state.CLUT[start].Blue;
        !          1741:            picasso_vidinfo.clut[start++] = (doMask256 (r, red_bits, red_shift)
        !          1742:                                             | doMask256 (g, green_bits, green_shift)
        !          1743:                                             | doMask256 (b, blue_bits, blue_shift));
        !          1744:        }
1.1       root     1745:        return;
1.1.1.2 ! root     1746:     }
1.1       root     1747: 
                   1748:     /* Set our DirectX palette here */
1.1.1.2 ! root     1749:     if (lpDDP && current_pixbytes == 1) {
1.1       root     1750:        /* For now, until I figure this out, just set the entire range of CLUT values */
1.1.1.2 ! root     1751:        ddrval = IDirectDrawPalette_SetEntries (lpDDP, 0, start, count, (LPPALETTEENTRY) & (picasso96_state.CLUT[start]));
1.1       root     1752:        if (ddrval != DD_OK)
1.1.1.2 ! root     1753:            write_log ("DX_SetPalette() failed with %s/%d\n", getddrname (ddrval), ddrval);
        !          1754:        else
        !          1755:            printf ("DX_SetPalette OK\n");
1.1       root     1756:     } else
1.1.1.2 ! root     1757:        write_log ("ERROR - DX_SetPalette() doesn't have palette, or isn't Chunky mode.\n");
1.1       root     1758: }
                   1759: 
                   1760: void DX_Invalidate (int first, int last)
                   1761: {
                   1762: }
                   1763: 
                   1764: int DX_BitsPerCannon (void)
                   1765: {
                   1766:     return 8;
                   1767: }
                   1768: 
                   1769: int DX_FillRect (uaecptr addr, uae_u16 X, uae_u16 Y, uae_u16 Width, uae_u16 Height, uae_u32 Pen, uae_u8 Bpp)
                   1770: {
                   1771:     return 0;
                   1772: }
                   1773: 
                   1774: void gfx_set_picasso_state (int on)
                   1775: {
                   1776:     if (screen_is_picasso == on)
                   1777:        return;
1.1.1.2 ! root     1778: 
1.1       root     1779:     screen_is_picasso = on;
1.1.1.2 ! root     1780:     close_windows ();
        !          1781:     open_windows ();
        !          1782:     DX_SetPalette (0, 256);
1.1       root     1783: }
                   1784: 
1.1.1.2 ! root     1785: void gfx_set_picasso_modeinfo (int w, int h, int depth, int rgbfmt)
1.1       root     1786: {
                   1787:     depth >>= 3;
                   1788:     if (picasso_vidinfo.width == w
                   1789:        && picasso_vidinfo.height == h
1.1.1.2 ! root     1790:        && picasso_vidinfo.depth == depth
        !          1791:        && picasso_vidinfo.selected_rgbformat == rgbfmt)
1.1       root     1792:        return;
                   1793: 
1.1.1.2 ! root     1794:     picasso_vidinfo.selected_rgbformat = rgbfmt;
1.1       root     1795:     picasso_vidinfo.width = w;
                   1796:     picasso_vidinfo.height = h;
                   1797:     picasso_vidinfo.depth = depth;
                   1798:     picasso_vidinfo.extra_mem = 1;
                   1799: 
                   1800:     if (screen_is_picasso) {
1.1.1.2 ! root     1801:        close_windows ();
        !          1802:        open_windows ();
        !          1803:        DX_SetPalette (0, 256);
1.1       root     1804:     }
                   1805: }
                   1806: 
1.1.1.2 ! root     1807: int graphics_init (void)
        !          1808: {
        !          1809:     SetPriorityClass (GetCurrentProcess (), process_desired_pri);
        !          1810: 
        !          1811:     return open_windows ();
        !          1812: }
        !          1813: 
        !          1814: int graphics_setup (void)
        !          1815: {
        !          1816:     char *posn;
        !          1817:     int i;
        !          1818: 
        !          1819:     debugfile = CreateFile ("outfile", GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
        !          1820:                            0, NULL);
        !          1821: 
        !          1822:     /* Get our executable's root-path */
        !          1823:     start_path = xmalloc (MAX_PATH);
        !          1824:     GetModuleFileName (0, start_path, MAX_PATH);
        !          1825:     if (posn = strrchr (start_path, '\\'))
        !          1826:        *posn = 0;
        !          1827: 
        !          1828:     write_log ("UAE " UAEWINVERSION " Win32/DirectX, release " UAEWINRELEASE "\n");
        !          1829:     strcpy (VersionStr, PROGNAME);
        !          1830:     write_log ("\n(c) 1995-1997 Bernd Schmidt   - Core UAE concept and implementation."
        !          1831:               "\n(c) 1996-1997 Mathias Ortmann - Win32 port and enhancements."
        !          1832:               "\n(c) 1996-1997 Brian King      - Picasso96 and AHI support, GUI.\n"
        !          1833:               "\nPress F12 to show the Settings Dialog (GUI), Alt-F4 to quit.\n"
        !          1834:               "\nhttp://www.informatik.tu-muenchen.de/~ortmann/uae/\n\n");
        !          1835: 
        !          1836:     if (! initlibs ())
        !          1837:        return 0;
        !          1838: 
        !          1839:     if (! register_classes ())
        !          1840:        return 0;
        !          1841: 
        !          1842:     if (! start_ddraw ())
        !          1843:        return 0;
        !          1844:     IDirectDraw_EnumDisplayModes (lpDD, 0, NULL, NULL, modesCallback);
        !          1845: #if 0
        !          1846:     figure_pixel_formats ();
        !          1847: #endif
        !          1848:     release_ddraw ();
        !          1849: 
        !          1850:     return 1;
        !          1851: }
        !          1852: 
        !          1853: void machdep_init (void)
        !          1854: {
        !          1855: }
        !          1856: 
        !          1857: void graphics_leave (void)
        !          1858: {
        !          1859:     close_windows ();
        !          1860:     dumpcustom ();
        !          1861:     cleanuplibs ();
        !          1862: }
        !          1863: 
        !          1864: #if defined NO_MAIN_IN_MAIN_C
        !          1865: int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
        !          1866:                    int nCmdShow)
        !          1867: {
        !          1868:     hInst = hInstance;
        !          1869: 
        !          1870:     printf ("WinMain called\n");
        !          1871: 
        !          1872:     /*initgfxspecs(); */
        !          1873: #ifdef __CYGWIN32__
        !          1874:     {
        !          1875:        char *token, *tmpbuf;
        !          1876:        int my_argc, i;
        !          1877:        char ** my_argv;
        !          1878: 
        !          1879:        tmpbuf = my_strdup (lpCmdLine);
        !          1880:        my_argc = 1;
        !          1881:        if (strtok (tmpbuf, "\n ") != NULL) {
        !          1882:            do {
        !          1883:                my_argc++;
        !          1884:            } while (strtok (NULL, "\n ") != NULL);
        !          1885:        }
        !          1886:        free (tmpbuf);
        !          1887: 
        !          1888:        tmpbuf = my_strdup (lpCmdLine);
        !          1889: 
        !          1890:        my_argv = (char **)malloc ((1 + my_argc) * sizeof (char **));
        !          1891:        my_argv[0] = "uae.exe";
        !          1892: 
        !          1893:        token = strtok (tmpbuf, "\n ");
        !          1894:        i = 1;
        !          1895:        while (token != NULL) {
        !          1896:            my_argv[i++] = my_strdup (token);
        !          1897:            token = strtok (NULL, "\n ");
        !          1898:        }
        !          1899:        my_argv[my_argc] = NULL;
        !          1900: 
        !          1901:        real_main (my_argc, my_argv);
        !          1902:     }
        !          1903: #elif defined __MINGW32__
        !          1904:     real_main (_argc, _argv);
        !          1905: #else
        !          1906:     real_main (__argc, __argv);
        !          1907: #endif
        !          1908:     return FALSE;
        !          1909: }
1.1       root     1910: #endif

unix.superglobalmegacorp.com

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