[Scummvm-cvs-logs] CVS: scummvm/backends/sdl graphics.cpp,1.3,1.4 sdl-common.h,1.53,1.54 sdl.cpp,1.65,1.66

Max Horn fingolfin at users.sourceforge.net
Sat Mar 13 07:14:11 CET 2004


Update of /cvsroot/scummvm/scummvm/backends/sdl
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24656

Modified Files:
	graphics.cpp sdl-common.h sdl.cpp 
Log Message:
Added an OSD (On Screen Display) to the SDL backend

Index: graphics.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/sdl/graphics.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- graphics.cpp	1 Mar 2004 11:20:32 -0000	1.3
+++ graphics.cpp	13 Mar 2004 14:19:08 -0000	1.4
@@ -23,6 +23,7 @@
 #include "backends/sdl/sdl-common.h"
 #include "common/scaler.h"
 #include "common/util.h"
+#include "gui/font.h"
 
 static const OSystem::GraphicsMode s_supportedGraphicsModes[] = {
 	{"1x", "Normal (no scaling)", GFX_NORMAL},
@@ -107,19 +108,41 @@
 	}
 
 	_mode = mode;
-
+	_scaler_proc = newScalerProc;
 	if (newScaleFactor != _scaleFactor) {
+		_scaleFactor = newScaleFactor;
 		hotswap_gfx_mode();
-	} else {
-		_scaler_proc = newScalerProc;
-		_forceFull = true;
+	}
 
-		// Blit everything to the screen
-		internUpdateScreen();
-	
-		// Make sure that an EVENT_SCREEN_CHANGED gets sent later
-		_modeChanged = true;
+	if (!_screen)
+		return true;
+
+#ifdef USE_OSD
+	if (_osdSurface) {
+		const char *newScalerName = 0;
+		const GraphicsMode *g = s_supportedGraphicsModes;
+		while (g->name) {
+			if (g->id == mode) {
+				newScalerName = g->description;
+				break;
+			}
+			g++;
+		}
+		if (newScalerName) {
+			char buffer[128];
+			sprintf(buffer, "Active graphics filter: %s", newScalerName);
+			displayMessageOnOSD(buffer);
+		}
 	}
+#endif
+
+
+	// Blit everything to the screen
+	_forceFull = true;
+	internUpdateScreen();
+	
+	// Make sure that an EVENT_SCREEN_CHANGED gets sent later
+	_modeChanged = true;
 
 	return true;
 }
@@ -153,69 +176,13 @@
 	_mode_flags |= DF_UPDATE_EXPAND_1_PIXEL;
 
 	_tmpscreen = NULL;
-	_tmpScreenWidth = (_screenWidth + 3);
 	
-	switch(_mode) {
-	case GFX_NORMAL:
-		_scaleFactor = 1;
-		_scaler_proc = Normal1x;
-		break;
-	case GFX_DOUBLESIZE:
-		_scaleFactor = 2;
-		_scaler_proc = Normal2x;
-		break;
-	case GFX_TRIPLESIZE:
-		_scaleFactor = 3;
-		_scaler_proc = Normal3x;
-		break;
-
-	case GFX_2XSAI:
-		_scaleFactor = 2;
-		_scaler_proc = _2xSaI;
-		break;
-	case GFX_SUPER2XSAI:
-		_scaleFactor = 2;
-		_scaler_proc = Super2xSaI;
-		break;
-	case GFX_SUPEREAGLE:
-		_scaleFactor = 2;
-		_scaler_proc = SuperEagle;
-		break;
-	case GFX_ADVMAME2X:
-		_scaleFactor = 2;
-		_scaler_proc = AdvMame2x;
-		break;
-	case GFX_ADVMAME3X:
-		_scaleFactor = 3;
-		_scaler_proc = AdvMame3x;
-		break;
-	case GFX_HQ2X:
-		_scaleFactor = 2;
-		_scaler_proc = HQ2x;
-		break;
-	case GFX_HQ3X:
-		_scaleFactor = 3;
-		_scaler_proc = HQ3x;
-		break;
-	case GFX_TV2X:
-		_scaleFactor = 2;
-		_scaler_proc = TV2x;
-		break;
-	case GFX_DOTMATRIX:
-		_scaleFactor = 2;
-		_scaler_proc = DotMatrix;
-		break;
-
-	default:
-		error("unknown gfx mode %d", _mode);
-	}
-
 	//
 	// Create the surface that contains the 8 bit game data
 	//
 	_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, _screenWidth, _screenHeight, 8, 0, 0, 0, 0);
 	if (_screen == NULL)
