diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/common/file.cpp ./scummvm/common/file.cpp
--- ./scummvm.cvs/common/file.cpp	Wed May 11 00:55:47 2005
+++ ./scummvm/common/file.cpp	Mon Aug 29 09:32:10 2005
@@ -100,6 +100,65 @@
 	return file;
 }
 
+static bool removeNoCase(const char *filename, const char *directory) {
+	char buf[512];
+	char *ptr;
+
+	assert(directory);
+	strcpy(buf, directory);
+
+#if !defined(__GP32__) && !defined(__PALM_OS__)
+	// Add a trailing slash, if necessary.
+	if (buf[0] != 0) {
+		const int dirLen = strlen(buf);
+		if (buf[dirLen-1] != ':' && buf[dirLen-1] != '/' && buf[dirLen-1] != '\\')
+			strcat(buf, "/");
+	}
+#endif
+
+	// Append the filename to the path string
+	const int offsetToFileName = strlen(buf);
+	strcat(buf, filename);
+
+	//
+	// Try to remove the file normally
+	//
+	if (remove(buf) == 0)
+			return true;
+
+	//
+	// Try again, with file name converted to upper case
+	//
+	ptr = buf + offsetToFileName;
+	while (*ptr) {
+		*ptr = toupper(*ptr);
+		ptr++;
+	}
+	if (remove(buf) == 0)
+		return true;
+
+	//
+	// Try again, with file name converted to lower case
+	//
+	ptr = buf + offsetToFileName;
+	while (*ptr) {
+		*ptr = tolower(*ptr);
+		ptr++;
+	}
+	if (remove(buf) == 0)
+		return true;
+
+	//
+	// Try again, with file name capitalized
+	//
+	ptr = buf + offsetToFileName;
+	*ptr = toupper(*ptr);
+	if (remove(buf) == 0)
+		return true;
+
+	return false;
+}
+
 void File::addDefaultDirectory(const String &directory) {
 	_defaultDirectories.push_back(directory);
 }
@@ -186,6 +245,31 @@
 	// FIXME: Ugly ugly hack!
 	File tmp;
 	return tmp.open(filename, kFileReadMode, directory);
+}
+
+bool File::remove(const char *filename, const char *directory) {
+	if (!exists(filename, directory))
+		return false;
+
+	bool removed = false;
+
+	if (directory) {
+		if (removeNoCase(filename, directory))
+			removed = true;
+	} else {
+		// removes all files with this name in the standard directories
+		StringList::const_iterator x;
+		for (x = _defaultDirectories.begin(); x != _defaultDirectories.end(); ++x) {
+			if (removeNoCase(filename, x->c_str()))
+				removed = true;
+		}
+	}
+
+	if (!removed) {
+		debug(2, "Coudln't remove file '%s' (specified directory: '%s')", filename, directory);
+	}
+
+	return removed;
 }
 
 void File::close() {
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/common/file.h ./scummvm/common/file.h
--- ./scummvm.cvs/common/file.h	Sun Aug 14 09:39:23 2005
+++ ./scummvm/common/file.h	Mon Aug 29 08:44:54 2005
@@ -63,6 +63,8 @@
 
 	virtual bool open(const char *filename, AccessMode mode = kFileReadMode, const char *directory = NULL);
 	static bool exists(const char *filename, const char *directory = NULL);
+	// this COULD remove whole directories, so use with caution
+	static bool remove(const char *filename, const char *directory = NULL);
 
 	virtual void close();
 	bool isOpen() const;
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/dialogs.cpp ./scummvm/scumm/dialogs.cpp
--- ./scummvm.cvs/scumm/dialogs.cpp	Sun Aug 14 09:39:26 2005
+++ ./scummvm/scumm/dialogs.cpp	Mon Aug 29 10:43:13 2005
@@ -21,6 +21,7 @@
 #include "common/stdafx.h"
 
 #include "common/config-manager.h"
+#include "common/savefile.h"
 #include "common/system.h"
 #include "common/scaler.h"
 
@@ -28,6 +29,7 @@
 #include "gui/chooser.h"
 #include "gui/newgui.h"
 #include "gui/ListWidget.h"
+#include "gui/message.h"
 
 #include "scumm/dialogs.h"
 #include "scumm/sound.h"
@@ -193,9 +195,12 @@
 
 #pragma mark -
 
+Common::StringList generateSavegameList(ScummEngine *scumm, bool saveMode);
+
 enum {
 	kSaveCmd = 'SAVE',
 	kLoadCmd = 'LOAD',
+	kRemoveCmd = 'REM ',
 	kPlayCmd = 'PLAY',
 	kOptionsCmd = 'OPTN',
 	kHelpCmd = 'HELP',
@@ -208,9 +213,11 @@
 	typedef Common::StringList StringList;
 protected:
 	bool _saveMode;
+	GUI::ButtonWidget	*_removeButton;
+	ScummEngine		*_scumm;
 
 public:
-	SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode);
+	SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode, ScummEngine* scumm);
 
 	virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data);
 	const String &getResultString() const;
