[Scummvm-cvs-logs] CVS: scummvm/backends/sdl events.cpp,NONE,1.1 graphics.cpp,NONE,1.1 build.rules,1.4,1.5 module.mk,1.1,1.2 sdl-common.h,1.50,1.51 sdl.cpp,1.63,1.64 sdl-common.cpp,1.111,NONE

Max Horn fingolfin at users.sourceforge.net
Sat Feb 28 17:08:20 CET 2004


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

Modified Files:
	build.rules module.mk sdl-common.h sdl.cpp 
Added Files:
	events.cpp graphics.cpp 
Removed Files:
	sdl-common.cpp 
Log Message:
merged OSystem_SDL and OSystem_SDL_Common; split SDL backend into multiple source files

--- NEW FILE: events.cpp ---
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2001  Ludvig Strigeus
 * Copyright (C) 2001-2004 The ScummVM project
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Header: /cvsroot/scummvm/scummvm/backends/sdl/events.cpp,v 1.1 2004/02/29 00:49:40 fingolfin Exp $
 *
 */

#include "backends/sdl/sdl-common.h"
#include "common/util.h"

// FIXME move joystick defines out and replace with confile file options
// we should really allow users to map any key to a joystick button
#define JOY_DEADZONE 3200
#define JOY_ANALOG
// #define JOY_INVERT_Y
#define JOY_XAXIS 0
#define JOY_YAXIS 1
// buttons
#define JOY_BUT_LMOUSE 0
#define JOY_BUT_RMOUSE 2
#define JOY_BUT_ESCAPE 3
#define JOY_BUT_PERIOD 1
#define JOY_BUT_SPACE 4
#define JOY_BUT_F5 5


static const int s_gfxModeSwitchTable[][4] = {
		{ GFX_NORMAL, GFX_DOUBLESIZE, GFX_TRIPLESIZE, -1 },
		{ GFX_NORMAL, GFX_ADVMAME2X, GFX_ADVMAME3X, -1 },
		{ GFX_NORMAL, GFX_HQ2X, GFX_HQ3X, -1 },
		{ GFX_NORMAL, GFX_2XSAI, -1, -1 },
		{ GFX_NORMAL, GFX_SUPER2XSAI, -1, -1 },
		{ GFX_NORMAL, GFX_SUPEREAGLE, -1, -1 },
		{ GFX_NORMAL, GFX_TV2X, -1, -1 },
		{ GFX_NORMAL, GFX_DOTMATRIX, -1, -1 }
	};



static int mapKey(SDLKey key, SDLMod mod, Uint16 unicode)
{
	if (key >= SDLK_F1 && key <= SDLK_F9) {
		return key - SDLK_F1 + 315;
	} else if (key >= SDLK_KP0 && key <= SDLK_KP9) {
		return key - SDLK_KP0 + '0';
	} else if (key >= SDLK_UP && key <= SDLK_PAGEDOWN) {
		return key;
	} else if (unicode) {
		return unicode;
	} else if (key >= 'a' && key <= 'z' && mod & KMOD_SHIFT) {
		return key & ~0x20;
	} else if (key >= SDLK_NUMLOCK && key <= SDLK_EURO) {
		return 0;
	}
	return key;
}

void OSystem_SDL::fillMouseEvent(Event &event, int x, int y) {
	event.mouse.x = x;
	event.mouse.y = y;
	
	// Update the "keyboard mouse" coords
	km.x = event.mouse.x;
	km.y = event.mouse.y;

	// Adjust for the screen scaling
	event.mouse.x /= _scaleFactor;
	event.mouse.y /= _scaleFactor;

	// Optionally perform aspect ratio adjusting
	if (_adjustAspectRatio)
		event.mouse.y = aspect2Real(event.mouse.y);
}

void OSystem_SDL::kbd_mouse() {
	uint32 curTime = get_msecs();
	if (curTime >= km.last_time + km.delay_time) {
		km.last_time = curTime;
		if (km.x_down_count == 1) {
			km.x_down_time = curTime;
			km.x_down_count = 2;
		}
		if (km.y_down_count == 1) {
			km.y_down_time = curTime;
			km.y_down_count = 2;
		}

		if (km.x_vel || km.y_vel) {
			if (km.x_down_count) {
				if (curTime > km.x_down_time + km.delay_time * 12) {
					if (km.x_vel > 0)
						km.x_vel++;
					else
						km.x_vel--;
				} else if (curTime > km.x_down_time + km.delay_time * 8) {
					if (km.x_vel > 0)
						km.x_vel = 5;
					else
						km.x_vel = -5;
				}
			}
			if (km.y_down_count) {
				if (curTime > km.y_down_time + km.delay_time * 12) {
					if (km.y_vel > 0)
						km.y_vel++;
					else
						km.y_vel--;
				} else if (curTime > km.y_down_time + km.delay_time * 8) {
					if (km.y_vel > 0)
						km.y_vel = 5;
					else
						km.y_vel = -5;
				}
			}

			km.x += km.x_vel;
			km.y += km.y_vel;

			if (km.x < 0) {
				km.x = 0;
				km.x_vel = -1;
				km.x_down_count = 1;
			} else if (km.x > km.x_max) {
				km.x = km.x_max;
				km.x_vel = 1;
				km.x_down_count = 1;
			}

			if (km.y < 0) {
				km.y = 0;
				km.y_vel = -1;
				km.y_down_count = 1;
			} else if (km.y > km.y_max) {
				km.y = km.y_max;
				km.y_vel = 1;
				km.y_down_count = 1;
			}

			SDL_WarpMouse(km.x, km.y);
		}
	}
}