-		error("_screen failed");
+		error("allocating _screen failed");
 
 	//
 	// Create the surface that contains the scaled graphics in 16 bit mode
@@ -256,16 +223,31 @@
 		InitScalers(565);
 	
 	// Need some extra bytes around when using 2xSaI
-	uint16 *tmp_screen = (uint16 *)calloc(_tmpScreenWidth * (_screenHeight + 3), sizeof(uint16));
-	_tmpscreen = SDL_CreateRGBSurfaceFrom(tmp_screen,
-						_tmpScreenWidth, _screenHeight + 3, 16, _tmpScreenWidth * 2,
+	_tmpscreen = SDL_CreateRGBSurface(SDL_SWSURFACE,
+						_screenWidth + 3,
+						_screenHeight + 3,
+						16,
 						_hwscreen->format->Rmask,
 						_hwscreen->format->Gmask,
 						_hwscreen->format->Bmask,
 						_hwscreen->format->Amask);
 
 	if (_tmpscreen == NULL)
-		error("_tmpscreen failed");
+		error("allocating _tmpscreen failed");
+	
+#ifdef USE_OSD
+	_osdSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA,
+						_hwscreen->w,
+						_hwscreen->h,
+						16,
+						_hwscreen->format->Rmask,
+						_hwscreen->format->Gmask,
+						_hwscreen->format->Bmask,
+						_hwscreen->format->Amask);
+	if (_osdSurface == NULL)
+		error("allocating _osdSurface failed");
+	SDL_SetColorKey(_osdSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, kOSDColorKey);
+#endif
 
 	// keyboard cursor control, some other better place for it?
 	km.x_max = _screenWidth * _scaleFactor - 1;
@@ -286,10 +268,16 @@
 	}
 
 	if (_tmpscreen) {
-		free(_tmpscreen->pixels);
 		SDL_FreeSurface(_tmpscreen);
 		_tmpscreen = NULL;
 	}
+
+#ifdef USE_OSD
+	if (_osdSurface) {
+		SDL_FreeSurface(_osdSurface);
+		_osdSurface = NULL;
+	}
+#endif
 }
 
 void OSystem_SDL::hotswap_gfx_mode() {
@@ -304,6 +292,11 @@
 	// Release the HW screen surface
 	SDL_FreeSurface(_hwscreen); 
 
+#ifdef USE_OSD
+	// Release the OSD surface
+	SDL_FreeSurface(_osdSurface); 
+#endif
+
 	// Setup the new GFX mode
 	load_gfx_mode();
 
@@ -316,7 +309,6 @@
 	
 	// Free the old surfaces
 	SDL_FreeSurface(old_screen);
-	free(old_tmpscreen->pixels);
 	SDL_FreeSurface(old_tmpscreen);
 
 	// Blit everything to the screen
@@ -364,6 +356,26 @@
 		_forceFull = true;
 	}
 
+#ifdef USE_OSD
+	// OSD visible (i.e. non-transparent)?
+	if (_osdAlpha != SDL_ALPHA_TRANSPARENT) {
+		// Updated alpha value
+		const int diff = SDL_GetTicks() - _osdFadeStartTime;
+		if (diff > 0) {
+			if (diff >= kOSDFadeOutDuration) {
+				// Back to full transparency
+				_osdAlpha = SDL_ALPHA_TRANSPARENT;
+			} else {
+				// Do a linear fade out...
+				const int startAlpha = SDL_ALPHA_TRANSPARENT + kOSDInitialAlpha * (SDL_ALPHA_OPAQUE - SDL_ALPHA_TRANSPARENT) / 100;
+				_osdAlpha = startAlpha + diff * (SDL_ALPHA_TRANSPARENT - startAlpha) / kOSDFadeOutDuration;
+			}
+			SDL_SetAlpha(_osdSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, _osdAlpha);
+			_forceFull = true;
+		}
+	}
+#endif
+
 	// Force a full redraw if requested
 	if (_forceFull) {
 		_num_dirty_rects = 1;
@@ -453,6 +465,12 @@
 			_dirty_rect_list[0].h = effectiveScreenHeight();
 		}
 
+#ifdef USE_OSD
+		if (_osdAlpha != SDL_ALPHA_TRANSPARENT) {
+			SDL_BlitSurface(_osdSurface, 0, _hwscreen, 0);
+		}
+#endif
+
 		// Finally, blit all our changes to the screen
 		SDL_UpdateRects(_hwscreen, _num_dirty_rects, _dirty_rect_list);
 	}
