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

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

unix.superglobalmegacorp.com

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