--- hatari/src/falcon/hostscreen.c 2019/04/09 08:48:46 1.1.1.5 +++ hatari/src/falcon/hostscreen.c 2019/04/09 08:49:37 1.1.1.6 @@ -10,6 +10,7 @@ */ const char HostScreen_fileid[] = "Hatari hostscreen.c : " __DATE__ " " __TIME__; +#include #include "main.h" #include "configuration.h" #include "control.h" @@ -48,21 +49,20 @@ const char HostScreen_fileid[] = "Hatari #define RGB_WHITE 0xffff00ff -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 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 void HostScreen_remapPalette(void); + static struct { // TOS palette (bpp < 16) to SDL color mapping SDL_Color standard[256]; Uint32 native[256]; } palette; -static const unsigned long default_palette[] = { +static const Uint32 default_palette[] = { RGB_WHITE, RGB_RED, RGB_GREEN, RGB_YELLOW, RGB_BLUE, RGB_MAGENTA, RGB_CYAN, RGB_LTGRAY, RGB_GRAY, RGB_LTRED, RGB_LTGREEN, RGB_LTYELLOW, @@ -73,14 +73,12 @@ static const unsigned long default_palet void HostScreen_Init(void) { int i; - for(i=0; i<256; i++) { - unsigned long color = default_palette[i%16]; + for(i = 0; i < 256; i++) { + Uint32 color = default_palette[i%16]; palette.standard[i].r = color >> 24; palette.standard[i].g = (color >> 16) & 0xff; palette.standard[i].b = color & 0xff; } - - mainSurface=NULL; } void HostScreen_UnInit(void) @@ -91,9 +89,11 @@ void HostScreen_UnInit(void) void HostScreen_toggleFullScreen(void) { sdl_videoparams ^= SDL_FULLSCREEN; + Dprintf(("Fullscreen = %s, width = %d, height = %d, bpp = %d\n", + sdl_videoparams&SDL_FULLSCREEN?"true":"false", hs_width_req, hs_height_req, hs_bpp)); HostScreen_setWindowSize(hs_width_req, hs_height_req, hs_bpp); - /* refresh the screen */ + /* force screen redraw */ HostScreen_update1(true); } @@ -106,8 +106,23 @@ void HostScreen_setWindowSize(int width, if (bpp == 24) bpp = 32; - Resolution_GetLimits(&maxw, &maxh, &bpp); + /* constrain size request to user's desktop size */ + Resolution_GetDesktopSize(&maxw, &maxh); + scalex = scaley = 1; + while (width > maxw*scalex) { + scalex *= 2; + } + while (height > maxh*scalex) { + scalex *= 2; + } + if (scalex * scaley > 1) { + fprintf(stderr, "WARNING: too large screen size %dx%d -> divided by %dx%d!\n", + width, height, scalex, scaley); + width /= scalex; + height /= scaley; + } + Resolution_GetLimits(&maxw, &maxh, &bpp); nScreenZoomX = nScreenZoomY = 1; if (ConfigureParams.Screen.bAspectCorrect) { @@ -150,12 +165,14 @@ void HostScreen_setWindowSize(int width, width *= nScreenZoomX; height *= nScreenZoomY; + /* get statusbar size for this screen size */ sbarheight = Statusbar_GetHeightForSize(width, height); screenheight = height + sbarheight; screenwidth = width; - // Select a correct video mode + /* get resolution corresponding to these */ Resolution_Search(&screenwidth, &screenheight, &bpp); + /* re-calculate statusbar height for this resolution */ sbarheight = Statusbar_SetHeight(screenwidth, screenheight-sbarheight); hs_bpp = bpp; @@ -170,7 +187,9 @@ void HostScreen_setWindowSize(int width, sdlscrn->w == (signed)screenwidth && sdlscrn->h == (signed)screenheight && (sdlscrn->flags&SDL_FULLSCREEN) == (sdl_videoparams&SDL_FULLSCREEN)) { - /* no time consuming host video mode change needed */ + /* same host screen size despite Atari resolution change, + * -> no time consuming host video mode change needed + */ if (screenwidth > width || screenheight > height+sbarheight) { /* Atari screen smaller than host -> clear screen */ SDL_Rect rect; @@ -179,7 +198,14 @@ void HostScreen_setWindowSize(int width, rect.w = sdlscrn->w; rect.h = sdlscrn->h - sbarheight; SDL_FillRect(sdlscrn, &rect, SDL_MapRGB(sdlscrn->format, 0, 0, 0)); + /* re-calculate variables in case height + statusbar height + * don't anymore match SDL surface size (there's an assert + * for that) + */ + Statusbar_Init(sdlscrn); } + // check in case switched from VDI to Hostscreen + doUpdate = ( sdlscrn->flags & SDL_HWSURFACE ) == 0; return; } @@ -196,8 +222,7 @@ void HostScreen_setWindowSize(int width, __mf_unregister(sdlscrn->pixels, sdlscrn->pitch*sdlscrn->h, __MF_TYPE_GUESS); } #endif - mainSurface = SDL_SetVideoMode(screenwidth, screenheight, bpp, sdl_videoparams); - sdlscrn = surf = mainSurface; + sdlscrn = SDL_SetVideoMode(screenwidth, screenheight, bpp, sdl_videoparams); #ifdef _MUDFLAP __mf_register(sdlscrn->pixels, sdlscrn->pitch*sdlscrn->h, __MF_TYPE_GUESS, "SDL pixels"); #endif @@ -206,52 +231,48 @@ void HostScreen_setWindowSize(int width, Control_ReparentWindow(screenwidth, screenheight, bInFullScreen); } - // update the surface's palette - HostScreen_updatePalette( 256 ); + // In case surface format changed, update SDL palette & remap the native palette + HostScreen_updatePalette(256); + HostScreen_remapPalette(); // redraw statusbar - Statusbar_Init(mainSurface); + Statusbar_Init(sdlscrn); - Dprintf(("Surface Pitch = %d, width = %d, height = %d\n", surf->pitch, surf->w, surf->h)); - Dprintf(("Must Lock? %s\n", SDL_MUSTLOCK(surf) ? "YES" : "NO")); + Dprintf(("Surface Pitch = %d, width = %d, height = %d\n", sdlscrn->pitch, sdlscrn->w, sdlscrn->h)); + Dprintf(("Must Lock? %s\n", SDL_MUSTLOCK(sdlscrn) ? "YES" : "NO")); // is the SDL_update needed? - doUpdate = ( surf->flags & SDL_HWSURFACE ) == 0; + doUpdate = ( sdlscrn->flags & SDL_HWSURFACE ) == 0; 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", - surf->format->BitsPerPixel, - 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)); + sdlscrn->format->BitsPerPixel, + sdlscrn->format->Rmask, sdlscrn->format->Gmask, sdlscrn->format->Bmask, + sdlscrn->format->Rshift, sdlscrn->format->Gshift, sdlscrn->format->Bshift, + sdlscrn->format->Rloss, sdlscrn->format->Gloss, sdlscrn->format->Bloss)); Main_WarpMouse(sdlscrn->w/2,sdlscrn->h/2); } -static void HostScreen_update5(Sint32 x, Sint32 y, Sint32 w, Sint32 h, bool forced) +void HostScreen_update1(bool forced) { if ( !forced && !doUpdate ) // the HW surface is available return; - SDL_UpdateRect(mainSurface, x, y, w, h); -} - -void HostScreen_update1(bool forced) -{ - HostScreen_update5( 0, 0, hs_width, hs_height, forced ); + SDL_UpdateRect( sdlscrn, 0, 0, hs_width, hs_height ); } Uint32 HostScreen_getBpp(void) { - return surf->format->BytesPerPixel; + return sdlscrn->format->BytesPerPixel; } Uint32 HostScreen_getPitch(void) { - return surf->pitch; + return sdlscrn->pitch; } Uint32 HostScreen_getWidth(void) @@ -266,17 +287,22 @@ Uint32 HostScreen_getHeight(void) Uint8 *HostScreen_getVideoramAddress(void) { - return surf->pixels; /* FIXME maybe this should be mainSurface? */ + return sdlscrn->pixels; +} + +SDL_PixelFormat *HostScreen_getFormat(void) +{ + return sdlscrn->format; } -void HostScreen_setPaletteColor(Uint8 idx, Uint32 red, Uint32 green, Uint32 blue) +void HostScreen_setPaletteColor(Uint8 idx, Uint8 red, Uint8 green, Uint8 blue) { // set the SDL standard RGB palette settings palette.standard[idx].r = red; palette.standard[idx].g = green; palette.standard[idx].b = blue; // convert the color to native - palette.native[idx] = SDL_MapRGB( surf->format, red, green, blue ); + palette.native[idx] = SDL_MapRGB( sdlscrn->format, red, green, blue ); } Uint32 HostScreen_getPaletteColor(Uint8 idx) @@ -284,21 +310,27 @@ Uint32 HostScreen_getPaletteColor(Uint8 return palette.native[idx]; } -void HostScreen_updatePalette(Uint16 colorCount) +void HostScreen_updatePalette(int colorCount) { - SDL_SetColors( surf, palette.standard, 0, colorCount ); + SDL_SetColors( sdlscrn, palette.standard, 0, colorCount ); } -Uint32 HostScreen_getColor(Uint32 red, Uint32 green, Uint32 blue) +static void HostScreen_remapPalette(void) { - return SDL_MapRGB( surf->format, red, green, blue ); -} + int i; + Uint32 *native = palette.native; + SDL_Color *standard = palette.standard; + SDL_PixelFormat *fmt = sdlscrn->format; + for(i = 0; i < 256; i++, native++, standard++) { + *native = SDL_MapRGB(fmt, standard->r, standard->g, standard->b); + } +} bool HostScreen_renderBegin(void) { - if (SDL_MUSTLOCK(surf)) - if (SDL_LockSurface(surf) < 0) { + if (SDL_MUSTLOCK(sdlscrn)) + if (SDL_LockSurface(sdlscrn) < 0) { printf("Couldn't lock surface to refresh!\n"); return false; } @@ -308,7 +340,7 @@ bool HostScreen_renderBegin(void) void HostScreen_renderEnd(void) { - if (SDL_MUSTLOCK(surf)) - SDL_UnlockSurface(surf); - Statusbar_Update(surf); + if (SDL_MUSTLOCK(sdlscrn)) + SDL_UnlockSurface(sdlscrn); + Statusbar_Update(sdlscrn); }