bool OSystem_SDL::poll_event(Event *event) {
	SDL_Event ev;
	int axis;
	byte b = 0;
	
	kbd_mouse();
	
	// If the screen mode changed, send an EVENT_SCREEN_CHANGED
	if (_modeChanged) {
		_modeChanged = false;
		event->event_code = EVENT_SCREEN_CHANGED;
		return true;
	}

	while(SDL_PollEvent(&ev)) {
		switch(ev.type) {
		case SDL_KEYDOWN:
#ifdef LINUPY
			// Yopy has no ALT key, steal the SHIFT key 
			// (which isn't used much anyway)
			if (ev.key.keysym.mod & KMOD_SHIFT)
				b |= KBD_ALT;
			if (ev.key.keysym.mod & KMOD_CTRL)
				b |= KBD_CTRL;
#else
			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;
#endif
			event->kbd.flags = b;

			// Alt-Return toggles full screen mode				
			if (b == KBD_ALT && ev.key.keysym.sym == SDLK_RETURN) {
				setFeatureState(kFeatureFullscreenMode, !_full_screen);
				break;
			}

			// Alt-S: Create a screenshot
			if (b == KBD_ALT && ev.key.keysym.sym == 's') {
				char filename[20];

				for (int n = 0;; n++) {
					SDL_RWops *file;

					sprintf(filename, "scummvm%05d.bmp", n);
					file = SDL_RWFromFile(filename, "r");
					if (!file)
						break;
					SDL_RWclose(file);
				}
				if (save_screenshot(filename))
					printf("Saved '%s'\n", filename);
				else
					printf("Could not save screenshot!\n");
				break;
			}

			// Ctrl-m toggles mouse capture
			if (b == KBD_CTRL && ev.key.keysym.sym == 'm') {
				toggleMouseGrab();
				break;
			}

#ifdef MACOSX
			// On Macintosh', Cmd-Q quits
			if ((ev.key.keysym.mod & KMOD_META) && ev.key.keysym.sym == 'q') {
				event->event_code = EVENT_QUIT;
				return true;
			}
#else
			// Ctrl-z and Alt-X quit
			if ((b == KBD_CTRL && ev.key.keysym.sym == 'z') || (b == KBD_ALT && ev.key.keysym.sym == 'x')) {
				event->event_code = EVENT_QUIT;
				return true;
			}
#endif

			// Ctrl-Alt-<key> will change the GFX mode
			if ((b & (KBD_CTRL|KBD_ALT)) == (KBD_CTRL|KBD_ALT)) {
				// FIXME EVIL HACK: This shouldn't be a static int, rather it
				// should be a member variable. Furthermore, it shouldn't be
				// set in this code, rather it should be set by load_gfx_mode().
				// But for now this quick&dirty hack works.
				static int _scalerType = 0;
				if (_mode != GFX_NORMAL) {
					// Try to figure out which gfx mode "group" we are in
					// This is just a temporary hack until the proper solution
					// (i.e. code in load_gfx_mode()) is in effect.
					for (int i = 0; i < ARRAYSIZE(s_gfxModeSwitchTable); i++) {
						if (s_gfxModeSwitchTable[i][1] == _mode || s_gfxModeSwitchTable[i][2] == _mode) {
							_scalerType = i;
							break;
						}
					}
				}
				
				int factor = _scaleFactor - 1;

				// Ctrl-Alt-a toggles aspect ratio correction
				if (ev.key.keysym.sym == 'a') {
					setFeatureState(kFeatureAspectRatioCorrection, !_adjustAspectRatio);
					break;
				}

				// Increase/decrease the scale factor
				// TODO: Shall we 'wrap around' here?
				if (ev.key.keysym.sym == '=' || ev.key.keysym.sym == '+' || ev.key.keysym.sym == '-') {
					factor += (ev.key.keysym.sym == '-' ? -1 : +1);
					if (0 <= factor && factor < 4 && s_gfxModeSwitchTable[_scalerType][factor] >= 0) {
						setGraphicsMode(s_gfxModeSwitchTable[_scalerType][factor]);
					}
					break;
				}
				
				if ('1' <= ev.key.keysym.sym && ev.key.keysym.sym <= '9') {
					_scalerType = ev.key.keysym.sym - '1';
					if (_scalerType >= ARRAYSIZE(s_gfxModeSwitchTable))
						break;
					
					while (s_gfxModeSwitchTable[_scalerType][factor] < 0) {
						assert(factor > 0);
						factor--;
					}
					setGraphicsMode(s_gfxModeSwitchTable[_scalerType][factor]);
					break;
				}
			}

#ifdef LINUPY
			// On Yopy map the End button to quit
			if ((ev.key.keysym.sym==293)) {
				event->event_code = EVENT_QUIT;
				return true;
			}
			// Map menu key to f5 (scumm menu)
			if (ev.key.keysym.sym==306) {
				event->event_code = EVENT_KEYDOWN;
				event->kbd.keycode = SDLK_F5;
				event->kbd.ascii = mapKey(SDLK_F5, ev.key.keysym.mod, 0);
				return true;
			}
			// Map action key to action
			if (ev.key.keysym.sym==291) {
				event->event_code = EVENT_KEYDOWN;
				event->kbd.keycode = SDLK_TAB;
				event->kbd.ascii = mapKey(SDLK_TAB, ev.key.keysym.mod, 0);
				return true;
			}
			// Map OK key to skip cinematic
			if (ev.key.keysym.sym==292) {
				event->event_code = EVENT_KEYDOWN;
				event->kbd.keycode = SDLK_ESCAPE;
				event->kbd.ascii = mapKey(SDLK_ESCAPE, ev.key.keysym.mod, 0);
				return true;
			}
#endif

#ifdef QTOPIA
			// quit on fn+backspace on zaurus
			if (ev.key.keysym.sym == 127) {
				event->event_code = EVENT_QUIT;
				return true;
			}

			// map menu key (f11) to f5 (scumm menu)
			if (ev.key.keysym.sym == SDLK_F11) {
				event->event_code = EVENT_KEYDOWN;
				event->kbd.keycode = SDLK_F5;
				event->kbd.ascii = mapKey(SDLK_F5, ev.key.keysym.mod, 0);
			}
			// map center (space) to tab (default action )
			// I wanted to map the calendar button but the calendar comes up
			//
			else if (ev.key.keysym.sym == SDLK_SPACE) {
				event->event_code = EVENT_KEYDOWN;
				event->kbd.keycode = SDLK_TAB;
				event->kbd.ascii = mapKey(SDLK_TAB, ev.key.keysym.mod, 0);
			}
			// since we stole space (pause) above we'll rebind it to the tab key on the keyboard
			else if (ev.key.keysym.sym == SDLK_TAB) {
				event->event_code = EVENT_KEYDOWN;
				event->kbd.keycode = SDLK_SPACE;
				event->kbd.ascii = mapKey(SDLK_SPACE, ev.key.keysym.mod, 0);
			} else {
			// let the events fall through if we didn't change them, this may not be the best way to
			// set it up, but i'm not sure how sdl would like it if we let if fall through then redid it though.
			// and yes i have an huge terminal size so i dont wrap soon enough.
				event->event_code = EVENT_KEYDOWN;
				event->kbd.keycode = ev.key.keysym.sym;
				event->kbd.ascii = mapKey(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode);
			}
#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, ev.key.keysym.unicode);
#endif
			
			switch(ev.key.keysym.sym) {
			case SDLK_LEFT:
				km.x_vel = -1;
				km.x_down_count = 1;
				break;
			case SDLK_RIGHT:
				km.x_vel =  1;
				km.x_down_count = 1;
				break;
			case SDLK_UP:
				km.y_vel = -1;
				km.y_down_count = 1;
				break;
			case SDLK_DOWN:
				km.y_vel =  1;
				km.y_down_count = 1;
				break;
			default:
				break;
			}

			return true;
	
		case SDL_KEYUP:
			event->event_code = EVENT_KEYUP;
			event->kbd.keycode = ev.key.keysym.sym;
			event->kbd.ascii = mapKey(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode);

			switch(ev.key.keysym.sym) {
			case SDLK_LEFT:
				if (km.x_vel < 0) {
					km.x_vel = 0;
					km.x_down_count = 0;
				}
				break;
			case SDLK_RIGHT:
				if (km.x_vel > 0) {
					km.x_vel = 0;
					km.x_down_count = 0;
				}
				break;
			case SDLK_UP:
				if (km.y_vel < 0) {
					km.y_vel = 0;
					km.y_down_count = 0;
				}
				break;
			case SDLK_DOWN:
				if (km.y_vel > 0) {
					km.y_vel = 0;
					km.y_down_count = 0;
				}
				break;
			default:
				break;
			}
			return true;

		case SDL_MOUSEMOTION:
			event->event_code = EVENT_MOUSEMOVE;
			fillMouseEvent(*event, ev.motion.x, ev.motion.y);
			
			set_mouse_pos(event->mouse.x, event->mouse.y);
			return true;

		case SDL_MOUSEBUTTONDOWN:
			if (ev.button.button == SDL_BUTTON_LEFT)
				event->event_code = EVENT_LBUTTONDOWN;
			else if (ev.button.button == SDL_BUTTON_RIGHT)
				event->event_code = EVENT_RBUTTONDOWN;
#if defined(SDL_BUTTON_WHEELUP) && defined(SDL_BUTTON_WHEELDOWN)
			else if (ev.button.button == SDL_BUTTON_WHEELUP)
				event->event_code = EVENT_WHEELUP;
			else if (ev.button.button == SDL_BUTTON_WHEELDOWN)
				event->event_code = EVENT_WHEELDOWN;
#endif
			else
				break;

			fillMouseEvent(*event, ev.button.x, ev.button.y);

			return true;

		case SDL_MOUSEBUTTONUP:
			if (ev.button.button == SDL_BUTTON_LEFT)
				event->event_code = EVENT_LBUTTONUP;
			else if (ev.button.button == SDL_BUTTON_RIGHT)
				event->event_code = EVENT_RBUTTONUP;
			else
				break;
			fillMouseEvent(*event, ev.button.x, ev.button.y);

			return true;

		case SDL_JOYBUTTONDOWN:
			if (ev.jbutton.button == JOY_BUT_LMOUSE) {
				event->event_code = EVENT_LBUTTONDOWN;
			} else if (ev.jbutton.button == JOY_BUT_RMOUSE) {
				event->event_code = EVENT_RBUTTONDOWN;
			} else {
				event->event_code = EVENT_KEYDOWN;
				switch (ev.jbutton.button) {
					case JOY_BUT_ESCAPE:
						event->kbd.keycode = SDLK_ESCAPE;
						event->kbd.ascii = mapKey(SDLK_ESCAPE, ev.key.keysym.mod, 0);
						break;
					case JOY_BUT_PERIOD:
						event->kbd.keycode = SDLK_PERIOD;
						event->kbd.ascii = mapKey(SDLK_PERIOD, ev.key.keysym.mod, 0);
						break;
					case JOY_BUT_SPACE:
						event->kbd.keycode = SDLK_SPACE;
						event->kbd.ascii = mapKey(SDLK_SPACE, ev.key.keysym.mod, 0);
						break;
					case JOY_BUT_F5:
						event->kbd.keycode = SDLK_F5;
						event->kbd.ascii = mapKey(SDLK_F5, ev.key.keysym.mod, 0);
						break; 
				}
			}
			return true;

		case SDL_JOYBUTTONUP:
			if (ev.jbutton.button == JOY_BUT_LMOUSE) {
				event->event_code = EVENT_LBUTTONUP;
			} else if (ev.jbutton.button == JOY_BUT_RMOUSE) {
				event->event_code = EVENT_RBUTTONUP;
			} else {
				event->event_code = EVENT_KEYUP;
				switch (ev.jbutton.button) {
					case JOY_BUT_ESCAPE:
						event->kbd.keycode = SDLK_ESCAPE;
						event->kbd.ascii = mapKey(SDLK_ESCAPE, ev.key.keysym.mod, 0);
						break;
					case JOY_BUT_PERIOD:
						event->kbd.keycode = SDLK_PERIOD;
						event->kbd.ascii = mapKey(SDLK_PERIOD, ev.key.keysym.mod, 0);
						break;
					case JOY_BUT_SPACE:
						event->kbd.keycode = SDLK_SPACE;
						event->kbd.ascii = mapKey(SDLK_SPACE, ev.key.keysym.mod, 0);
						break;
					case JOY_BUT_F5:
						event->kbd.keycode = SDLK_F5;
						event->kbd.ascii = mapKey(SDLK_F5, ev.key.keysym.mod, 0);
						break;
				} 
			}
			return true;

		case SDL_JOYAXISMOTION:
			axis = ev.jaxis.value;
			if ( axis > JOY_DEADZONE) {
				axis -= JOY_DEADZONE;
				event->event_code = EVENT_MOUSEMOVE;
			} else if ( axis < -JOY_DEADZONE ) {
				axis += JOY_DEADZONE;
				event->event_code = EVENT_MOUSEMOVE;
			} else
				axis = 0;

			if ( ev.jaxis.axis == JOY_XAXIS) { 
#ifdef JOY_ANALOG
				km.x_vel = axis/2000;
				km.x_down_count = 0;
#else
				if (axis != 0) {
					km.x_vel = (axis > 0) ? 1:-1;
					km.x_down_count = 1;
				} else {
					km.x_vel = 0;
					km.x_down_count = 0;
				}
#endif

			} else if (ev.jaxis.axis == JOY_YAXIS) { 
#ifndef JOY_INVERT_Y
				axis = -axis;
#endif
#ifdef JOY_ANALOG
				km.y_vel = -axis / 2000;
				km.y_down_count = 0;
#else
				if (axis != 0) {
					km.y_vel = (-axis > 0) ? 1: -1;
					km.y_down_count = 1;
				} else {
					km.y_vel = 0;
					km.y_down_count = 0;
				}
#endif
			}
			event->mouse.x = km.x;
			event->mouse.y = km.y;
			event->mouse.x /= _scaleFactor;
			event->mouse.y /= _scaleFactor;

			if (_adjustAspectRatio)
				event->mouse.y = aspect2Real(event->mouse.y);

			return true;

		case SDL_VIDEOEXPOSE:
			_forceFull = true;
			break;

		case SDL_QUIT:
			event->event_code = EVENT_QUIT;
			return true;
		}
	}
	return false;
}