@@ -218,11 +225,14 @@
 	int runModal() { return GUI_ChooserDialog::runModal(); }
 };
 
-SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode)
-	: GUI::ChooserDialog(title, buttonLabel, 182), _saveMode(saveMode) {
+SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel, bool saveMode, ScummEngine* scumm)
+	: GUI::ChooserDialog(title, buttonLabel, 182), _saveMode(saveMode), _scumm(scumm) {
 
 	_list->setEditable(saveMode);
 	_list->setNumberingMode(saveMode ? GUI::kListNumberingOne : GUI::kListNumberingZero);
+
+	_removeButton = addButton(this, _x + 10, _h - kButtonHeight - 8, "Remove", kRemoveCmd, 0, GUI::kNormalWidgetSize);
+	_removeButton->setEnabled(false);
 }
 
 const Common::String &SaveLoadChooser::getResultString() const {
@@ -241,6 +251,24 @@
 			}
 		}
 		break;
+	case kRemoveCmd: {
+		GUI::MessageDialog alert("Do you really want to remove this savegame?", "Yes", "No");
+		if (alert.runModal() == GUI::kMessageOK) {
+			if (_scumm->removeState(_saveMode ? selItem + 1 : selItem)) {
+				GUI::TimedMessageDialog msg("Removed savegame successfully", 1000);
+				msg.runModal();
+				setList(generateSavegameList(_scumm, _saveMode));
+			} else {
+				GUI::TimedMessageDialog msg("Couldn't remove savegame", 1000);
+				msg.runModal();
+			}
+		}
+		_list->draw();
+		_chooseButton->setEnabled(false);
+		_chooseButton->draw();
+		_removeButton->setEnabled(false);
+		_removeButton->draw();
+	} break;
 	case GUI::kListSelectionChangedCmd:
 		if (_saveMode) {
 			_list->startEditMode();
@@ -250,6 +278,9 @@
 		// because we then just assign a default name.
 		_chooseButton->setEnabled(selItem >= 0 && (_saveMode || !getResultString().isEmpty()));
 		_chooseButton->draw();
+
+		_removeButton->setEnabled(selItem >= 0 && !getResultString().isEmpty());
+		_removeButton->draw();
 		break;
 	default:
 		GUI_ChooserDialog::handleCommand(sender, cmd, data);
@@ -270,7 +301,11 @@
 	bool _saveMode;
 	GUI::ListWidget		*_list;
 	GUI::ButtonWidget	*_chooseButton;
+	GUI::ButtonWidget	*_removeButton;
 	GUI::GraphicsWidget	*_gfxWidget;
+	GUI::StaticTextWidget	*_date;
+	GUI::StaticTextWidget	*_time;
+	GUI::StaticTextWidget	*_playtime;
 	ScummEngine			*_scumm;
 
 public:
@@ -300,7 +335,42 @@
 			((_scumm->_system->getHeight() % 200 && _scumm->_system->getHeight() != 350) ? kThumbnailHeight2 : kThumbnailHeight1) + 8);
 	_gfxWidget->setFlags(GUI::WIDGET_BORDER);
 
