|
|
1.1 root 1: /*
2: Hatari - hostscreen.c
3:
4: This file is distributed under the GNU Public License, version 2 or at
5: your option any later version. Read the file gpl.txt for details.
6:
7: Host video routines. This file originally came from the Aranym project but
8: has been thoroughly reworked for Hatari. However, integration with the rest
9: of the Hatari source code is still bad and needs a lot of improvement...
10: */
1.1.1.4 root 11: const char HostScreen_fileid[] = "Hatari hostscreen.c : " __DATE__ " " __TIME__;
1.1 root 12:
13: #include "main.h"
14: #include "configuration.h"
1.1.1.2 root 15: #include "control.h"
1.1 root 16: #include "sysdeps.h"
17: #include "stMemory.h"
18: #include "ioMem.h"
19: #include "hostscreen.h"
1.1.1.5 ! root 20: #include "resolution.h"
1.1 root 21: #include "screen.h"
1.1.1.2 root 22: #include "statusbar.h"
1.1 root 23:
24: #define VIDEL_DEBUG 0
25:
26: #if VIDEL_DEBUG
27: #define Dprintf(a) printf a
28: #else
29: #define Dprintf(a)
30: #endif
31:
32:
33: #define RGB_BLACK 0x00000000
34: #define RGB_BLUE 0x000000ff
35: #define RGB_GREEN 0x00ff0000
36: #define RGB_CYAN 0x00ff00ff
37: #define RGB_RED 0xff000000
38: #define RGB_MAGENTA 0xff0000ff
39: #define RGB_LTGRAY 0xbbbb00bb
40: #define RGB_GRAY 0x88880088
41: #define RGB_LTBLUE 0x000000aa
42: #define RGB_LTGREEN 0x00aa0000
43: #define RGB_LTCYAN 0x00aa00aa
44: #define RGB_LTRED 0xaa000000
45: #define RGB_LTMAGENTA 0xaa0000aa
46: #define RGB_YELLOW 0xffff0000
47: #define RGB_LTYELLOW 0xaaaa0000
48: #define RGB_WHITE 0xffff00ff
49:
50:
51: static SDL_Surface *mainSurface; // The main window surface
52: static SDL_Surface *surf; // pointer to actual surface
53:
1.1.1.5 ! root 54: /* TODO: put these hostscreen globals to some struct */
1.1.1.2 root 55: static Uint32 sdl_videoparams;
1.1.1.5 ! root 56: static int hs_width, hs_height, hs_width_req, hs_height_req, hs_bpp;
1.1.1.2 root 57: static bool doUpdate; // the HW surface is available -> the SDL need not to update the surface after ->pixel access
1.1 root 58:
59: static struct { // TOS palette (bpp < 16) to SDL color mapping
60: SDL_Color standard[256];
1.1.1.2 root 61: Uint32 native[256];
1.1 root 62: } palette;
63:
64:
65: static const unsigned long default_palette[] = {
66: RGB_WHITE, RGB_RED, RGB_GREEN, RGB_YELLOW,
67: RGB_BLUE, RGB_MAGENTA, RGB_CYAN, RGB_LTGRAY,
68: RGB_GRAY, RGB_LTRED, RGB_LTGREEN, RGB_LTYELLOW,
69: RGB_LTBLUE, RGB_LTMAGENTA, RGB_LTCYAN, RGB_BLACK
70: };
71:
72:
1.1.1.4 root 73: void HostScreen_Init(void)
74: {
1.1 root 75: int i;
76: for(i=0; i<256; i++) {
77: unsigned long color = default_palette[i%16];
78: palette.standard[i].r = color >> 24;
79: palette.standard[i].g = (color >> 16) & 0xff;
80: palette.standard[i].b = color & 0xff;
81: }
82:
83: mainSurface=NULL;
84: }
85:
1.1.1.4 root 86: void HostScreen_UnInit(void)
87: {
1.1 root 88: }
89:
90:
91: void HostScreen_toggleFullScreen(void)
92: {
93: sdl_videoparams ^= SDL_FULLSCREEN;
94:
1.1.1.5 ! root 95: HostScreen_setWindowSize(hs_width_req, hs_height_req, hs_bpp);
! 96: /* refresh the screen */
! 97: HostScreen_update1(true);
1.1 root 98: }
99:
100:
1.1.1.5 ! root 101: void HostScreen_setWindowSize(int width, int height, int bpp)
1.1 root 102: {
1.1.1.5 ! root 103: int screenwidth, screenheight, maxw, maxh;
! 104: int scalex, scaley, sbarheight;
1.1 root 105:
1.1.1.5 ! root 106: if (bpp == 24)
! 107: bpp = 32;
1.1 root 108:
1.1.1.5 ! root 109: Resolution_GetLimits(&maxw, &maxh, &bpp);
1.1 root 110:
1.1.1.5 ! root 111: nScreenZoomX = nScreenZoomY = 1;
! 112:
! 113: if (ConfigureParams.Screen.bAspectCorrect) {
! 114: /* Falcon (and TT) pixel scaling factors seem to 2^x
! 115: * (quarter/half pixel, interlace/double line), so
! 116: * do aspect correction as 2's exponent.
! 117: */
! 118: while (nScreenZoomX*width < height &&
! 119: 2*nScreenZoomX*width < maxw) {
! 120: nScreenZoomX *= 2;
1.1 root 121: }
1.1.1.5 ! root 122: while (2*nScreenZoomY*height < width &&
! 123: 2*nScreenZoomY*height < maxh) {
! 124: nScreenZoomY *= 2;
! 125: }
! 126: if (nScreenZoomX*nScreenZoomY > 2) {
! 127: fprintf(stderr, "WARNING: strange screen size %dx%d -> aspect corrected by %dx%d!\n",
! 128: width, height, nScreenZoomX, nScreenZoomY);
1.1 root 129: }
130: }
131:
1.1.1.5 ! root 132: /* then select scale as close to target size as possible
! 133: * without having larger size than it
! 134: */
! 135: scalex = maxw/(nScreenZoomX*width);
! 136: scaley = maxh/(nScreenZoomY*height);
! 137: if (scalex > 1 && scaley > 1) {
! 138: /* keep aspect ratio */
! 139: if (scalex < scaley) {
! 140: nScreenZoomX *= scalex;
! 141: nScreenZoomY *= scalex;
! 142: } else {
! 143: nScreenZoomX *= scaley;
! 144: nScreenZoomY *= scaley;
! 145: }
1.1 root 146: }
147:
1.1.1.5 ! root 148: hs_width_req = width;
! 149: hs_height_req = height;
! 150: width *= nScreenZoomX;
! 151: height *= nScreenZoomY;
! 152:
! 153: sbarheight = Statusbar_GetHeightForSize(width, height);
! 154: screenheight = height + sbarheight;
! 155: screenwidth = width;
1.1.1.4 root 156:
1.1.1.5 ! root 157: // Select a correct video mode
! 158: Resolution_Search(&screenwidth, &screenheight, &bpp);
! 159: sbarheight = Statusbar_SetHeight(screenwidth, screenheight-sbarheight);
1.1.1.4 root 160:
1.1.1.5 ! root 161: hs_bpp = bpp;
! 162: /* videl.c might scale things differently in fullscreen than
! 163: * in windowed mode because this uses screensize instead of using
! 164: * the aspect scaled sizes directly, but it works better this way.
! 165: */
! 166: hs_width = screenwidth;
! 167: hs_height = screenheight - sbarheight;
! 168:
! 169: if (sdlscrn && (!bpp || sdlscrn->format->BitsPerPixel == bpp) &&
! 170: sdlscrn->w == (signed)screenwidth && sdlscrn->h == (signed)screenheight &&
! 171: (sdlscrn->flags&SDL_FULLSCREEN) == (sdl_videoparams&SDL_FULLSCREEN))
1.1 root 172: {
1.1.1.5 ! root 173: /* no time consuming host video mode change needed */
! 174: if (screenwidth > width || screenheight > height+sbarheight) {
! 175: /* Atari screen smaller than host -> clear screen */
! 176: SDL_Rect rect;
! 177: rect.x = 0;
! 178: rect.y = 0;
! 179: rect.w = sdlscrn->w;
! 180: rect.h = sdlscrn->h - sbarheight;
! 181: SDL_FillRect(sdlscrn, &rect, SDL_MapRGB(sdlscrn->format, 0, 0, 0));
1.1 root 182: }
1.1.1.5 ! root 183: return;
1.1 root 184: }
185:
1.1.1.2 root 186: if (bInFullScreen) {
187: /* un-embed the Hatari WM window for fullscreen */
1.1.1.5 ! root 188: Control_ReparentWindow(screenwidth, screenheight, bInFullScreen);
1.1.1.2 root 189:
1.1 root 190: sdl_videoparams = SDL_SWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN;
1.1.1.2 root 191: } else {
1.1 root 192: sdl_videoparams = SDL_SWSURFACE|SDL_HWPALETTE;
1.1.1.2 root 193: }
1.1.1.5 ! root 194: #ifdef _MUDFLAP
! 195: if (sdlscrn) {
! 196: __mf_unregister(sdlscrn->pixels, sdlscrn->pitch*sdlscrn->h, __MF_TYPE_GUESS);
! 197: }
! 198: #endif
! 199: mainSurface = SDL_SetVideoMode(screenwidth, screenheight, bpp, sdl_videoparams);
! 200: sdlscrn = surf = mainSurface;
! 201: #ifdef _MUDFLAP
! 202: __mf_register(sdlscrn->pixels, sdlscrn->pitch*sdlscrn->h, __MF_TYPE_GUESS, "SDL pixels");
! 203: #endif
1.1.1.2 root 204: if (!bInFullScreen) {
205: /* re-embed the new Hatari SDL window */
1.1.1.5 ! root 206: Control_ReparentWindow(screenwidth, screenheight, bInFullScreen);
1.1.1.2 root 207: }
1.1 root 208:
209: // update the surface's palette
210: HostScreen_updatePalette( 256 );
211:
1.1.1.5 ! root 212: // redraw statusbar
1.1.1.2 root 213: Statusbar_Init(mainSurface);
214:
1.1 root 215: Dprintf(("Surface Pitch = %d, width = %d, height = %d\n", surf->pitch, surf->w, surf->h));
216: Dprintf(("Must Lock? %s\n", SDL_MUSTLOCK(surf) ? "YES" : "NO"));
217:
218: // is the SDL_update needed?
219: doUpdate = ( surf->flags & SDL_HWSURFACE ) == 0;
220:
221: Dprintf(("Pixel format:bitspp=%d, tmasks r=%04x g=%04x b=%04x"
222: ", tshifts r=%d g=%d b=%d"
223: ", tlosses r=%d g=%d b=%d\n",
224: surf->format->BitsPerPixel,
225: surf->format->Rmask, surf->format->Gmask, surf->format->Bmask,
226: surf->format->Rshift, surf->format->Gshift, surf->format->Bshift,
227: surf->format->Rloss, surf->format->Gloss, surf->format->Bloss));
1.1.1.5 ! root 228:
! 229: Main_WarpMouse(sdlscrn->w/2,sdlscrn->h/2);
1.1 root 230: }
231:
232:
1.1.1.2 root 233: static void HostScreen_update5(Sint32 x, Sint32 y, Sint32 w, Sint32 h, bool forced)
1.1 root 234: {
235: if ( !forced && !doUpdate ) // the HW surface is available
236: return;
237:
238: SDL_UpdateRect(mainSurface, x, y, w, h);
239: }
240:
1.1.1.2 root 241: void HostScreen_update1(bool forced)
1.1 root 242: {
243: HostScreen_update5( 0, 0, hs_width, hs_height, forced );
244: }
245:
246:
1.1.1.4 root 247: Uint32 HostScreen_getBpp(void)
1.1 root 248: {
249: return surf->format->BytesPerPixel;
250: }
251:
1.1.1.4 root 252: Uint32 HostScreen_getPitch(void)
253: {
1.1 root 254: return surf->pitch;
255: }
256:
1.1.1.4 root 257: Uint32 HostScreen_getWidth(void)
258: {
1.1 root 259: return hs_width;
260: }
261:
1.1.1.4 root 262: Uint32 HostScreen_getHeight(void)
263: {
1.1 root 264: return hs_height;
265: }
266:
1.1.1.4 root 267: Uint8 *HostScreen_getVideoramAddress(void)
268: {
1.1 root 269: return surf->pixels; /* FIXME maybe this should be mainSurface? */
270: }
271:
1.1.1.4 root 272: void HostScreen_setPaletteColor(Uint8 idx, Uint32 red, Uint32 green, Uint32 blue)
273: {
1.1 root 274: // set the SDL standard RGB palette settings
275: palette.standard[idx].r = red;
276: palette.standard[idx].g = green;
277: palette.standard[idx].b = blue;
278: // convert the color to native
279: palette.native[idx] = SDL_MapRGB( surf->format, red, green, blue );
280: }
281:
1.1.1.4 root 282: Uint32 HostScreen_getPaletteColor(Uint8 idx)
283: {
1.1 root 284: return palette.native[idx];
285: }
286:
1.1.1.4 root 287: void HostScreen_updatePalette(Uint16 colorCount)
288: {
1.1 root 289: SDL_SetColors( surf, palette.standard, 0, colorCount );
290: }
291:
1.1.1.4 root 292: Uint32 HostScreen_getColor(Uint32 red, Uint32 green, Uint32 blue)
293: {
1.1 root 294: return SDL_MapRGB( surf->format, red, green, blue );
295: }
296:
297:
1.1.1.2 root 298: bool HostScreen_renderBegin(void)
299: {
1.1 root 300: if (SDL_MUSTLOCK(surf))
301: if (SDL_LockSurface(surf) < 0) {
302: printf("Couldn't lock surface to refresh!\n");
1.1.1.4 root 303: return false;
1.1 root 304: }
305:
1.1.1.4 root 306: return true;
1.1 root 307: }
308:
1.1.1.4 root 309: void HostScreen_renderEnd(void)
310: {
1.1 root 311: if (SDL_MUSTLOCK(surf))
312: SDL_UnlockSurface(surf);
1.1.1.2 root 313: Statusbar_Update(surf);
1.1 root 314: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.