@@ -488,11 +506,21 @@
 		if (!SDL_WM_ToggleFullScreen(_hwscreen)) {
 			// if ToggleFullScreen fails, achieve the same effect with hotswap gfx mode
 			hotswap_gfx_mode();
-		} else {
-			// Make sure that an EVENT_SCREEN_CHANGED gets sent later
-			_modeChanged = true;
 		}
 #endif
+			
+#ifdef USE_OSD
+		if (_full_screen)
+			displayMessageOnOSD("Fullscreen mode");
+		else
+			displayMessageOnOSD("Windowed mode");
+#endif
+
+		// Blit everything to the screen
+		internUpdateScreen();
+		
+		// Make sure that an EVENT_SCREEN_CHANGED gets sent later
+		_modeChanged = true;
 	}
 }
 
@@ -830,7 +858,7 @@
 	_forceFull = true;
 }
 
-void OSystem_SDL::grab_overlay(int16 *buf, int pitch) {
+void OSystem_SDL::grab_overlay(OverlayColor *buf, int pitch) {
 	if (!_overlayVisible)
 		return;
 
@@ -843,18 +871,18 @@
 	if (SDL_LockSurface(_tmpscreen) == -1)
 		error("SDL_LockSurface failed: %s", SDL_GetError());
 
-	int16 *src = (int16 *)_tmpscreen->pixels + _tmpScreenWidth + 1;
+	byte *src = (byte *)_tmpscreen->pixels + _tmpscreen->pitch + 2;	// Offset by one row, one column
 	int h = _screenHeight;
 	do {
 		memcpy(buf, src, _screenWidth*2);
-		src += _tmpScreenWidth;
+		src += _tmpscreen->pitch;
 		buf += pitch;
 	} while (--h);
 
 	SDL_UnlockSurface(_tmpscreen);
 }
 
-void OSystem_SDL::copy_rect_overlay(const int16 *buf, int pitch, int x, int y, int w, int h) {
+void OSystem_SDL::copy_rect_overlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) {
 	if (!_overlayVisible)
 		return;
 
@@ -894,21 +922,21 @@
 	if (SDL_LockSurface(_tmpscreen) == -1)
 		error("SDL_LockSurface failed: %s", SDL_GetError());
 
-	int16 *dst = (int16 *)_tmpscreen->pixels + (y + 1) * _tmpScreenWidth + (x + 1);
+	byte *dst = (byte *)_tmpscreen->pixels + (y + 1) * _tmpscreen->pitch + (x + 1) * 2;
 	do {
 		memcpy(dst, buf, w * 2);
-		dst += _tmpScreenWidth;
+		dst += _tmpscreen->pitch;
 		buf += pitch;
 	} while (--h);
 
 	SDL_UnlockSurface(_tmpscreen);
 }
 
-int16 OSystem_SDL::RGBToColor(uint8 r, uint8 g, uint8 b) {
+OverlayColor OSystem_SDL::RGBToColor(uint8 r, uint8 g, uint8 b) {
 	return SDL_MapRGB(_tmpscreen->format, r, g, b);
 }
 
-void OSystem_SDL::colorToRGB(int16 color, uint8 &r, uint8 &g, uint8 &b) {
+void OSystem_SDL::colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b) {
 	SDL_GetRGB(color, _tmpscreen->format, &r, &g, &b);
 }
 
@@ -1040,22 +1068,22 @@
 	
 	} else {
 		uint16 *bak = (uint16 *)_mouseBackup;	// Surface used to backup the area obscured by the mouse
-		uint16 *dst;					// Surface we are drawing into
+		byte *dst;					// Surface we are drawing into
 	
-		dst = (uint16 *)_tmpscreen->pixels + (y + 1) * _tmpScreenWidth + (x + 1);
+		dst = (byte *)_tmpscreen->pixels + (y + 1) * _tmpscreen->pitch + (x + 1) * 2;
 		while (h > 0) {
 			int width = w;
 			while (width > 0) {
-				*bak++ = *dst;
+				*bak++ = *(uint16 *)dst;
 				color = *src++;
 				if (color != 0xFF)	// 0xFF = transparent, don't draw
-					*dst = RGBToColor(_currentPalette[color].r, _currentPalette[color].g, _currentPalette[color].b);
-				dst++;
+					*(uint16 *)dst = RGBToColor(_currentPalette[color].r, _currentPalette[color].g, _currentPalette[color].b);
+				dst += 2;
 				width--;
 			}
 			src += _mouseCurState.w - w;
 			bak += MAX_MOUSE_W - w;
-			dst += _tmpScreenWidth - w;
+			dst += _tmpscreen->pitch - w * 2;
 			h--;
 		}
 	}
@@ -1113,13 +1141,14 @@
 	
 	} else {
 
-		uint16 *dst, *bak = (uint16 *)_mouseBackup;
+		byte *dst;
+		uint16 *bak = (uint16 *)_mouseBackup;
 	
 		// No need to do clipping here, since draw_mouse() did that already
-		dst = (uint16 *)_tmpscreen->pixels + (old_mouse_y + 1) * _tmpScreenWidth + (old_mouse_x + 1);
-		for (y = 0; y < old_mouse_h; ++y, bak += MAX_MOUSE_W, dst += _tmpScreenWidth) {
+		dst = (byte *)_tmpscreen->pixels + (old_mouse_y + 1) * _tmpscreen->pitch + (old_mouse_x + 1) * 2;
+		for (y = 0; y < old_mouse_h; ++y, bak += MAX_MOUSE_W, dst += _tmpscreen->pitch) {
 			for (x = 0; x < old_mouse_w; ++x) {
-				dst[x] = bak[x];
+				*((uint16 *)dst + x) = bak[x];
 			}
 		}
 	}
@@ -1128,3 +1157,61 @@
 
 	SDL_UnlockSurface(_overlayVisible ? _tmpscreen : _screen);
 }
