--- uae/src/od-win32/win32.c 2018/04/24 16:40:31 1.1.1.1 +++ uae/src/od-win32/win32.c 2018/04/24 16:45:43 1.1.1.3 @@ -6,31 +6,28 @@ * Copyright 1997 Mathias Ortmann */ -#ifdef __GNUC__ -#define __int64 long long -#include "machdep/winstuff.h" -#else -#include -#include +#include "config.h" +#include "sysconfig.h" + #include #include +#include + +/* No idea what this is for, but it doesn't link without it if we use + QueryInterface. */ +#define INITGUID + +#include +#include #include #include -#include -#include -#include #include -#endif -#include "config.h" -#include "sysconfig.h" #include "sysdeps.h" - #include "options.h" #include "gensound.h" #include "sounddep/sound.h" #include "uae.h" -#include "threaddep/penguin.h" #include "memory.h" #include "custom.h" #include "events.h" @@ -38,64 +35,58 @@ #include "keyboard.h" #include "picasso96.h" +#include "osdep/win32.h" #include "osdep/win32gui.h" #include "resource.h" -#include "osdep/win32.h" - -extern struct picasso_vidbuf_description picasso_vidinfo; -#define IHF_WINDOWHIDDEN 6 -static BOOL (WINAPI *pGetOpenFileNameA) (LPOPENFILENAME); -static HRESULT (WINAPI *pDirectDrawCreate) (GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *); -static HRESULT CALLBACK modesCallback (LPDDSURFACEDESC modeDesc, LPVOID context); +#define IHF_WINDOWHIDDEN 6 -HWND hAmigaWnd, hMainWnd; HINSTANCE hInst; -/*DWORD Keys;*/ + +static BOOL (WINAPI * pGetOpenFileNameA) (LPOPENFILENAME); +static HRESULT (WINAPI * pDirectDrawCreate) (GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *); +static HRESULT CALLBACK modesCallback (LPDDSURFACEDESC modeDesc, LPVOID context); + +static int display_change_requested = 0; + +int julian_mode; +int debug_logging = 3; + +HWND hAmigaWnd, hMainWnd, hStatusWnd; +/*DWORD Keys; */ static RECT amigawin_rect; -drive_specs drives[NUM_DRIVES]; char *start_path = NULL; static LPDIRECTDRAW lpDD; +static LPDIRECTDRAW2 lpDD2; static LPDIRECTDRAWSURFACE lpDDS; static LPDIRECTDRAWCLIPPER lpDDC; static LPDIRECTDRAWPALETTE lpDDP; +static DDSURFACEDESC current_surface; static DDSURFACEDESC ddsd; -HANDLE hEmuThread; - -static HDC hBackDC; -static HBITMAP hBackBM; - -static CRITICAL_SECTION csDraw; #define TITLETEXT PROGNAME " -- Amiga Display" -char VersionStr[256]; -extern int current_width, current_height; -static uae_sem_t picasso_switch_sem; +char VersionStr[256]; -static int fullscreen = 0; -int current_width, current_height; +static int current_width, current_height, current_depth; +static int fullscreen, needs_fullscreen; static int current_pixbytes; -static int changemode; +static int in_sizemove; static int screen_is_picasso = 0; -static int picasso_fullscreen = 1; -int amiga_fullscreen = 1, customsize = 0; + +int customsize = 0; int bActive; -int capslock; int toggle_sound; int process_desired_pri; -int cycles_per_instruction = 4; -int good_cpu = 0; - -BOOL allow_quit_from_property_sheet = TRUE; BOOL viewing_child = FALSE; +BOOL running_winnt = FALSE; static char scrlinebuf[8192]; /* this is too large, but let's rather play on the safe side here */ static int scrindirect; @@ -112,36 +103,18 @@ static void set_linemem (void) static LPARAM keysdown[256]; static short numkeysdown; -int getcapslock (void) -{ - BYTE keyState[256]; - - GetKeyboardState (keyState); - return keyState[VK_CAPITAL] & 1; -} - -int helppressed (void) -{ - return GetAsyncKeyState (VK_END) & 0x8000; -} - -int shiftpressed (void) -{ - return GetAsyncKeyState (VK_SHIFT) & 0x8000 ? 1 : 0; -} - int checkkey (int vkey, LPARAM lParam) { switch (vkey) { - case VK_SHIFT: - case VK_LSHIFT: - case VK_RSHIFT: - case VK_CONTROL: - case VK_LCONTROL: - case VK_RCONTROL: - case VK_MENU: - case VK_LMENU: - case VK_RMENU: + case VK_SHIFT: + case VK_LSHIFT: + case VK_RSHIFT: + case VK_CONTROL: + case VK_LCONTROL: + case VK_RCONTROL: + case VK_MENU: + case VK_LMENU: + case VK_RMENU: return GetKeyState (vkey) & 0x8000; } return GetAsyncKeyState (vkey) & 0x8000; @@ -178,7 +151,7 @@ void setmouseactive (int active) static int hascapture = 0; -void setcapture (void) +static void setcapture (void) { if (hascapture) return; @@ -194,183 +167,193 @@ static __inline__ void releasecapture (v ReleaseCapture (); } +static void illhandler(int foo) +{ + rpt_available = 0; +} + static void figure_processor_speed (void) { - SYSTEM_INFO sysinfo; - OSVERSIONINFO osinfo; - HKEY hKey; - DWORD value; - DWORD type, size; - unsigned long mhz = 0; - char cpuid[40]; - char *envptr; - - vsynctime = -1; - if ((envptr = getenv ("PROCESSOR_LEVEL")) && atoi (envptr) < 5) - goto bad_cpu; - - if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0L, KEY_READ, &hKey) == ERROR_SUCCESS) { - size = sizeof (value); - if (RegQueryValueEx (hKey, "~MHz", NULL, &type, (LPBYTE) & value, &size) == ERROR_SUCCESS) - mhz = value; - size = sizeof cpuid; - if (RegQueryValueEx (hKey, "VendorIdentifier", NULL, &type, (LPBYTE) cpuid, &size) == ERROR_SUCCESS) { - good_cpu = (strncmp (cpuid, "AuthenticAMD", 12) == 0 - || strncmp (cpuid, "GenuineIntel", 12) == 0); - } - RegCloseKey (hKey); - } - if (!good_cpu) - goto bad_cpu; - -#ifdef FRAME_RATE_HACK - if (mhz == 0) { - frame_time_t t; - DWORD oldpri = GetPriorityClass (GetCurrentProcess ()); - - write_log ("Calibrating delay loop.. "); - - SetPriorityClass (GetCurrentProcess (), REALTIME_PRIORITY_CLASS); - vsynctime = 1; - t = read_processor_time (); - Sleep (1001); - t = 2*read_processor_time () - t; - Sleep (1); - t -= read_processor_time (); - SetPriorityClass (GetCurrentProcess (), oldpri); + frame_time_t best_time; + int i; - MyOutputDebugString ("ok - %.2f BogoMIPS\n", (double)t / 1000000.0); - vsynctime = t / 50; + rpt_available = 1; + signal (SIGILL, illhandler); + read_processor_time (); + signal (SIGILL, SIG_DFL); + if (! rpt_available) { + fprintf (stderr, "Your processor does not support the RDTSC instruction.\n"); return; } -#endif - if (mhz != 0) { - vsynctime = mhz * 1000000 / 50; - return; + fprintf (stderr, "Calibrating delay loop.. "); + fflush (stderr); + best_time = (frame_time_t)-1; + for (i = 0; i < 5; i++) { + frame_time_t t = read_processor_time (); + Sleep (1001); + t = 2 * read_processor_time () - t; + Sleep (1); + t -= read_processor_time (); + if (t < best_time) + best_time = t; } - write_log ("Could not determine clock speed of your CPU.\n"); - return; -bad_cpu: - write_log ("Processor level too low - disabling frame rate hack\n"); + fprintf (stderr, "ok - %.2f BogoMIPS\n", + ((double)best_time / 1000000), best_time); + vsynctime = best_time / 50; } -/* DirectDraw stuff*/ -char *getddrname (HRESULT ddrval) +/* DirectDraw stuff */ +static char *getddrname (HRESULT ddrval) { switch (ddrval) { - case DDERR_ALREADYINITIALIZED: + case DDERR_ALREADYINITIALIZED: return "This object is already initialized."; - case DDERR_BLTFASTCANTCLIP: - return "Cannot use BLTFAST with Clipper attached to surface."; - case DDERR_CANNOTATTACHSURFACE: + case DDERR_CANNOTATTACHSURFACE: return "Cannot attach surface."; - case DDERR_CANNOTDETACHSURFACE: + case DDERR_CANNOTDETACHSURFACE: return "Cannot detach surface."; - case DDERR_CANTCREATEDC: - return "Cannot create DC Device Context."; - case DDERR_CANTDUPLICATE: - return "Cannot duplicate."; - case DDERR_CANTLOCKSURFACE: - return "Access to surface refused (no DCI provider)."; - case DDERR_CANTPAGELOCK: - return "PageLock failure."; - case DDERR_CANTPAGEUNLOCK: - return "PageUnlock failure."; - case DDERR_CLIPPERISUSINGHWND: - return "Can't set a clip-list for a Clipper which is attached to an HWND."; - case DDERR_COLORKEYNOTSET: - return "No source colour-key provided."; - case DDERR_CURRENTLYNOTAVAIL: + case DDERR_CURRENTLYNOTAVAIL: return "Support unavailable."; - case DDERR_DCALREADYCREATED: - return "Surface already has a Device Context."; - case DDERR_DIRECTDRAWALREADYCREATED: - return "DirectDraw already bound to this process."; - case DDERR_EXCEPTION: + case DDERR_EXCEPTION: return "Unexpected exception."; - case DDERR_EXCLUSIVEMODEALREADYSET: - return "Already in exclusive mode."; - case DDERR_GENERIC: + case DDERR_GENERIC: return "Undefined"; /* THIS MAKES SENSE! FUCKING M$ */ - - case DDERR_HEIGHTALIGN: + case DDERR_HEIGHTALIGN: return "Height needs to be aligned."; - case DDERR_HWNDALREADYSET: - return "HWND already set for cooperative level."; - case DDERR_HWNDSUBCLASSED: - return "HWND has been subclassed."; - case DDERR_IMPLICITLYCREATED: - return "Can't restore an implicitly created surface."; - case DDERR_INCOMPATIBLEPRIMARY: + case DDERR_INCOMPATIBLEPRIMARY: return "New params doesn't match existing primary surface."; - case DDERR_INVALIDCAPS: + case DDERR_INVALIDCAPS: return "Device doesn't have requested capabilities."; - case DDERR_INVALIDCLIPLIST: + case DDERR_INVALIDCLIPLIST: return "Provided clip-list not supported."; - case DDERR_INVALIDDIRECTDRAWGUID: - return "Invalid GUID."; - case DDERR_INVALIDMODE: + case DDERR_INVALIDMODE: return "Mode not supported."; - case DDERR_INVALIDOBJECT: + case DDERR_INVALIDOBJECT: return "Invalid object."; - case DDERR_INVALIDPARAMS: + case DDERR_INVALIDPARAMS: return "Invalid params."; - case DDERR_INVALIDPIXELFORMAT: + case DDERR_INVALIDPIXELFORMAT: return "Device doesn't support requested pixel format."; - case DDERR_INVALIDPOSITION: - return "Overlay position illegal."; - case DDERR_INVALIDRECT: + case DDERR_INVALIDRECT: return "Invalid RECT."; - case DDERR_INVALIDSURFACETYPE: - return "Wrong type of surface."; - case DDERR_LOCKEDSURFACES: + case DDERR_LOCKEDSURFACES: return "Surface locked."; - case DDERR_NO3D: + case DDERR_NO3D: return "No 3d capabilities."; - case DDERR_NOALPHAHW: + case DDERR_NOALPHAHW: return "No alpha h/w."; - case DDERR_NOBLTHW: - return "No blit h/w."; - case DDERR_NOCLIPLIST: + case DDERR_NOCLIPLIST: return "No clip-list."; - case DDERR_NOCLIPPERATTACHED: - return "No Clipper attached."; - case DDERR_NOCOLORCONVHW: + case DDERR_NOCOLORCONVHW: return "No colour-conversion h/w."; - case DDERR_NOCOLORKEY: + case DDERR_NOCOOPERATIVELEVELSET: + return "No cooperative-level set."; + case DDERR_NOCOLORKEY: return "No colour-key."; + case DDERR_NOCOLORKEYHW: + return "No colour-key hardware."; + case DDERR_NODIRECTDRAWSUPPORT: + return "No DirectDraw support with this display driver!"; + case DDERR_NOEXCLUSIVEMODE: + return "Exlusive-mode needed but not set yet."; + case DDERR_NOFLIPHW: + return "No flipping hardware."; + case DDERR_NOGDI: + return "No GDI present."; + case DDERR_NOMIRRORHW: + return "No mirror hardware."; + case DDERR_NOTFOUND: + return "Requested item not found."; + case DDERR_NOOVERLAYHW: + return "No overlay hardware."; + case DDERR_NORASTEROPHW: + return "No raster-op hardware."; + case DDERR_NOROTATIONHW: + return "No rotation hardware."; + case DDERR_NOSTRETCHHW: + return "No stretch hardware."; + case DDERR_NOT4BITCOLOR: + return "Not a 4-bit colour palette."; + case DDERR_NOT4BITCOLORINDEX: + return "Not a 4-bit colour-index."; + case DDERR_NOT8BITCOLOR: + return "Not an 8-bit colour palette."; + case DDERR_NOTEXTUREHW: + return "No texture hardware."; + case DDERR_BLTFASTCANTCLIP: + return "Cannot use BLTFAST with Clipper attached to surface."; + case DDERR_CANTCREATEDC: + return "Cannot create DC Device Context."; + case DDERR_CANTDUPLICATE: + return "Cannot duplicate."; + case DDERR_CANTLOCKSURFACE: + return "Access to surface refused (no DCI Provider)."; + case DDERR_CANTPAGELOCK: + return "PageLock failure."; + case DDERR_CANTPAGEUNLOCK: + return "PageUnlock failure."; + case DDERR_CLIPPERISUSINGHWND: + return "Can't set a clip-list for a Clipper which is attached to an HWND."; + case DDERR_COLORKEYNOTSET: + return "No source colour-key provided."; + case DDERR_DCALREADYCREATED: + return "Surface already has a Device Context."; + case DDERR_DIRECTDRAWALREADYCREATED: + return "DirectDraw already bound to this process."; + case DDERR_EXCLUSIVEMODEALREADYSET: + return "Already in exclusive mode."; + case DDERR_HWNDALREADYSET: + return "HWND already set for cooperative level."; + case DDERR_HWNDSUBCLASSED: + return "HWND has been subclassed."; + case DDERR_IMPLICITLYCREATED: + return "Can't restore an implicitly created surface."; + case DDERR_INVALIDDIRECTDRAWGUID: + return "Invalid GUID."; + case DDERR_INVALIDPOSITION: + return "Overlay position illegal."; + case DDERR_INVALIDSURFACETYPE: + return "Wrong type of surface."; + case DDERR_NOBLTHW: + return "No blit h/w."; + case DDERR_NOCLIPPERATTACHED: + return "No Clipper attached."; - case DDERR_NOTLOCKED: + case DDERR_NOTLOCKED: return "Not locked."; - case DDERR_NOTPAGELOCKED: + case DDERR_NOTPAGELOCKED: return "Not page-locked."; - case DDERR_NOTPALETTIZED: + case DDERR_NOTPALETTIZED: return "Not palette-based."; - case DDERR_OUTOFCAPS: + case DDERR_OUTOFCAPS: return "out of caps"; - case DDERR_OUTOFMEMORY: + case DDERR_OUTOFMEMORY: return "Out of memory."; - case DDERR_OUTOFVIDEOMEMORY: + case DDERR_OUTOFVIDEOMEMORY: return "out of video memory."; - case DDERR_PALETTEBUSY: + case DDERR_PALETTEBUSY: return "Palette busy."; - case DDERR_PRIMARYSURFACEALREADYEXISTS: + case DDERR_PRIMARYSURFACEALREADYEXISTS: return "Already a primary surface."; - case DDERR_SURFACEBUSY: + case DDERR_SURFACEBUSY: return "Surface busy."; - /*case DDERR_SURFACEOBSCURED: return "Surface is obscured.";*/ - case DDERR_SURFACELOST: + /*case DDERR_SURFACEOBSCURED: return "Surface is obscured."; */ + case DDERR_SURFACELOST: return "Surface lost."; - case DDERR_UNSUPPORTED: + case DDERR_UNSUPPORTED: return "Unsupported."; - case DDERR_UNSUPPORTEDFORMAT: + case DDERR_UNSUPPORTEDFORMAT: return "Unsupported format."; - case DDERR_WASSTILLDRAWING: + case DDERR_WASSTILLDRAWING: return "Was still drawing."; + + case DDERR_WRONGMODE: + return "Wrong Mode."; + } return ""; } @@ -384,7 +367,7 @@ static int do_surfacelock (void) if (ddrval == DDERR_SURFACELOST) ddrval = IDirectDrawSurface_Restore (lpDDS); else if (ddrval != DDERR_SURFACEBUSY) - MyOutputDebugString ("lpDDS->Lock() failed - %s (%d)\n", getddrname (ddrval), (unsigned short) ddrval); + write_log ("lpDDS->Lock() failed - %s (%d)\n", getddrname (ddrval), (unsigned short) ddrval); return 0; } lockcnt++; @@ -397,60 +380,175 @@ void unlockscr (void) IDirectDrawSurface_Unlock (lpDDS, ddsd.lpSurface); } -static void release_ddraw_stuff (void) +/* Return one of the pixel formats declared in picasso96.h if the surface + * is usable for us, or RGBFB_NONE if it is not usable. */ +static RGBFTYPE surface_pixelformat (DDSURFACEDESC *surface) +{ + DDPIXELFORMAT *pfp = &surface->ddpfPixelFormat; + DWORD r, g, b; + + if ((surface->dwFlags & (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_REFRESHRATE)) + != (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_REFRESHRATE)) + return RGBFB_NONE; + + if ((pfp->dwFlags & DDPF_RGB) == 0) + return RGBFB_NONE; + + r = pfp->dwRBitMask; + g = pfp->dwGBitMask; + b = pfp->dwBBitMask; + switch (pfp->dwRGBBitCount) { + case 8: + if ((pfp->dwFlags & DDPF_PALETTEINDEXED8) != 0) + return RGBFB_CHUNKY; + break; + + case 16: + if (r == 0xF800 && g == 0x07E0 && b == 0x001F) + return RGBFB_R5G6B5PC; + if (r == 0x7C00 && g == 0x03E0 && b == 0x001F) + return RGBFB_R5G5B5PC; + if (b == 0xF800 && g == 0x07E0 && r == 0x001F) + return RGBFB_B5G6R5PC; + if (b == 0x7C00 && g == 0x03E0 && r == 0x001F) + return RGBFB_B5G5R5PC; + /* This happens under NT - with r == b == g == 0 !!! */ + printf ("Unknown 16 bit format %d %d %d\n", r, g, b); + break; + + case 24: + if (r == 0xFF0000 && g == 0x00FF00 && b == 0x0000FF) + return RGBFB_B8G8R8; + if (r == 0x0000FF && g == 0x00FF00 && b == 0xFF0000) + return RGBFB_R8G8B8; + break; + + case 32: + if (r == 0x00FF0000 && g == 0x0000FF00 && b == 0x000000FF) + return RGBFB_B8G8R8A8; + if (r == 0x000000FF && g == 0x0000FF00 && b == 0x00FF0000) + return RGBFB_R8G8B8A8; + if (r == 0xFF000000 && g == 0x00FF0000 && b == 0x0000FF00) + return RGBFB_A8B8G8R8; + if (r == 0x0000FF00 && g == 0x00FF0000 && b == 0xFF000000) + return RGBFB_A8R8G8B8; + break; + + default: + printf ("Unknown %d bit format %d %d %d\n", pfp->dwRGBBitCount, r, g, b); + break; + } + return RGBFB_NONE; +} + +static int rgbformat_bits (RGBFTYPE t) +{ + unsigned long f = 1 << t; + return ((f & RGBMASK_8BIT) != 0 ? 8 + : (f & RGBMASK_15BIT) != 0 ? 15 + : (f & RGBMASK_16BIT) != 0 ? 16 + : (f & RGBMASK_24BIT) != 0 ? 24 + : (f & RGBMASK_32BIT) != 0 ? 32 + : 0); +} + +static void release_ddraw (void) { +#if 0 + if (lpDD2) { + IDirectDraw2_RestoreDisplayMode (lpDD2); + IDirectDraw2_SetCooperativeLevel (lpDD2, hAmigaWnd, DDSCL_NORMAL); + } +#else if (lpDD) { IDirectDraw_RestoreDisplayMode (lpDD); IDirectDraw_SetCooperativeLevel (lpDD, hAmigaWnd, DDSCL_NORMAL); } +#endif + if (lpDDC) IDirectDrawClipper_Release (lpDDC); if (lpDDS) IDirectDrawSurface_Release (lpDDS); if (lpDDP) IDirectDrawPalette_Release (lpDDP); + if (lpDD2) + IDirectDraw2_Release (lpDD2); if (lpDD) IDirectDraw_Release (lpDD); lpDDC = 0; lpDDS = 0; lpDDP = 0; + lpDD2 = 0; lpDD = 0; } -static int set_ddraw (int width, int height, int wantfull, int *pbytes, - LPPALETTEENTRY pal) + +static int start_ddraw (void) { - int bits = 8 * *pbytes; HRESULT ddrval; -#ifdef __GNUC__ ddrval = (*pDirectDrawCreate) (NULL, &lpDD, NULL); -#else - ddrval = DirectDrawCreate (NULL, &lpDD, NULL); + if (ddrval != DD_OK) + goto oops; + +#if 0 + ddrval = IDirectDraw_QueryInterface (lpDD, &IID_IDirectDraw2, (LPVOID *)&lpDD2); + if (ddrval != DD_OK) + goto oops; #endif + + current_surface.dwSize = sizeof current_surface; + ddrval = IDirectDraw_GetDisplayMode (lpDD, ¤t_surface); if (ddrval != DD_OK) goto oops; + return 1; + + oops: + write_log ("DirectDraw initialization failed with %s/%d\n", getddrname (ddrval), ddrval); + release_ddraw (); + return 0; +} + +static int set_ddraw (int width, int height, int wantfull, int bits, + LPPALETTEENTRY pal) +{ + HRESULT ddrval; + + bits = (bits + 7) & ~7; + ddrval = IDirectDraw_SetCooperativeLevel (lpDD, hAmigaWnd, - (wantfull - ? DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN - : DDSCL_NORMAL)); + (wantfull + ? DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN + : DDSCL_NORMAL)); if (ddrval != DD_OK) goto oops; ddrval = IDirectDraw_CreateClipper (lpDD, 0, &lpDDC, NULL); - if (ddrval != DD_OK) { - MyOutputDebugString ("DirectDraw error: Clipper unavailable! (%d)\n", ddrval); - } else { - if (IDirectDrawClipper_SetHWnd (lpDDC, 0, hAmigaWnd) != DD_OK) - MyOutputDebugString ("DirectDraw error: Can't attach HWnd!\n"); - } + if (ddrval != DD_OK) + goto oops; + + ddrval = IDirectDrawClipper_SetHWnd (lpDDC, 0, hAmigaWnd); + if (ddrval != DD_OK) + goto oops; if (wantfull) { + /* Hmmm... + * The "bits" parameter is somewhat suspicious. What if a graphics + * card supports A8R8G8B8 and A8B8G8R8 modes? */ + printf ("Trying %dx%d, %d\n", width, height, bits); ddrval = IDirectDraw_SetDisplayMode (lpDD, width, height, bits); if (ddrval != DD_OK) goto oops; + printf ("ok\n"); + + current_surface.dwSize = sizeof current_surface; + ddrval = IDirectDraw_GetDisplayMode (lpDD, ¤t_surface); + if (ddrval != DD_OK) + goto oops; } + ddsd.dwSize = sizeof (ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; @@ -463,57 +561,37 @@ static int set_ddraw (int width, int hei return 0; unlockscr (); - bits = (ddsd.ddpfPixelFormat.dwRGBBitCount + 7) & ~7; - current_pixbytes = *pbytes = bits >> 3; + current_pixbytes = (ddsd.ddpfPixelFormat.dwRGBBitCount + 7) >> 3; - if (bits == 8) { + if (current_pixbytes == 1) { ddrval = IDirectDraw_CreatePalette (lpDD, DDPCAPS_8BIT | DDPCAPS_ALLOW256, - pal, - &lpDDP, NULL); + pal, + &lpDDP, NULL); if (ddrval != DD_OK) goto oops; ddrval = IDirectDrawSurface2_SetPalette (lpDDS, lpDDP); if (ddrval != DD_OK) goto oops; - } - /* Set global values for current width,height */ - current_width = width; - current_height = height; + } return 1; -oops: - MyOutputDebugString ("DirectDraw initialization failed with %s/%d\n", getddrname (ddrval), ddrval); + oops: + write_log ("DirectDraw initialization failed with %s/%d\n", getddrname (ddrval), ddrval); return 0; } /* Color management */ -static int bits_in_mask (unsigned long mask) -{ - int n = 0; - while (mask) { - n += mask & 1; - mask >>= 1; - } - return n; -} - -static int mask_shift (unsigned long mask) -{ - int n = 0; - while (!(mask & 1)) { - n++; - mask >>= 1; - } - return n; -} static xcolnr xcol8[4096]; static PALETTEENTRY colors256[256]; static int ncols256 = 0; -static int get_color (int r, int g, int b, xcolnr *cnp) +static int red_bits, green_bits, blue_bits; +static int red_shift, green_shift, blue_shift; + +static int get_color (int r, int g, int b, xcolnr * cnp) { if (ncols256 == 256) return 0; @@ -528,118 +606,102 @@ static int get_color (int r, int g, int static void init_colors (void) { - if (ncols256 == 0) + int i; + + if (ncols256 == 0) { alloc_colors256 (get_color); - memcpy (xcol8, xcolors, sizeof xcol8); + memcpy (xcol8, xcolors, sizeof xcol8); + } /* init colors */ switch (current_pixbytes) { - case 1: + case 1: memcpy (xcolors, xcol8, sizeof xcolors); if (lpDDP != 0) { HRESULT ddrval = IDirectDrawPalette_SetEntries (lpDDP, 0, 0, 256, colors256); if (ddrval != DD_OK) - MyOutputDebugString ("DX_SetPalette() failed with %s/%d\n", getddrname (ddrval), ddrval); + write_log ("DX_SetPalette() failed with %s/%d\n", getddrname (ddrval), ddrval); } break; - case 2: - case 3: - case 4: - { - int red_bits = bits_in_mask (ddsd.ddpfPixelFormat.dwRBitMask); - int green_bits = bits_in_mask (ddsd.ddpfPixelFormat.dwGBitMask); - int blue_bits = bits_in_mask (ddsd.ddpfPixelFormat.dwBBitMask); - int red_shift = mask_shift (ddsd.ddpfPixelFormat.dwRBitMask); - int green_shift = mask_shift (ddsd.ddpfPixelFormat.dwGBitMask); - int blue_shift = mask_shift (ddsd.ddpfPixelFormat.dwBBitMask); + case 2: + case 3: + case 4: + red_bits = bits_in_mask (ddsd.ddpfPixelFormat.dwRBitMask); + green_bits = bits_in_mask (ddsd.ddpfPixelFormat.dwGBitMask); + blue_bits = bits_in_mask (ddsd.ddpfPixelFormat.dwBBitMask); + red_shift = mask_shift (ddsd.ddpfPixelFormat.dwRBitMask); + green_shift = mask_shift (ddsd.ddpfPixelFormat.dwGBitMask); + blue_shift = mask_shift (ddsd.ddpfPixelFormat.dwBBitMask); - alloc_colors64k (red_bits, green_bits, blue_bits, red_shift, - green_shift, blue_shift); - } + alloc_colors64k (red_bits, green_bits, blue_bits, red_shift, + green_shift, blue_shift); + break; + } + switch (gfxvidinfo.pixbytes) { + case 2: + for (i = 0; i < 4096; i++) + xcolors[i] = xcolors[i] * 0x00010001; + gfxvidinfo.can_double = 1; + break; + case 1: + for (i = 0; i < 4096; i++) + xcolors[i] = xcolors[i] * 0x01010101; + gfxvidinfo.can_double = 1; + break; + default: + gfxvidinfo.can_double = 0; break; } } static void close_windows (void) { - int i; - gfxvidinfo.bufmem = 0; gfxvidinfo.linemem = 0; releasecapture (); setmouseactive (0); ClipCursor (NULL); - release_ddraw_stuff (); + release_ddraw (); + dsound_newwindow (0); - if (!hMainWnd && hAmigaWnd) { - /*ShowWindow (hAmigaWnd, SW_MINIMIZE);*/ - } if (hAmigaWnd) DestroyWindow (hAmigaWnd); + if (hStatusWnd) + DestroyWindow (hStatusWnd); if (hMainWnd) DestroyWindow (hMainWnd); - PostQuitMessage (0); + hMainWnd = 0; + hStatusWnd = 0; hAmigaWnd = 0; } -static void destroy_window (int nowait) -{ - if (currprefs.produce_sound > 1) - stopsound (); - - if (!nowait) { - frame_do_semup = 1; - set_inhibit_frame (5); - uae_sem_wait (&frame_sem); - } - - /*SuspendThread (hEmuThread);*/ - close_windows (); -} - -void displaychange (void) -{ - changemode = 1; - destroy_window (0); -} - void toggle_fullscreen (void) { - changemode = 1; + if (needs_fullscreen) + return; + + display_change_requested = 1; if (screen_is_picasso) - picasso_fullscreen ^= 1; + currprefs.gfx_pfullscreen ^= 1; else - amiga_fullscreen ^= 1; - destroy_window (0); + currprefs.gfx_afullscreen ^= 1; } -int can_draw (void) -{ - return gfxvidinfo.pixbytes != 0; -} - -long FAR PASCAL AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +static long FAR PASCAL AmigaWindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hDC; - if (changemode != 0) - return DefWindowProc (hWnd, message, wParam, lParam); - switch (message) { - case WM_ACTIVATEAPP: + case WM_ACTIVATEAPP: if (bActive = wParam) { if (fullscreen) { SetCursor (NULL); - SetCursorPos (mousecx, mousecy); -#ifdef PICASSO96 - if( !picasso96_state.RefreshPending ) - picasso96_state.RefreshPending = 1; -#endif + SetCursorPos (mousecx, mousecy); } my_kbd_handler (VK_CAPITAL, 0x3a, TRUE); } else { @@ -648,35 +710,35 @@ long FAR PASCAL AmigaWindowProc (HWND hW } break; - case WM_ACTIVATE: + case WM_ACTIVATE: if (LOWORD (wParam) != WA_INACTIVE) { ShowWindow (hWnd, SW_RESTORE); } break; - case WM_SETCURSOR: + case WM_SETCURSOR: if (fullscreen) { SetCursor (NULL); return TRUE; } break; - case WM_SYSCOMMAND: + case WM_SYSCOMMAND: if (wParam == SC_ZOOM) { toggle_fullscreen (); return 0; } break; - case WM_KEYUP: - case WM_SYSKEYUP: + case WM_KEYUP: + case WM_SYSKEYUP: numkeysdown--; keysdown[wParam] = 0; my_kbd_handler (wParam, (lParam >> 16) & 0x1ff, FALSE); break; - case WM_KEYDOWN: - case WM_SYSKEYDOWN: + case WM_KEYDOWN: + case WM_SYSKEYDOWN: if (LOWORD (lParam) == 1) { if (numkeysdown) { int key; @@ -702,7 +764,7 @@ long FAR PASCAL AmigaWindowProc (HWND hW } break; - case WM_LBUTTONDOWN: + case WM_LBUTTONDOWN: if (ievent_alive) { setcapture (); buttonstate[0] = 1; @@ -712,34 +774,34 @@ long FAR PASCAL AmigaWindowProc (HWND hW buttonstate[0] = 1; break; - case WM_LBUTTONUP: + case WM_LBUTTONUP: releasecapture (); buttonstate[0] = 0; break; - case WM_MBUTTONDOWN: + case WM_MBUTTONDOWN: if (ievent_alive) setcapture (); buttonstate[1] = 1; break; - case WM_MBUTTONUP: + case WM_MBUTTONUP: releasecapture (); buttonstate[1] = 0; break; - case WM_RBUTTONDOWN: + case WM_RBUTTONDOWN: if (ievent_alive) setcapture (); buttonstate[2] = 1; break; - case WM_RBUTTONUP: + case WM_RBUTTONUP: releasecapture (); buttonstate[2] = 0; break; - case WM_MOUSEMOVE: + case WM_MOUSEMOVE: if ((mouseactive && !ievent_alive) || fullscreen) { /* * In this mode, the mouse pointer is always centered in the window, @@ -769,21 +831,14 @@ long FAR PASCAL AmigaWindowProc (HWND hW lastmy = (signed short) HIWORD (lParam); break; - case WM_PAINT: - hDC = BeginPaint (hWnd, &ps); + case WM_PAINT: clear_inhibit_frame (IHF_WINDOWHIDDEN); - if (hBackDC) - BitBlt (hDC, ps.rcPaint.left, ps.rcPaint.top, - ps.rcPaint.right - ps.rcPaint.left, - ps.rcPaint.bottom - ps.rcPaint.top, hBackDC, - ps.rcPaint.left, ps.rcPaint.top, SRCCOPY); - else - notice_screen_contents_lost (); - + hDC = BeginPaint (hWnd, &ps); EndPaint (hWnd, &ps); + notice_screen_contents_lost (); break; - case WM_DROPFILES: + case WM_DROPFILES: if (DragQueryFile ((HDROP) wParam, (UINT) - 1, NULL, 0)) { if (DragQueryFile ((HDROP) wParam, 0, NULL, 0) < 255) DragQueryFile ((HDROP) wParam, 0, changed_prefs.df[0], sizeof (changed_prefs.df[0])); @@ -791,55 +846,41 @@ long FAR PASCAL AmigaWindowProc (HWND hW DragFinish ((HDROP) wParam); break; - case WM_CAPTURECHANGED: - if (lParam != hWnd) + case WM_CAPTURECHANGED: + if ((HWND)lParam != hAmigaWnd) buttonstate[0] = buttonstate[1] = buttonstate[2] = 0; break; - case WM_TIMER: -#if 0 - if (wParam == 2) { - KillTimer (hwnd, timer_id); - timer_id = 0; - ClearVisibleAreaAndRefresh (); - } else -#endif - { - finishjob (); - } - break; - - case WM_USER + 0x200: - DoSomeWeirdPrintingStuff(wParam); + case WM_TIMER: + finishjob (); break; - case WM_USER + 0x201: - changemode = 2; - destroy_window (1); + case WM_USER + 0x200: + DoSomeWeirdPrintingStuff (wParam); break; - case WM_CREATE: + case WM_CREATE: DragAcceptFiles (hWnd, TRUE); break; - case WM_DESTROY: - changemode = 3; - destroy_window (0); + case WM_CLOSE: + uae_quit (); + return 0; + + case WM_WINDOWPOSCHANGED: + GetWindowRect (hAmigaWnd, &amigawin_rect); break; } return DefWindowProc (hWnd, message, wParam, lParam); } -long FAR PASCAL MainWindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +static long FAR PASCAL MainWindowProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; - RECT rc, rc2; + RECT rc; HDC hDC; - if (changemode != 0) - return DefWindowProc (hWnd, message, wParam, lParam); - switch (message) { case WM_LBUTTONDOWN: case WM_MOUSEMOVE: @@ -860,50 +901,43 @@ long FAR PASCAL MainWindowProc (HWND hWn case WM_CREATE: case WM_DESTROY: case WM_USER + 0x200: - case WM_USER + 0x201: + case WM_CLOSE: return AmigaWindowProc (hWnd, message, wParam, lParam); case WM_DISPLAYCHANGE: - if (!fullscreen && !changemode && (wParam + 7) / 8 != current_pixbytes) - displaychange (); + if (!fullscreen && (wParam + 7) / 8 != current_pixbytes) + display_change_requested = 1; break; - + case WM_ENTERSIZEMOVE: - if (!fullscreen) { - frame_do_semup = 1; - set_inhibit_frame (5); - uae_sem_wait (&frame_sem); - } + in_sizemove++; break; case WM_EXITSIZEMOVE: - clear_inhibit_frame (5); + in_sizemove--; + /* fall through */ case WM_WINDOWPOSCHANGED: GetWindowRect (hAmigaWnd, &amigawin_rect); + if (in_sizemove > 0) + break; + if (!fullscreen && hAmigaWnd) { - if (current_pixbytes == 2) { - if (amigawin_rect.left & 1) { - GetWindowRect (hMainWnd, &rc2); - if (1 /*!mon || rc2.left + 4 < GetSystemMetrics (SM_CXSCREEN)*/) - MoveWindow (hMainWnd, rc2.left + 1, rc2.top, - rc2.right - rc2.left, rc2.bottom - rc2.top, TRUE); - } - } else if (current_pixbytes == 3) { - if (amigawin_rect.left >= 0) { - if (amigawin_rect.left & 3) { - GetWindowRect (hMainWnd, &rc2); - if (1 /*!mon || rc2.left + 4 < GetSystemMetrics (SM_CXSCREEN)*/) - MoveWindow (hMainWnd, rc2.left - amigawin_rect.left % 4, rc2.top, - rc2.right - rc2.left, rc2.bottom - rc2.top, TRUE); - } + if (amigawin_rect.left & 3) { + RECT rc2; + GetWindowRect (hMainWnd, &rc2); + if (1 /*!mon || rc2.left + 4 < GetSystemMetrics (SM_CXSCREEN) */ ) { + MoveWindow (hMainWnd, rc2.left + 4 - amigawin_rect.left % 4, rc2.top, + rc2.right - rc2.left, rc2.bottom - rc2.top, TRUE); } } + setmouseactive (0); return 0; } + break; case WM_PAINT: @@ -919,13 +953,12 @@ long FAR PASCAL MainWindowProc (HWND hWn toggle_fullscreen (); return 0; } + break; } return DefWindowProc (hWnd, message, wParam, lParam); } -static int HasConsole; -static HANDLE stdouthandle; static HANDLE debugfile; /* Console Win32 helper routines */ @@ -952,54 +985,6 @@ void remove_brkhandler (void) SetConsoleCtrlHandler ((PHANDLER_ROUTINE) ctrlchandler, FALSE); } -int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, - int nCmdShow) -{ - char *posn; - int i; - - hInst = hInstance; - - debugfile = CreateFile ("outfile", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, - 0, NULL); - - for (i = 0; i < NUM_DRIVES; i++) { - drives[i].path[0] = 0; - drives[i].name[0] = 0; - drives[i].rw = TRUE; - } - - /* Get our executable's root-path */ - start_path = xmalloc(MAX_PATH); - GetModuleFileName (hInst, start_path, MAX_PATH); - if (posn = strrchr (start_path, '\\')) - *posn = 0; - - - HasConsole = 0;/*AllocConsole ();*/ - if (HasConsole) - stdouthandle = GetStdHandle (STD_OUTPUT_HANDLE); - - write_log ("UAE " UAEWINVERSION " Win32/DirectX, release " UAEWINRELEASE "\n"); - strcpy (VersionStr, PROGNAME); - write_log ("\n(c) 1995-1997 Bernd Schmidt - Core UAE concept and implementation." - "\n(c) 1996-1997 Mathias Ortmann - Win32 port and enhancements." - "\n(c) 1996-1997 Brian King - Picasso96 and AHI support, GUI.\n" - "\nPress F12 to show the Settings Dialog (GUI), Alt-F4 to quit.\n" - "\nhttp://www.informatik.tu-muenchen.de/~ortmann/uae/\n\n"); - - currprefs.copper_pos = -1; - /*initgfxspecs();*/ - if (initlibs ()) - real_main (__argc, __argv); - cleanuplibs(); - - if (HasConsole) - FreeConsole (); - - return FALSE; -} - static int register_classes (void) { WNDCLASS wc; @@ -1012,7 +997,7 @@ static int register_classes (void) wc.hIcon = LoadIcon (GetModuleHandle (NULL), IDI_APPICON); wc.hCursor = LoadCursor (NULL, IDC_ARROW); wc.hbrBackground = GetStockObject (BLACK_BRUSH); - wc.lpszMenuName = NULL; + wc.lpszMenuName = 0; wc.lpszClassName = "AmigaPowah"; if (!RegisterClass (&wc)) return 0; @@ -1025,70 +1010,162 @@ static int register_classes (void) wc.hIcon = LoadIcon (GetModuleHandle (NULL), IDI_APPICON); wc.hCursor = LoadCursor (NULL, IDC_ARROW); wc.hbrBackground = GetStockObject (BLACK_BRUSH); - wc.lpszMenuName = NULL; + wc.lpszMenuName = 0; wc.lpszClassName = "PCsuxRox"; if (!RegisterClass (&wc)) return 0; return 1; } -int graphics_setup (void) +struct win32_displaymode *win32_displaymode_list; + +static HRESULT CALLBACK modesCallback (LPDDSURFACEDESC modeDesc, LPVOID context) { - DWORD ddrval; + struct win32_displaymode **dmpp; + RGBFTYPE colortype; - if (!register_classes ()) - return 0; + colortype = surface_pixelformat (modeDesc); + if (colortype == RGBFB_NONE) + return DDENUMRET_OK; + + dmpp = &win32_displaymode_list; + while (*dmpp != 0) { + if ((*dmpp)->width == modeDesc->dwWidth + && (*dmpp)->height == modeDesc->dwHeight + && (*dmpp)->refreshrate == modeDesc->dwRefreshRate) + break; + dmpp = &(*dmpp)->next; + } - uae_sem_init (&picasso_switch_sem, 0, 0); - return 1; + if (*dmpp == 0) { + *dmpp = (struct win32_displaymode *)malloc (sizeof **dmpp); + (*dmpp)->next = 0; + (*dmpp)->width = modeDesc->dwWidth; + (*dmpp)->height = modeDesc->dwHeight; + (*dmpp)->refreshrate = modeDesc->dwRefreshRate; + (*dmpp)->colormodes = 0; + } + (*dmpp)->colormodes |= 1 << colortype; + return DDENUMRET_OK; } -#define NORMAL_WINDOW_STYLE (WS_VISIBLE | WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX) +static int our_possible_depths[] = { 8, 15, 16, 24, 32 }; -static int create_windows (void) +static void figure_pixel_formats (void) { - POINT pt; + HWND tmpw; + HRESULT ddrval; + struct win32_displaymode *dm; + + tmpw = CreateWindowEx (WS_EX_TOPMOST, + "AmigaPowah", PROGNAME, + WS_VISIBLE | WS_POPUP, + CW_USEDEFAULT, CW_USEDEFAULT, + GetSystemMetrics (SM_CXSCREEN), + GetSystemMetrics (SM_CYSCREEN), + 0, NULL, 0, NULL); + + ddrval = IDirectDraw_SetCooperativeLevel (lpDD, tmpw, + DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); + if (ddrval != DD_OK) { + printf ("error %s\n", getddrname (ddrval)); + goto out; + } + + for (dm = win32_displaymode_list; dm != 0; dm = dm->next) { + int i; + printf ("Attempting %dx%d: ", dm->width, dm->height); + dm->colormodes = 0; + + for (i = 0; i < 5; i++) { + RGBFTYPE colortype; + ddrval = IDirectDraw_SetDisplayMode (lpDD, dm->width, dm->height, our_possible_depths[i]); + if (ddrval != DD_OK) + continue; + + current_surface.dwSize = sizeof current_surface; + ddrval = IDirectDraw_GetDisplayMode (lpDD, ¤t_surface); + if (ddrval != DD_OK) + continue; + colortype = surface_pixelformat (¤t_surface); + if (colortype != RGBFB_NONE) { + printf ("%d ", our_possible_depths[i]); + dm->colormodes |= 1 << colortype; + } + } + printf ("(%08lx)\n", dm->colormodes); + } + out: + DestroyWindow (tmpw); +} + +#define NORMAL_WINDOW_STYLE (WS_VISIBLE | WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX) + +#define NUM_PARTS 6 +#define LED_WIDTH 50 +#define DRIVE_WIDTH 16 + +static int create_windows (void) +{ if (!fullscreen) { RECT rc; + HLOCAL hloc; + LPINT lpParts; rc.left = 0; rc.top = 0; rc.right = current_width; - rc.bottom = current_height; + rc.bottom = current_height + GetSystemMetrics (SM_CYMENU); rc.right += 4; rc.bottom += 4; AdjustWindowRect (&rc, NORMAL_WINDOW_STYLE, FALSE); + printf ("(%d %d) (%d %d)\n", rc.left, rc.top, rc.right, rc.bottom); - hMainWnd = CreateWindowEx (WS_EX_ACCEPTFILES, - "PCsuxRox", - TITLETEXT, - NORMAL_WINDOW_STYLE, - CW_USEDEFAULT, CW_USEDEFAULT, + hMainWnd = CreateWindowEx (WS_EX_ACCEPTFILES, "PCsuxRox", TITLETEXT, + NORMAL_WINDOW_STYLE, CW_USEDEFAULT, CW_USEDEFAULT, rc.right - rc.left, rc.bottom - rc.top, - NULL, - NULL, - 0, - NULL); + NULL, NULL, 0, NULL); if (! hMainWnd) return 0; + hStatusWnd = CreateStatusWindow (WS_CHILD | WS_VISIBLE, "", hMainWnd, 1); + if (hStatusWnd) { + GetClientRect (hMainWnd, &rc); + /* Allocate an array for holding the right edge coordinates. */ + hloc = LocalAlloc (LHND, sizeof (int) * NUM_PARTS); + if (hloc) { + lpParts = LocalLock (hloc); + + /* Calculate the right edge coordinate for each part, and copy the coords + * to the array. */ + lpParts[0] = rc.right - (DRIVE_WIDTH * 4) - LED_WIDTH - 2; + lpParts[1] = lpParts[0] + LED_WIDTH; + lpParts[2] = lpParts[1] + DRIVE_WIDTH; + lpParts[3] = lpParts[2] + DRIVE_WIDTH; + lpParts[4] = lpParts[3] + DRIVE_WIDTH; + lpParts[5] = lpParts[4] + DRIVE_WIDTH; + + /* Create the six parts */ + SendMessage (hStatusWnd, SB_SETPARTS, (WPARAM) NUM_PARTS, (LPARAM) lpParts); + + LocalUnlock (hloc); + LocalFree (hloc); + } + } } else hMainWnd = NULL; hAmigaWnd = CreateWindowEx (fullscreen ? WS_EX_TOPMOST : WS_EX_ACCEPTFILES, - "AmigaPowah", - PROGNAME, + "AmigaPowah", PROGNAME, hMainWnd ? WS_VISIBLE | WS_CHILD : WS_VISIBLE | WS_POPUP, hMainWnd ? 2 : CW_USEDEFAULT, hMainWnd ? 2 : CW_USEDEFAULT, fullscreen ? GetSystemMetrics (SM_CXSCREEN) : current_width, fullscreen ? GetSystemMetrics (SM_CYSCREEN) : current_height, - hMainWnd, - NULL, - 0, - NULL); + hMainWnd, NULL, 0, NULL); - if (!hAmigaWnd) { + + if (! hAmigaWnd) { if (hMainWnd) DestroyWindow (hMainWnd); return 0; @@ -1101,55 +1178,85 @@ static int create_windows (void) return 1; } - -void doPreInit( void ) -{ - void *blah; - DWORD ddrval; -#ifdef __GNUC__ - ddrval = (*pDirectDrawCreate)(NULL,&lpDD,NULL); -#else - ddrval = DirectDrawCreate( NULL, &lpDD, NULL ); -#endif - if (ddrval == DD_OK) - { - //IDirectDraw2_QueryInterface( lpDD, &IID_IDirectDraw2, &blah ); - - mode_count = DX_FillResolutions( &picasso96_pixel_format ); - - // If we've got no command-line arguments, then we use the integrated-GUI - if( ( __argc == 1 ) && - ( GetSettings() == FALSE ) ) - { - MyOutputDebugString("GetSettings() trying to quit...\n"); - shutdownmain(); - } - } -} -BOOL doInit (void) +/* DirectX will fail with "Mode not supported" if we try to switch to a full + * screen mode that doesn't match one of the dimensions we got during enumeration. + * So try to find a best match for the given resolution in our list. */ +static int adjust_screenmode (int *pwidth, int *pheight, int *ppixbits) +{ + struct win32_displaymode *best; + uae_u32 selected_mask = (*ppixbits == 8 ? RGBMASK_8BIT + : *ppixbits == 15 ? RGBMASK_15BIT + : *ppixbits == 16 ? RGBMASK_16BIT + : *ppixbits == 24 ? RGBMASK_24BIT + : RGBMASK_32BIT); + int pass; + + for (pass = 0; pass < 2; pass++) { + struct win32_displaymode *dm; + uae_u32 mask = (pass == 0 + ? selected_mask + : RGBMASK_8BIT | RGBMASK_16BIT | RGBMASK_24BIT | RGBMASK_32BIT); + + best = win32_displaymode_list; + dm = best->next; + + while (dm != 0) { + if ((dm->colormodes & mask) != 0) { + if (dm->width <= best->width && dm->height <= best->height + && dm->width >= *pwidth && dm->height >= *pheight) + best = dm; + if (dm->width >= best->width && dm->height >= best->height + && dm->width <= *pwidth && dm->height <= *pheight) + best = dm; + } + dm = dm->next; + } + if (best->width == *pwidth && best->height == *pheight) + break; + } + *pwidth = best->width; + *pheight = best->height; + if ((best->colormodes & selected_mask) != 0) + return 1; + if (best->colormodes & RGBMASK_8BIT) + *ppixbits = 8; + else if (best->colormodes & RGBMASK_16BIT) + *ppixbits = 16; + else if (best->colormodes & RGBMASK_32BIT) + *ppixbits = 32; + else if (best->colormodes & RGBMASK_24BIT) + *ppixbits = 24; + + return 1; +} + +static BOOL doInit (void) { if (! create_windows ()) - return 0; -#ifdef PICASSO96 + goto oops; + if (screen_is_picasso) { - if (!set_ddraw (current_width, current_height, fullscreen, &picasso_vidinfo.depth, - (LPPALETTEENTRY)&picasso96_state.CLUT)) + if (! set_ddraw (current_width, current_height, fullscreen, current_depth, + (LPPALETTEENTRY) & picasso96_state.CLUT)) goto oops; picasso_vidinfo.rowbytes = ddsd.lPitch; - } else -#endif - { - gfxvidinfo.pixbytes = 2; - if (!set_ddraw (current_width, current_height, fullscreen, &gfxvidinfo.pixbytes, colors256)) + picasso_vidinfo.pixbytes = current_pixbytes; + picasso_vidinfo.rgbformat = surface_pixelformat (¤t_surface); + } else { + if (fullscreen) + if (! adjust_screenmode (¤t_width, ¤t_height, ¤t_depth)) + abort (); + + if (! set_ddraw (current_width, current_height, fullscreen, current_depth, colors256)) goto oops; gfxvidinfo.bufmem = 0; gfxvidinfo.linemem = 0; gfxvidinfo.maxblocklines = 0; + gfxvidinfo.pixbytes = current_pixbytes; gfxvidinfo.width = current_width; gfxvidinfo.height = current_height; gfxvidinfo.rowbytes = ddsd.lPitch; - gfxvidinfo.can_double = 1; } if (fullscreen) { @@ -1157,41 +1264,27 @@ BOOL doInit (void) gfxvidinfo.linemem = 0; mousecx = 160, mousecy = 100, mousedx = 160, mousedy = 100, mousecl = MAKELONG (160, 100); } - if (! do_surfacelock ()) goto oops; unlockscr (); - if ((ddsd.ddpfPixelFormat.dwFlags & (DDPF_RGB | DDPF_PALETTEINDEXED8 | DDPF_RGBTOYUV)) != 0) - { - MyOutputDebugString ("%s mode (bits: %d, pixbytes: %d)\n", fullscreen ? "Full screen" : "Window", - ddsd.ddpfPixelFormat.dwRGBBitCount, current_pixbytes); -#ifdef PICASSO96 - if( ddsd.ddpfPixelFormat.dwRBitMask == 0x0000F800 ) - picasso96_pixel_format |= RGBFF_R5G6B5PC; - else if( ddsd.ddpfPixelFormat.dwRBitMask == 0x00007C00 ) - picasso96_pixel_format |= RGBFF_R5G5B5PC; - else if( ddsd.ddpfPixelFormat.dwBBitMask == 0x0000F800 ) - picasso96_pixel_format |= RGBFF_B5G6R5PC; - else - picasso96_pixel_format |= RGBFF_B5G5R5PC; -#endif + if ((ddsd.ddpfPixelFormat.dwFlags & (DDPF_RGB | DDPF_PALETTEINDEXED8 | DDPF_RGBTOYUV)) != 0) { + write_log ("%s mode (bits: %d, pixbytes: %d)\n", fullscreen ? "Full screen" : "Window", + ddsd.ddpfPixelFormat.dwRGBBitCount, current_pixbytes); } else { - MyOutputDebugString ("Error: Unsupported pixel format - use a different screen mode\n"); + write_log ("Error: Unsupported pixel format - use a different screen mode\n"); goto oops; } -#ifdef PICASSO96 - if (screen_is_picasso) - DX_SetPalette (0, 256); - else -#endif - init_colors (); - if (!fullscreen) + init_colors (); + + if (! fullscreen) MainWindowProc (0, WM_WINDOWPOSCHANGED, 0, 0); + dsound_newwindow (hAmigaWnd); return 1; -oops: + oops: + release_ddraw (); if (hMainWnd) DestroyWindow (hMainWnd); if (hAmigaWnd) @@ -1201,11 +1294,8 @@ oops: struct myRGNDATA { RGNDATAHEADER rdh; - RECT rects[640]; /* fixed buffers suck, but this is _very_ unlikely to overflow */ -} ClipList = { { - sizeof (ClipList), RDH_RECTANGLES, 0, 640 * sizeof (RECT) -} }; - + RECT rects[640]; /* fixed buffers suck, but this is _very_ unlikely to overflow */ +} ClipList = { { sizeof (ClipList), RDH_RECTANGLES, 0, 640 * sizeof (RECT) } }; /* this is the way the display line is put to screen * if the display is not 16 bits deep or the window is not fully visible */ @@ -1215,67 +1305,63 @@ static void clipped_linetoscr (char *dst int i; switch (current_pixbytes) { - case 1: + case 1: for (i = ClipList.rdh.nCount; i--; lpRect++) { - if (y >= lpRect->top && y < lpRect->bottom) { + if (y >= lpRect->top && y < lpRect->bottom) memcpy (dst + lpRect->left, src + lpRect->left, lpRect->right); - } } break; - case 2: + case 2: for (i = ClipList.rdh.nCount; i--; lpRect++) { - if (y >= lpRect->top && y < lpRect->bottom) { - memcpy (dst + lpRect->left*2, src + lpRect->left*2, lpRect->right*2); - } + if (y >= lpRect->top && y < lpRect->bottom) + memcpy (dst + lpRect->left * 2, src + lpRect->left * 2, lpRect->right * 2); } break; - case 3: + case 3: for (i = ClipList.rdh.nCount; i--; lpRect++) { - if (y >= lpRect->top && y < lpRect->bottom) { - memcpy (dst + lpRect->left*3, src + lpRect->left*3, lpRect->right*3); - } + if (y >= lpRect->top && y < lpRect->bottom) + memcpy (dst + lpRect->left * 3, src + lpRect->left * 3, lpRect->right * 3); } break; case 4: for (i = ClipList.rdh.nCount; i--; lpRect++) { - if (y >= lpRect->top && y < lpRect->bottom) { - memcpy (dst + lpRect->left*4, src + lpRect->left*4, lpRect->right*4); - } + if (y >= lpRect->top && y < lpRect->bottom) + memcpy (dst + lpRect->left * 4, src + lpRect->left * 4, lpRect->right * 4); } break; } } -void flush_line(int lineno) +void flush_line (int lineno) { if (scrindirect) - clipped_linetoscr(gfxvidinfo.bufmem + lineno * gfxvidinfo.rowbytes, - scrlinebuf, lineno); + clipped_linetoscr (gfxvidinfo.bufmem + lineno * gfxvidinfo.rowbytes, + scrlinebuf, lineno); } -void flush_block(int a, int b) +void flush_block (int a, int b) { } -void flush_screen(int a, int b) +void flush_screen (int a, int b) { } -char *lockscr (void) +static uae_u8 *dolock (void) { - char *surface, *oldsurface; + char *surface = NULL, *oldsurface; DWORD tmp; LPRECT lpRect; - if (!do_surfacelock ()) - return NULL; + if (! do_surfacelock ()) + return 0; surface = ddsd.lpSurface; oldsurface = gfxvidinfo.bufmem; - if (!fullscreen) { + if (! fullscreen) { surface += amigawin_rect.top * ddsd.lPitch + current_pixbytes * amigawin_rect.left; } gfxvidinfo.bufmem = surface; @@ -1283,7 +1369,6 @@ char *lockscr (void) write_log ("Need to init_row_map\n"); init_row_map (); } - scrindirect = 0; if (fullscreen) { @@ -1291,7 +1376,6 @@ char *lockscr (void) clear_inhibit_frame (IHF_WINDOWHIDDEN); return surface; } - tmp = sizeof (ClipList.rects); /* This is the VERY instruction that drags other threads (input/file system) down when in windowed @@ -1300,12 +1384,10 @@ char *lockscr (void) lpRect = ClipList.rects; if (!ClipList.rdh.nCount) { - write_log("ClipList empty\n"); set_inhibit_frame (IHF_WINDOWHIDDEN); unlockscr (); return 0; } - if (ClipList.rdh.nCount != 1 || lpRect->right - lpRect->left != current_width || lpRect->bottom - lpRect->top != current_height) @@ -1321,146 +1403,118 @@ char *lockscr (void) } } } - set_linemem (); clear_inhibit_frame (IHF_WINDOWHIDDEN); return surface; } -int graphics_init (void) +int lockscr (void) { - static int first_time = 1; - if (first_time) - figure_processor_speed (); - first_time = 0; -#ifdef PICASSO96 - if (screen_is_picasso) { - fullscreen = picasso_fullscreen; - current_width = picasso_vidinfo.width; - current_height = picasso_vidinfo.height; - } else -#endif - { - fullscreen = amiga_fullscreen; - current_width = currprefs.gfx_width; - current_height = currprefs.gfx_height; - - if (!fullscreen) { - if (current_height > 290 << currprefs.gfx_linedbl) - current_height = 290 << currprefs.gfx_linedbl; - if (current_width > 800 >> currprefs.gfx_lores) - current_width = 800 >> currprefs.gfx_lores; - } - current_width = (current_width + 7) & ~7; - } - - if (!doInit ()) - return 0; - - *xcolors = 0; - - return 1; + return dolock () != 0; } -void graphics_leave (void) +uae_u8 *gfx_lock_picasso (void) { - dumpcustom (); + return dolock (); } -void shutdownmain (void) -{ - changemode = 3; - PostMessage (hAmigaWnd, WM_QUIT, 0, 0); -} - -void workthread(void) +void gfx_unlock_picasso (void) { - if (use_debugger && debuggable ()) - activate_debugger (); - - do_start_program(); - shutdownmain(); + unlockscr (); } -void start_program (void) +static int open_windows (void) { - DWORD id; - MSG msg; - - SetPriorityClass (GetCurrentProcess (), process_desired_pri); + char *fs_warning = 0; + RGBFTYPE colortype; - hEmuThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) workthread, 0, CREATE_SUSPENDED, &id); - SetThreadPriority (hEmuThread, THREAD_PRIORITY_BELOW_NORMAL); - ResumeThread (hEmuThread); - - for (;;) { - int cm; - while (GetMessage (&msg, NULL, 0, 0)) { - TranslateMessage (&msg); - DispatchMessage (&msg); - } - cm = changemode; - if (cm == 3) - break; + current_pixbytes = 0; - changemode = 0; - current_pixbytes = 0; - if (!graphics_init ()) - break; + in_sizemove = 0; + fixup_prefs_dimensions (&currprefs); - if (cm == 2) { - uae_sem_post (&picasso_switch_sem); - } - clear_inhibit_frame (5); - notice_screen_contents_lost (); - notice_new_xcolors (); - - notice_new_xcolors (); + if (! start_ddraw ()) + return 0; - /*ResumeThread (hEmuThread);*/ + colortype = surface_pixelformat (¤t_surface); + printf ("Ct: %08lx, picasso_vidinfo.selected_rgbformat %08lx\n", (unsigned long)colortype, + picasso_vidinfo.selected_rgbformat); - if (currprefs.produce_sound > 1) - startsound (); + if (screen_is_picasso) { + fullscreen = currprefs.gfx_pfullscreen; + current_width = picasso_vidinfo.width; + current_height = picasso_vidinfo.height; + current_depth = rgbformat_bits (picasso_vidinfo.selected_rgbformat); + } else { + fullscreen = currprefs.gfx_afullscreen; + current_width = currprefs.gfx_width; + current_height = currprefs.gfx_height; + current_depth = (currprefs.color_mode == 0 ? 8 + : currprefs.color_mode == 1 ? 15 + : currprefs.color_mode == 2 ? 16 + : currprefs.color_mode == 3 ? 8 + : currprefs.color_mode == 4 ? 8 : 32); + } + + needs_fullscreen = 0; + if (colortype == RGBFB_NONE) { + needs_fullscreen = 1; + fs_warning = "the desktop is running in an unknown color mode."; + } else if (colortype == RGBFB_CLUT) { + needs_fullscreen = 1; + fs_warning = "the desktop is running in 8 bit color depth, which UAE can't use in windowed mode."; + } else if (current_width > current_surface.dwWidth || current_height > current_surface.dwHeight) { + needs_fullscreen = 1; + fs_warning = "the desktop is too small for the specified window size."; + } else if (screen_is_picasso + && picasso_vidinfo.selected_rgbformat != RGBFB_CHUNKY + && picasso_vidinfo.selected_rgbformat != colortype) + { + needs_fullscreen = 1; + fs_warning = "you selected a Picasso display with a color depth different from that of the desktop."; } -} - -void handle_events (void) -{ -} - -#ifdef CONFIG_FOR_SMP -int uae_sem_initcs (LPCRITICAL_SECTION * cs) -{ - *cs = (LPCRITICAL_SECTION) GlobalAlloc (GPTR, sizeof csDraw); - InitializeCriticalSection (*cs); -} -void uae_sem_enter (LPCRITICAL_SECTION cs) -{ - EnterCriticalSection (cs); -} + if (needs_fullscreen && ! fullscreen) { + char tmpstr[300]; + fullscreen = needs_fullscreen; + /* Temporarily drop the DirectDraw stuff. This is necessary, otherwise + * WinNT will just return 1 for the message box without ever displaying + * it on the screen. */ + release_ddraw (); + sprintf (tmpstr, "The selected screen mode can't be displayed in a window, because %s\n" + "Switching to full-screen display.", fs_warning); + MessageBox (0, tmpstr, "UAE", MB_ICONEXCLAMATION | MB_OK); + start_ddraw (); + } + + if (! fullscreen) + current_depth = rgbformat_bits (colortype); + + if (! doInit ()) + return 0; -void uae_sem_leave (LPCRITICAL_SECTION cs) -{ - LeaveCriticalSection (cs); + return 1; } -void uae_sleep (int ms) +void handle_events (void) { - Sleep (ms); -} - -#endif + MSG msg; -/* this is the semaphore for protecting the actual drawing against intermittent window movements */ -void begindrawing (void) -{ - EnterCriticalSection (&csDraw); + while (PeekMessage (&msg, 0, 0, 0, PM_REMOVE)) { + TranslateMessage (&msg); + DispatchMessage (&msg); + } } -void enddrawing (void) +int check_prefs_changed_gfx (void) { - LeaveCriticalSection (&csDraw); + if (display_change_requested) { + display_change_requested = 0; + close_windows (); + open_windows (); + return 1; + } + return 0; } /* this truly sucks, I'll include a native gunzip() routine soon */ @@ -1481,14 +1535,14 @@ int gunzip_hack (const char *src, const WaitForSingleObject (pi.hProcess, INFINITE); return -1; } else { - MyOutputDebugString ("Error: You need gzip.exe (32 bit) to use .adz/.roz files!\n"); + write_log ("Error: You need gzip.exe (32 bit) to use .adz/.roz files!\n"); } } return 0; } -/* file name requester. hBackBM will hopefully be dropped in the near future. */ -static OPENFILENAME ofn = { +static OPENFILENAME ofn = +{ sizeof (OPENFILENAME), NULL, NULL, "Amiga Disk Files\000*.adf;*.adz\000", NULL, 0, 0, 0, 256, NULL, 0, "", @@ -1504,12 +1558,7 @@ static OPENFILENAME ofn = { int requestfname (char *title, char *name) { - HDC hDC; char *result; - RECT rc; -#ifdef PICASSO96 - uae_u8 old_switch_state = picasso96_state.SwitchState; -#endif ofn.hwndOwner = hAmigaWnd; ofn.lpstrTitle = title; @@ -1518,44 +1567,18 @@ int requestfname (char *title, char *nam if (pGetOpenFileNameA == 0) return 0; - if (IDirectDrawSurface_GetDC (lpDDS, &hDC) == DD_OK) { - if ((hBackBM = CreateCompatibleBitmap (hDC, currprefs.gfx_width, currprefs.gfx_height)) - && (hBackDC = CreateCompatibleDC (hDC))) { - SelectObject (hBackDC, hBackBM); - - if (fullscreen) - BitBlt (hBackDC, 0, 0, currprefs.gfx_width, currprefs.gfx_height, hDC, 0, 0, SRCCOPY); - else { - BitBlt (hBackDC, 0, 0, currprefs.gfx_width, currprefs.gfx_height, hDC, - amigawin_rect.left, amigawin_rect.top, SRCCOPY); - } - } - IDirectDrawSurface_ReleaseDC (lpDDS, hDC); - } if (!fullscreen) setmouseactive (0); if (title) - result = (char *)((*pGetOpenFileNameA) (&ofn)); + result = (char *) ((*pGetOpenFileNameA) (&ofn)); else { - GetSettings (); + GetSettings (0); } if (!fullscreen || !mouseactive) SetCursor (NULL); - if (hBackBM) { - if (hBackDC) { - if (fullscreen && IDirectDrawSurface_GetDC (lpDDS, &hDC) == DD_OK) { - BitBlt (hDC, 0, 0, currprefs.gfx_width, currprefs.gfx_height, hBackDC, 0, 0, SRCCOPY); - IDirectDrawSurface_ReleaseDC (lpDDS, hDC); - } - DeleteObject (hBackDC); - hBackDC = NULL; - } - DeleteObject (hBackBM); - hBackBM = NULL; - } notice_screen_contents_lost (); if (result) @@ -1563,97 +1586,43 @@ int requestfname (char *title, char *nam return 0; } - -int DisplayGUI( void ) -{ - HBITMAP hBackBM2 = NULL; -#ifdef PICASSO96 - BITMAPINFO bminfo = { sizeof( BITMAPINFOHEADER ), current_width, -current_height, 1, 8, BI_RGB, 0, 0, 0, 0, 0, &picasso96_state.CLUT }; -#endif - HDC hDC; - void *blah; - RECT rc; - uae_u8 p96_8bit = 0; - - if (pGetOpenFileNameA) - { - if (IDirectDrawSurface_GetDC(lpDDS,&hDC) == DD_OK) - { -#ifdef PICASSO96 - if( picasso96_state.SwitchState && ( picasso96_state.BytesPerPixel == 1 ) ) - { - p96_8bit = 1; - hBackBM2 = CreateDIBSection( hDC, &bminfo, DIB_PAL_COLORS, &blah, NULL, 0 ); - } - else -#endif - hBackBM = CreateCompatibleBitmap( hDC, current_width, current_height ); - - if( (hBackBM2 || hBackBM ) && ( hBackDC = CreateCompatibleDC( hDC ) ) ) - { -#ifdef PICASSO96 - if( hBackBM2 ) - { - SelectObject( hBackDC, hBackBM2 ); - hBackBM = CreateCompatibleBitmap( hDC, current_width, current_height ); - } - else -#endif - SelectObject( hBackDC, hBackBM ); - - if( fullscreen ) - BitBlt( hBackDC, 0, 0, current_width, current_height, hDC, 0, 0, SRCCOPY ); - else - { - GetWindowRect(hAmigaWnd,&rc); - BitBlt(hBackDC,0,0,current_width,current_height,hDC,rc.left,rc.top,SRCCOPY); - } - - IDirectDrawSurface2_SetPalette( lpDDS, NULL ); - if( hBackBM2 ) - BitBlt( hDC, 0, 0, current_width, current_height, hBackDC, 0, 0, SRCCOPY ); - } - IDirectDrawSurface_ReleaseDC( lpDDS, hDC ); - } - - if (!fullscreen) setmouseactive(FALSE); - - GetSettings(); - if( lpDDP ) - IDirectDrawSurface2_SetPalette( lpDDS, lpDDP ); - - if (!fullscreen || !mouseactive) SetCursor(NULL); - - if( hBackBM || hBackBM2 ) - { - if( hBackDC ) - { -#ifdef PICASSO96 - if( p96_8bit ) - { - picasso96_state.RefreshPending = 1; - } - else -#endif - if( fullscreen && IDirectDrawSurface_GetDC( lpDDS, &hDC ) == DD_OK ) - { - BitBlt( hDC, 0, 0, current_width, current_height, hBackDC, 0, 0, SRCCOPY ); - IDirectDrawSurface_ReleaseDC( lpDDS, hDC ); - } - DeleteObject( hBackDC ); - hBackDC = NULL; - } - if( hBackBM2 ) - DeleteObject( hBackBM2 ); - if( hBackBM ) - { - DeleteObject( hBackBM ); - hBackBM = NULL; - } - } - } - return 0; -} + +int DisplayGUI (void) +{ +#ifdef PICASSO96 + BITMAPINFO bminfo = + { + { + sizeof (BITMAPINFOHEADER), + 0, 0, + 1, 8, BI_RGB, 0, 0, 0, 0, 0, + }, + 0 + }; +#endif + + bminfo.bmiHeader.biWidth = current_width; + bminfo.bmiHeader.biHeight = -current_height; +#if 0 + /* ??????? */ + bminfo.bmiColors[0] = &picasso96_state.CLUT; +#endif + if (pGetOpenFileNameA) { + if (lpDDP) + IDirectDrawSurface_SetPalette (lpDDS, NULL); + + if (!fullscreen) + setmouseactive (FALSE); + GetSettings (0); + + if (lpDDP) + IDirectDrawSurface2_SetPalette (lpDDS, lpDDP); + + if (!fullscreen || !mouseactive) + SetCursor (NULL); + } + return 0; +} #ifdef __GNUC__ #undef WINAPI @@ -1662,21 +1631,31 @@ int DisplayGUI( void ) static HINSTANCE hDDraw = NULL, hComDlg32 = NULL, hRichEdit = NULL; -int cleanuplibs(void) +static int cleanuplibs (void) { if (hRichEdit) - FreeLibrary(hRichEdit); + FreeLibrary (hRichEdit); if (hDDraw) - FreeLibrary(hDDraw); + FreeLibrary (hDDraw); if (hComDlg32) - FreeLibrary(hComDlg32); + FreeLibrary (hComDlg32); return 1; } /* try to load COMDLG32 and DDRAW, initialize csDraw, try to obtain the system clock frequency * from the registry, try to find out if we are running on a Pentium */ -int initlibs (void) +static int initlibs (void) { + OSVERSIONINFO osinfo; + /* Figure out which Win32 OS we're running under */ + osinfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); + if (GetVersionEx (&osinfo)) { + if (osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT) + running_winnt = TRUE; + else + running_winnt = FALSE; + } + figure_processor_speed (); /* Make sure we do an InitCommonControls() to get some advanced controls */ InitCommonControls (); @@ -1684,48 +1663,38 @@ int initlibs (void) pGetOpenFileNameA = (BOOL (WINAPI *) (LPOPENFILENAME)) GetProcAddress (hComDlg32, "GetOpenFileNameA"); } else /* System administrator? ROFL! -- Bernd */ - MyOutputDebugString ("COMDLG32.DLL not available. Please contact your system administrator.\n"); + write_log ("COMDLG32.DLL not available. Please contact your system administrator.\n"); /* LoadLibrary the richedit control stuff */ if ((hRichEdit = LoadLibrary ("RICHED32.DLL")) == NULL) { - MyOutputDebugString ("RICHED32.DLL not available. Please contact your system administrator.\n"); + write_log ("RICHED32.DLL not available. Please contact your system administrator.\n"); } - if (hDDraw = LoadLibrary ("DDRAW.DLL")) { -#ifdef __GNUC__ - pDirectDrawCreate = (HRESULT (WINAPI *) (GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *)) GetProcAddress (hDDraw, "DirectDrawCreate"); -#endif - InitializeCriticalSection (&csDraw); - - process_desired_pri = IDLE_PRIORITY_CLASS; + hDDraw = LoadLibrary ("DDRAW.DLL"); + if (hDDraw == 0) { + write_log ("You have to install DirectX on your system before you can use UAE.\n" + "Refer to the documentation for further details.\n"); + return 0; + } + pDirectDrawCreate = (HRESULT (WINAPI *) (GUID FAR *, LPDIRECTDRAW FAR *, IUnknown FAR *)) GetProcAddress (hDDraw, "DirectDrawCreate"); - return 1; - } else - MyOutputDebugString ("You have to install DirectX on your system before you can use UAE.\nRefer to the documentation for further details.\n"); + process_desired_pri = IDLE_PRIORITY_CLASS; - return 0; + return 1; } -void MyOutputDebugString (char *format,...) +void write_log (const char *format,...) { + DWORD numwritten; char buffer[512]; va_list parms; va_start (parms, format); vsprintf (buffer, format, parms); va_end (parms); - write_log (buffer); -} -void write_log (const char *txt) -{ - DWORD numwritten; -#ifdef _DEBUG - OutputDebugString( txt ); -#endif - fprintf (stderr, "%s", txt); - /* if (HasConsole) - WriteConsole (stdouthandle, txt, strlen (txt), &numwritten, NULL);*/ - WriteFile (debugfile, txt, strlen (txt), &numwritten, NULL); + fprintf (stderr, "%s", buffer); + + WriteFile (debugfile, buffer, strlen (buffer), &numwritten, NULL); } int debuggable (void) @@ -1738,107 +1707,89 @@ int needmousehack (void) return 1; } -void LED (int on) +void LED (int a) { } - -static uae_u16 *ppicasso_format; -static int picasso_modecount; - -static HRESULT CALLBACK modesCallback (LPDDSURFACEDESC modeDesc, LPVOID context) +int DX_FillResolutions (uae_u16 * ppixel_format) { - int bpp; + struct win32_displaymode *dm; + int count = 0; - if (picasso_modecount >= MAX_PICASSO_MODES) - return DDENUMRET_CANCEL; - - if (modeDesc->dwFlags & (DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_REFRESHRATE)) { - bpp = modeDesc->ddpfPixelFormat.dwRGBBitCount; -#ifdef PICASSO96 - switch (bpp) { - case 8: - *ppicasso_format |= RGBFF_CHUNKY; + *ppixel_format = 0; + for (dm = win32_displaymode_list; dm != 0; dm = dm->next) { + *ppixel_format |= dm->colormodes; + if (dm->colormodes & RGBMASK_8BIT) { + DisplayModes[count].res.width = dm->width; + DisplayModes[count].res.height = dm->height; + DisplayModes[count].refresh = 75; + DisplayModes[count].depth = 1; + count++; + } + if (count >= MAX_PICASSO_MODES) break; - case 16: - /* figure out which actual format it is using based on the RGB masks */ - - /* Bernd - this doesn't work for some reason. Instead, I figure out the modes in doInit(), - * where I have the surface's description and pixel formats. Damned DirectDraw stuff! - */ + if (dm->colormodes & (RGBMASK_16BIT | RGBMASK_15BIT)) { + DisplayModes[count].res.width = dm->width; + DisplayModes[count].res.height = dm->height; + DisplayModes[count].refresh = 75; + DisplayModes[count].depth = 2; + count++; + } + if (count >= MAX_PICASSO_MODES) break; - case 24: - /* figure out which actual format it is using based on the RGB masks */ - if (modeDesc->ddpfPixelFormat.dwRBitMask == 0x00FF0000) - *ppicasso_format |= RGBFF_B8G8R8; - else - *ppicasso_format |= RGBFF_R8G8B8; + if (dm->colormodes & RGBMASK_24BIT) { + DisplayModes[count].res.width = dm->width; + DisplayModes[count].res.height = dm->height; + DisplayModes[count].refresh = 75; + DisplayModes[count].depth = 3; + count++; + } + if (count >= MAX_PICASSO_MODES) break; - case 32: - /* figure out which actual format it is using based on the RGB masks */ - if (modeDesc->ddpfPixelFormat.dwRBitMask == 0x00FF0000) - *ppicasso_format |= RGBFF_B8G8R8A8; - else if (modeDesc->ddpfPixelFormat.dwRBitMask == 0x000000FF) - *ppicasso_format |= RGBFF_R8G8B8A8; - else if (modeDesc->ddpfPixelFormat.dwBBitMask == 0xFF000000) - *ppicasso_format |= RGBFF_A8R8G8B8; - else - *ppicasso_format |= RGBFF_A8B8G8R8; + if (dm->colormodes & RGBMASK_32BIT) { + DisplayModes[count].res.width = dm->width; + DisplayModes[count].res.height = dm->height; + DisplayModes[count].refresh = 75; + DisplayModes[count].depth = 4; + count++; + } + if (count >= MAX_PICASSO_MODES) break; - } -#endif - DisplayModes[picasso_modecount].res.width = modeDesc->dwWidth; - DisplayModes[picasso_modecount].res.height = modeDesc->dwHeight; - DisplayModes[picasso_modecount].depth = bpp/8; - if (modeDesc->dwRefreshRate) - { - sprintf(DisplayModes[picasso_modecount].name,"%dx%d, %d-bit, %d Hz",modeDesc->dwWidth, - modeDesc->dwHeight, bpp, modeDesc->dwRefreshRate ); - DisplayModes[picasso_modecount].refresh = modeDesc->dwRefreshRate; - } - else - { - sprintf(DisplayModes[picasso_modecount].name,"%dx%d, %d-bit",modeDesc->dwWidth, - modeDesc->dwHeight, bpp ); - DisplayModes[picasso_modecount].refresh = 75; /* fake a 75-Hz refresh rate... BLAH! */ - } - picasso_modecount++; } - return DDENUMRET_OK; + return count; } - -int DX_FillResolutions (uae_u16 *ppixel_format) -{ - static int from_preInit = 1; - if( from_preInit ) - { - picasso_modecount = 0; - *ppixel_format = 0; - ppicasso_format = ppixel_format; - - IDirectDraw_EnumDisplayModes (lpDD, 0, NULL, NULL, modesCallback); - from_preInit = 0; - } - return picasso_modecount; -} - -#ifdef PICASSO96 - + void DX_SetPalette (int start, int count) { HRESULT ddrval; - if (!screen_is_picasso) + if (! screen_is_picasso || picasso96_state.RGBFormat != RGBFB_CHUNKY) return; + if (picasso_vidinfo.pixbytes != 1) { + printf ("DX Setpalette emulation\n"); + /* This is the case when we're emulating a 256 color display. */ + while (count-- > 0) { + int r = picasso96_state.CLUT[start].Red; + int g = picasso96_state.CLUT[start].Green; + int b = picasso96_state.CLUT[start].Blue; + picasso_vidinfo.clut[start++] = (doMask256 (r, red_bits, red_shift) + | doMask256 (g, green_bits, green_shift) + | doMask256 (b, blue_bits, blue_shift)); + } + return; + } + /* Set our DirectX palette here */ - if (lpDDP && (picasso96_state.BytesPerPixel == 1)) { + if (lpDDP && current_pixbytes == 1) { /* For now, until I figure this out, just set the entire range of CLUT values */ - ddrval = IDirectDrawPalette_SetEntries (lpDDP, 0, 0, 256, (LPPALETTEENTRY) &picasso96_state.CLUT); + ddrval = IDirectDrawPalette_SetEntries (lpDDP, 0, start, count, (LPPALETTEENTRY) & (picasso96_state.CLUT[start])); if (ddrval != DD_OK) - MyOutputDebugString ("DX_SetPalette() failed with %s/%d\n", getddrname (ddrval), ddrval); + write_log ("DX_SetPalette() failed with %s/%d\n", getddrname (ddrval), ddrval); + else + printf ("DX_SetPalette OK\n"); } else - MyOutputDebugString ("ERROR - DX_SetPalette() doesn't have palette, or isn't Chunky mode.\n"); + write_log ("ERROR - DX_SetPalette() doesn't have palette, or isn't Chunky mode.\n"); } void DX_Invalidate (int first, int last) @@ -1859,28 +1810,136 @@ void gfx_set_picasso_state (int on) { if (screen_is_picasso == on) return; + screen_is_picasso = on; - PostMessage (hAmigaWnd, WM_USER + 0x201, 0, 0); - uae_sem_wait (&picasso_switch_sem); + close_windows (); + open_windows (); + DX_SetPalette (0, 256); } -void gfx_set_picasso_modeinfo (int w, int h, int depth) +void gfx_set_picasso_modeinfo (int w, int h, int depth, int rgbfmt) { depth >>= 3; if (picasso_vidinfo.width == w && picasso_vidinfo.height == h - && picasso_vidinfo.depth == depth) + && picasso_vidinfo.depth == depth + && picasso_vidinfo.selected_rgbformat == rgbfmt) return; + picasso_vidinfo.selected_rgbformat = rgbfmt; picasso_vidinfo.width = w; picasso_vidinfo.height = h; picasso_vidinfo.depth = depth; picasso_vidinfo.extra_mem = 1; if (screen_is_picasso) { - PostMessage (hAmigaWnd, WM_USER + 0x201, 0, 0); - uae_sem_wait (&picasso_switch_sem); + close_windows (); + open_windows (); + DX_SetPalette (0, 256); } } +int graphics_init (void) +{ + SetPriorityClass (GetCurrentProcess (), process_desired_pri); + + return open_windows (); +} + +int graphics_setup (void) +{ + char *posn; + int i; + + debugfile = CreateFile ("outfile", GENERIC_WRITE, 0, 0, CREATE_ALWAYS, + 0, NULL); + + /* Get our executable's root-path */ + start_path = xmalloc (MAX_PATH); + GetModuleFileName (0, start_path, MAX_PATH); + if (posn = strrchr (start_path, '\\')) + *posn = 0; + + write_log ("UAE " UAEWINVERSION " Win32/DirectX, release " UAEWINRELEASE "\n"); + strcpy (VersionStr, PROGNAME); + write_log ("\n(c) 1995-1997 Bernd Schmidt - Core UAE concept and implementation." + "\n(c) 1996-1997 Mathias Ortmann - Win32 port and enhancements." + "\n(c) 1996-1997 Brian King - Picasso96 and AHI support, GUI.\n" + "\nPress F12 to show the Settings Dialog (GUI), Alt-F4 to quit.\n" + "\nhttp://www.informatik.tu-muenchen.de/~ortmann/uae/\n\n"); + + if (! initlibs ()) + return 0; + + if (! register_classes ()) + return 0; + + if (! start_ddraw ()) + return 0; + IDirectDraw_EnumDisplayModes (lpDD, 0, NULL, NULL, modesCallback); +#if 0 + figure_pixel_formats (); +#endif + release_ddraw (); + + return 1; +} + +void machdep_init (void) +{ +} + +void graphics_leave (void) +{ + close_windows (); + dumpcustom (); + cleanuplibs (); +} + +#if defined NO_MAIN_IN_MAIN_C +int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, + int nCmdShow) +{ + hInst = hInstance; + + printf ("WinMain called\n"); + + /*initgfxspecs(); */ +#ifdef __CYGWIN32__ + { + char *token, *tmpbuf; + int my_argc, i; + char ** my_argv; + + tmpbuf = my_strdup (lpCmdLine); + my_argc = 1; + if (strtok (tmpbuf, "\n ") != NULL) { + do { + my_argc++; + } while (strtok (NULL, "\n ") != NULL); + } + free (tmpbuf); + + tmpbuf = my_strdup (lpCmdLine); + + my_argv = (char **)malloc ((1 + my_argc) * sizeof (char **)); + my_argv[0] = "uae.exe"; + + token = strtok (tmpbuf, "\n "); + i = 1; + while (token != NULL) { + my_argv[i++] = my_strdup (token); + token = strtok (NULL, "\n "); + } + my_argv[my_argc] = NULL; + + real_main (my_argc, my_argv); + } +#elif defined __MINGW32__ + real_main (_argc, _argv); +#else + real_main (__argc, __argv); +#endif + return FALSE; +} #endif