+	int height = 18 + ((_scumm->_system->getHeight() % 200 && _scumm->_system->getHeight() != 350) ? kThumbnailHeight2 : kThumbnailHeight1) + 8;
+
+	_date = new StaticTextWidget(this,
+					_w - (kThumbnailWidth + 22),
+					height,
+					kThumbnailWidth + 8,
+					kLineHeight,
+					"Date: 00.00.0000",
+					kTextAlignCenter);
+	_date->setFlags(GUI::WIDGET_CLEARBG);
+
+	height += kLineHeight;
+
+	_time = new StaticTextWidget(this,
+					_w - (kThumbnailWidth + 22),
+					height,
+					kThumbnailWidth + 8,
+					kLineHeight,
+					"Time: 00:00",
+					kTextAlignCenter);
+	_time->setFlags(GUI::WIDGET_CLEARBG);
+
+	height += kLineHeight;
+
+	_playtime = new StaticTextWidget(this,
+					_w - (kThumbnailWidth + 22),
+					height,
+					kThumbnailWidth + 8,
+					kLineHeight,
+					"Playtime: 00:00",
+					kTextAlignCenter);
+	_playtime->setFlags(GUI::WIDGET_CLEARBG);
+
 	// Buttons
+	_removeButton = addButton(this, _x + 10, _h - kBigButtonHeight - 8, "Remove", kRemoveCmd, 0, GUI::kBigWidgetSize);
+	_removeButton->setEnabled(false);
 	addButton(this, _w - 2 * (kBigButtonWidth + 10), _h - kBigButtonHeight - 8, "Cancel", kCloseCmd, 0, GUI::kBigWidgetSize);
 	_chooseButton = addButton(this, _w - (kBigButtonWidth + 10), _h - kBigButtonHeight - 8, buttonLabel, kChooseCmd, 0, GUI::kBigWidgetSize);
 	_chooseButton->setEnabled(false);
@@ -338,13 +408,70 @@
 		setResult(selItem);
 		close();
 		break;
+	case kRemoveCmd: {
+		GUI::MessageDialog alert("Do you really want to remove this savegame?", "Yes", "No");
+		if (alert.runModal() == GUI::kMessageOK) {
+			if (_scumm->removeState(_saveMode ? selItem + 1 : selItem)) {
+				GUI::TimedMessageDialog msg("Removed savegame successfully", 1000);
+				msg.runModal();
+				setList(generateSavegameList(_scumm, _saveMode));
+			} else {
+				GUI::TimedMessageDialog msg("Couldn't remove savegame", 1000);
+				msg.runModal();
+			}
+		}
+		_list->draw();
+		_chooseButton->setEnabled(false);
+		_chooseButton->draw();
+		_removeButton->setEnabled(false);
+		_removeButton->draw();
+	} break;
 	case GUI::kListSelectionChangedCmd: {
 		Graphics::Surface *thumb;
 		thumb = _scumm->loadThumbnailFromSlot(_saveMode ? selItem + 1 : selItem);
 		_gfxWidget->setGfx(thumb);
+		if (thumb)
+			thumb->free();
 		delete thumb;
 		_gfxWidget->draw();
 
+		InfoStuff infos;
+		memset(&infos, 0, sizeof(InfoStuff));
+		char buffer[32];
+		if (_scumm->loadInfosFromSlot(_saveMode ? selItem + 1 : selItem, &infos)) {
+			snprintf(buffer, 32, "Date: %.2d.%.2d.%.4d",
+				(infos.date >> 24) & 0xFF, (infos.date >> 16) & 0xFF,
+				infos.date & 0xFFFF);
+			_date->setLabel(buffer);
+			_date->draw();
+			
+			snprintf(buffer, 32, "Time: %.2d:%.2d",
+				(infos.time >> 8) & 0xFF, infos.time & 0xFF);
+			_time->setLabel(buffer);
+			_time->draw();
+
+			int minutes = infos.playtime / 60;
+			int hours = minutes / 60;
+			minutes %= 60;
+
+			snprintf(buffer, 32, "Playtime: %.2d:%.2d",
+				hours & 0xFF, minutes & 0xFF);
+			_playtime->setLabel(buffer);
+			_playtime->draw();
+		} else {
+			snprintf(buffer, 32, "No date saved");
+			_date->setLabel(buffer);
+			_date->draw();
+			
+			snprintf(buffer, 32, "No time saved");
+			_time->setLabel(buffer);
+			_time->draw();
+
+			snprintf(buffer, 32, "No playtime saved");
+			_playtime->setLabel(buffer);
+			_playtime->draw();
+		}
+
 		if (_saveMode) {
 			_list->startEditMode();
 		}
@@ -353,6 +480,10 @@
 		// because we then just assign a default name.
 		_chooseButton->setEnabled(selItem >= 0 && (_saveMode || !getResultString().isEmpty()));
 		_chooseButton->draw();
+		// same as above only that in save mode it is also disabled when choosing an
+		// empty savegame.
+		_removeButton->setEnabled(selItem >= 0 && !getResultString().isEmpty());
+		_removeButton->draw();
 	} break;
 	case kCloseCmd:
 		setResult(-1);