--- NEW FILE: graphics.cpp ---
/* ScummVM - Scumm Interpreter
 * Copyright (C) 2001  Ludvig Strigeus
 * Copyright (C) 2001-2004 The ScummVM project
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 * $Header: /cvsroot/scummvm/scummvm/backends/sdl/graphics.cpp,v 1.1 2004/02/29 00:49:40 fingolfin Exp $
[...1079 lines suppressed...]
		}
	
	} else {

		uint16 *dst, *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) {
			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(_overlayVisible ? _tmpscreen : _screen);
}


Index: build.rules
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/sdl/build.rules,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- build.rules	25 Feb 2004 04:23:58 -0000	1.4
+++ build.rules	29 Feb 2004 00:49:40 -0000	1.5
@@ -3,10 +3,7 @@
 DEFINES  += -DUNIX
 INCLUDES += `sdl-config --cflags`
 LIBS     += `sdl-config --libs`
-OBJS	 += backends/sdl/sdl-common.o 
-
-# The normal (non OpenGL-accelerated) SDL backend
-OBJS	 += backends/sdl/sdl.o 
+OBJS	 += backends/sdl/events.o backends/sdl/graphics.o backends/sdl/sdl.o 
 
 # Uncomment this in addition to the above if you compile on Mac OS X
 # DEFINES += -DMACOSX

Index: module.mk
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/sdl/module.mk,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- module.mk	25 Feb 2004 11:41:55 -0000	1.1
+++ module.mk	29 Feb 2004 00:49:40 -0000	1.2
@@ -1,8 +1,9 @@
 MODULE := backends/sdl
 
 MODULE_OBJS := \
-	backends/sdl/sdl.o \
-	backends/sdl/sdl-common.o
+	backends/sdl/events.o \
+	backends/sdl/graphics.o \
+	backends/sdl/sdl.o
 
 MODULE_DIRS += \
 	backend/sdl

Index: sdl-common.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/sdl/sdl-common.h,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -d -r1.50 -r1.51
--- sdl-common.h	28 Feb 2004 12:57:52 -0000	1.50
+++ sdl-common.h	29 Feb 2004 00:49:40 -0000	1.51
@@ -1,4 +1,5 @@
 /* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001  Ludvig Strigeus
  * Copyright (C) 2001-2004 The ScummVM project
  *
  * This program is free software; you can redistribute it and/or
@@ -30,8 +31,11 @@
 
 #include <SDL.h>
 
-class OSystem_SDL_Common : public OSystem {
+class OSystem_SDL : public OSystem {
 public:
+	OSystem_SDL();
+	virtual ~OSystem_SDL();
+
 	// Set the size of the video bitmap.
 	// Typically, 320x200
 	void initSize(uint w, uint h);
@@ -129,17 +133,12 @@
 	virtual void setFeatureState(Feature f, bool enable);
 	virtual bool getFeatureState(Feature f);
 
-
-	static OSystem *create();
-
 protected:
-	OSystem_SDL_Common();
-	virtual ~OSystem_SDL_Common();
-
-	static OSystem_SDL_Common *create_intern();
-
 	void init_intern();
 
+	// hardware screen
+	SDL_Surface *_hwscreen;
+
 	// unseen game screen
 	SDL_Surface *_screen;
 	int _screenWidth, _screenHeight;
@@ -227,27 +226,27 @@
 	void add_dirty_rgn_auto(const byte *buf);
 	void mk_checksums(const byte *buf);
 
-	virtual void add_dirty_rect(int x, int y, int w, int h);
+	void add_dirty_rect(int x, int y, int w, int h);
 
-	virtual void draw_mouse();
-	virtual void undraw_mouse();
+	void draw_mouse();
+	void undraw_mouse();
 	/** Set the position of the virtual mouse cursor. */
 	void set_mouse_pos(int x, int y);
 	void fillMouseEvent(Event &event, int x, int y);
 	void toggleMouseGrab();
 
 
