Annotation of uae/src/od-win32/win32.c, revision 1.1.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.