@@ -452,8 +583,8 @@
 	_helpDialog = new HelpDialog(scumm);
 #endif
 	if (scumm->_system->getOverlayWidth() <= 320) {
-		_saveDialog = new SaveLoadChooser("Save game:", "Save", true);
-		_loadDialog = new SaveLoadChooser("Load game:", "Load", false);
+		_saveDialog = new SaveLoadChooser("Save game:", "Save", true, scumm);
+		_loadDialog = new SaveLoadChooser("Load game:", "Load", false, scumm);
 	} else {
 		_saveDialog = new SaveLoadChooserEx("Save game:", "Save", true, scumm);
 		_loadDialog = new SaveLoadChooserEx("Load game:", "Load", false, scumm);
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/saveload.cpp ./scummvm/scumm/saveload.cpp
--- ./scummvm.cvs/scumm/saveload.cpp	Sun Aug 14 09:39:26 2005
+++ ./scummvm/scumm/saveload.cpp	Mon Aug 29 09:51:07 2005
@@ -51,6 +51,17 @@
 	char name[32];
 };
 
+struct SaveInfoHeader {
+	uint32 type;
+	uint32 size;
+	byte version;
+	
+	uint32 date;
+	uint16 time;
+	uint32 playtime;
+};
+
+#define INFOHEADER_VERSION 1
 
 void ScummEngine::requestSave(int slot, const char *name, bool temporary) {
 	_saveLoadSlot = slot;
@@ -84,6 +95,7 @@
 
 	out->write(&hdr, sizeof(hdr));
 	saveThumbnail(out);
+	saveInfos(out);
 
 	Serializer ser(0, out, CURRENT_VER);
 	saveOrLoad(&ser, CURRENT_VER);
@@ -111,7 +123,7 @@
 	}
 
 	// In older versions of ScummVM, the header version was not endian safe.
-	// We account for that by retrying once with swapped byte order.
+	// We account for that by retrying once wi_system->getMillis() / 1000th swapped byte order.
 	if (hdr.ver > CURRENT_VER)
 		hdr.ver = SWAP_BYTES_32(hdr.ver);
 	if (hdr.ver < VER(7) || hdr.ver > CURRENT_VER)
@@ -144,6 +156,22 @@
 		in->skip(size - 8);
 	}
 
