[Scummvm-cvs-logs] SF.net SVN: scummvm:[33870] scummvm/branches/branch-0-12-0/backends/ platform/ds

agent-q at users.sourceforge.net agent-q at users.sourceforge.net
Thu Aug 14 21:48:41 CEST 2008


Revision: 33870
          http://scummvm.svn.sourceforge.net/scummvm/?rev=33870&view=rev
Author:   agent-q
Date:     2008-08-14 19:48:39 +0000 (Thu, 14 Aug 2008)

Log Message:
-----------
DS: Code changes for 0.12.0 beta1.  New touch screen control method, support for new engines, tap screen controls.

Modified Paths:
--------------
    scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/makefile
    scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/dsmain.cpp
    scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/dsmain.h
    scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/dsoptions.cpp
    scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/dsoptions.h
    scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/gbampsave.cpp
    scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/osystem_ds.cpp
    scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/osystem_ds.h
    scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/portdefs.h
    scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/touchkeyboard.cpp
    scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/touchkeyboard.h
    scummvm/branches/branch-0-12-0/backends/platform/ds/makefile

Modified: scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/makefile
===================================================================
--- scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/makefile	2008-08-14 19:20:25 UTC (rev 33869)
+++ scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/makefile	2008-08-14 19:48:39 UTC (rev 33870)
@@ -75,9 +75,10 @@
 # I actually had to use
 # ./configure --host=arm-elf --enable-speed --enable-sso -enable-fpm=arm CFLAGS='-specs=ds_arm9.specs -mthumb-interwork' LDFLAGS='C:/Progra~1/devkitpro/libnds/lib/libnds9.a' --disable-shared --disable-debugging
 
+ARM = 1
 USE_ARM_SOUND_ASM = 1
-ARM = 1
 USE_ARM_COSTUME_ASM = 1
+ARM_USE_GFX_ASM = 1
 
 ifdef DS_BUILD_A
 	DEFINES = -DDS_SCUMM_BUILD -DDS_BUILD_A -DUSE_ARM_GFX_ASM -DUSE_ARM_COSTUME_ASM
@@ -130,7 +131,8 @@
 
 ifdef DS_BUILD_G
 	DEFINES = -DDS_NON_SCUMM_BUILD -DDS_BUILD_G
-	LOGO = logog.bmp
+	LOGO = logof.bmp
+	ENABLE_PARALLACTION = STATIC_PLUGIN
 	ENABLE_LURE = STATIC_PLUGIN
 	BUILD=scummvm-G
 endif
@@ -145,7 +147,7 @@
 CFLAGS	=	-Wno-multichar -Wall\
 		-Wno-multichar -mcpu=arm9tdmi -mtune=arm9tdmi \
 		-mcpu=arm9tdmi -mtune=arm9tdmi -fomit-frame-pointer\
-		-mthumb-interwork -DUSE_ARM_COSTUME_ASM=1
+		-mthumb-interwork -DUSE_ARM_COSTUME_ASM=1 -D$(BUILD)
 
 # -ffast-math 
 
@@ -160,7 +162,7 @@
 endif
 
 CXXFLAGS=	$(CFLAGS) -Wno-non-virtual-dtor -Wno-unknown-pragmas -Wno-reorder  \
-		-fno-exceptions -fno-rtti -mthumb-interwork
+		-fno-exceptions -fno-rtti -mthumb-interwork -ffunction-sections -fdata-sections
 
 #		-mthumb
 
@@ -180,7 +182,7 @@
 endif
 
 
-LDFLAGS = -specs=ds_arm9.specs -mthumb-interwork -Wl,--wrap,time -mno-fpu -Wl,-Map,map.txt
+LDFLAGS = -specs=ds_arm9.specs -mthumb-interwork -Wl,--wrap,time -mno-fpu -Wl,-Map,map.txt -Wl,--gc-sections
 
 INCLUDES= -I./ -I$(portdir)/$(BUILD) -I$(srcdir) -I$(srcdir)/common -I$(portdir)/source \
 			-I$(portdir)/data -I$(libndsdir)/include -I$(portdir)/../commoninclude\
@@ -259,7 +261,7 @@
 #OPTLIST :=
 
 # Compiler options for files which should be optimised for speed
-OPT_SPEED := -O2
+OPT_SPEED := -O3
 
 # Compiler options for files which should be optimised for space
 OPT_SIZE := -Os
@@ -281,7 +283,7 @@
 include $(srcdir)/Makefile.common
 
 semiclean:
-	$(RM) $(portdir)/source/dsoptions.o $(portdir)/source/dsmain.o $(FAT_OBJS) $(DATA_OBJS) $(portdir)/source/wordcompletion.o
+	$(RM) $(portdir)/source/dsoptions.o $(portdir)/source/dsmain.o $(FAT_OBJS) $(DATA_OBJS) $(portdir)/source/wordcompletion.o $(portdir)/source/dsoptions.o 
 
 clean:
 	$(RM) $(OBJS) $(EXECUTABLE)

Modified: scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/dsmain.cpp
===================================================================
--- scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/dsmain.cpp	2008-08-14 19:20:25 UTC (rev 33869)
+++ scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/dsmain.cpp	2008-08-14 19:48:39 UTC (rev 33870)
@@ -168,7 +168,7 @@
 u8 gameID;
 
 bool snapToBorder = false;
-bool consoleEnable = true;
+bool consoleEnable = false;
 bool gameScreenSwap = false;
 bool isCpuScalerEnabled();
 //#define HEAVY_LOGGING
@@ -197,7 +197,14 @@
 bool cursorEnable = false;
 bool mouseCursorVisible = true;
 bool rightButtonDown = false;
+bool touchPadStyle = false;
+int touchPadSensitivity = 8;
+bool tapScreenClicks = true;
 
+int tapCount = 0;
+int tapTimeout = 0;
+int tapComplete = 0;
+
 // Dragging
 int dragStartX, dragStartY;
 bool dragging = false;
@@ -213,14 +220,22 @@
 // Scale
 bool twoHundredPercentFixedScale = false;
 bool cpuScalerEnable = false;
-#define NUM_SUPPORTED_GAMES 20
 
+		// 100    256
+		// 150	  192
+		// 200	  128
+
+		// (256 << 8) / scale 
+		
+
+
 #ifdef USE_PROFILER
 int hBlankCount = 0;
 #endif
 
 u8* scalerBackBuffer = NULL;
 
+#define NUM_SUPPORTED_GAMES 21
 
 gameListType gameList[NUM_SUPPORTED_GAMES] = {
 	// Unknown game - use normal SCUMM controls
@@ -248,6 +263,7 @@
 	{"elvira2",		CONT_SIMON},
 	{"elvira1",		CONT_SIMON},
 	{"waxworks",		CONT_SIMON},
+	{"parallaction",	CONT_NIPPON},
 };
 
 gameListType* currentGame = NULL;
@@ -260,6 +276,7 @@
 bool penReleased;
 bool penDownLastFrame;
 s32 penX, penY;
+s32 penDownX, penDownY;
 int keysDownSaved;
 int keysReleasedSaved;
 int keysChangedSaved;
@@ -299,10 +316,42 @@
 	cpuScalerEnable = enable;
 }
 
+void setTrackPadStyleEnable(bool enable) {
+	touchPadStyle = enable;
+}
 
+void setTapScreenClicksEnable(bool enable) {
+	tapScreenClicks = enable;
+}
+
+void setGameScreenSwap(bool enable) {
+	gameScreenSwap = enable;
+}
+
+void setSensitivity(int sensitivity) {
+	touchPadSensitivity = sensitivity;
+}
+
+void setTopScreenZoom(int percentage) {
+		// 100    256
+		// 150	  192
+		// 200	  128
+
+		// (256 << 8) / scale 
+		
+	s32 scale = (percentage << 8) / 100;
+	subScreenScale = (256 * 256) / scale;
+
+//	consolePrintf("Scale is %d %%\n", percentage);
+}
+
 //	return (ConfMan.hasKey("cpu_scaler", "ds") && ConfMan.getBool("cpu_scaler", "ds"));
 
+controlType getControlType() {
+	return currentGame->control;
+}
 
