DC: Allow plugins to be grouped into subdirectories

By letting the user select which group of plugins to load, an out of
memory condition can be avoided while still allowing all plugins to be
stored on the same disc.
This commit is contained in:
Marcus Comstedt 2018-07-17 13:00:29 +02:00
parent d7f4cc9382
commit 0d6c83212a
3 changed files with 84 additions and 0 deletions

View file

@ -250,6 +250,11 @@ public:
protected: protected:
Plugin* createPlugin(const Common::FSNode &node) const; Plugin* createPlugin(const Common::FSNode &node) const;
bool isPluginFilename(const Common::FSNode &node) const; bool isPluginFilename(const Common::FSNode &node) const;
void addCustomDirectories(Common::FSList &dirs) const;
public:
PluginList getPlugins();
private:
const char *pluginCustomDirectory;
#endif #endif
}; };
@ -258,3 +263,6 @@ extern int handleInput(struct mapledev *pad,
int &mouse_x, int &mouse_y, int &mouse_x, int &mouse_y,
byte &shiftFlags, Interactive *inter = NULL); byte &shiftFlags, Interactive *inter = NULL);
extern bool selectGame(char *&, char *&, Common::Language &, Common::Platform &, class Icon &); extern bool selectGame(char *&, char *&, Common::Language &, Common::Platform &, class Icon &);
#ifdef DYNAMIC_MODULES
extern bool selectPluginDir(Common::String &selection, const Common::FSNode &base);
#endif

View file

@ -130,4 +130,27 @@ bool OSystem_Dreamcast::isPluginFilename(const Common::FSNode &node) const {
return true; return true;
} }
void OSystem_Dreamcast::addCustomDirectories(Common::FSList &dirs) const
{
FilePluginProvider::addCustomDirectories(dirs);
if (pluginCustomDirectory != NULL)
dirs.push_back(Common::FSNode(pluginCustomDirectory));
}
PluginList OSystem_Dreamcast::getPlugins()
{
pluginCustomDirectory = NULL;
PluginList list = FilePluginProvider::getPlugins();
if (list.empty()) {
Common::String selection;
if (selectPluginDir(selection, Common::FSNode("plugins"))) {
pluginCustomDirectory = selection.c_str();
list = FilePluginProvider::getPlugins();
pluginCustomDirectory = NULL;
}
}
return list;
}
#endif // defined(DYNAMIC_MODULES) #endif // defined(DYNAMIC_MODULES)

View file

@ -39,6 +39,7 @@
#define MAX_GAMES 100 #define MAX_GAMES 100
#define MAX_DIR 100 #define MAX_DIR 100
#define MAX_PLUGIN_DIRS 100
void draw_solid_quad(float x1, float y1, float x2, float y2, void draw_solid_quad(float x1, float y1, float x2, float y2,
@ -517,3 +518,55 @@ bool selectGame(char *&ret, char *&dir_ret, Common::Language &lang_ret, Common::
} else } else
return false; return false;
} }
#ifdef DYNAMIC_MODULES
static int findPluginDirs(Game *plugin_dirs, int max, const Common::FSNode &base)
{
Common::FSList fslist;
int curr_dir = 0;
base.getChildren(fslist, Common::FSNode::kListDirectoriesOnly);
for (Common::FSList::const_iterator entry = fslist.begin(); entry != fslist.end();
++entry) {
if (entry->isDirectory()) {
if (curr_dir >= max)
break;
strncpy(plugin_dirs[curr_dir].dir, (*entry).getPath().c_str(), 256);
strncpy(plugin_dirs[curr_dir].text, (*entry).getDisplayName().c_str(), 256);
plugin_dirs[curr_dir].icon.load(NULL, 0, 0);
curr_dir++;
}
}
return curr_dir;
}
bool selectPluginDir(Common::String &selection, const Common::FSNode &base)
{
Game *plugin_dirs = new Game[MAX_PLUGIN_DIRS];
int selected, num_plugin_dirs;
ta_sync();
void *mark = ta_txmark();
num_plugin_dirs = findPluginDirs(plugin_dirs, MAX_PLUGIN_DIRS, base);
for (int i=0; i<num_plugin_dirs; i++) {
plugin_dirs[i].icon.create_texture();
plugin_dirs[i].label.create_texture(plugin_dirs[i].text);
}
selected = gameMenu(plugin_dirs, num_plugin_dirs);
ta_sync();
ta_txrelease(mark);
if (selected >= num_plugin_dirs)
selected = -1;
if (selected >= 0)
selection = plugin_dirs[selected].dir;
delete[] plugin_dirs;
return selected >= 0;
}
#endif