+	// Since version 56 we have informations about the creating of the save game and the save time here
+	if (hdr.ver >= VER(56)) {
+		InfoStuff infos;
+		if (!loadInfos(in, &infos)) {
+			delete in;
+			return false;
+		}
+
+		_engineStartTime = _system->getMillis() / 1000 - infos.playtime;
+	} else {
+		// start time counting
+		_engineStartTime = _system->getMillis() / 1000;
+	}
+
+	_dialogStartTime = _system->getMillis() / 1000;
+
 	// Due to a bug in scummvm up to and including 0.3.0, save games could be saved
 	// in the V8/V9 format but were tagged with a V7 mark. Ouch. So we just pretend V7 == V8 here
 	if (hdr.ver == VER(7))
@@ -359,6 +387,9 @@
 
 	_sound->pauseSounds(false);
 
+	_engineStartTime += _system->getMillis() / 1000 - _dialogStartTime;
+	_dialogStartTime = 0;
+
 	return true;
 }
 
@@ -438,6 +469,105 @@
 
 	delete in;
 	return thumb;
+}
+
+bool ScummEngine::loadInfosFromSlot(int slot, InfoStuff *stuff) {
+	char filename[256];
+	Common::InSaveFile *in;
+	SaveGameHeader hdr;
+	int len;
+
+	makeSavegameName(filename, slot, false);
+	if (!(in = _saveFileMan->openForLoading(filename))) {
+		return false;
+	}
+	len = in->read(&hdr, sizeof(hdr));
+
+	if (len != sizeof(hdr) || hdr.type != MKID('SCVM')) {
+		delete in;
+		return false;
+	}
+
+	if (hdr.ver > CURRENT_VER)
+		hdr.ver = TO_LE_32(hdr.ver);
+	if (hdr.ver < VER(56)) {
+		delete in;
+		return false;
+	}
+
+	uint32 type;
+	in->read(&type, 4);
+
+	// Check for the THMB header. Also, work around a bug which caused
+	// the chunk type (incorrectly) to be written in LE on LE machines.
+	if (! (type == MKID('THMB') || (hdr.ver < VER(55) && type == MKID('BMHT')))){
+		delete in;
+		return false;
+	}
+	uint32 size = in->readUint32BE();
+	in->skip(size - 8);
+
+	if (!loadInfos(in, stuff)) {
+		delete in;
+		return false;
+	}
+	
+	delete in;	
+	return true;
+}
+
+bool ScummEngine::removeState(int slot) {
+	const char* savePath = _saveFileMan->getSavePath();
+	char filename[256];
+	makeSavegameName(filename, slot, false);
+	return Common::File::remove(filename, savePath);
+}
+
+bool ScummEngine::loadInfos(Common::InSaveFile *file, InfoStuff *stuff) {
+	SaveInfoHeader header;
+	file->read(&header.type, 4);
+	if (header.type != MKID('INFO')) {
+		warning("Couldn't load info section");
+		return false;
+	}
+
+	header.version = file->readByte();
+	if (header.version > INFOHEADER_VERSION) {
+		warning("Infoheader version is too high");
+		return false;
+	}
+
+	header.size = file->readUint32BE();
+	
+	header.date = file->readUint32BE();
+	header.time = file->readUint16BE();
+	header.playtime = file->readUint32BE();
+
+	stuff->date = header.date;
+	stuff->time = header.time;
+	stuff->playtime = header.playtime;
+
+	return true;
+}
+
+void ScummEngine::saveInfos(Common::OutSaveFile* file) {
+	SaveInfoHeader header;
+	header.type = MKID('INFO');
+	header.version = INFOHEADER_VERSION;
+	header.size = sizeof(SaveInfoHeader);
+
+	time_t curTime_ = time(0);
+	tm *curTime = localtime(&curTime_);
+	header.date = (curTime->tm_mday & 0xFF) << 24 | ((curTime->tm_mon + 1) & 0xFF) << 16 | (curTime->tm_year + 1900) & 0xFFFF;
+	header.time = (curTime->tm_hour & 0xFF) << 8 | curTime->tm_min & 0xFF;
+	header.playtime = _system->getMillis() / 1000 - _engineStartTime;
+
+	file->write(&header.type, 4);
+	file->writeByte(header.version);
+	file->writeUint32BE(header.size);
+	file->writeUint32BE(header.date);
+	file->writeUint16BE(header.time);
+	file->writeUint32BE(header.playtime);
 }
 
 void ScummEngine::saveOrLoad(Serializer *s, uint32 savegameVersion) {
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/saveload.h ./scummvm/scumm/saveload.h
--- ./scummvm.cvs/scumm/saveload.h	Sun Aug 14 09:39:26 2005
+++ ./scummvm/scumm/saveload.h	Mon Aug 29 08:24:54 2005
@@ -45,7 +45,7 @@
  * only saves/loads those which are valid for the version of the savegame
  * which is being loaded/saved currently.
  */
-#define CURRENT_VER 55
+#define CURRENT_VER 56
 
 /**
  * An auxillary macro, used to specify savegame versions. We use this instead
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/scumm.cpp ./scummvm/scumm/scumm.cpp
--- ./scummvm.cvs/scumm/scumm.cpp	Sun Aug 14 09:39:26 2005
+++ ./scummvm/scumm/scumm.cpp	Mon Aug 29 08:24:54 2005
@@ -2012,6 +2012,8 @@
 #pragma mark -
 
 int ScummEngine::go() {
+	_engineStartTime = _system->getMillis() / 1000;
+
 	// If requested, load a save game instead of running the boot script
 	if (_saveLoadFlag != 2 || !loadState(_saveLoadSlot, _saveTemporaryState)) {
 		int args[16];
@@ -2448,6 +2450,8 @@
 #pragma mark -
 
 int ScummEngine::runDialog(Dialog &dialog) {
+	_dialogStartTime = _system->getMillis() / 1000;
+
 	// Pause sound & video
 	bool old_soundsPaused = _sound->_soundsPaused;
 	_sound->pauseSounds(true);
@@ -2463,6 +2467,9 @@
 	// Resume sound & video
 	_sound->pauseSounds(old_soundsPaused);
 	_smushPaused = oldSmushPaused;
+
+	_engineStartTime += (_system->getMillis() / 1000) - _dialogStartTime;
+	_dialogStartTime = 0;
 
 	// Return the result
 	return result;
diff --exclude=.cvsignore --exclude=.deps --exclude=CVS -Pur ./scummvm.cvs/scumm/scumm.h ./scummvm/scumm/scumm.h
--- ./scummvm.cvs/scumm/scumm.h	Sun Aug 14 09:39:26 2005
+++ ./scummvm/scumm/scumm.h	Mon Aug 29 09:52:29 2005
@@ -309,6 +309,12 @@
 	int subIndex;
 };
 
+struct InfoStuff {
+	uint32 date;
+	uint16 time;
+	uint32 playtime;
+};
+
 class ResourceManager {
 	friend class ScummDebugger;
 	friend class ScummEngine;
@@ -582,13 +588,21 @@
 	void requestSave(int slot, const char *name, bool temporary = false);
 	void requestLoad(int slot);
 
-// thumbnail stuff
+	bool removeState(int slot);
+
+// thumbnail + info stuff
 public:
 	Graphics::Surface *loadThumbnailFromSlot(int slot);
+	bool loadInfosFromSlot(int slot, InfoStuff *stuff);
 
 protected:
 	Graphics::Surface *loadThumbnail(Common::InSaveFile *file);
+	bool loadInfos(Common::InSaveFile *file, InfoStuff *stuff);
 	void saveThumbnail(Common::OutSaveFile *file);
+	void saveInfos(Common::OutSaveFile* file);
+
+	int32 _engineStartTime;
+	int32 _dialogStartTime;
 
 protected:
 	/* Script VM - should be in Script class */