+
+
+#pragma mark -
+#pragma mark --- Mouse ---
+#pragma mark -
+
+#ifdef USE_OSD
+void OSystem_SDL::displayMessageOnOSD(const char *msg) {
+	
+//	printf("displayMessageOnOSD(%s)\n", msg);
+	if (SDL_LockSurface(_osdSurface))
+		error("displayMessageOnOSD: SDL_LockSurface failed: %s", SDL_GetError());
+
+	GUI::Surface dst;
+	dst.pixels = _osdSurface->pixels;
+	dst.w = _osdSurface->w;
+	dst.h = _osdSurface->h;
+	dst.pitch = _osdSurface->pitch;
+	dst.bytesPerPixel = _osdSurface->format->BytesPerPixel;
+	
+	// Clear everything with the "transparent" color, i.e. the colorkey
+	SDL_FillRect(_osdSurface, 0, kOSDColorKey);
+
+	// Determine a rect which would contain the message string (clipped to the
+	// screen dimensions).
+	const int vOffset = 10;
+	int width = GUI::g_sysfont.getStringWidth(msg) + 16;
+	int height = GUI::g_sysfont.getFontHeight() + 2 * vOffset;
+	if (width > dst.w)
+		width = dst.w;
+	if (height > dst.h)
+		height = dst.h;
+
+	// Draw a dark gray rect
+	// TODO: Rounded corners ? Border?
+	SDL_Rect osdRect;
+	osdRect.x = (dst.w - width) / 2;
+	osdRect.y = (dst.h - height) / 2;
+	osdRect.w = width;
+	osdRect.h = height;
+	SDL_FillRect(_osdSurface, &osdRect, SDL_MapRGB(_osdSurface->format, 64, 64, 64));
+
+	// Render the message, centered, and in white
+	GUI::g_sysfont.drawString(&dst, msg, osdRect.x, osdRect.y + vOffset, osdRect.w,
+							SDL_MapRGB(_osdSurface->format, 255, 255, 255),
+							GUI::kTextAlignCenter);
+
+	SDL_UnlockSurface(_osdSurface);
+
+	// Init the OSD display parameters, and the fade out
+	_osdAlpha = SDL_ALPHA_TRANSPARENT +  kOSDInitialAlpha * (SDL_ALPHA_OPAQUE - SDL_ALPHA_TRANSPARENT) / 100;
+	_osdFadeStartTime = SDL_GetTicks() + kOSDFadeOutDelay;
+	SDL_SetAlpha(_osdSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, _osdAlpha);
+	
+	// Ensure a full redraw takes place next time the screen is updated
+	_forceFull = true;
+}
+#endif

Index: sdl-common.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/sdl/sdl-common.h,v
retrieving revision 1.53
retrieving revision 1.54
diff -u -d -r1.53 -r1.54
--- sdl-common.h	1 Mar 2004 01:44:36 -0000	1.53
+++ sdl-common.h	13 Mar 2004 14:19:08 -0000	1.54
@@ -31,6 +31,9 @@
 
 #include <SDL.h>
 