-	virtual void internUpdateScreen() = 0;
+	void internUpdateScreen();
 
-	virtual void load_gfx_mode() = 0;
-	virtual void unload_gfx_mode() = 0;
-	virtual void hotswap_gfx_mode() = 0;
+	void load_gfx_mode();
+	void unload_gfx_mode();
+	void hotswap_gfx_mode();
 	
-	virtual void setFullscreenMode(bool enable) = 0;
+	void setFullscreenMode(bool enable);
 
-	virtual bool save_screenshot(const char *filename) = 0;
+	bool save_screenshot(const char *filename);
 	
-	virtual int effectiveScreenHeight() { return (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor; }
+	int effectiveScreenHeight() { return (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor; }
 
 	void setup_icon();
 	void kbd_mouse();

Index: sdl.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/backends/sdl/sdl.cpp,v
retrieving revision 1.63
retrieving revision 1.64
diff -u -d -r1.63 -r1.64
--- sdl.cpp	28 Feb 2004 13:00:19 -0000	1.63
+++ sdl.cpp	29 Feb 2004 00:49:40 -0000	1.64
@@ -20,373 +20,345 @@
  *
  */
 
-#include "sdl-common.h"
+#include "backends/sdl/sdl-common.h"
+#include "common/config-manager.h"
 #include "common/util.h"
 
-class OSystem_SDL : public OSystem_SDL_Common {
-public:
-	OSystem_SDL();
-
-	// Update the dirty areas of the screen
-	void internUpdateScreen();
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
 
-protected:
-	SDL_Surface *_hwscreen;    // hardware screen
+#include "scummvm.xpm"
 
-	virtual void load_gfx_mode();
-	virtual void unload_gfx_mode();
-	virtual bool save_screenshot(const char *filename);
-	virtual void hotswap_gfx_mode();
-	
-	virtual void setFullscreenMode(bool enable);
-};
 
-OSystem_SDL_Common *OSystem_SDL_Common::create_intern() {
+OSystem *OSystem_SDL_create() {
 	return new OSystem_SDL();
 }
 
-OSystem_SDL::OSystem_SDL()
-	 : _hwscreen(0)
-{
-}
-
-void OSystem_SDL::load_gfx_mode() {
-	_forceFull = true;
-	_mode_flags |= DF_UPDATE_EXPAND_1_PIXEL;
+void OSystem_SDL::init_intern() {
 
-	_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;
+	int joystick_num = ConfMan.getInt("joystick_num");
+	uint32 sdlFlags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER;
 
-	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;
+	if (joystick_num > -1)
+		sdlFlags |= SDL_INIT_JOYSTICK;
 
-	default:
-		error("unknown gfx mode %d", _mode);
+	if (SDL_Init(sdlFlags) == -1) {
+		error("Could not initialize SDL: %s", SDL_GetError());
 	}
 
-	//
-	// 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");
+	_graphicsMutex = createMutex();
 
-	//
-	// Create the surface that contains the scaled graphics in 16 bit mode
-	//
+	SDL_ShowCursor(SDL_DISABLE);
+	
+	// Enable unicode support if possible
+	SDL_EnableUNICODE(1); 
 
-	_hwscreen = SDL_SetVideoMode(_screenWidth * _scaleFactor, (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor, 16, 
-		_full_screen ? (SDL_FULLSCREEN|SDL_SWSURFACE) : SDL_SWSURFACE
-	);
-	if (_hwscreen == NULL) {
-		// DON'T use error(), as this tries to bring up the debug
-		// console, which WON'T WORK now that _hwscreen is hosed.
+	cksum_valid = false;
+	_mode = GFX_DOUBLESIZE;
+	_full_screen = ConfMan.getBool("fullscreen");
+	_adjustAspectRatio = ConfMan.getBool("aspect_ratio");
+	_mode_flags = 0;
 
-		// FIXME: We should be able to continue the game without
-		// shutting down or bringing up the debug console, but at
-		// this point we've already screwed up all our member vars.
-		// We need to find a way to call SDL_SetVideoMode *before*
-		// that happens and revert to all the old settings if we
-		// can't pull off the switch to the new settings.
-		//
-		// Fingolfin says: the "easy" way to do that is not to modify
-		// the member vars before we are sure everything is fine. Think
-		// of "transactions, commit, rollback" style... we use local vars
-		// in place of the member vars, do everything etc. etc.. In case
-		// of a failure, rollback is trivial. Only if everything worked fine
-		// do we "commit" the changed values to the member vars.
-		warning("SDL_SetVideoMode says we can't switch to that mode");
-		quit();
+
+#ifndef MACOSX		// Don't set icon on OS X, as we use a nicer external icon there
+	// Setup the icon
+	setup_icon();
+#endif
+
+	// enable joystick
+	if (joystick_num > -1 && SDL_NumJoysticks() > 0) {
+		printf("Using joystick: %s\n", SDL_JoystickName(0));
+		init_joystick(joystick_num);
 	}
+}
 
-	//
-	// Create the surface used for the graphics in 16 bit before scaling, and also the overlay
-	//
+OSystem_SDL::OSystem_SDL()
+	: _hwscreen(0), _screen(0), _screenWidth(0), _screenHeight(0),
+	_tmpscreen(0), _tmpScreenWidth(0), _overlayVisible(false),
+	_cdrom(0), _scaler_proc(0), _modeChanged(false), _dirty_checksums(0),
+	_mouseVisible(false), _mouseDrawn(false), _mouseData(0),
+	_mouseHotspotX(0), _mouseHotspotY(0),
+	_currentShakePos(0), _newShakePos(0),
+	_paletteDirtyStart(0), _paletteDirtyEnd(0),
+	_graphicsMutex(0) {
 
-	// Distinguish 555 and 565 mode
-	if (_hwscreen->format->Rmask == 0x7C00)
-		InitScalers(555);
-	else
-		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,
-						_hwscreen->format->Rmask,
-						_hwscreen->format->Gmask,
-						_hwscreen->format->Bmask,
-						_hwscreen->format->Amask);
+	// allocate palette storage
+	_currentPalette = (SDL_Color *)calloc(sizeof(SDL_Color), 256);
 
-	if (_tmpscreen == NULL)
-		error("_tmpscreen failed");
+	// allocate the dirty rect storage
+	_mouseBackup = (byte *)malloc(MAX_MOUSE_W * MAX_MOUSE_H * MAX_SCALING * 2);
 
-	// keyboard cursor control, some other better place for it?
-	km.x_max = _screenWidth * _scaleFactor - 1;
-	km.y_max = (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor - 1;
-	km.delay_time = 25;
-	km.last_time = 0;
+	// reset mouse state
+	memset(&km, 0, sizeof(km));
+	
+	init_intern();
 }
 
-void OSystem_SDL::unload_gfx_mode() {
-	if (_screen) {
-		SDL_FreeSurface(_screen);
-		_screen = NULL; 
-	}
+OSystem_SDL::~OSystem_SDL() {
+//	unload_gfx_mode();
 
-	if (_hwscreen) {
-		SDL_FreeSurface(_hwscreen); 
-		_hwscreen = NULL;
-	}
+	if (_dirty_checksums)
+		free(_dirty_checksums);
+	free(_currentPalette);
+	free(_mouseBackup);
+	deleteMutex(_graphicsMutex);
 
-	if (_tmpscreen) {
-		free(_tmpscreen->pixels);
-		SDL_FreeSurface(_tmpscreen);
-		_tmpscreen = NULL;
-	}
+	SDL_ShowCursor(SDL_ENABLE);
+	SDL_Quit();
 }
 
-void OSystem_SDL::hotswap_gfx_mode() {
-	if (!_screen)
-		return;
+uint32 OSystem_SDL::get_msecs() {
+	return SDL_GetTicks();	
+}
 
-	// Keep around the old _screen & _tmpscreen so we can restore the screen data
-	// after the mode switch.
-	SDL_Surface *old_screen = _screen;
-	SDL_Surface *old_tmpscreen = _tmpscreen;
+void OSystem_SDL::delay_msecs(uint msecs) {
+	SDL_Delay(msecs);
+}
 
-	// Release the HW screen surface
-	SDL_FreeSurface(_hwscreen); 
+void OSystem_SDL::set_timer(TimerProc callback, int timer) {
+	SDL_SetTimer(timer, (SDL_TimerCallback) callback);
+}
 
-	// Setup the new GFX mode
-	load_gfx_mode();
+void OSystem_SDL::setWindowCaption(const char *caption) {
+	SDL_WM_SetCaption(caption, caption);
+}
 
-	// reset palette
-	SDL_SetColors(_screen, _currentPalette, 0, 256);
+bool OSystem_SDL::hasFeature(Feature f) {
+	return
+		(f == kFeatureFullscreenMode) ||
+		(f == kFeatureAspectRatioCorrection) ||
+		(f == kFeatureAutoComputeDirtyRects);
+}
 
-	// Restore old screen content
-	SDL_BlitSurface(old_screen, NULL, _screen, NULL);
-	SDL_BlitSurface(old_tmpscreen, NULL, _tmpscreen, NULL);
-	
-	// Free the old surfaces
-	SDL_FreeSurface(old_screen);
-	free(old_tmpscreen->pixels);
-	SDL_FreeSurface(old_tmpscreen);
+void OSystem_SDL::setFeatureState(Feature f, bool enable) {
+	Common::StackLock lock(_graphicsMutex, this);
 
-	// Blit everything to the screen
-	internUpdateScreen();
-	
-	// Make sure that an EVENT_SCREEN_CHANGED gets sent later
-	_modeChanged = true;
+	switch (f) {
+	case kFeatureFullscreenMode:
+		setFullscreenMode(enable);
+		break;
+	case kFeatureAspectRatioCorrection:
+		if (_screenHeight == 200 && _adjustAspectRatio != enable) {
+			//assert(_hwscreen != 0);
+			_adjustAspectRatio ^= true;
+			hotswap_gfx_mode();
+		}
+		break;
+	case kFeatureAutoComputeDirtyRects:
+		if (enable)
+			_mode_flags |= DF_WANT_RECT_OPTIM;		
+		else
+			_mode_flags &= ~DF_WANT_RECT_OPTIM;		
+		break;
+	default:
+		break;
+	}
 }
 
-void OSystem_SDL::internUpdateScreen() {
-	assert(_hwscreen != NULL);
+bool OSystem_SDL::getFeatureState(Feature f) {
+	switch (f) {
+	case kFeatureFullscreenMode:
+		return _full_screen;
+	case kFeatureAspectRatioCorrection:
+		return _adjustAspectRatio;
+	case kFeatureAutoComputeDirtyRects:
+		return _mode_flags & DF_WANT_RECT_OPTIM;
+	default:
+		return false;
+	}
+}
 
-	// If the shake position changed, fill the dirty area with blackness
-	if (_currentShakePos != _newShakePos) {
-		SDL_Rect blackrect = {0, 0, _screenWidth * _scaleFactor, _newShakePos * _scaleFactor};
+void OSystem_SDL::quit() {
+	if(_cdrom) {
+		SDL_CDStop(_cdrom);
+		SDL_CDClose(_cdrom);
+	}
+	unload_gfx_mode();
 
-		if (_adjustAspectRatio)
-			blackrect.h = real2Aspect(blackrect.h - 1) + 1;
+	SDL_ShowCursor(SDL_ENABLE);
+	SDL_Quit();
 
-		SDL_FillRect(_hwscreen, &blackrect, 0);
+	exit(0);
+}
 
-		_currentShakePos = _newShakePos;
+void OSystem_SDL::setup_icon() {
+	int w, h, ncols, nbytes, i;
+	unsigned int rgba[256], icon[32 * 32];
+	unsigned char mask[32][4];
 
-		_forceFull = true;
+	sscanf(scummvm_icon[0], "%d %d %d %d", &w, &h, &ncols, &nbytes);
+	if ((w != 32) || (h != 32) || (ncols > 255) || (nbytes > 1)) {
+		warning("Could not load the icon (%d %d %d %d)", w, h, ncols, nbytes);
+		return;
 	}
-
-	// Make sure the mouse is drawn, if it should be drawn.
-	draw_mouse();
-	
-	// Check whether the palette was changed in the meantime and update the
-	// screen surface accordingly. 
-	if (_paletteDirtyEnd != 0) {
-		SDL_SetColors(_screen, _currentPalette + _paletteDirtyStart, 
-			_paletteDirtyStart,
-			_paletteDirtyEnd - _paletteDirtyStart);
+	for (i = 0; i < ncols; i++) {
+		unsigned char code;
+		char color[32];
+		unsigned int col;
+		sscanf(scummvm_icon[1 + i], "%c c %s", &code, color);
+		if (!strcmp(color, "None"))
+			col = 0x00000000;
+		else if (!strcmp(color, "black"))
+			col = 0xFF000000;
+		else if (color[0] == '#') {
+			sscanf(color + 1, "%06x", &col);
+			col |= 0xFF000000;
+		} else {
+			warning("Could not load the icon (%d %s - %s) ", code, color, scummvm_icon[1 + i]);
+			return;
+		}
 		
-		_paletteDirtyEnd = 0;
-
-		_forceFull = true;
+		rgba[code] = col;
 	}
-
-	// Force a full redraw if requested
-	if (_forceFull) {
-		_num_dirty_rects = 1;
-
-		_dirty_rect_list[0].x = 0;
-		_dirty_rect_list[0].y = 0;
-		_dirty_rect_list[0].w = _screenWidth;
-		_dirty_rect_list[0].h = _screenHeight;
+	memset(mask, 0, sizeof(mask));
+	for (h = 0; h < 32; h++) {
+		const char *line = scummvm_icon[1 + ncols + h];
+		for (w = 0; w < 32; w++) {
+			icon[w + 32 * h] = rgba[(int)line[w]];
+			if (rgba[(int)line[w]] & 0xFF000000) {
+				mask[h][w >> 3] |= 1 << (7 - (w & 0x07));
+			}
+		}
 	}
 
-	// Only draw anything if necessary
-	if (_num_dirty_rects > 0) {
+	SDL_Surface *sdl_surf = SDL_CreateRGBSurfaceFrom(icon, 32, 32, 32, 32 * 4, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000);
+	SDL_WM_SetIcon(sdl_surf, (unsigned char *) mask);
+	SDL_FreeSurface(sdl_surf);
+}
 
-		SDL_Rect *r; 
-		SDL_Rect dst;
-		uint32 srcPitch, dstPitch;
-		SDL_Rect *last_rect = _dirty_rect_list + _num_dirty_rects;
+OSystem::MutexRef OSystem_SDL::createMutex(void) {
+	return (MutexRef) SDL_CreateMutex();
+}
 
-		if (_scaler_proc == Normal1x && !_adjustAspectRatio) {
-			SDL_Surface *target = _overlayVisible ? _tmpscreen : _screen;
-			for (r = _dirty_rect_list; r != last_rect; ++r) {
-				dst = *r;
-				
-				if (_overlayVisible) {
-					// FIXME: I don't understand why this is necessary...
-					dst.x--;
-					dst.y--;
-				}
-				dst.y += _currentShakePos;
-				if (SDL_BlitSurface(target, r, _hwscreen, &dst) != 0)
-					error("SDL_BlitSurface failed: %s", SDL_GetError());
-			}
-		} else {
-			if (!_overlayVisible) {
-				for (r = _dirty_rect_list; r != last_rect; ++r) {
-					dst = *r;
-					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(_screen, r, _tmpscreen, &dst) != 0)
-						error("SDL_BlitSurface failed: %s", SDL_GetError());
-				}
-			}
+void OSystem_SDL::lockMutex(MutexRef mutex) {
+	SDL_mutexP((SDL_mutex *) mutex);
+}
 
-			SDL_LockSurface(_tmpscreen);
-			SDL_LockSurface(_hwscreen);
+void OSystem_SDL::unlockMutex(MutexRef mutex) {
+	SDL_mutexV((SDL_mutex *) mutex);
+}
 
-			srcPitch = _tmpscreen->pitch;
-			dstPitch = _hwscreen->pitch;
+void OSystem_SDL::deleteMutex(MutexRef mutex) {
+	SDL_DestroyMutex((SDL_mutex *) mutex);
+}
 
-			for (r = _dirty_rect_list; r != last_rect; ++r) {
-				register int dst_y = r->y + _currentShakePos;
-				register int dst_h = 0;
-				register int orig_dst_y = 0;
+#pragma mark -
+#pragma mark --- Audio ---
+#pragma mark -
 
-				if (dst_y < _screenHeight) {
-					dst_h = r->h;
-					if (dst_h > _screenHeight - dst_y)
-						dst_h = _screenHeight - dst_y;
+bool OSystem_SDL::setSoundCallback(SoundProc proc, void *param) {
+	SDL_AudioSpec desired;
 
-					dst_y *= _scaleFactor;
+	memset(&desired, 0, sizeof(desired));
 
-					if (_adjustAspectRatio) {
-						orig_dst_y = dst_y;
-						dst_y = real2Aspect(dst_y);
-					}
+	desired.freq = SAMPLES_PER_SEC;
+	desired.format = AUDIO_S16SYS;
+	desired.channels = 2;
+	desired.samples = 2048;
+	desired.callback = proc;
+	desired.userdata = param;
+	if (SDL_OpenAudio(&desired, NULL) != 0) {
+		return false;
+	}
+	SDL_PauseAudio(0);
+	return true;
+}
 
-					_scaler_proc((byte *)_tmpscreen->pixels + (r->x * 2 + 2) + (r->y + 1) * srcPitch, srcPitch,
-						(byte *)_hwscreen->pixels + r->x * 2 * _scaleFactor + dst_y * dstPitch, dstPitch, r->w, dst_h);
-				}
+void OSystem_SDL::clearSoundCallback() {
+	SDL_CloseAudio();
+}
 
-				r->x *= _scaleFactor;
-				r->y = dst_y;
-				r->w *= _scaleFactor;
-				r->h = dst_h * _scaleFactor;
+int OSystem_SDL::getOutputSampleRate() const {
+	return SAMPLES_PER_SEC;
+}
 
-				if (_adjustAspectRatio && orig_dst_y / _scaleFactor < _screenHeight)
-					r->h = stretch200To240((uint8 *) _hwscreen->pixels, dstPitch, r->w, r->h, r->x, r->y, orig_dst_y);
-			}
-			SDL_UnlockSurface(_tmpscreen);
-			SDL_UnlockSurface(_hwscreen);
-		}
+#pragma mark -
+#pragma mark --- CD Audio ---
+#pragma mark -
 
-		// Readjust the dirty rect list in case we are doing a full update.
-		// This is necessary if shaking is active.
-		if (_forceFull) {
-			_dirty_rect_list[0].y = 0;
-			_dirty_rect_list[0].h = (_adjustAspectRatio ? 240 : _screenHeight) * _scaleFactor;
+bool OSystem_SDL::openCD(int drive) {
+	if (SDL_InitSubSystem(SDL_INIT_CDROM) == -1)
+		_cdrom = NULL;
+	else {
+		_cdrom = SDL_CDOpen(drive);
+		// Did it open? Check if _cdrom is NULL
+		if (!_cdrom) {
+			warning("Couldn't open drive: %s", SDL_GetError());
+		} else {
+			cd_num_loops = 0;
+			cd_stop_time = 0;
+			cd_end_time = 0;
 		}
-
-		// Finally, blit all our changes to the screen
-		SDL_UpdateRects(_hwscreen, _num_dirty_rects, _dirty_rect_list);
 	}
+	
+	return (_cdrom != NULL);
+}
 
-	_num_dirty_rects = 0;
-	_forceFull = false;
+void OSystem_SDL::stop_cdrom() {	/* Stop CD Audio in 1/10th of a second */
+	cd_stop_time = SDL_GetTicks() + 100;
+	cd_num_loops = 0;
 }
 
-bool OSystem_SDL::save_screenshot(const char *filename) {
-	assert(_hwscreen != NULL);
+void OSystem_SDL::play_cdrom(int track, int num_loops, int start_frame, int duration) {
+	if (!num_loops && !start_frame)
+		return;
 
-	Common::StackLock lock(_graphicsMutex, this);	// Lock the mutex until this function ends
-	SDL_SaveBMP(_hwscreen, filename);
-	return true;
+	if (!_cdrom)
+		return;
+	
+	if (duration > 0)
+		duration += 5;
+
+	cd_track = track;
+	cd_num_loops = num_loops;
+	cd_start_frame = start_frame;
+
+	SDL_CDStatus(_cdrom);
+	if (start_frame == 0 && duration == 0)
+		SDL_CDPlayTracks(_cdrom, track, 0, 1, 0);
+	else
+		SDL_CDPlayTracks(_cdrom, track, start_frame, 0, duration);
+	cd_duration = duration;
+	cd_stop_time = 0;
+	cd_end_time = SDL_GetTicks() + _cdrom->track[track].length * 1000 / CD_FPS;
 }
 
-void OSystem_SDL::setFullscreenMode(bool enable) {
-	if (_full_screen != enable) {
-		assert(_hwscreen != 0);
-		_full_screen ^= true;
+bool OSystem_SDL::poll_cdrom() {
+	if (!_cdrom)
+		return false;
 
-		if (_mouseDrawn)
-			undraw_mouse();
-	
-#if defined(MACOSX) && !SDL_VERSION_ATLEAST(1, 2, 6)
-		// On OS X, SDL_WM_ToggleFullScreen is currently not implemented. Worse,
-		// before SDL 1.2.6 it always returned -1 (which would indicate a
-		// successful switch). So we simply don't call it at all and use
-		// hotswap_gfx_mode() directly to switch to fullscreen mode.
-		hotswap_gfx_mode();
-#else
-		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
+	return (cd_num_loops != 0 && (SDL_GetTicks() < cd_end_time || SDL_CDStatus(_cdrom) != CD_STOPPED));
+}
+
+void OSystem_SDL::update_cdrom() {
+	if (!_cdrom)
+		return;
+
+	if (cd_stop_time != 0 && SDL_GetTicks() >= cd_stop_time) {
+		SDL_CDStop(_cdrom);
+		cd_num_loops = 0;
+		cd_stop_time = 0;
+		return;
+	}
+
+	if (cd_num_loops == 0 || SDL_GetTicks() < cd_end_time)
+		return;
+
+	if (cd_num_loops != 1 && SDL_CDStatus(_cdrom) != CD_STOPPED) {
+		// Wait another second for it to be done
+		cd_end_time += 1000;
+		return;
+	}
+
+	if (cd_num_loops > 0)
+		cd_num_loops--;
+
+	if (cd_num_loops != 0) {
+		if (cd_start_frame == 0 && cd_duration == 0)
+			SDL_CDPlayTracks(_cdrom, cd_track, 0, 1, 0);
+		else
+			SDL_CDPlayTracks(_cdrom, cd_track, cd_start_frame, 0, cd_duration);
+		cd_end_time = SDL_GetTicks() + _cdrom->track[cd_track].length * 1000 / CD_FPS;
 	}
 }

--- sdl-common.cpp DELETED ---





More information about the Scummvm-git-logs mailing list