From ce3cde15a027fd092d0d27fa165f0166d4ecb927 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Tue, 19 Nov 2002 01:36:47 +0000 Subject: added some preliminary game auto detect code to the launcher; this required a small change to the FS API, Windows/Morphos code will have to be adapted slightly I fear. Also, not all games are detected correctly, and some probably never will be, so we still have to add a dialog for cases where auto detect doesn't work svn-id: r5600 --- gui/browser.cpp | 28 ++++++++++++++++---- gui/browser.h | 4 +++ gui/dialog.cpp | 5 ++-- gui/dialog.h | 7 ++++- gui/launcher.cpp | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- gui/message.cpp | 77 ++++++++++++++++++++++++++++--------------------------- 6 files changed, 152 insertions(+), 47 deletions(-) (limited to 'gui') diff --git a/gui/browser.cpp b/gui/browser.cpp index 44f1f94e34..0bd16d7c32 100644 --- a/gui/browser.cpp +++ b/gui/browser.cpp @@ -58,6 +58,13 @@ BrowserDialog::BrowserDialog(NewGui *gui) addButton(_w-(kButtonWidth+10), _h-24, "Choose", kChooseCmd, 0); } +BrowserDialog::~BrowserDialog() +{ + delete _node; + delete _nodeContent; + delete _choice; +} + void BrowserDialog::open() { // If no node has been set, or the last used one is now invalid, @@ -71,6 +78,10 @@ void BrowserDialog::open() // Alway refresh file list updateListing(); + // Nothing chosen by default + delete _choice; + _choice = 0; + // Call super implementation Dialog::open(); } @@ -92,11 +103,18 @@ void BrowserDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data FilesystemNode *tmp; switch (cmd) { - case kChooseCmd: - // If nothing is selected in the list widget, choose the current dir. - // Else, choose the dir that is selected. - // TODO - close(); + case kChooseCmd: { + // If nothing is selected in the list widget, choose the current dir. + // Else, choose the dir that is selected. + int selection = _fileList->getSelected(); + if (selection >= 0) { + _choice = (*_nodeContent)[selection].clone(); + } else { + _choice = _node->clone(); + } + setResult(1); + close(); + } break; case kGoUpCmd: tmp = _node->parent(); diff --git a/gui/browser.h b/gui/browser.h index 4fda0b1596..139ac3d26a 100644 --- a/gui/browser.h +++ b/gui/browser.h @@ -36,16 +36,20 @@ class BrowserDialog : public Dialog { typedef ScummVM::StringList StringList; public: BrowserDialog(NewGui *gui); + virtual ~BrowserDialog(); virtual void open(); virtual void close(); virtual void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); + + FilesystemNode *getResult() { return _choice; }; protected: ListWidget *_fileList; StaticTextWidget*_currentPath; FilesystemNode *_node; FSList *_nodeContent; + FilesystemNode *_choice; void updateListing(); }; diff --git a/gui/dialog.cpp b/gui/dialog.cpp index 5805e95f2f..d8569d979e 100644 --- a/gui/dialog.cpp +++ b/gui/dialog.cpp @@ -58,14 +58,15 @@ int Dialog::runModal() // Start processing events _gui->runLoop(); - // FIXME - for now always return 0.... - return 0; + // Return the result code + return _result; } void Dialog::open() { Widget *w = _firstWidget; + _result = 0; _visible = true; _gui->openDialog(this); diff --git a/gui/dialog.h b/gui/dialog.h index fa74737818..2f8abf58fe 100644 --- a/gui/dialog.h +++ b/gui/dialog.h @@ -45,6 +45,9 @@ protected: Widget *_focusedWidget; bool _visible; +private: + int _result; + public: Dialog(NewGui *gui, int x, int y, int w, int h) : _gui(gui), _x(x), _y(y), _w(w), _h(h), _firstWidget(0), @@ -62,7 +65,7 @@ public: protected: virtual void open(); virtual void close(); - + virtual void draw(); virtual void drawDialog(); @@ -79,6 +82,8 @@ protected: ButtonWidget* addButton(int x, int y, const ScummVM::String &label, uint32 cmd, char hotkey); PushButtonWidget* addPushButton(int x, int y, const ScummVM::String &label, uint32 cmd, char hotkey); + + void setResult(int result) { _result = result; } }; #endif diff --git a/gui/launcher.cpp b/gui/launcher.cpp index 2526d0a6ba..8d3e727b83 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -24,10 +24,12 @@ #include "newgui.h" #include "ListWidget.h" +#include "backends/fs/fs.h" #include "common/config-file.h" #include "common/engine.h" #include "common/gameDetector.h" + enum { kStartCmd = 'STRT', kOptionsCmd = 'OPTN', @@ -118,6 +120,74 @@ LauncherDialog::LauncherDialog(NewGui *gui, GameDetector &detector) bw->setEnabled(false); } +bool findGame(FilesystemNode *dir) +{ + /* + atlantis -> ATLANTIS.000 + dig -> dig.la0 + ft -> ft.la0 + indy3 -> 00.LFL, ??? + indy3vga -> 00.LFL, INDYVGA.EXE + loom -> 00.LFL, LOOMEXE.EXE + loomcd -> 000.LFL, LOOM.EXE + maniac -> 00.LFL, MANIACEX.EXE + monkey -> monkey.000 + monkey2 -> monkey2.000 + monkeyvga -> 000.LFL, MONKEY.EXE + samnmax -> samnmax.000 + tentacle -> tentacle.000 + zak -> 00.LFL, zakexe.exe + zak256 -> 00.LFL, ZAK.EXP + */ + + // TODO - this doesn't deal with Simon games at all yet! + // We may have to offer a choice dialog between win/dos/talkie versions... + + // TODO - if we can't decide which game this supposedly is, we should ask the user. + // We simply can't autodetect all games, e.g. for old games (with 00.LFL), it is + // hard to distinguish them based on file names alone. We do luck for .exe files + // but those could be deleted by the user, or for the Amiga/Mac/... versions + // may not be present at all. + // Or maybe somebody has a better idea? Is there a reliable way to tell from + // the XX.lfl files which game we are dealing with (taking into account that + // for most of the games many variations exist, so we can't just hard code expected + // file sizes or checksums). + +// ScummVM::Map map; + + FSList *files = dir->listDir(FilesystemNode::kListFilesOnly); + int size = files->size(); + for (int i = 0; i < size; i++) { + const char *filename = (*files)[i].displayName().c_str(); + //printf("%2d. %s\n", i, filename); + + // Check if there is any game matching this file + const VersionSettings *v = version_settings; + while (v->filename && v->gamename) { + char detectName[256]; + if (v->detectname) + strcpy(detectName, v->detectname); + else { + strcpy(detectName, v->filename); + if (v->features & GF_AFTER_V7) + strcat(detectName, ".la0"); + else if (v->features & GF_HUMONGOUS) + strcat(detectName, ".he0"); + else + strcat(detectName, ".000"); + } + if (0 == scumm_stricmp(detectName, filename)) { + printf("Match found, apparently this is '%s'\n", v->gamename); + return true; + } + v++; + } + } + + printf("Unable to autodetect a game in %s\n", dir->displayName().c_str()); + return false; +} + void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { int item; @@ -132,7 +202,13 @@ void LauncherDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat // which choices are possible. E.g. if we don't find atlantis.000 in that // directory, then it's not FOA etc. BrowserDialog *browser = new BrowserDialog(_gui); - browser->runModal(); + if (browser->runModal()) { + // User did make a choice... + FilesystemNode *dir = browser->getResult(); + + // ...so let's examine it and try to figure out which game it is + findGame(dir); + } delete browser; } break; diff --git a/gui/message.cpp b/gui/message.cpp index ff678e9dd5..8dc9931a9c 100644 --- a/gui/message.cpp +++ b/gui/message.cpp @@ -23,44 +23,6 @@ #include "newgui.h" -int MessageDialog::addLine(const char *line, int size) -{ - int width = 0, maxWidth = 0; - const char *start = line; - String tmp; - - for (int i = 0; i < size; ++i) { - int w = _gui->getCharWidth(*line); - - // Check if we exceed the maximum line width, if so, split the line - // TODO - we could make this more clever by trying to split at - // non-letters, e.g. at space/slash/dot - if (width + w > 280) { - if (maxWidth < width) - maxWidth = width; - - // Add the substring from intervall [start, i-1] - tmp = String(start, line - start); - _lines.push_back(tmp); - - start = line; - width = w; - } else - width += w; - - line++; - } - - if (maxWidth < width) - maxWidth = width; - - if (start < line) { - tmp = String(start, line - start); - _lines.push_back(tmp); - } - return maxWidth; -} - MessageDialog::MessageDialog(NewGui *gui, const String &message) : Dialog(gui, 30, 20, 260, 124) { @@ -107,3 +69,42 @@ MessageDialog::MessageDialog(NewGui *gui, const String &message) // was selected. addButton((_w - kButtonWidth)/2, _h - 24, "OK", kCloseCmd, '\n'); // Confirm dialog } + +int MessageDialog::addLine(const char *line, int size) +{ + int width = 0, maxWidth = 0; + const char *start = line; + String tmp; + + for (int i = 0; i < size; ++i) { + int w = _gui->getCharWidth(*line); + + // Check if we exceed the maximum line width, if so, split the line + // TODO - we could make this more clever by trying to split at + // non-letters, e.g. at space/slash/dot + if (width + w > 280) { + if (maxWidth < width) + maxWidth = width; + + // Add the substring from intervall [start, i-1] + tmp = String(start, line - start); + _lines.push_back(tmp); + + start = line; + width = w; + } else + width += w; + + line++; + } + + if (maxWidth < width) + maxWidth = width; + + if (start < line) { + tmp = String(start, line - start); + _lines.push_back(tmp); + } + return maxWidth; +} + -- cgit v1.2.3