+
 //plays an 8 bit mono sample at 11025Hz
 void playSound(const void* data, u32 length, bool loop, bool adpcm, int rate)
 {
@@ -436,7 +485,7 @@
 
 	//strcpy(gameName, ConfMan.getActiveDomain().c_str());
 	strcpy(gameName, ConfMan.get("gameid").c_str());
-	consolePrintf("\n\n\n\nCurrent game: '%s' %d\n", gameName, gameName[0]);
+//	consolePrintf("\n\n\n\nCurrent game: '%s' %d\n", gameName, gameName[0]);
 
 	currentGame = &gameList[0];		// Default game
 	
@@ -660,17 +709,20 @@
 	
 		memset(SPRITE_GFX + off, 0, 32 * 32 * 2);
 		memset(SPRITE_GFX_SUB + off, 0, 32 * 32 * 2);
+
 	
 		for (uint y=0; y<h; y++) {
 			for (uint x=0; x<w; x++) {
 				int color = icon[y*w+x];
+
+				//consolePrintf("%d:%d ", color, OSystem_DS::instance()->getDSPaletteEntry(color));
 	
 				if (color == keycolor) {
 					SPRITE_GFX[off+(y)*32+x] = 0x0000; // black background
 					SPRITE_GFX_SUB[off+(y)*32+x] = 0x0000; // black background
 				} else {
-					SPRITE_GFX[off+(y)*32+x] = BG_PALETTE[color] | 0x8000;
-					SPRITE_GFX_SUB[off+(y)*32+x] = BG_PALETTE[color] | 0x8000;
+					SPRITE_GFX[off+(y)*32+x] = OSystem_DS::instance()->getDSCursorPaletteEntry(color) | 0x8000;
+					SPRITE_GFX_SUB[off+(y)*32+x] = OSystem_DS::instance()->getDSCursorPaletteEntry(color) | 0x8000;
 				}
 			}
 		}
@@ -733,6 +785,7 @@
 		sprites[1].attribute[1] = ATTR1_SIZE_64 | pos;
 		sprites[1].attribute[2] = ATTR2_ALPHA(1) | 176;
 	}
+
 }
 
 
@@ -745,6 +798,7 @@
 
 	u16 buffer[32 * 32 * 2];
 
+	releaseAllKeys();
 
 	if (displayModeIs8Bit) {
 //		static int test = 0;
@@ -1109,7 +1163,7 @@
 
 	} else {
 
-
+		DS::releaseAllKeys();
 		// Restore the palette that the keyboard has used
 		for (int r = 0; r < 256; r++) {
 			BG_PALETTE_SUB[r] = BG_PALETTE[r];
@@ -1157,6 +1211,178 @@
 	return displayModeIs8Bit;
 }
 
+void doScreenTapMode(OSystem_DS* system)
+{
+	Common::Event event;
+	static bool left = false, right = false;
+
+	if (left) {
+		event.type = Common::EVENT_LBUTTONUP;
+		event.mouse = Common::Point(getPenX(), getPenY());
+		system->addEvent(event);
+		left = false;
+	}
+
+	if (right) {
+		event.type = Common::EVENT_RBUTTONUP;
+		event.mouse = Common::Point(getPenX(), getPenY());
+		system->addEvent(event);
+		right = false;
+	}
+
+
+	if (tapComplete == 1) {
+		event.type = Common::EVENT_LBUTTONDOWN;
+		event.mouse = Common::Point(getPenX(), getPenY());
+		system->addEvent(event);
+		tapComplete = 0;
+		left = true;
+	} else if (tapComplete == 2) {
+		event.type = Common::EVENT_RBUTTONDOWN;
+		event.mouse = Common::Point(getPenX(), getPenY());
+		system->addEvent(event);
+		tapComplete = 0;
+		right = true;
+	}
+
+
+	if (getKeysDown() & KEY_LEFT) {
+		event.type = Common::EVENT_LBUTTONDOWN;
+		event.mouse = Common::Point(getPenX(), getPenY());
+		system->addEvent(event);
+	}
+
+	if (getKeysReleased() & KEY_LEFT) {
+		event.type = Common::EVENT_LBUTTONUP;
+		event.mouse = Common::Point(getPenX(), getPenY());
+		system->addEvent(event);
+	}
+
+
+	if (getKeysDown() & KEY_RIGHT) {
+		event.type = Common::EVENT_RBUTTONDOWN;
+		event.mouse = Common::Point(getPenX(), getPenY());
+		system->addEvent(event);
+	}
+
+	if (getKeysReleased() & KEY_RIGHT) {
+		event.type = Common::EVENT_RBUTTONUP;
+		event.mouse = Common::Point(getPenX(), getPenY());
+		system->addEvent(event);
+	}
+
+	event.type = Common::EVENT_MOUSEMOVE;
+	event.mouse = Common::Point(getPenX(), getPenY());
+	system->addEvent(event);
+}
+
+void doButtonSelectMode(OSystem_DS* system)
+{
+	Common::Event event;
+
+
+	if ((!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R))) {
+		event.type = Common::EVENT_MOUSEMOVE;
+		event.mouse = Common::Point(getPenX(), getPenY());
+		system->addEvent(event);
+		//consolePrintf("x=%d   y=%d  \n", getPenX(), getPenY());
+	}
+
+
+	if ((mouseMode != MOUSE_HOVER) || (!displayModeIs8Bit)) {
+		if (getPenDown() && (!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R))) {	
+			event.type = ((mouseMode == MOUSE_LEFT) || (!displayModeIs8Bit))? Common::EVENT_LBUTTONDOWN: Common::EVENT_RBUTTONDOWN;
+			event.mouse = Common::Point(getPenX(), getPenY());
+			system->addEvent(event);
+		}
+		
+		if (getPenReleased()) {
+			event.type = mouseMode == MOUSE_LEFT? Common::EVENT_LBUTTONUP: Common::EVENT_RBUTTONUP;
+			event.mouse = Common::Point(getPenX(), getPenY());
+			system->addEvent(event);
+		}
+	} else {
+		// In hover mode, D-pad left and right click the mouse when the pen is on the screen
+
+		if (getPenHeld()) {
+			if (getKeysDown() & KEY_LEFT) {
+				event.type = Common::EVENT_LBUTTONDOWN;
+				event.mouse = Common::Point(getPenX(), getPenY());
+				system->addEvent(event);
+			}
+			if (getKeysReleased() & KEY_LEFT) {
+				event.type = Common::EVENT_LBUTTONUP;
+				event.mouse = Common::Point(getPenX(), getPenY());
+				system->addEvent(event);
+			}
+
+
+			if (getKeysDown() & KEY_RIGHT) {
+				event.type = Common::EVENT_RBUTTONDOWN;
+				event.mouse = Common::Point(getPenX(), getPenY());
+				system->addEvent(event);
+			}
+			if (getKeysReleased() & KEY_RIGHT) {
+				event.type = Common::EVENT_RBUTTONUP;
+				event.mouse = Common::Point(getPenX(), getPenY());
+				system->addEvent(event);
+			}
+		}
+	}
+
+	if (!((getKeysHeld() & KEY_L) || (getKeysHeld() & KEY_R)) && (!getIndyFightState()) && (!getKeyboardEnable())) {
+
+		if (!getPenHeld() || (mouseMode != MOUSE_HOVER)) {
+			if (getKeysDown() & KEY_LEFT) {
+				mouseMode = MOUSE_LEFT;
+			}
+		
+			if (rightButtonDown)
+			{
+				Common::Event event;
+				event.mouse = Common::Point(getPenX(), getPenY());
+				event.type = Common::EVENT_RBUTTONUP;
+				system->addEvent(event);
+				rightButtonDown = false;
+			}
+				
+		
+			if (getKeysDown() & KEY_RIGHT) {
+				if ((currentGame->control != CONT_SCUMM_SAMNMAX) && (currentGame->control != CONT_FUTURE_WARS) && (currentGame->control != CONT_GOBLINS)) {
+					mouseMode = MOUSE_RIGHT;
+				} else {
+					// If we're playing sam and max, click and release the right mouse
+					// button to change verb
+					Common::Event event;
+		
+					if (currentGame->control == CONT_FUTURE_WARS) {
+						event.mouse = Common::Point(320 - 128, 200 - 128);
+						event.type = Common::EVENT_MOUSEMOVE;
+						system->addEvent(event);
+					} else {
+						event.mouse = Common::Point(getPenX(), getPenY());
+					}
+					
+					rightButtonDown = true;
+		
+		
+					event.type = Common::EVENT_RBUTTONDOWN;
+					system->addEvent(event);
+		
+					//event.type = Common::EVENT_RBUTTONUP;
+					//system->addEvent(event);
+				}
+			}
+		
+		
+		
+			if (getKeysDown() & KEY_UP) {
+				mouseMode = MOUSE_HOVER;
+			}
+		}
+	}
+}
+
 void addEventsToQueue() {
 	#ifdef HEAVY_LOGGING
 	consolePrintf("addEventsToQueue\n");
@@ -1286,54 +1512,6 @@
 
 				}
 	
-				if (!getPenHeld() || (mouseMode != MOUSE_HOVER)) {
-					if (getKeysDown() & KEY_LEFT) {
-						mouseMode = MOUSE_LEFT;
-					}
-
-					if (rightButtonDown)
-					{
-						Common::Event event;
-						event.mouse = Common::Point(getPenX(), getPenY());
-						event.type = Common::EVENT_RBUTTONUP;
-						system->addEvent(event);
-						rightButtonDown = false;
-					}
-						
-
-					if (getKeysDown() & KEY_RIGHT) {
-						if ((currentGame->control != CONT_SCUMM_SAMNMAX) && (currentGame->control != CONT_FUTURE_WARS) && (currentGame->control != CONT_GOBLINS)) {
-							mouseMode = MOUSE_RIGHT;
-						} else {
-							// If we're playing sam and max, click and release the right mouse
-							// button to change verb
-							Common::Event event;
-
-							if (currentGame->control == CONT_FUTURE_WARS) {
-								event.mouse = Common::Point(320 - 128, 200 - 128);
-								event.type = Common::EVENT_MOUSEMOVE;
-								system->addEvent(event);
-							} else {
-								event.mouse = Common::Point(getPenX(), getPenY());
-							}
-							
-							rightButtonDown = true;
-
-		
-							event.type = Common::EVENT_RBUTTONDOWN;
-							system->addEvent(event);
-		
-							//event.type = Common::EVENT_RBUTTONUP;
-							//system->addEvent(event);
-						}
-					}
-
-
-
-					if (getKeysDown() & KEY_UP) {
-						mouseMode = MOUSE_HOVER;
-					}
-				}
 	
 					
 				
