[Scummvm-cvs-logs] CVS: scummvm/backends/sdl sdl-common.cpp,1.3,1.4 sdl-common.h,1.2,1.3 sdl.cpp,1.3,1.4 sdl_gl.cpp,1.3,1.4

Max Horn fingolfin at users.sourceforge.net
Thu Sep 19 09:08:02 CEST 2002


Update of /cvsroot/scummvm/scummvm/backends/sdl
In directory usw-pr-cvs1:/tmp/cvs-serv18083/backends/sdl

Modified Files:
	sdl-common.cpp sdl-common.h sdl.cpp sdl_gl.cpp 
Log Message:
Added overlay to OSystem interface; implemented overlay in SDL backend (all other backends, including SDL_gl, still need to implement this!); changed NewGUI to make use of the overlay; added Cmd-Q as a shortcut for Quit on MacOS X

Index: sdl-common.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/sdl/sdl-common.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- sdl-common.cpp	9 Sep 2002 05:56:10 -0000	1.3
+++ sdl-common.cpp	19 Sep 2002 16:06:46 -0000	1.4
@@ -81,7 +81,7 @@
 	_cur_pal = (SDL_Color*)calloc(sizeof(SDL_Color), 256);
 
 	dirty_rect_list = (SDL_Rect*)calloc(NUM_DIRTY_RECT, sizeof(SDL_Rect));
-	_mouse_backup = (byte*)malloc(MAX_MOUSE_W * MAX_MOUSE_H * MAX_SCALING);
+	_mouse_backup = (byte*)malloc(MAX_MOUSE_W * MAX_MOUSE_H * MAX_SCALING * 2);
 	dirty_checksums = (uint32*)calloc(CKSUM_NUM*2, sizeof(uint32));
 
 	load_gfx_mode();
