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

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

unix.superglobalmegacorp.com

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