@@ -1359,52 +1537,13 @@
 	
 		if (!keyboardEnable) {
 
-			if ((!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R))) {
-				event.type = Common::EVENT_MOUSEMOVE;
-				event.mouse = Common::Point(getPenX(), getPenY());
-				system->addEvent(event);
-				//consolePrintf("x=%d   y=%d  \n", getPenX(), getPenY());
+			if ((tapScreenClicks) && (getIsDisplayMode8Bit()))
+			{
+				doScreenTapMode(system);
 			}
-
-			if ((mouseMode != MOUSE_HOVER) || (!displayModeIs8Bit)) {
-					if (getPenDown() && (!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R))) {	
-						event.type = ((mouseMode == MOUSE_LEFT) || (!displayModeIs8Bit))? Common::EVENT_LBUTTONDOWN: Common::EVENT_RBUTTONDOWN;
-						event.mouse = Common::Point(getPenX(), getPenY());
-						system->addEvent(event);
-					}
-					
-					if (getPenReleased()) {
-						event.type = mouseMode == MOUSE_LEFT? Common::EVENT_LBUTTONUP: Common::EVENT_RBUTTONUP;
-						event.mouse = Common::Point(getPenX(), getPenY());
-						system->addEvent(event);
-					}
-			} else {
-				// In hover mode, D-pad left and right click the mouse when the pen is on the screen
-	
-				if (getPenHeld()) {
-					if (getKeysDown() & KEY_LEFT) {
-						event.type = Common::EVENT_LBUTTONDOWN;
-						event.mouse = Common::Point(getPenX(), getPenY());
-						system->addEvent(event);
-					}
-					if (getKeysReleased() & KEY_LEFT) {
-						event.type = Common::EVENT_LBUTTONUP;
-						event.mouse = Common::Point(getPenX(), getPenY());
-						system->addEvent(event);
-					}
-
-
-					if (getKeysDown() & KEY_RIGHT) {
-						event.type = Common::EVENT_RBUTTONDOWN;
-						event.mouse = Common::Point(getPenX(), getPenY());
-						system->addEvent(event);
-					}
-					if (getKeysReleased() & KEY_RIGHT) {
-						event.type = Common::EVENT_RBUTTONUP;
-						event.mouse = Common::Point(getPenX(), getPenY());
-						system->addEvent(event);
-					}
-				}
+			else
+			{
+				doButtonSelectMode(system);
 			}
 			
 			if (((!(getKeysHeld() & KEY_L)) && (!(getKeysHeld() & KEY_R)) || (indyFightState))  && (displayModeIs8Bit)) {
@@ -1537,8 +1676,8 @@
 	
 
 void setIcon(int num, int x, int y, int imageNum, int flags, bool enable) {
-	sprites[num].attribute[0] = ATTR0_BMP | (enable? y: 192) | (!enable? ATTR0_DISABLED: 0); 
-	sprites[num].attribute[1] = ATTR1_SIZE_32 | x | flags;
+	sprites[num].attribute[0] = ATTR0_BMP | (enable? (y & 0xFF): 192) | (!enable? ATTR0_DISABLED: 0); 
+	sprites[num].attribute[1] = ATTR1_SIZE_32 | (x & 0x1FF) | flags;
 	sprites[num].attribute[2] = ATTR2_ALPHA(1)| (imageNum * 16);
 }
 
@@ -1552,28 +1691,30 @@
 	int offs;
 
 	if (displayModeIs8Bit) {
-		switch (mouseMode) {
-			case MOUSE_LEFT: {
-				offs = 1;
-				break;
+		if (!touchPadStyle) {
+			switch (mouseMode) {
+				case MOUSE_LEFT: {
+					offs = 1;
+					break;
+				}
+				case MOUSE_RIGHT: {
+					offs = 2;
+					break;
+				}
+ 				case MOUSE_HOVER: {
+					offs = 0;
+					break;
+				}
+				default: {
+					// Nothing!
+					offs = 0;
+					break;
+				}
 			}
-			case MOUSE_RIGHT: {
-				offs = 2;
-				break;
-			}
-			case MOUSE_HOVER: {
-				offs = 0;
-				break;
-			}
-			default: {
-				// Nothing!
-				offs = 0;
-				break;
-			}
+		
+			setIcon(0, 208, 150, offs, 0, true);
 		}
 	
-		setIcon(0, 208, 150, offs, 0, true);
-	
 		if (indyFightState) {
 			setIcon(1, (190 - 32), 150, 3, (indyFightRight? 0: ATTR1_FLIP_X), true);
 //			consolePrintf("%d\n", indyFightRight);
@@ -1631,7 +1772,7 @@
 		BG3_CX = x + (((frameCount & 1) == 0)? 64: 0);
 		BG3_CY = y;
 		
-		if (!gameScreenSwap) {
+		if ((!gameScreenSwap) || (touchPadStyle)) {
 			touchX = x >> 8;
 			touchY = y >> 8;
 		}
@@ -1660,7 +1801,7 @@
 			BG3_YDY = y;
 		}
 		
-		if (!gameScreenSwap) {		
+		if ((!gameScreenSwap) || (touchPadStyle)) {		
 			touchScX = x;
 			touchScY = y;
 		}
@@ -1676,7 +1817,7 @@
 		touchY = y >> 8;
 	} else */{
 
-		if (gameScreenSwap) {
+		if ((gameScreenSwap) && (!touchPadStyle)) {
 			touchX = x >> 8;
 			touchY = y >> 8;
 		}
@@ -1696,7 +1837,7 @@
 
 	} else */{
 
-		if (gameScreenSwap) {
+		if ((gameScreenSwap) && (!touchPadStyle)) {
 			touchScX = x;
 			touchScY = y;
 		}
@@ -1764,11 +1905,18 @@
 			storedMouseY = penY;
 		}
 
-		setIconMain(3, storedMouseX - mouseHotspotX, storedMouseY - mouseHotspotY, 8, 0, true);
+		if (gameScreenSwap) {
+			setIcon(3, storedMouseX - mouseHotspotX, storedMouseY - mouseHotspotY, 8, 0, true);
+			setIconMain(3, 0, 0, 0, 0, false);
+		} else {
+			setIconMain(3, storedMouseX - mouseHotspotX, storedMouseY - mouseHotspotY, 8, 0, true);
+			setIcon(3, 0, 0, 0, 0, false);
+		}
 	}
 	else
 	{
 		setIconMain(3, 0, 0, 0, 0, false);
+		setIcon(3, 0, 0, 0, 0, false);
 	}
 
 
@@ -1826,7 +1974,7 @@
     SUB_BG3_YDX = 0;
     SUB_BG3_YDY = (int) (subScreenHeight / 192.0f * 256);*/
 
-	static int ratio = ( 320 << 8) / SCUMM_GAME_WIDTH;
+	static int ratio = (320 << 8) / SCUMM_GAME_WIDTH;
 	
 	bool zooming = false;
 	
@@ -1851,8 +1999,12 @@
 		subScreenWidth = 256 >> 1;
 		subScreenHeight = 192 >> 1;
 	} else {
-		subScreenWidth = (((SCUMM_GAME_HEIGHT * 256) / 192) * subScreenScale) >> 8;
-		subScreenHeight = SCUMM_GAME_HEIGHT * subScreenScale >> 8;
+//		subScreenWidth = (((SCUMM_GAME_HEIGHT * 256) / 192) * subScreenScale) >> 8;
+//		subScreenHeight = SCUMM_GAME_HEIGHT * subScreenScale >> 8;
+
+
+		subScreenWidth = (256 * subScreenScale) >> 8; 
+		subScreenHeight = (192 * subScreenScale) >> 8;
 		
 		if ( ((subScreenWidth) > 256 - 8) && ((subScreenWidth) < 256 + 8) ) {
 			subScreenWidth = 256;
@@ -2215,43 +2367,141 @@
 
 //	if (getKeysHeld() & KEY_L) consolePrintf("%d, %d   penX=%d, penY=%d tz=%d\n", IPC->touchXpx, IPC->touchYpx, penX, penY, IPC->touchZ1);
 
-	if ((penDownFrames > 1)) {			// Is this right?  Dunno, but it works for me.
+	bool penDownThisFrame = (IPC->touchZ1 > 0) && (IPC->touchXpx > 0) && (IPC->touchYpx > 0);
+	bool firstFrame = penDownFrames == 2;
+	static bool moved = false;
 
-		if ((penHeld)) {
-			penHeld = true;
+	if ((tapScreenClicks) && (!getKeyboardEnable()) && (getIsDisplayMode8Bit())) {
+
+		if ((tapTimeout >= 0)) {
+			tapTimeout++;
+	
+			if (((tapTimeout > 15) || (tapCount == 2)) && (tapCount > 0)) {
+				tapComplete = tapCount;
+				tapCount = 0;
+//				consolePrintf("Taps: %d\n", tapComplete);
+			}
+		}
+
+		
+
+		if ((penHeld) && (!penDownThisFrame)) {
+			if ((touchPadStyle) || (moved) || (tapCount == 1)) {
+				if ((penDownFrames > 0) && (penDownFrames < 6) && ((tapTimeout == -1) || (tapTimeout > 2))) {
+					tapCount++;
+					tapTimeout = 0;
+//					consolePrintf("Tap! %d\n", penDownFrames);
+					moved = false;
+				}
+			}
+		}
+	}
+
+	
+
+	if ((touchPadStyle) && (getIsDisplayMode8Bit())) {
+	
+		if ((penDownFrames > 0)) {			
+	
+	
+			if ((penHeld)) {
+	
+				if (penDownThisFrame)
+				{
+					if (penDownFrames >= 2) {
+						int diffX = IPC->touchXpx - penDownX;
+						int diffY = IPC->touchYpx - penDownY;
+
+						int speed = ABS(diffX) + ABS(diffY);
+
+						if ((ABS(diffX) < 35) && (ABS(diffY) < 35))
+						{
+	
+							if (speed >= 8)
+							{
+								diffX *= ((speed >> 3) * touchPadSensitivity) >> 3;
+								diffY *= ((speed >> 3) * touchPadSensitivity) >> 3;
+							}
+		
+							penX += diffX;
+							penY += diffY;
+							if (penX > 255) penX = 255;
+							if (penX < 0) penX = 0;
+							if (penY > 191) penY = 191;
+							if (penY < 0) penY = 0;
+						}
+	
+//						consolePrintf("x: %d y: %d\n", IPC->touchYpx - penDownY, IPC->touchYpx - penDownY);
+						penDownX = IPC->touchXpx;
+						penDownY = IPC->touchYpx;
+	
+					}
+				}
+				else
+				{
+				}
+	
+	
+			} else {
+				penDown = true;
+				penHeld = true;
+				penDownSaved = true;
+	
+				// First frame, so save pen positions
+				if (penDownThisFrame) {
+					penDownX = IPC->touchXpx;
+					penDownY = IPC->touchYpx;
+				}
+			}
+	
+		} else {
+			if (penHeld) {
+				penReleased = true;
+				penReleasedSaved = true;
+			} else {
+				penReleased = false;
+			}
+	
 			penDown = false;
+			penHeld = false;
+		}
+	} else {
+		if ((penDownFrames > 1)) {			// Is this right?  Dunno, but it works for me.
+	
+			if ((penHeld)) {
+				penHeld = true;
+				penDown = false;
+			} else {
+				penDown = true;
+				penHeld = true;
+				penDownSaved = true;
+			}
 
 			if ((IPC->touchZ1 > 0) && (IPC->touchXpx > 0) && (IPC->touchYpx > 0)) {
 				penX = IPC->touchXpx + touchXOffset;
 				penY = IPC->touchYpx + touchYOffset;
+				moved = true;
 			}
+					
 
+	
 		} else {
-			penDown = true;
-			penHeld = true;
-			penDownSaved = true;
-
-			//if ( (ABS(penX - IPC->touchXpx) < 10) && (ABS(penY - IPC->touchYpx) < 10) ) {
-			if ((IPC->touchZ1 > 0) && (IPC->touchXpx > 0) && (IPC->touchYpx > 0)) {
-				penX = IPC->touchXpx;
-				penY = IPC->touchYpx;
+			if (penHeld) {
+				penReleased = true;
+				penReleasedSaved = true;
+			} else {
+				penReleased = false;
 			}
-			//}
+	
+			penDown = false;
+			penHeld = false;
 		}
+	
+	
+	}
 
-	} else {
-		if (penHeld) {
-			penReleased = true;
-			penReleasedSaved = true;
-		} else {
-			penReleased = false;
-		}
 
-		penDown = false;
-		penHeld = false;
-	}
 
-
 	if ((IPC->touchZ1 > 0) || ((penDownFrames == 2)) ) {
 		penDownLastFrame = true;
 		penDownFrames++;
@@ -2259,7 +2509,6 @@
 		penDownLastFrame = false;
 		penDownFrames = 0;
 	}
-	
 }
 
 int leftHandedSwap(int keys) {
@@ -2346,8 +2595,7 @@
 	int x = ((penX * touchScX) >> 8) + touchX;
 	x = x < 0? 0: (x > gameWidth - 1? gameWidth - 1: x);
 
-	if (snapToBorder)
-	{
+	if (snapToBorder) {
 		if (x < 8) x = 0;
 		if (x > gameWidth - 8) x = gameWidth - 1;
 	}
@@ -2359,8 +2607,7 @@
 	int y = ((penY * touchScY) >> 8) + touchY;
 	y = y < 0? 0: (y > gameHeight - 1? gameHeight - 1: y);
 
-	if (snapToBorder)
-	{
+	if (snapToBorder) {
 		if (y < 8) y = 0;
 		if (y > gameHeight - 8) y = gameHeight - 1;
 	}
@@ -2663,7 +2910,7 @@
 	consolePrintf("-------------------------------\n");
 	consolePrintf("ScummVM DS\n");
 	consolePrintf("Ported by Neil Millstone\n");
-	consolePrintf("Version 0.11.1 beta2");
+	consolePrintf("Version 0.12.0 beta1 ");
 #if defined(DS_BUILD_A)
 	consolePrintf("build A\n");
 	consolePrintf("Lucasarts SCUMM games (SCUMM)\n");
@@ -2689,8 +2936,8 @@
 	consolePrintf("The Legend of Kyrandia (KYRA)\n");
 	consolePrintf("-------------------------------\n");
 #elif defined(DS_BUILD_G)
-	consolePrintf("build F\n");
-	consolePrintf("Lure of the Temptress (LURE)\n");
+	consolePrintf("build G\n");
+	consolePrintf("PARALLATION, LURE\n");
 	consolePrintf("-------------------------------\n");
 #endif
 	consolePrintf("L/R + D-pad/pen:    Scroll view\n");

Modified: scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/dsmain.h
===================================================================
--- scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/dsmain.h	2008-08-14 19:20:25 UTC (rev 33869)
+++ scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/dsmain.h	2008-08-14 19:48:39 UTC (rev 33870)
@@ -38,7 +38,8 @@
 	CONT_SIMON,
 	CONT_FUTURE_WARS,
 	CONT_AGI,
-	CONT_GOBLINS
+	CONT_GOBLINS,
+	CONT_NIPPON,
 };
 
 struct gameListType {
@@ -56,6 +57,7 @@
 int 	getPenY();
 GLvector getPenPos();
 void 	consumePenEvents();
+controlType getControlType();
 
 // Pad reading
 int 	getKeysHeld();
@@ -64,6 +66,8 @@
 int 	getKeysReleased();
 void 	consumeKeys();
 int 	leftHandedSwap(int keys);
+void	setGameScreenSwap(bool enable);
+void	setSensitivity(int sensitivity);
 
 // Video
 void 	displayMode8Bit();											// Switch to 8-bit mode5
@@ -81,6 +85,7 @@
 void 	setTalkPos(int x, int y);
 void 	setTopScreenTarget(int x, int y);
 void	set200PercentFixedScale(bool on);
+void	setTopScreenZoom(int percentage);
 
 // Timers
 void 	setTimerCallback(OSystem_DS::TimerProc proc, int interval);		// Setup a callback function at a regular interval
@@ -131,6 +136,8 @@
 bool 	getIndyFightState();
 bool    isCpuScalerEnabled();
 void	setCpuScalerEnable(bool enable);
+void	setTrackPadStyleEnable(bool enable);
+void	setTapScreenClicksEnable(bool enable);
 
 // Display
 bool 	getIsDisplayMode8Bit();

Modified: scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/dsoptions.cpp
===================================================================
--- scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/dsoptions.cpp	2008-08-14 19:20:25 UTC (rev 33869)
+++ scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/dsoptions.cpp	2008-08-14 19:48:39 UTC (rev 33870)
@@ -25,6 +25,7 @@
 #include "gui/dialog.h"
 #include "gui/newgui.h"
 #include "gui/ListWidget.h"
+#include "gui/TabWidget.h"
 #include "osystem_ds.h"
 #include "engines/scumm/scumm.h"
 #include "touchkeyboard.h"
@@ -41,9 +42,68 @@
 
 namespace DS {
 
-DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(5, 0, 320 - 5, 230 - 20) {
-	addButton(this, 10, 175, "Close", GUI::kCloseCmd, 'C');
+DSOptionsDialog::DSOptionsDialog() : GUI::Dialog(0, 0, 320 - 10, 230 - 40) {
 
+	addButton(this, 10, 170, "Close", GUI::kCloseCmd, 'C');
+	_tab = new GUI::TabWidget(this, 5, 5, 300, 230 - 20 - 40 - 10);
+
+	_tab->addTab("Controls");
+
+	_leftHandedCheckbox = new GUI::CheckboxWidget(_tab, 5, 5, 130, 20, "Left handed mode", 0, 'L');
+	_indyFightCheckbox = new GUI::CheckboxWidget(_tab, 5, 20, 140, 20, "Indy fight controls", 0, 'I');
+	_showCursorCheckbox = new GUI::CheckboxWidget(_tab, 150, 5, 130, 20, "Show mouse cursor", 0, 'T');
+	_snapToBorderCheckbox = new GUI::CheckboxWidget(_tab, 150, 20, 130, 20, "Snap to edges", 0, 'T');
+
+	new GUI::StaticTextWidget(_tab, 20, 35, 100, 15, "Touch X Offset", GUI::kTextAlignLeft);
+	_touchX = new GUI::SliderWidget(_tab, 130, 35, 130, 12, 1);
+	_touchX->setMinValue(-8);
+	_touchX->setMaxValue(+8);
+	_touchX->setValue(0);
+	_touchX->setFlags(GUI::WIDGET_CLEARBG);
+
+	new GUI::StaticTextWidget(_tab, 20, 50, 100, 15, "Touch Y Offset", GUI::kTextAlignLeft);
+	_touchY = new GUI::SliderWidget(_tab, 130, 50, 130, 12, 2);
+	_touchY->setMinValue(-8);
+	_touchY->setMaxValue(+8);
+	_touchY->setValue(0);
+	_touchY->setFlags(GUI::WIDGET_CLEARBG);
+
+	new GUI::StaticTextWidget(_tab, 130 + 65 - 10, 65, 20, 15, "0", GUI::kTextAlignCenter);
+	new GUI::StaticTextWidget(_tab, 130 + 130 - 10, 65, 20, 15, "8", GUI::kTextAlignCenter);
+	new GUI::StaticTextWidget(_tab, 130 - 20, 65, 20, 15, "-8", GUI::kTextAlignCenter);
+
+
+	_touchPadStyle = new GUI::CheckboxWidget(_tab, 5, 80, 270, 20, "Use laptop trackpad-style cursor control", 0x20000001, 'T');
+	_screenTaps = new GUI::CheckboxWidget(_tab, 5, 95, 285, 20, "Tap for left click, double tap right click", 0x20000002, 'T');
+
+	_sensitivityLabel = new GUI::StaticTextWidget(_tab, 20, 110, 110, 15, "Sensitivity", GUI::kTextAlignLeft);
+	_sensitivity = new GUI::SliderWidget(_tab, 130, 110, 130, 12, 1);
+	_sensitivity->setMinValue(4);
+	_sensitivity->setMaxValue(16);
+	_sensitivity->setValue(8);
+	_sensitivity->setFlags(GUI::WIDGET_CLEARBG);
+
+	_tab->addTab("Graphics");
+
+	new GUI::StaticTextWidget(_tab, 5, 70, 180, 15, "Initial top screen scale:", GUI::kTextAlignLeft);
+
+	_100PercentCheckbox = new GUI::CheckboxWidget(_tab, 5, 85, 230, 20, "100%", 0x30000001, 'T');
+	_150PercentCheckbox = new GUI::CheckboxWidget(_tab, 5, 100, 230, 20, "150%", 0x30000002, 'T');
+	_200PercentCheckbox = new GUI::CheckboxWidget(_tab, 5, 115, 230, 20, "200%", 0x30000003, 'T');
+
+	new GUI::StaticTextWidget(_tab, 5, 5, 180, 15, "Main screen scaling:", GUI::kTextAlignLeft);
+
+	_hardScaler = new GUI::CheckboxWidget(_tab, 5, 20, 270, 20, "Hardware scale (fast, but low quality)", 0x10000001, 'T');
+	_cpuScaler = new GUI::CheckboxWidget(_tab, 5, 35, 270, 20, "Software scale (good quality, but slower)", 0x10000002, 'S');
+	_unscaledCheckbox = new GUI::CheckboxWidget(_tab, 5, 50, 270, 20, "Unscaled (you must scroll left and right)", 0x10000003, 'S');
+
+	_tab->addTab("General");
+
+	_highQualityAudioCheckbox = new GUI::CheckboxWidget(_tab, 5, 5, 250, 20, "High quality audio (slower) (reboot)", 0, 'T');
+	_disablePowerOff = new GUI::CheckboxWidget(_tab, 5, 20, 200, 20, "Disable power off", 0, 'T');
+
+	_tab->setActiveTab(0);
+
 	_radioButtonMode = false;
 	
 #ifdef DS_SCUMM_BUILD
@@ -52,47 +112,18 @@
 	}
 #endif
 
-	new GUI::StaticTextWidget(this, 90, 10, 130, 15, "ScummVM DS Options", GUI::kTextAlignCenter);
+//	new GUI::StaticTextWidget(this, 90, 10, 130, 15, "ScummVM DS Options", GUI::kTextAlignCenter);
 
-	_leftHandedCheckbox = new GUI::CheckboxWidget(this, 5, 70, 130, 20, "Left handed mode", 0, 'L');
-	_indyFightCheckbox = new GUI::CheckboxWidget(this, 5, 40, 200, 20, "Indy fighting controls", 0, 'I');
-	_twoHundredPercentCheckbox = new GUI::CheckboxWidget(this, 5, 55, 230, 20, "Zoomed screen at fixed 200% zoom", 0, 'T');
-	_highQualityAudioCheckbox = new GUI::CheckboxWidget(this, 5, 25, 250, 20, "High quality audio (slower) (reboot)", 0, 'T');
-	_disablePowerOff = new GUI::CheckboxWidget(this, 5, 85, 130, 20, "Disable power off", 0, 'T');
-	_showCursorCheckbox = new GUI::CheckboxWidget(this, 5, 100, 130, 20, "Show mouse cursor", 0, 'T');
 
 //#ifdef ALLOW_CPU_SCALER
 //	_cpuScaler = new GUI::CheckboxWidget(this, 160, 115, 90, 20, "CPU scaler", 0, 'T');
 //#endif
 
-	new GUI::StaticTextWidget(this, 180, 70, 130, 15, "Main screen:", GUI::kTextAlignLeft);
-
-	_hardScaler = new GUI::CheckboxWidget(this, 140, 85, 170, 20, "Hardware scale (fast)", 0x10000001, 'T');
-	_cpuScaler = new GUI::CheckboxWidget(this, 140, 100, 170, 20, "Software scale (quality)", 0x10000002, 'S');
-	_unscaledCheckbox = new GUI::CheckboxWidget(this, 140, 115, 170, 20, "Unscaled", 0x10000003, 'S');
 	
 
 
-	_snapToBorderCheckbox = new GUI::CheckboxWidget(this, 5, 115, 120, 20, "Snap to border", 0, 'T');
 
-	new GUI::StaticTextWidget(this, 20, 145, 110, 15, "Touch X Offset", GUI::kTextAlignLeft);
-	_touchX = new GUI::SliderWidget(this, 130, 145, 130, 12, 1);
-	_touchX->setMinValue(-8);
-	_touchX->setMaxValue(+8);
-	_touchX->setValue(0);
-	_touchX->setFlags(GUI::WIDGET_CLEARBG);
 
-	new GUI::StaticTextWidget(this, 20, 160, 110, 15, "Touch Y Offset", GUI::kTextAlignLeft);
-	_touchY = new GUI::SliderWidget(this, 130, 160, 130, 12, 2);
-	_touchY->setMinValue(-8);
-	_touchY->setMaxValue(+8);
-	_touchY->setValue(0);
-	_touchY->setFlags(GUI::WIDGET_CLEARBG);
-
-	new GUI::StaticTextWidget(this, 130 + 65 - 10, 175, 20, 15, "0", GUI::kTextAlignCenter);
-	new GUI::StaticTextWidget(this, 130 + 130 - 10, 175, 20, 15, "8", GUI::kTextAlignCenter);
-	new GUI::StaticTextWidget(this, 130 - 10, 175, 20, 15, "-8", GUI::kTextAlignCenter);
-
 #ifdef DS_SCUMM_BUILD
 	_delDialog = new Scumm::SaveLoadChooser("Delete game:", "Delete", false, Scumm::g_scumm);
 #endif
@@ -125,10 +156,36 @@
 		_unscaledCheckbox->setState(false);
 	}
 
-	if (ConfMan.hasKey("twohundredpercent", "ds")) {
-		_twoHundredPercentCheckbox->setState(ConfMan.getBool("twohundredpercent", "ds"));
+	
+	if (ConfMan.hasKey("topscreenzoom", "ds")) {
+
+		_100PercentCheckbox->setState(false);		
+		_150PercentCheckbox->setState(false);		
+		_200PercentCheckbox->setState(false);		
+		
+		switch (ConfMan.getInt("topscreenzoom", "ds"))
+		{
+			case 100: {
+				_100PercentCheckbox->setState(true);
+				break;
+			}
+
+			case 150: {
+				_150PercentCheckbox->setState(true);
+				break;
+			}
+
+			case 200: {
+				_200PercentCheckbox->setState(true);
+				break;
+			}
+		}
+
+	} else if (ConfMan.hasKey("twohundredpercent", "ds")) {
+		_200PercentCheckbox->setState(ConfMan.getBool("twohundredpercent", "ds"));
 	} else {
-		_twoHundredPercentCheckbox->setState(false);
+		// No setting
+		_150PercentCheckbox->setState(true);
 	}
 
 	if (ConfMan.hasKey("22khzaudio", "ds")) {
@@ -165,6 +222,29 @@
 		_touchY->setValue(0);
 	}
 
+	if (ConfMan.hasKey("sensitivity", "ds")) {
+		_sensitivity->setValue(ConfMan.getInt("sensitivity", "ds"));
+	} else {
+		_sensitivity->setValue(8);
+	}
+
+	if (ConfMan.hasKey("touchpad", "ds")) {
+		_touchPadStyle->setState(ConfMan.getBool("touchpad", "ds"));
+	} else {
+		_touchPadStyle->setState(0);
+	}
+
+	if (ConfMan.hasKey("screentaps", "ds")) {
+		_screenTaps->setState(ConfMan.getBool("screentaps", "ds"));
+	} else {
+		_screenTaps->setState(0);
+	}
+
+	_screenTaps->setEnabled(!_touchPadStyle->getState());
+	_sensitivity->setEnabled(_touchPadStyle->getState());
+	_sensitivityLabel->setEnabled(_touchPadStyle->getState());
+	_sensitivityLabel->draw();
+
 	if (!_cpuScaler->getState() && !_unscaledCheckbox->getState()) {
 		_hardScaler->setState(true);
 	}
@@ -180,7 +260,7 @@
 void DSOptionsDialog::updateConfigManager() {
 	ConfMan.setBool("lefthanded", _leftHandedCheckbox->getState(), "ds");
 	ConfMan.setBool("unscaled", _unscaledCheckbox->getState(), "ds");
-	ConfMan.setBool("twohundredpercent", _twoHundredPercentCheckbox->getState(), "ds");
+//	ConfMan.setBool("twohundredpercent", _twoHundredPercentCheckbox->getState(), "ds");
 	ConfMan.setBool("22khzaudio", _highQualityAudioCheckbox->getState(), "ds");
 	ConfMan.setBool("disablepoweroff", _disablePowerOff->getState(), "ds");
 #ifdef ALLOW_CPU_SCALER
@@ -190,6 +270,24 @@
 	ConfMan.setInt("yoffset", _touchY->getValue(), "ds");
 	ConfMan.setBool("showcursor", _showCursorCheckbox->getState(), "ds");
 	ConfMan.setBool("snaptoborder", _snapToBorderCheckbox->getState(), "ds");
+	ConfMan.setBool("touchpad", _touchPadStyle->getState(), "ds");
+	ConfMan.setBool("screentaps", _screenTaps->getState(), "ds");
+	ConfMan.setInt("sensitivity", _sensitivity->getValue(), "ds");
+
+	u32 zoomLevel = 150;
+
+	if (_100PercentCheckbox->getState()) {
+		zoomLevel = 100;
+	} else if (_150PercentCheckbox->getState()) {
+		zoomLevel = 150;
+	} else if (_200PercentCheckbox->getState()) {
+		zoomLevel = 200;
+	}
+
+	consolePrintf("Saved zoom: %d\n", zoomLevel);
+
+	ConfMan.setInt("topscreenzoom", zoomLevel, "ds");
+
 	DS::setOptions();
 }
 
@@ -227,6 +325,70 @@
 
 	}
 
+	if ((!guard) && (_radioButtonMode))
+	{
+		guard = true;
+
+		if ((sender == _touchPadStyle) && (cmd == 0x20000001)) {
+
+			if (_touchPadStyle->getState()) {
+				// Swap screens when turning on trackpad style, it feels
+				// much more natural!
+				DS::setGameScreenSwap(true);
+
+				_screenTaps->setState(true);
+				_screenTaps->setEnabled(false);
+				_screenTaps->draw();
+				_sensitivity->setEnabled(true);
+				_sensitivityLabel->setEnabled(true);
+				_sensitivityLabel->draw();
+				_sensitivity->draw();
+			} else {
+				DS::setGameScreenSwap(false);
+
+				_screenTaps->setEnabled(true);
+				_screenTaps->setState(false);
+				_screenTaps->draw();
+				_sensitivity->setEnabled(false);
+				_sensitivityLabel->setEnabled(false);
+				_sensitivityLabel->draw();
+				_sensitivity->draw();
+			}
+		}
+
+		guard = false;
+	}
+
+	if ((!guard) && (_radioButtonMode)) {
+
+		guard = true;
+
+		if (cmd == 0x30000001) {
+			_100PercentCheckbox->setState(true);
+			_150PercentCheckbox->setState(false);
+			_200PercentCheckbox->setState(false);
+			DS::setTopScreenZoom(100);
+		}
+
+		if (cmd == 0x30000002) {
+			_100PercentCheckbox->setState(false);
+			_150PercentCheckbox->setState(true);
+			_200PercentCheckbox->setState(false);
+			DS::setTopScreenZoom(150);
+		}
+
+		if (cmd == 0x30000003) {
+			_100PercentCheckbox->setState(false);
+			_150PercentCheckbox->setState(false);
+			_200PercentCheckbox->setState(true);
+			DS::setTopScreenZoom(200);
+		}
+
+		guard = false;
+
+	}
+
+
 	if (cmd == GUI::kCloseCmd) {
 		updateConfigManager();
 		close();
@@ -297,6 +459,8 @@
 }
 
 void setOptions() {
+	static bool firstLoad = true;
+
 	ConfMan.addGameDomain("ds");
 
 	if (ConfMan.hasKey("lefthanded", "ds")) {
@@ -327,10 +491,16 @@
 		DS::setUnscaledMode(false);
 	}
 
-	if (ConfMan.hasKey("twohundredpercent", "ds")) {
-		DS::set200PercentFixedScale(ConfMan.getBool("twohundredpercent", "ds"));
-	} else {
-		DS::set200PercentFixedScale(false);
+	if (firstLoad) {
+		if (ConfMan.hasKey("topscreenzoom", "ds")) {
+			DS::setTopScreenZoom(ConfMan.getInt("topscreenzoom", "ds"));
+		} else {
+			if (ConfMan.hasKey("twohundredpercent", "ds")) {
+				DS::setTopScreenZoom(200);
+			} else {
+				DS::setTopScreenZoom(150);
+			}
+		}
 	}
 
 	if (ConfMan.hasKey("xoffset", "ds")) {
@@ -345,6 +515,12 @@
 		DS::setTouchXOffset(0);
 	}
 
+	if (ConfMan.hasKey("sensitivity", "ds")) {
+		DS::setSensitivity(ConfMan.getInt("sensitivity", "ds"));
+	} else {
+		DS::setSensitivity(8);
+	}
+
 #ifdef ALLOW_CPU_SCALER
 	if (ConfMan.hasKey("cpu_scaler", "ds")) {
 		DS::setCpuScalerEnable(ConfMan.getBool("cpu_scaler", "ds"));
@@ -353,6 +529,33 @@
 	}
 #endif	
 
+	if (ConfMan.hasKey("screentaps", "ds")) {
+		DS::setTapScreenClicksEnable(ConfMan.getBool("screentaps", "ds"));
+	} else {
+		DS::setTapScreenClicksEnable(false);
+	}
+
+	if (ConfMan.hasKey("touchpad", "ds")) {
+		bool enable = ConfMan.getBool("touchpad", "ds");
+		
+		DS::setTrackPadStyleEnable(enable);
+
+		if ((enable) and (firstLoad)) {
+			// If we've just booted up, want to swap screens when trackpad mode is in use
+			// but not every time we enter the options dialog.
+			DS::setGameScreenSwap(true);
+		}
+
+		if (enable) {
+			DS::setTapScreenClicksEnable(true);
+		}
+			
+	} else {
+		DS::setTrackPadStyleEnable(false);
+	}
+
+
+	firstLoad = false;
 }
 
 }

Modified: scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/dsoptions.h
===================================================================
--- scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/dsoptions.h	2008-08-14 19:20:25 UTC (rev 33869)
+++ scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/dsoptions.h	2008-08-14 19:48:39 UTC (rev 33870)
@@ -30,6 +30,7 @@
 #include "gui/object.h"
 #include "gui/widget.h"
 #include "gui/dialog.h"
+#include "gui/TabWidget.h"
 #include "scumm/dialogs.h"
 
 namespace DS {
@@ -45,11 +46,18 @@
 	void togglePause();
 	void updateConfigManager();
 
+	GUI::TabWidget* _tab;
+
+	GUI::StaticTextWidget* _sensitivityLabel;
+
 	GUI::SliderWidget* _touchX;
 	GUI::SliderWidget* _touchY;
+	GUI::SliderWidget* _sensitivity;
 	GUI::CheckboxWidget* _leftHandedCheckbox;
 	GUI::CheckboxWidget* _unscaledCheckbox;
-	GUI::CheckboxWidget* _twoHundredPercentCheckbox;
+	GUI::CheckboxWidget* _100PercentCheckbox;
+	GUI::CheckboxWidget* _150PercentCheckbox;
+	GUI::CheckboxWidget* _200PercentCheckbox;
 	GUI::CheckboxWidget* _indyFightCheckbox;
 	GUI::CheckboxWidget* _highQualityAudioCheckbox;
 	GUI::CheckboxWidget* _disablePowerOff;
@@ -59,6 +67,9 @@
 	GUI::CheckboxWidget* _hardScaler;
 	GUI::CheckboxWidget* _cpuScaler;
 	
+	GUI::CheckboxWidget* _touchPadStyle;
+	GUI::CheckboxWidget* _screenTaps;
+
 #ifdef DS_SCUMM_BUILD
 	Scumm::SaveLoadChooser* _delDialog;
 #endif

Modified: scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/gbampsave.cpp
===================================================================
--- scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/gbampsave.cpp	2008-08-14 19:20:25 UTC (rev 33869)
+++ scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/gbampsave.cpp	2008-08-14 19:48:39 UTC (rev 33870)
@@ -155,11 +155,13 @@
 		sprintf(fileSpec, "%s/%s", getSavePath(), name);
 	}
 	
-//	consolePrintf(fileSpec);
+//	consolePrintf("Opening the file: %s\n", fileSpec);
 	GBAMPSaveFile* sf = new GBAMPSaveFile(fileSpec, saveOrLoad);
 	if (sf->isOpen()) {
+//		consolePrintf("Ok");
 		return sf;	
 	} else {
+//		consolePrintf("Fail");
 		delete sf;
 		return NULL;	
 	}

Modified: scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/osystem_ds.cpp
===================================================================
--- scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/osystem_ds.cpp	2008-08-14 19:20:25 UTC (rev 33869)
+++ scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/osystem_ds.cpp	2008-08-14 19:48:39 UTC (rev 33870)
@@ -41,7 +41,8 @@
 OSystem_DS* OSystem_DS::_instance = NULL;
 
 OSystem_DS::OSystem_DS()
-	: eventNum(0), lastPenFrame(0), queuePos(0), _mixer(NULL), _timer(NULL), _frameBufferExists(false)
+	: eventNum(0), lastPenFrame(0), queuePos(0), _mixer(NULL), _timer(NULL), _frameBufferExists(false),
+	_disableCursorPalette(true), _graphicsEnable(true)
 {
 //	eventNum = 0;
 //	lastPenFrame = 0;
@@ -79,7 +80,7 @@
 
 bool OSystem_DS::hasFeature(Feature f) {
 //	consolePrintf("hasfeature\n");
-	return (f == kFeatureVirtualKeyboard);
+	return (f == kFeatureVirtualKeyboard) || (f == kFeatureCursorHasPalette);
 }
 
 void OSystem_DS::setFeatureState(Feature f, bool enable) {
@@ -107,7 +108,7 @@
 }
 
 bool OSystem_DS::setGraphicsMode(const char *name) {
-//	consolePrintf("Set gfx mode %s\n", name);
+	consolePrintf("Set gfx mode %s\n", name);
 	return true;
 }
 
@@ -116,8 +117,15 @@
 }
 
 void OSystem_DS::initSize(uint width, uint height) {
-//	consolePrintf("Set gfx mode %d x %d\n", width, height);
-	DS::setGameSize(width, height);
+	// For Lost in Time, the title screen is displayed in 640x400.
+	// In order to support this game, the screen mode is set, but
+	// all draw calls are ignored until the game switches to 320x200.
+	if ((width == 640) && (height == 400)) {
+		_graphicsEnable = false;
+	} else {
+		_graphicsEnable = true;
+		DS::setGameSize(width, height);
+	}
 }
 
 int16 OSystem_DS::getHeight() {
@@ -129,9 +137,6 @@
 }
 
 void OSystem_DS::setPalette(const byte *colors, uint start, uint num) {
-//	consolePrintf("Set palette %d, %d colours\n", start, num);
-//return;
-	if (!DS::getIsDisplayMode8Bit()) return;
 	for (unsigned int r = start; r < start + num; r++) {
 		int red = *colors;
 		int green = *(colors + 1);
@@ -141,20 +146,48 @@
 		green >>= 3;
 		blue >>= 3;
 		
-		if (r != 255)
+//		if (r != 255)
 		{		
-			BG_PALETTE[r] = red | (green << 5) | (blue << 10);
-			if (!DS::getKeyboardEnable()) {
-				BG_PALETTE_SUB[r] = red | (green << 5) | (blue << 10);
+			u16 paletteValue = red | (green << 5) | (blue << 10);
+
+			if (DS::getIsDisplayMode8Bit()) {
+				BG_PALETTE[r] = paletteValue;
+				if (!DS::getKeyboardEnable()) {
+					BG_PALETTE_SUB[r] = paletteValue;
+				}
 			}
+
+			_palette[r] = paletteValue;
 		}
-//		if (num == 16) consolePrintf("pal:%d r:%d g:%d b:%d\n", r, red, green, blue);
+	//	if (num == 255) consolePrintf("pal:%d r:%d g:%d b:%d\n", r, red, green, blue);
 		
 		colors += 4;
 	}
 }
 
+void OSystem_DS::setCursorPalette(const byte *colors, uint start, uint num) {
+
+//	consolePrintf("Cursor palette set: start: %d, cols: %d\n", start, num);
+	for (unsigned int r = start; r < start + num; r++) {
+		int red = *colors;
+		int green = *(colors + 1);
+		int blue = *(colors + 2);
+		
+		red >>= 3;
+		green >>= 3;
+		blue >>= 3;
+		
+		u16 paletteValue = red | (green << 5) | (blue << 10);
+		_cursorPalette[r] = paletteValue;
+	
+		colors += 4;
+	}
+
+	_disableCursorPalette = false;
+}
+
 bool OSystem_DS::grabRawScreen(Graphics::Surface* surf) {
+
 	surf->create(DS::getGameWidth(), DS::getGameHeight(), 1);
 
 	// Ensure we copy using 16 bit quantities due to limitation of VRAM addressing
@@ -184,9 +217,11 @@
 }
 
 
+#define MISALIGNED16(ptr) (((u32) (ptr) & 1) != 0)
+
 void OSystem_DS::copyRectToScreen(const byte *buf, int pitch, int x, int y, int w, int h) {
-//	consolePrintf("Copy rect %d, %d   %d, %d ", x, y, w, h);
-	
+	//consolePrintf("Copy rect %d, %d   %d, %d ", x, y, w, h);
+	if (!_graphicsEnable) return;	
 	if (w <= 1) return;
 	if (h < 0) return;
 	if (!DS::getIsDisplayMode8Bit()) return;
@@ -195,6 +230,9 @@
 	s32 stride;
 	u16* bgSub = (u16 *) BG_GFX_SUB;
 
+	// The DS video RAM doesn't support 8-bit writes because Nintendo wanted
+	// to save a few pennies/euro cents on the hardware.
+
 	if (_frameBufferExists) {
 		bg = (u16 *) _framebuffer.pixels;
 		stride = _framebuffer.pitch;
@@ -203,36 +241,111 @@
 		stride = DS::get8BitBackBufferStride();
 	}
 
-	u16* src = (u16 *) buf;
+	if (((pitch & 1) != 0) || ((w & 1) != 0) || (((int) (buf) & 1) != 0)) {
+
+		// Something is misaligned, so we have to use the slow but sure method
+
+		int by = 0;
+
+		for (int dy = y; dy < y + h; dy++) {
+			u8* dest = ((u8 *) (bg)) + (dy * stride) + x;
+			u8* destSub = ((u8 *) (bgSub)) + (dy * 512) + x;
+			u8* src = (u8 *) buf + (pitch * by);
+			
+			u32 dx;
+
+			u32 pixelsLeft = w;
+
+			if (MISALIGNED16(dest))	{
+				// Read modify write
+
+				dest--;
+				u16 mix = *((u16 *) dest);
+
+				mix = (mix & 0x00FF) | (*src++ << 8);
+
+				*dest = mix;
+				*destSub = mix;
+
+				dest += 2;
+				destSub += 2;
+				pixelsLeft--;
+			}
+
+			// We can now assume dest is aligned
+			u16* dest16 = (u16 *) dest;
+			u16* destSub16 = (u16 *) destSub;
+
+			for (dx = 0; dx < pixelsLeft; dx+=2)	{
+				u16 mix;
+
+				mix = *src + (*(src + 1) << 8);
+				*dest16++ = mix;
+				*destSub16++ = mix;
+				src += 2;
+			}
+
+			pixelsLeft -= dx;
+
+			// At the end we may have one pixel left over
+
+			if (pixelsLeft != 0) {
+				u16 mix = *dest16;
+
+				mix = (mix & 0xFF00) | (*src++);
+
+				*dest16 = mix;
+				*destSub16 = mix;
+			}
+
+			by++;
+				
+		}
+
+//		consolePrintf("Slow method used!\n");
+
+
+	} else {
+
+		// Stuff is aligned to 16-bit boundaries, so it's safe to do DMA.
 	
-	if (DS::getKeyboardEnable()) {
+		u16* src = (u16 *) buf;
+		
+		if (DS::getKeyboardEnable()) {
+		
+			for (int dy = y; dy < y + h; dy++) {
+				u16* dest = bg + (dy * (stride >> 1)) + (x >> 1);
+			
+				DC_FlushRange(src, w << 1);
+				DC_FlushRange(dest, w << 1);
+				dmaCopyHalfWords(3, src, dest, w);
 	
-		for (int dy = y; dy < y + h; dy++) {
-			u16* dest = bg + (dy * (stride >> 1)) + (x >> 1);
+				while (dmaBusy(3));
+						
+				src += pitch >> 1;
+			}
 		
-			DC_FlushRange(src, w << 1);
-			DC_FlushRange(dest, w << 1);
-			dmaCopyHalfWords(3, src, dest, w);
-					
-			src += pitch >> 1;
-		}
+		} else {
+			for (int dy = y; dy < y + h; dy++) {
+				u16* dest1 = bg + (dy * (stride >> 1)) + (x >> 1);
+				u16* dest2 = bgSub + (dy << 8) + (x >> 1);
+				
+				DC_FlushRange(src, w << 1);
+				DC_FlushRange(dest1, w << 1);
+				DC_FlushRange(dest2, w << 1);
+						
+				dmaCopyHalfWords(3, src, dest1, w);
 	
-	} else {
-		for (int dy = y; dy < y + h; dy++) {
-			u16* dest1 = bg + (dy * (stride >> 1)) + (x >> 1);
-			u16* dest2 = bgSub + (dy << 8) + (x >> 1);
-			
-			DC_FlushRange(src, w << 1);
-			DC_FlushRange(dest1, w << 1);
-			DC_FlushRange(dest2, w << 1);
-					
-			dmaCopyHalfWords(3, src, dest1, w);
-			dmaCopyHalfWords(3, src, dest2, w);
-					
-			src += pitch >> 1;
+				if ((!_frameBufferExists) || (buf == _framebuffer.pixels)) {
+					dmaCopyHalfWords(2, src, dest2, w);
+				}
+	
+				while (dmaBusy(2) || dmaBusy(3));
+						
+				src += pitch >> 1;
+			}
 		}
 	}
-	
 //	consolePrintf("Done\n");
 	
 			
@@ -241,6 +354,8 @@
 
 void OSystem_DS::updateScreen() {
 
+
+
 	if ((_frameBufferExists) && (DS::getIsDisplayMode8Bit()))
 	{
 		_frameBufferExists = false;
@@ -253,6 +368,12 @@
 	DS::doSoundCallback();
 //	DS::doTimerCallback();
 	DS::addEventsToQueue();
+
+	// Force back buffer usage for Nippon Safes, as it doesn't double buffer it's output
+	if (DS::getControlType() == DS::CONT_NIPPON) {
+		OSystem_DS::instance()->lockScreen();
+		OSystem_DS::instance()->unlockScreen();
+	}
 }
 
 void OSystem_DS::setShakePos(int shakeOffset) {
@@ -559,6 +680,7 @@
 
 
 Graphics::Surface *OSystem_DS::lockScreen() {
+	
 	if (!_frameBufferExists) {
 		createTempFrameBuffer();
 	}

Modified: scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/osystem_ds.h
===================================================================
--- scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/osystem_ds.h	2008-08-14 19:20:25 UTC (rev 33869)
+++ scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/osystem_ds.h	2008-08-14 19:48:39 UTC (rev 33870)
@@ -58,11 +58,15 @@
 	DSTimerManager* _timer;
 	Graphics::Surface _framebuffer;
 	bool _frameBufferExists;
+	bool _graphicsEnable;
 
+	static OSystem_DS* _instance;
 
-	static OSystem_DS* _instance;
+	u16 _palette[256];
+	u16 _cursorPalette[256];
 	
 	Graphics::Surface* createTempFrameBuffer();
+	bool _disableCursorPalette;
 
 public:
 	typedef void (*SoundProc)(byte *buf, int len);
@@ -159,6 +163,13 @@
 	virtual void clearAutoComplete();
 	virtual void setCharactersEntered(int count);
 
+	u16 getDSPaletteEntry(u32 entry) { return _palette[entry]; }
+	u16 getDSCursorPaletteEntry(u32 entry) { return !_disableCursorPalette? _cursorPalette[entry]: _palette[entry]; }
+
+	virtual void setCursorPalette(const byte *colors, uint start, uint num);
+
+	virtual void disableCursorPalette(bool dis) { _disableCursorPalette = dis; }
+
 	FilesystemFactory *getFilesystemFactory();
 };
 

Modified: scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/portdefs.h
===================================================================
--- scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/portdefs.h	2008-08-14 19:20:25 UTC (rev 33869)
+++ scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/portdefs.h	2008-08-14 19:48:39 UTC (rev 33870)
@@ -81,8 +81,11 @@
 
 #define ITCM_DATA	__attribute__((section(".itcm")))
 
+// Since I can't change the engine at the moment (post lockdown) this define can go here.
+// This define changes the mouse-relative motion which doesn't make sense on a touch screen to 
+// a more conventional form of input where the menus can be clicked on.
+#define LURE_CLICKABLE_MENUS
 
-
 //#include "common/array.h"
 //#include "common/str.h"
 

Modified: scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/touchkeyboard.cpp
===================================================================
--- scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/touchkeyboard.cpp	2008-08-14 19:20:25 UTC (rev 33869)
+++ scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/touchkeyboard.cpp	2008-08-14 19:48:39 UTC (rev 33870)
@@ -402,6 +402,23 @@
 	}				
 }
 
+void releaseAllKeys() {
+	for (int r = 0; r < DS_NUM_KEYS; r++) {
+		if (keys[r].pressed) {
+			DS::setKeyHighlight(r, false);
+
+			OSystem_DS* system = OSystem_DS::instance();
+			
+			Common::Event event;
+			createKeyEvent(r, event);
+			event.type = Common::EVENT_KEYUP;
+			system->addEvent(event);
+
+			keys[r].pressed = false;
+		}
+	}	
+}
+
 void addKeyboardEvents() {
 	bool resetShift = false;
 
@@ -446,7 +463,7 @@
 //				consolePrintf("Key: %d\n", r);
 				if ((keys[r].character == Common::KEYCODE_INVALID)) {
 					// Close button
-					DS::closed = true;
+					//DS::closed = true;
 				} else {
 					createKeyEvent(r, event);
 				}				
@@ -492,9 +509,14 @@
 			   	OSystem_DS* system = OSystem_DS::instance();
 				
 				Common::Event event;
-				createKeyEvent(r, event);
-				event.type = Common::EVENT_KEYUP;
-				system->addEvent(event);
+				if ((keys[r].character == Common::KEYCODE_INVALID)) {
+					// Close button
+					DS::closed = true;
+				} else {
+					createKeyEvent(r, event);
+					event.type = Common::EVENT_KEYUP;
+					system->addEvent(event);
+				}
 
 				keys[r].pressed = false;
 

Modified: scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/touchkeyboard.h
===================================================================
--- scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/touchkeyboard.h	2008-08-14 19:20:25 UTC (rev 33869)
+++ scummvm/branches/branch-0-12-0/backends/platform/ds/arm9/source/touchkeyboard.h	2008-08-14 19:48:39 UTC (rev 33870)
@@ -40,6 +40,7 @@
 void addAutoComplete(char* word);
 void clearAutoComplete();
 void setCharactersEntered(int count);
+void releaseAllKeys();
 
 }
 

Modified: scummvm/branches/branch-0-12-0/backends/platform/ds/makefile
===================================================================
--- scummvm/branches/branch-0-12-0/backends/platform/ds/makefile	2008-08-14 19:20:25 UTC (rev 33869)
+++ scummvm/branches/branch-0-12-0/backends/platform/ds/makefile	2008-08-14 19:48:39 UTC (rev 33870)
@@ -36,3 +36,19 @@
 	make all       SCUMM_BUILD=f
 	make semiclean
 	make all       SCUMM_BUILD=g
+
+allbuildssafe:
+	make clean     SCUMM_BUILD=a
+	make all       SCUMM_BUILD=a
+	make clean     SCUMM_BUILD=b
+	make all       SCUMM_BUILD=b
+	make clean     SCUMM_BUILD=c
+	make all       SCUMM_BUILD=c
+	make clean     SCUMM_BUILD=d
+	make all       SCUMM_BUILD=d
+	make clean     SCUMM_BUILD=e
+	make all       SCUMM_BUILD=e
+	make clean     SCUMM_BUILD=f
+	make all       SCUMM_BUILD=f
+	make clean     SCUMM_BUILD=g
+	make all       SCUMM_BUILD=g


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list