@@ -424,12 +424,15 @@
 		switch(ev.type) {
 		case SDL_KEYDOWN: {
 				byte b = 0;
-				if (ev.key.keysym.mod & KMOD_SHIFT) b |= KBD_SHIFT;
-				if (ev.key.keysym.mod & KMOD_CTRL) b |= KBD_CTRL;
-				if (ev.key.keysym.mod & KMOD_ALT) b |= KBD_ALT;
+				if (ev.key.keysym.mod & KMOD_SHIFT)
+					b |= KBD_SHIFT;
+				if (ev.key.keysym.mod & KMOD_CTRL)
+					b |= KBD_CTRL;
+				if (ev.key.keysym.mod & KMOD_ALT)
+					b |= KBD_ALT;
 				event->kbd.flags = b;
 
-				/* internal keypress? */				
+				// Alt-Return toggles full screen mode				
 				if (b == KBD_ALT && ev.key.keysym.sym==SDLK_RETURN) {
 					property(PROP_TOGGLE_FULLSCREEN, NULL);
 					break;
@@ -439,6 +442,7 @@
 					quit();
 					break;
 				}
+				// Ctr-Alt-1 till Ctrl-Alt-7 will change the GFX mode
 				if (b == (KBD_CTRL|KBD_ALT) && 
 				    (ev.key.keysym.sym>='1') && (ev.key.keysym.sym<='7')) {
 					Property prop;
@@ -446,20 +450,28 @@
 					property(PROP_SET_GFX_MODE, &prop);
 					break;
 				}
-				#ifdef QTOPIA
+#ifdef MACOSX
+				// quit on Cmd-Q on Mac
+				if ((ev.key.keysym.mod & KMOD_META) && ev.key.keysym.sym=='q') {
+					quit();
+					break;
+				}
+#endif
+
+#ifdef QTOPIA
 				// quit on fn+backspace on zaurus
-				if (ev.key.keysym.sym==127) {
+				if (ev.key.keysym.sym == 127) {
 					quit();
 					break;
 				}
 				// map menu key (f11) to f5 (scumm menu)
-				if (ev.key.keysym.sym==292) {
+				if (ev.key.keysym.sym == 292) {
 					event->event_code = EVENT_KEYDOWN;
 					event->kbd.keycode = 286;
 					event->kbd.ascii = mapKey(286, ev.key.keysym.mod);
 				}
 				// map center (space) to tab (default action )
-				// i wanted to map the calendar button but the calendar comes up
+				// I wanted to map the calendar button but the calendar comes up
 				//
 				else if (ev.key.keysym.sym==32) {
 					event->event_code = EVENT_KEYDOWN;
@@ -480,12 +492,11 @@
 					event->kbd.keycode = ev.key.keysym.sym;
 					event->kbd.ascii = mapKey(ev.key.keysym.sym, ev.key.keysym.mod);
 				}
-				#endif
-				#ifndef QTOPIA
+#else
 				event->event_code = EVENT_KEYDOWN;
 				event->kbd.keycode = ev.key.keysym.sym;
 				event->kbd.ascii = mapKey(ev.key.keysym.sym, ev.key.keysym.mod);
-				#endif
+#endif
 				
 				switch(ev.key.keysym.sym) {
 					case SDLK_LEFT:
@@ -718,8 +729,6 @@
 	if (SDL_LockSurface(sdl_screen) == -1)
 		error("SDL_LockSurface failed: %s.\n", SDL_GetError());
 
-	add_dirty_rect(x, y, w, h);
-
 	dst = (byte *)sdl_screen->pixels + y * SCREEN_WIDTH + x;
 	while (h > 0) {
 		int width = w;
@@ -739,6 +748,9 @@
 
 	SDL_UnlockSurface(sdl_screen);
 	
+	// Mark as dirty
+	add_dirty_rect(x, y, w, h);
+
 	// Finally, set the flag to indicate the mouse has been drawn
 	_mouse_drawn = true;
 }

Index: sdl-common.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/sdl/sdl-common.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- sdl-common.h	9 Sep 2002 05:56:10 -0000	1.2
+++ sdl-common.h	19 Sep 2002 16:06:47 -0000	1.3
@@ -106,17 +106,12 @@
 	static OSystem *create(int gfx_mode, bool full_screen);
 
 protected:
-	typedef void TwoXSaiProc(uint8 *srcPtr, uint32 srcPitch, uint8 *deltaPtr,
-								uint8 *dstPtr, uint32 dstPitch, int width, int height);
 
 	SDL_Surface *sdl_screen;      // unseen game screen
-	SDL_Surface *sdl_tmpscreen;   // temporary screen (for 2xsai)
 	SDL_CD *cdrom;
 
 	enum {
 		DF_WANT_RECT_OPTIM			= 1 << 0,
-		DF_REAL_8BIT				= 1 << 1,
-		DF_SEPARATE_TEMPSCREEN		= 1 << 2,
 		DF_UPDATE_EXPAND_1_PIXEL	= 1 << 3
 	};
 
@@ -166,7 +161,6 @@
 	int16 _mouse_hotspot_y;
 	int _current_shake_pos;
 	int _new_shake_pos;
-	TwoXSaiProc *_sai_func;
 	SDL_Color *_cur_pal;
 
 	uint _palette_changed_first, _palette_changed_last;
@@ -180,8 +174,8 @@
 	
 	void add_dirty_rect(int x, int y, int w, int h);
 
-	void draw_mouse();
-	void undraw_mouse();
+	virtual void draw_mouse();
+	virtual void undraw_mouse();
 
 	virtual void load_gfx_mode() = 0;
 	virtual void unload_gfx_mode() = 0;

Index: sdl.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/sdl/sdl.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- sdl.cpp	8 Sep 2002 01:08:11 -0000	1.3
+++ sdl.cpp	19 Sep 2002 16:06:47 -0000	1.4
@@ -24,6 +24,10 @@
 #include "common/scaler.h"
 #include "common/engine.h"	// Only #included for error() and warning()
 
+// FIXME - this macro assumes that we use 565 mode. But what if we are in 555 mode?
+#define RGB_TO_16(r,g,b)	((((r>>3)&0x1F) << 11) | (((g>>2)&0x3F) << 5) | ((b>>3)&0x1F))
+//#define RGB_TO_16(r,g,b)	((((r>>3)&0x1F) << 10) | (((g>>3)&0x1F) << 5) | ((b>>3)&0x1F))
+
 
 class OSystem_SDL_Normal : public OSystem_SDL_Common {
 public:
@@ -36,12 +40,31 @@
 	// Set a parameter
 	uint32 property(int param, Property *value);
 
+	// Overlay
+	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);
+
 protected:
+	typedef void ScalerProc(uint8 *srcPtr, uint32 srcPitch, uint8 *deltaPtr,
+								uint8 *dstPtr, uint32 dstPitch, int width, int height);
+
+	SDL_Surface *sdl_tmpscreen;   // temporary screen (for scalers/overlay)
 	SDL_Surface *sdl_hwscreen;    // hardware screen
+	bool _overlay_visible;
 
-	void load_gfx_mode();
-	void unload_gfx_mode();
+	ScalerProc *_scaler_proc;
+
+	virtual void draw_mouse();
+	virtual void undraw_mouse();
+
+	virtual void load_gfx_mode();
+	virtual void unload_gfx_mode();
 	void hotswap_gfx_mode();
+	
+	int TMP_SCREEN_WIDTH;
 };
 
 OSystem_SDL_Common *OSystem_SDL_Common::create() {
@@ -52,7 +75,7 @@
 	const byte *b = colors;
 	uint i;
 	SDL_Color *base = _cur_pal + start;
-	for(i=0;i!=num;i++) {
+	for(i = 0; i < num; i++) {
 		base[i].r = b[0];
 		base[i].g = b[1];
 		base[i].b = b[2];
@@ -66,34 +89,151 @@
 		_palette_changed_last = start + num;
 }
 
+void OSystem_SDL_Normal::draw_mouse() {
+	if (!_overlay_visible) {
+		OSystem_SDL_Common::draw_mouse();
+	}
+
+
+	if (_mouse_drawn || !_mouse_visible)
+		return;
+
+	int x = _mouse_cur_state.x - _mouse_hotspot_x;
+	int y = _mouse_cur_state.y - _mouse_hotspot_y;
+	int w = _mouse_cur_state.w;
+	int h = _mouse_cur_state.h;
+	byte color;
+	byte *src = _mouse_data;		// Image representing the mouse
+	uint16 *bak = (uint16*)_mouse_backup;	// Surface used to backup the area obscured by the mouse
+	uint16 *dst;					// Surface we are drawing into
+
+	// clip the mouse rect, and addjust the src pointer accordingly
+	if (x < 0) {
+		w += x;
+		src -= x;
+		x = 0;
+	}
+	if (y < 0) {
+		h += y;
+		src -= y * _mouse_cur_state.w;
+		y = 0;
+	}
+	if (w > SCREEN_WIDTH - x)
+		w = SCREEN_WIDTH - x;
+	if (h > SCREEN_HEIGHT - y)
+		h = SCREEN_HEIGHT - y;
+
+	// Adjust for tmp_screen offset
+	x++;
+	y++;
+
+	// Store the bounding box so that undraw mouse can restore the area the
+	// mouse currently covers to its original content.
+	_mouse_old_state.x = x;
+	_mouse_old_state.y = y;
+	_mouse_old_state.w = w;
+	_mouse_old_state.h = h;
+
+	// Quick check to see if anything has to be drawn at all
+	if (w <= 0 || h <= 0)
+		return;
+
+	// Draw the mouse cursor; backup the covered area in "bak"
+
+	if (SDL_LockSurface(sdl_tmpscreen) == -1)
+		error("SDL_LockSurface failed: %s.\n", SDL_GetError());
+
+	dst = (uint16 *)sdl_tmpscreen->pixels + y * TMP_SCREEN_WIDTH + x;
+	while (h > 0) {
+		int width = w;
+		while (width > 0) {
+			*bak++ = *dst;
+			color = *src++;
+			if (color != 0xFF)	// 0xFF = transparent, don't draw
+				*dst = RGB_TO_16(_cur_pal[color].r, _cur_pal[color].g, _cur_pal[color].b);
+			dst++;
+			width--;
+		}
+		src += _mouse_cur_state.w - w;
+		bak += MAX_MOUSE_W - w;
+		dst += TMP_SCREEN_WIDTH - w;
+		h--;
+	}
+
+	SDL_UnlockSurface(sdl_tmpscreen);
+	
+	// Mark as dirty
+	add_dirty_rect(x, y, w, h);
+
+	// Finally, set the flag to indicate the mouse has been drawn
+	_mouse_drawn = true;
+}
+
+void OSystem_SDL_Normal::undraw_mouse() {
+	if (!_overlay_visible) {
+		OSystem_SDL_Common::undraw_mouse();
+	}
+
+
+	if (!_mouse_drawn)
+		return;
+	_mouse_drawn = false;
+
+	uint16 *dst, *bak = (uint16 *)_mouse_backup;
+	const int old_mouse_x = _mouse_old_state.x;
+	const int old_mouse_y = _mouse_old_state.y;
+	const int old_mouse_w = _mouse_old_state.w;
+	const int old_mouse_h = _mouse_old_state.h;
+	int x,y;
+
+	if (SDL_LockSurface(sdl_tmpscreen) == -1)
+		error("SDL_LockSurface failed: %s.\n", SDL_GetError());
+
+	// No need to do clipping here, since draw_mouse() did that already
+
+	dst = (uint16 *)sdl_tmpscreen->pixels + old_mouse_y * TMP_SCREEN_WIDTH + old_mouse_x;
+	for (y = 0; y < old_mouse_h; ++y, bak += MAX_MOUSE_W, dst += TMP_SCREEN_WIDTH) {
+		for (x = 0; x < old_mouse_w; ++x) {
+			dst[x] = bak[x];
+		}
+	}
+
+	add_dirty_rect(old_mouse_x, old_mouse_y, old_mouse_w, old_mouse_h);
+
+	SDL_UnlockSurface(sdl_tmpscreen);
+}
+
 void OSystem_SDL_Normal::load_gfx_mode() {
 	force_full = true;
 	scaling = 1;
 	_mode_flags = 0;
+	_overlay_visible = false;
 
-	_sai_func = NULL;
+	_scaler_proc = NULL;
 	sdl_tmpscreen = NULL;
+	TMP_SCREEN_WIDTH = (SCREEN_WIDTH + 3);
 	
 	switch(_mode) {
 	case GFX_2XSAI:
 		scaling = 2;
-		_sai_func = _2xSaI;
+		_scaler_proc = _2xSaI;
 		break;
 	case GFX_SUPER2XSAI:
 		scaling = 2;
-		_sai_func = Super2xSaI;
+		_scaler_proc = Super2xSaI;
 		break;
 	case GFX_SUPEREAGLE:
 		scaling = 2;
-		_sai_func = SuperEagle;
+		_scaler_proc = SuperEagle;
 		break;
 	case GFX_ADVMAME2X:
 		scaling = 2;
-		_sai_func = AdvMame2x;
+		_scaler_proc = AdvMame2x;
 		break;
 
 	case GFX_DOUBLESIZE:
 		scaling = 2;
+		_scaler_proc = Normal2x;
 		break;
 
 	case GFX_TRIPLESIZE:
@@ -102,11 +242,13 @@
 			goto normal_mode;
 		}
 		scaling = 3;
+		_scaler_proc = Normal3x;
 		break;
 
 	case GFX_NORMAL:
 normal_mode:;
 		scaling = 1;
+		_scaler_proc = Normal1x;
 		break;
 	}
 
@@ -114,55 +256,30 @@
 	if (sdl_screen == NULL)
 		error("sdl_screen failed failed");
 
-	if (_sai_func) {
-		uint16 *tmp_screen = (uint16*)calloc((SCREEN_WIDTH+3)*(SCREEN_HEIGHT+3),sizeof(uint16));
-		_mode_flags = DF_WANT_RECT_OPTIM | DF_SEPARATE_TEMPSCREEN | DF_UPDATE_EXPAND_1_PIXEL;
-
-		sdl_hwscreen = SDL_SetVideoMode(SCREEN_WIDTH * scaling, SCREEN_HEIGHT * scaling, 16, 
-			_full_screen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
-		);
-		if (sdl_hwscreen == NULL)
-			error("sdl_hwscreen failed");
-		
-		/* Need some extra bytes around when using 2XSAI */
-		if (sdl_hwscreen->format->Rmask == 0x7C00)	// HACK HACK HACK
-			Init_2xSaI(555);
-		else
-			Init_2xSaI(565);
-		sdl_tmpscreen = SDL_CreateRGBSurfaceFrom(tmp_screen,
-							SCREEN_WIDTH + 3, SCREEN_HEIGHT + 3, 16, (SCREEN_WIDTH + 3)*2,
-							sdl_hwscreen->format->Rmask,
-							sdl_hwscreen->format->Gmask,
-							sdl_hwscreen->format->Bmask,
-							sdl_hwscreen->format->Amask);
-
-		if (sdl_tmpscreen == NULL)
-			error("sdl_tmpscreen failed");
-		
-	} else {
-		switch(scaling) {
-		case 3:
-			_sai_func = Normal3x;
-			break;
-		case 2:
-			_sai_func = Normal2x;
-			break;
-		case 1:
-			_sai_func = Normal1x;
-			break;
-		}
-
-		_mode_flags = DF_WANT_RECT_OPTIM | DF_REAL_8BIT;
+	uint16 *tmp_screen = (uint16*)calloc(TMP_SCREEN_WIDTH*(SCREEN_HEIGHT+3),sizeof(uint16));
+	_mode_flags = DF_WANT_RECT_OPTIM | DF_UPDATE_EXPAND_1_PIXEL;
 
-		sdl_hwscreen = SDL_SetVideoMode(SCREEN_WIDTH * scaling, SCREEN_HEIGHT * scaling, 8, 
-			_full_screen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
-		);
-		if (sdl_hwscreen == NULL)
-			error("sdl_hwscreen failed");
-		
-		sdl_tmpscreen = sdl_screen;
-	}
+	sdl_hwscreen = SDL_SetVideoMode(SCREEN_WIDTH * scaling, SCREEN_HEIGHT * scaling, 16, 
+		_full_screen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
+	);
+	if (sdl_hwscreen == NULL)
+		error("sdl_hwscreen failed");
+	
+	/* Need some extra bytes around when using 2XSAI */
+	if (sdl_hwscreen->format->Rmask == 0x7C00)	// HACK HACK HACK
+		Init_2xSaI(555);
+	else
+		Init_2xSaI(565);
+	sdl_tmpscreen = SDL_CreateRGBSurfaceFrom(tmp_screen,
+						TMP_SCREEN_WIDTH, SCREEN_HEIGHT + 3, 16, TMP_SCREEN_WIDTH*2,
+						sdl_hwscreen->format->Rmask,
+						sdl_hwscreen->format->Gmask,
+						sdl_hwscreen->format->Bmask,
+						sdl_hwscreen->format->Amask);
 
+	if (sdl_tmpscreen == NULL)
+		error("sdl_tmpscreen failed");
+	
 	// keyboard cursor control, some other better place for it?
 	km.x_max = SCREEN_WIDTH * scaling - 1;
 	km.y_max = SCREEN_HEIGHT * scaling - 1;
@@ -182,11 +299,11 @@
 		sdl_hwscreen = NULL;
 	}
 	
-	if (_mode_flags & DF_SEPARATE_TEMPSCREEN) {
+	if (sdl_tmpscreen) {
 		free((uint16*)sdl_tmpscreen->pixels);
 		SDL_FreeSurface(sdl_tmpscreen);
+		sdl_tmpscreen = NULL;
 	}
-	sdl_tmpscreen = NULL;
 }
 
 void OSystem_SDL_Normal::update_screen() {
@@ -194,14 +311,12 @@
 	if (sdl_hwscreen == NULL)
 		return;	// Can this really happen?
 
-	/* First make sure the mouse is drawn, if it should be drawn. */
+	// First make sure the mouse is drawn, if it should be drawn.
 	draw_mouse();
 	
-	/* Palette update in case we are NOT in "real" 8 bit color mode.
-	 * Must take place before updating the screen, since the palette must
-	 * be set up for conversion from 8bit to 16bit.
-	 */ 
-	if (((_mode_flags & DF_REAL_8BIT) == 0) && _palette_changed_last != 0) {
+	// Check whether the palette was changed in the meantime and update the
+	// screen surface accordingly. 
+	if (_palette_changed_last != 0) {
 		SDL_SetColors(sdl_screen, _cur_pal + _palette_changed_first, 
 			_palette_changed_first,
 			_palette_changed_last - _palette_changed_first);
@@ -222,7 +337,7 @@
 		force_full = true;
 	}
 
-	/* force a full redraw if requested */
+	// Force a full redraw if requested
 	if (force_full) {
 		num_dirty_rects = 1;
 
@@ -232,20 +347,20 @@
 		dirty_rect_list[0].h = SCREEN_HEIGHT;
 	}
 
-	/* Only draw anything if necessary */
+	// Only draw anything if necessary
 	if (num_dirty_rects > 0) {
 	
 		SDL_Rect *r; 
 		uint32 srcPitch, dstPitch;
 		SDL_Rect *last_rect = dirty_rect_list + num_dirty_rects;
 	
-		/* Convert appropriate parts of the image into 16bpp */
-		if ((_mode_flags & DF_REAL_8BIT) == 0) {
+		// Convert appropriate parts of the 8bpp image into 16bpp
+		if (!_overlay_visible) {
 			SDL_Rect dst;
 			for(r=dirty_rect_list; r!=last_rect; ++r) {
 				dst = *r;
-				dst.x++;
-				dst.y++;
+				dst.x++;	// Shift rect by one since 2xSai needs to acces the data around
+				dst.y++;	// any pixel to scale it, and we want to avoid mem access crashes.
 				if (SDL_BlitSurface(sdl_screen, r, sdl_tmpscreen, &dst) != 0)
 					error("SDL_BlitSurface failed: %s", SDL_GetError());
 			}
@@ -257,46 +372,24 @@
 		srcPitch = sdl_tmpscreen->pitch;
 		dstPitch = sdl_hwscreen->pitch;
 	
-		if ((_mode_flags & DF_REAL_8BIT) == 0) {
-			for(r=dirty_rect_list; r!=last_rect; ++r) {
-				register int dst_y = r->y + _current_shake_pos;
-				register int dst_h = 0;
-				if (dst_y < SCREEN_HEIGHT) {
-					dst_h = r->h;
-					if (dst_h > SCREEN_HEIGHT - dst_y)
-						dst_h = SCREEN_HEIGHT - dst_y;
-					
-					r->x <<= 1;
-					dst_y <<= 1;
-					
-					_sai_func((byte*)sdl_tmpscreen->pixels + (r->x+2) + (r->y+1)*srcPitch, srcPitch, NULL, 
-						(byte*)sdl_hwscreen->pixels + r->x*scaling + dst_y*dstPitch, dstPitch, r->w, dst_h);
-				}
+		for(r=dirty_rect_list; r!=last_rect; ++r) {
+			register int dst_y = r->y + _current_shake_pos;
+			register int dst_h = 0;
+			if (dst_y < SCREEN_HEIGHT) {
+				dst_h = r->h;
+				if (dst_h > SCREEN_HEIGHT - dst_y)
+					dst_h = SCREEN_HEIGHT - dst_y;
 				
-				r->y = dst_y;
-				r->w <<= 1;
-				r->h = dst_h << 1;
-			}
-		} else {
-			for(r=dirty_rect_list; r!=last_rect; ++r) {
-				register int dst_y = r->y + _current_shake_pos;
-				register int dst_h = 0;
-				if (dst_y < SCREEN_HEIGHT) {
-					dst_h = r->h;
-					if (dst_h > SCREEN_HEIGHT - dst_y)
-						dst_h = SCREEN_HEIGHT - dst_y;
-					
-					dst_y *= scaling;
-					
-					_sai_func((byte*)sdl_tmpscreen->pixels + r->x + r->y*srcPitch, srcPitch, NULL, 
-						(byte*)sdl_hwscreen->pixels + r->x*scaling + dst_y*dstPitch, dstPitch, r->w, dst_h);
-				}
+				dst_y *= scaling;
 				
-				r->x *= scaling;
-				r->y = dst_y;
-				r->w *= scaling;
-				r->h = dst_h * scaling;
+				_scaler_proc((byte*)sdl_tmpscreen->pixels + (r->x*2+2) + (r->y+1)*srcPitch, srcPitch, NULL, 
+					(byte*)sdl_hwscreen->pixels + r->x*2*scaling + dst_y*dstPitch, dstPitch, r->w, dst_h);
 			}
+			
+			r->x *= scaling;
+			r->y = dst_y;
+			r->w *= scaling;
+			r->h = dst_h * scaling;
 		}
 	
 		if (force_full) {
@@ -308,19 +401,6 @@
 		SDL_UnlockSurface(sdl_hwscreen);
 	}
 	
-	/* Palette update in case we are in "real" 8 bit color mode.
-	 * Must take place after the screen data was updated, since with
-	 * "real" 8bit mode, palatte changes may be visible immediatly,
-	 * and we want to avoid any ugly effects.
-	 */
-	if (_mode_flags & DF_REAL_8BIT && _palette_changed_last != 0) {
-		SDL_SetColors(sdl_hwscreen, _cur_pal + _palette_changed_first, 
-			_palette_changed_first,
-			_palette_changed_last - _palette_changed_first);
-		
-		_palette_changed_last = 0;
-	}
-	
 	if (num_dirty_rects > 0) {
 		/* Finally, blit all our changes to the screen */
 		SDL_UpdateRects(sdl_hwscreen, num_dirty_rects, dirty_rect_list);
@@ -345,13 +425,10 @@
 
 	force_full = true;
 
-	/* reset palette */
-	if (_mode_flags & DF_REAL_8BIT)
-		SDL_SetColors(sdl_hwscreen, _cur_pal, 0, 256);
-	else
-		SDL_SetColors(sdl_screen, _cur_pal, 0, 256);
+	// reset palette
+	SDL_SetColors(sdl_screen, _cur_pal, 0, 256);
 
-	/* blit image */
+	// blit image
 	OSystem_SDL_Normal::copy_rect(bak_mem, SCREEN_WIDTH, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
 	free(bak_mem);
 
@@ -372,3 +449,102 @@
 	
 	return OSystem_SDL_Common::property(param, value);
 }
+
+
+void OSystem_SDL_Normal::show_overlay()
+{
+	// hide the mouse
+	undraw_mouse();
+
+	_overlay_visible = true;
+	clear_overlay();
+}
+
+void OSystem_SDL_Normal::hide_overlay()
+{
+	_overlay_visible = false;
+	force_full = true;
+}
+
+void OSystem_SDL_Normal::clear_overlay()
+{
+	if (!_overlay_visible)
+		return;
+	
+	// hide the mouse
+	undraw_mouse();
+
+	// Clear the overlay by making the game screen "look through" everywhere.
+	SDL_Rect src, dst;
+	src.x = src.y = 0;
+	dst.x = dst.y = 1;
+	src.w = dst.w = SCREEN_WIDTH;
+	src.h = dst.h = SCREEN_HEIGHT;
+	if (SDL_BlitSurface(sdl_screen, &src, sdl_tmpscreen, &dst) != 0)
+		error("SDL_BlitSurface failed: %s", SDL_GetError());
+
+	force_full = true;
+}
+
+void OSystem_SDL_Normal::grab_overlay(int16 *buf, int pitch)
+{
+	if (!_overlay_visible)
+		return;
+
+	if (sdl_tmpscreen == NULL)
+		return;
+
+	// hide the mouse
+	undraw_mouse();
+
+	if (SDL_LockSurface(sdl_tmpscreen) == -1)
+		error("SDL_LockSurface failed: %s.\n", SDL_GetError());
+
+	int16 *src = (int16 *)sdl_tmpscreen->pixels + TMP_SCREEN_WIDTH + 1;
+	int h = SCREEN_HEIGHT;
+	do {
+		memcpy(buf, src, SCREEN_WIDTH*2);
+		src += TMP_SCREEN_WIDTH;
+		buf += pitch;
+	} while (--h);
+
+	SDL_UnlockSurface(sdl_tmpscreen);
+}
+
+void OSystem_SDL_Normal::copy_rect_overlay(const int16 *buf, int pitch, int x, int y, int w, int h)
+{
+	if (!_overlay_visible)
+		return;
+
+	if (sdl_tmpscreen == NULL)
+		return;
+
+	// Clip the coordinates
+	if (x < 0) { w+=x; buf-=x; x = 0; }
+	if (y < 0) { h+=y; buf-=y*pitch; y = 0; }
+	if (w > SCREEN_WIDTH-x) { w = SCREEN_WIDTH - x; }
+	if (h > SCREEN_HEIGHT-y) { h = SCREEN_HEIGHT - y; }
+	if (w <= 0 || h <= 0)
+		return;
+	
+	// Mark the modified region as dirty
+	cksum_valid = false;
+	add_dirty_rect(x, y, w, h);
+
+	/* FIXME: undraw mouse only if the draw rect intersects with the mouse rect */
+	undraw_mouse();
+
+	if (SDL_LockSurface(sdl_tmpscreen) == -1)
+		error("SDL_LockSurface failed: %s.\n", SDL_GetError());
+
+	int16 *dst = (int16 *)sdl_tmpscreen->pixels + (y+1) * TMP_SCREEN_WIDTH + (x+1);
+	do {
+		memcpy(dst, buf, w*2);
+		dst += TMP_SCREEN_WIDTH;
+		buf += pitch;
+	} while (--h);
+
+	SDL_UnlockSurface(sdl_tmpscreen);
+}
+
+

Index: sdl_gl.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/sdl/sdl_gl.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- sdl_gl.cpp	8 Sep 2002 01:08:11 -0000	1.3
+++ sdl_gl.cpp	19 Sep 2002 16:06:48 -0000	1.4
@@ -47,6 +47,13 @@
 	// Set a parameter
 	uint32 property(int param, Property *value);
 
+	// Overlay
+	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);
+
 protected:
 	FB2GL fb2gl;
 
@@ -78,22 +85,14 @@
 void OSystem_SDL_GL::load_gfx_mode() {
 	int gl_flags =  FB2GL_320 | FB2GL_PITCH; 
 	force_full = true;
-	scaling = 1;
+	scaling = 2;
 	_mode_flags = 0;
-
-	_sai_func = NULL;
-	sdl_tmpscreen = NULL;
-
-	/* It's easier to work with 8 bit (256 colors) */
-	_mode_flags |= DF_REAL_8BIT;
 	
 	sdl_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, SCREEN_WIDTH, SCREEN_HEIGHT, 8, 0, 0, 0, 0);
 	if (sdl_screen == NULL)
 		error("sdl_screen failed failed");
 
-	_sai_func = Normal1x;
-
-	_mode_flags = DF_WANT_RECT_OPTIM | DF_REAL_8BIT;
+	_mode_flags = DF_WANT_RECT_OPTIM;
 
 	if (_full_screen) gl_flags |= (FB2GL_FS);
 	
@@ -109,8 +108,6 @@
 	}
 
 	SDL_SetGamma(1.25,1.25,1.25);
-	  
-	sdl_tmpscreen = sdl_screen;
 }
 
 void OSystem_SDL_GL::unload_gfx_mode() {
@@ -118,12 +115,6 @@
 		SDL_FreeSurface(sdl_screen);
 		sdl_screen = NULL; 
 	}
-
-	if (_mode_flags & DF_SEPARATE_TEMPSCREEN) {
-		free((uint16*)sdl_tmpscreen->pixels);
-		SDL_FreeSurface(sdl_tmpscreen);
-	}
-	sdl_tmpscreen = NULL;
 }
 
 void OSystem_SDL_GL::update_screen() {
@@ -150,7 +141,7 @@
 		_palette_changed_last = 0;
 	}
 
-	fb2gl.update(sdl_tmpscreen->pixels,320,200,320,0,_current_shake_pos);
+	fb2gl.update(sdl_screen->pixels,320,200,320,0,_current_shake_pos);
 
 }
 
@@ -168,7 +159,7 @@
 	load_gfx_mode();
 
 	fb2gl.setPalette(0,256);
-	fb2gl.update(sdl_tmpscreen->pixels,320,200,320,0,_current_shake_pos);
+	fb2gl.update(sdl_screen->pixels,320,200,320,0,_current_shake_pos);
 
 	/* blit image */
 	copy_rect(bak_mem, SCREEN_WIDTH, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);





More information about the Scummvm-git-logs mailing list