--- hatari/src/falcon/hostscreen.c 2019/04/09 08:47:21 1.1.1.4 +++ hatari/src/falcon/hostscreen.c 2019/04/09 08:48:46 1.1.1.5 @@ -17,6 +17,7 @@ const char HostScreen_fileid[] = "Hatari #include "stMemory.h" #include "ioMem.h" #include "hostscreen.h" +#include "resolution.h" #include "screen.h" #include "statusbar.h" @@ -50,9 +51,9 @@ const char HostScreen_fileid[] = "Hatari static SDL_Surface *mainSurface; // The main window surface static SDL_Surface *surf; // pointer to actual surface - +/* TODO: put these hostscreen globals to some struct */ static Uint32 sdl_videoparams; -static Uint32 hs_width, hs_height, hs_bpp; +static int hs_width, hs_height, hs_width_req, hs_height_req, hs_bpp; static bool doUpdate; // the HW surface is available -> the SDL need not to update the surface after ->pixel access static struct { // TOS palette (bpp < 16) to SDL color mapping @@ -68,9 +69,6 @@ static const unsigned long default_palet RGB_LTBLUE, RGB_LTMAGENTA, RGB_LTCYAN, RGB_BLACK }; -static int HostScreen_selectVideoMode(SDL_Rect **modes, Uint32 *width, Uint32 *height); -static void HostScreen_searchVideoMode( Uint32 *width, Uint32 *height, Uint32 *bpp ); - void HostScreen_Init(void) { @@ -93,174 +91,125 @@ void HostScreen_UnInit(void) void HostScreen_toggleFullScreen(void) { sdl_videoparams ^= SDL_FULLSCREEN; - if (sdl_videoparams & SDL_FULLSCREEN) { - /* un-embed the Hatari WM window for fullscreen */ - Control_ReparentWindow(hs_width, hs_height, true); - } - if(SDL_WM_ToggleFullScreen(mainSurface) == 0) { - // SDL_WM_ToggleFullScreen() did not work. - // We have to change video mode "by hand". - SDL_Surface *temp = SDL_ConvertSurface(mainSurface, mainSurface->format, - mainSurface->flags); - Dprintf(("toggleFullScreen: SDL_WM_ToggleFullScreen() not supported" - " -> using SDL_SetVideoMode()")); - if (temp == NULL) - Dprintf(("toggleFullScreen: Unable to save screen content.")); - -#if 1 - HostScreen_setWindowSize(hs_width, hs_height, hs_bpp); -#else - mainSurface = SDL_SetVideoMode(width, height, bpp, sdl_videoparams); - if (mainSurface == NULL) - Dprintf(("toggleFullScreen: Unable to set new video mode.")); - if (mainSurface->format->BitsPerPixel <= 8) - SDL_SetColors(mainSurface, temp->format->palette->colors, 0, - temp->format->palette->ncolors); -#endif - - if (SDL_BlitSurface(temp, NULL, mainSurface, NULL) != 0) - Dprintf(("toggleFullScreen: Unable to restore screen content.")); - SDL_FreeSurface(temp); - /* refresh the screen */ - HostScreen_update1(true); - } else { - if (!(sdl_videoparams & SDL_FULLSCREEN)) { - /* re-embed the new Hatari SDL window */ - Control_ReparentWindow(hs_width, hs_height, false); - } - } + HostScreen_setWindowSize(hs_width_req, hs_height_req, hs_bpp); + /* refresh the screen */ + HostScreen_update1(true); } -static int HostScreen_selectVideoMode(SDL_Rect **modes, Uint32 *width, Uint32 *height) -{ - int i, bestw, besth; - /* Search the smallest nearest mode */ - bestw = modes[0]->w; - besth = modes[0]->h; - for (i=0;modes[i]; ++i) { - if ((modes[i]->w >= *width) && (modes[i]->h >= *height)) { - if ((modes[i]->w < bestw) || (modes[i]->h < besth)) { - bestw = modes[i]->w; - besth = modes[i]->h; - } - } - } - - *width = bestw; - *height = besth; - Dprintf(("hostscreen: video mode found: %dx%d\n",*width,*height)); +void HostScreen_setWindowSize(int width, int height, int bpp) +{ + int screenwidth, screenheight, maxw, maxh; + int scalex, scaley, sbarheight; - return 1; -} + if (bpp == 24) + bpp = 32; -static void HostScreen_searchVideoMode( Uint32 *width, Uint32 *height, Uint32 *bpp ) -{ - SDL_Rect **modes; - SDL_PixelFormat pixelformat; - int modeflags; - - /* Search in available modes the best suited */ - Dprintf(("hostscreen: video mode asked: %dx%dx%d\n",*width,*height,*bpp)); - - if ((*width == 0) || (*height == 0)) { - *width = 640; - *height = 480; - } + Resolution_GetLimits(&maxw, &maxh, &bpp); - /* Read available video modes */ - modeflags = 0 /*SDL_HWSURFACE | SDL_HWPALETTE*/; - if (bInFullScreen) - modeflags |= SDL_FULLSCREEN; - - /*--- Search a video mode with asked bpp ---*/ - if (*bpp != 0) { - pixelformat.BitsPerPixel = *bpp; - modes = SDL_ListModes(&pixelformat, modeflags); - if ((modes != (SDL_Rect **) 0) && (modes != (SDL_Rect **) -1)) { - Dprintf(("hostscreen: searching a good video mode (any bpp)\n")); - if (HostScreen_selectVideoMode(modes,width,height)) { - Dprintf(("hostscreen: video mode selected: %dx%dx%d\n",*width,*height,*bpp)); - return; - } + nScreenZoomX = nScreenZoomY = 1; + + if (ConfigureParams.Screen.bAspectCorrect) { + /* Falcon (and TT) pixel scaling factors seem to 2^x + * (quarter/half pixel, interlace/double line), so + * do aspect correction as 2's exponent. + */ + while (nScreenZoomX*width < height && + 2*nScreenZoomX*width < maxw) { + nScreenZoomX *= 2; + } + while (2*nScreenZoomY*height < width && + 2*nScreenZoomY*height < maxh) { + nScreenZoomY *= 2; + } + if (nScreenZoomX*nScreenZoomY > 2) { + fprintf(stderr, "WARNING: strange screen size %dx%d -> aspect corrected by %dx%d!\n", + width, height, nScreenZoomX, nScreenZoomY); } } - /*--- Search a video mode with any bpp ---*/ - modes = SDL_ListModes(NULL, modeflags); - if ((modes != (SDL_Rect **) 0) && (modes != (SDL_Rect **) -1)) { - Dprintf(("hostscreen: searching a good video mode\n")); - if (HostScreen_selectVideoMode(modes,width,height)) { - Dprintf(("hostscreen: video mode selected: %dx%dx%d\n",*width,*height,*bpp)); - return; + /* then select scale as close to target size as possible + * without having larger size than it + */ + scalex = maxw/(nScreenZoomX*width); + scaley = maxh/(nScreenZoomY*height); + if (scalex > 1 && scaley > 1) { + /* keep aspect ratio */ + if (scalex < scaley) { + nScreenZoomX *= scalex; + nScreenZoomY *= scalex; + } else { + nScreenZoomX *= scaley; + nScreenZoomY *= scaley; } } - if (modes == (SDL_Rect **) 0) { - Dprintf(("hostscreen: No modes available\n")); - } - - if (modes == (SDL_Rect **) -1) { - /* Any mode available */ - Dprintf(("hostscreen: Any modes available\n")); - } - - Dprintf(("hostscreen: video mode selected: %dx%dx%d\n",*width,*height,*bpp)); -} + hs_width_req = width; + hs_height_req = height; + width *= nScreenZoomX; + height *= nScreenZoomY; + + sbarheight = Statusbar_GetHeightForSize(width, height); + screenheight = height + sbarheight; + screenwidth = width; -void HostScreen_setWindowSize( Uint32 width, Uint32 height, Uint32 bpp ) -{ - Uint32 screenheight; - - if (bpp == 24) - bpp = 32; + // Select a correct video mode + Resolution_Search(&screenwidth, &screenheight, &bpp); + sbarheight = Statusbar_SetHeight(screenwidth, screenheight-sbarheight); - nScreenZoomX = 1; - nScreenZoomY = 1; - if (ConfigureParams.Screen.bZoomLowRes) + hs_bpp = bpp; + /* videl.c might scale things differently in fullscreen than + * in windowed mode because this uses screensize instead of using + * the aspect scaled sizes directly, but it works better this way. + */ + hs_width = screenwidth; + hs_height = screenheight - sbarheight; + + if (sdlscrn && (!bpp || sdlscrn->format->BitsPerPixel == bpp) && + sdlscrn->w == (signed)screenwidth && sdlscrn->h == (signed)screenheight && + (sdlscrn->flags&SDL_FULLSCREEN) == (sdl_videoparams&SDL_FULLSCREEN)) { - /* Ugly: 400x300 threshold is currently hard-coded. */ - /* Should rather be selectable by the user! */ - if (width && width <= 400) - { - nScreenZoomX = (800/width); - width *= nScreenZoomX; - } - if (height && height <= 300) - { - nScreenZoomY = (550/height); - height *= nScreenZoomY; + /* no time consuming host video mode change needed */ + if (screenwidth > width || screenheight > height+sbarheight) { + /* Atari screen smaller than host -> clear screen */ + SDL_Rect rect; + rect.x = 0; + rect.y = 0; + rect.w = sdlscrn->w; + rect.h = sdlscrn->h - sbarheight; + SDL_FillRect(sdlscrn, &rect, SDL_MapRGB(sdlscrn->format, 0, 0, 0)); } + return; } - screenheight = height + Statusbar_SetHeight(width, height); - - // Select a correct video mode - HostScreen_searchVideoMode(&width, &screenheight, &bpp); - hs_width = width; - hs_height = height; - hs_bpp = bpp; - - // SelectVideoMode(); if (bInFullScreen) { /* un-embed the Hatari WM window for fullscreen */ - Control_ReparentWindow(width, screenheight, bInFullScreen); + Control_ReparentWindow(screenwidth, screenheight, bInFullScreen); sdl_videoparams = SDL_SWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN; } else { sdl_videoparams = SDL_SWSURFACE|SDL_HWPALETTE; } - mainSurface = SDL_SetVideoMode(width, screenheight, bpp, sdl_videoparams); +#ifdef _MUDFLAP + if (sdlscrn) { + __mf_unregister(sdlscrn->pixels, sdlscrn->pitch*sdlscrn->h, __MF_TYPE_GUESS); + } +#endif + mainSurface = SDL_SetVideoMode(screenwidth, screenheight, bpp, sdl_videoparams); + sdlscrn = surf = mainSurface; +#ifdef _MUDFLAP + __mf_register(sdlscrn->pixels, sdlscrn->pitch*sdlscrn->h, __MF_TYPE_GUESS, "SDL pixels"); +#endif if (!bInFullScreen) { /* re-embed the new Hatari SDL window */ - Control_ReparentWindow(width, screenheight, bInFullScreen); + Control_ReparentWindow(screenwidth, screenheight, bInFullScreen); } - sdlscrn = surf = mainSurface; // update the surface's palette HostScreen_updatePalette( 256 ); + // redraw statusbar Statusbar_Init(mainSurface); Dprintf(("Surface Pitch = %d, width = %d, height = %d\n", surf->pitch, surf->w, surf->h)); @@ -269,16 +218,6 @@ void HostScreen_setWindowSize( Uint32 wi // is the SDL_update needed? doUpdate = ( surf->flags & SDL_HWSURFACE ) == 0; - HostScreen_renderBegin(); - -// VideoRAMBaseHost = (uint8 *) surf->pixels; -// InitVMEMBaseDiff(VideoRAMBaseHost, VideoRAMBase); -// Dprintf(("VideoRAM starts at %p (%08x)\n", VideoRAMBaseHost, VideoRAMBase)); - Dprintf(("surf->pixels = %p, getVideoSurface() = %p\n", - surf->pixels, SDL_GetVideoSurface()->pixels)); - - HostScreen_renderEnd(); - Dprintf(("Pixel format:bitspp=%d, tmasks r=%04x g=%04x b=%04x" ", tshifts r=%d g=%d b=%d" ", tlosses r=%d g=%d b=%d\n", @@ -286,6 +225,8 @@ void HostScreen_setWindowSize( Uint32 wi surf->format->Rmask, surf->format->Gmask, surf->format->Bmask, surf->format->Rshift, surf->format->Gshift, surf->format->Bshift, surf->format->Rloss, surf->format->Gloss, surf->format->Bloss)); + + Main_WarpMouse(sdlscrn->w/2,sdlscrn->h/2); }