+// Uncomment this to enable the 'on screen display' code.
+#define USE_OSD	1
+
 class OSystem_SDL : public OSystem {
 public:
 	OSystem_SDL();
@@ -111,14 +114,14 @@
 	virtual void show_overlay();
 	virtual void hide_overlay();
 	virtual void clear_overlay();
-	virtual void grab_overlay(int16 *buf, int pitch);
-	virtual void copy_rect_overlay(const int16 *buf, int pitch, int x, int y, int w, int h);
+	virtual void grab_overlay(OverlayColor *buf, int pitch);
+	virtual void copy_rect_overlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h);
 	virtual int16 get_height();
 	virtual int16 get_width();
 
 	// Methods that convert RGB to/from colors suitable for the overlay.
-	virtual int16 RGBToColor(uint8 r, uint8 g, uint8 b);
-	virtual void colorToRGB(int16 color, uint8 &r, uint8 &g, uint8 &b);
+	virtual OverlayColor RGBToColor(uint8 r, uint8 g, uint8 b);
+	virtual void colorToRGB(OverlayColor color, uint8 &r, uint8 &g, uint8 &b);
 
 
 	virtual const GraphicsMode *getSupportedGraphicsModes() const;
@@ -136,6 +139,20 @@
 protected:
 	void init_intern();
 
+#ifdef USE_OSD
+	SDL_Surface *_osdSurface;
+	Uint8 _osdAlpha;			// Transparency level of the OSD
+	uint32 _osdFadeStartTime;	// When to start the fade out
+	enum {
+		kOSDFadeOutDelay = 2 * 1000,	// Delay before the OSD is faded out (in milliseconds)
+		kOSDFadeOutDuration = 500,		// Duration of the OSD fade out (in milliseconds)
+		kOSDColorKey = 1,
+		kOSDInitialAlpha = 80			// Initial alpha level, in percent
+	};
+	
+	void displayMessageOnOSD(const char *msg);
+#endif
+
 	// hardware screen
 	SDL_Surface *_hwscreen;
 
@@ -145,7 +162,6 @@
 
 	// temporary screen (for scalers/overlay)
 	SDL_Surface *_tmpscreen;
-	int _tmpScreenWidth;
 	bool _overlayVisible;
 
 	// CD Audio

Index: sdl.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/sdl/sdl.cpp,v
retrieving revision 1.65
retrieving revision 1.66
diff -u -d -r1.65 -r1.66
--- sdl.cpp	1 Mar 2004 01:41:22 -0000	1.65
+++ sdl.cpp	13 Mar 2004 14:19:08 -0000	1.66
@@ -56,6 +56,8 @@
 
 	cksum_valid = false;
 	_mode = GFX_DOUBLESIZE;
+	_scaleFactor = 2;
+	_scaler_proc = Normal2x;
 	_full_screen = ConfMan.getBool("fullscreen");
 	_adjustAspectRatio = ConfMan.getBool("aspect_ratio");
 	_mode_flags = 0;
@@ -74,8 +76,12 @@
 }
 
 OSystem_SDL::OSystem_SDL()
-	: _hwscreen(0), _screen(0), _screenWidth(0), _screenHeight(0),
-	_tmpscreen(0), _tmpScreenWidth(0), _overlayVisible(false),
+	:
+#ifdef USE_OSD
+	_osdSurface(0), _osdAlpha(SDL_ALPHA_TRANSPARENT), _osdFadeStartTime(0),
+#endif
+	_hwscreen(0), _screen(0), _screenWidth(0), _screenHeight(0),
+	_tmpscreen(0), _overlayVisible(false),
 	_cdrom(0), _scaler_proc(0), _modeChanged(false), _dirty_checksums(0),
 	_mouseVisible(false), _mouseDrawn(false), _mouseData(0),
 	_mouseHotspotX(0), _mouseHotspotY(0),
@@ -143,6 +149,19 @@
 			//assert(_hwscreen != 0);
 			_adjustAspectRatio ^= true;
 			hotswap_gfx_mode();
+			
+#ifdef USE_OSD
+			if (_adjustAspectRatio)
+				displayMessageOnOSD("Enabled aspect ratio correction");
+			else
+				displayMessageOnOSD("Disabled aspect ratio correction");
+#endif
+
+			// Blit everything to the screen
+			internUpdateScreen();
+			
+			// Make sure that an EVENT_SCREEN_CHANGED gets sent later
+			_modeChanged = true;
 		}
 		break;
 	case kFeatureAutoComputeDirtyRects:





More information about the Scummvm-git-logs mailing list