Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,85 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef NUVIE_CONF_CONFIG_NODE_H
#define NUVIE_CONF_CONFIG_NODE_H
#include "ultima/shared/std/string.h"
#include "ultima/nuvie/conf/configuration.h"
namespace Ultima {
namespace Nuvie {
class ConfigNode {
friend class Configuration;
ConfigNode(Configuration &config_, Std::string key_)
: config(config_), key(key_) {
}
public:
~ConfigNode() { }
// fix "assignment operator could not be generated" warning
const ConfigNode &operator = (const ConfigNode &other) {
config = other.config;
key = other.key;
return *this;
}
Std::string get_string(const char *defaultvalue = "") {
Std::string s;
config.value(key, s, defaultvalue);
return s;
}
int get_int(int defaultvalue = 0) {
int i;
config.value(key, i, defaultvalue);
return i;
}
bool get_bool(bool defaultvalue = false) {
bool b;
config.value(key, b, defaultvalue);
return b;
}
void set(const Std::string &value) {
config.set(key, value);
}
void set(const char *value) {
config.set(key, value);
}
void set(int value) {
config.set(key, value);
}
void set(bool value) {
config.set(key, value);
}
private:
Configuration &config;
Std::string key;
};
} // End of namespace Nuvie
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,441 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/nuvie/core/nuvie_defs.h"
#include "ultima/nuvie/conf/misc.h"
#include "ultima/nuvie/conf/configuration.h"
#include "ultima/nuvie/conf/config_node.h"
#include "ultima/shared/conf/xml_tree.h"
#include "common/config-manager.h"
#include "common/file.h"
namespace Ultima {
namespace Nuvie {
Configuration::Configuration() : _configChanged(false) {
// Set up keys that will be stored locally, since we don't want them being
// written out to the ScummVM configuration
_localKeys["GameType"] = "";
_localKeys["GameName"] = "";
_localKeys["GameID"] = "";
_localKeys["datadir"] = "data"; // This maps to ultima6/ in ultima.dat
_localKeys["quit"] = "no";
}
Configuration::~Configuration() {
for (Shared::XMLTree *t : _trees) {
delete(t);
}
if (_configChanged)
ConfMan.flushToDisk();
}
bool Configuration::readConfigFile(const Std::string &fname, const Std::string &root,
bool readonly) {
_configFilename = fname;
Shared::XMLTree *tree = new Shared::XMLTree();
if (!tree->readConfigFile(Common::Path(fname))) {
delete tree;
return false;
}
_trees.push_back(tree);
return true;
}
void Configuration::write() {
for (Shared::XMLTree *t : _trees) {
if (!t->isReadonly())
t->write();
}
}
void Configuration::clear() {
for (Shared::XMLTree *t : _trees) {
delete(t);
}
_trees.clear();
}
void Configuration::value(const Std::string &key, Std::string &ret,
const char *defaultvalue) const {
// Check for a .cfg file value in the trees
for (int i = _trees.size() - 1; i >= 0; --i) {
const Shared::XMLTree *tree = _trees[i];
if (tree->hasNode(key)) {
tree->value(key, ret, defaultvalue);
return;
}
}
assert(key.hasPrefix("config/"));
Std::string k = key.substr(7);
// Check for local entry
if (_localKeys.contains(k)) {
ret = _localKeys[k];
return;
}
// Check for ScummVM entry
if (_settings.contains(k)) {
ret = _settings[k];
return;
}
ret = defaultvalue;
}
void Configuration::value(const Std::string &key, int &ret, int defaultvalue) const {
// Check for a .cfg file value in the trees
for (int i = _trees.size() - 1; i >= 0; --i) {
const Shared::XMLTree *tree = _trees[i];
if (tree->hasNode(key)) {
tree->value(key, ret, defaultvalue);
return;
}
}
assert(key.hasPrefix("config/"));
Std::string k = key.substr(7);
// Check for local entry
if (_localKeys.contains(k)) {
ret = atoi(_localKeys[k].c_str());
return;
}
// Check for ScummVM key
if (_settings.contains(k)) {
ret = atoi(_settings[k].c_str());
return;
}
ret = defaultvalue;
}
void Configuration::value(const Std::string &key, bool &ret, bool defaultvalue) const {
// Check for a .cfg file value in the trees
for (int i = _trees.size() - 1; i >= 0; --i) {
const Shared::XMLTree *tree = _trees[i];
if (tree->hasNode(key)) {
tree->value(key, ret, defaultvalue);
return;
}
}
assert(key.hasPrefix("config/"));
Std::string k = key.substr(7);
// Check for local entry
if (_localKeys.contains(k)) {
ret = _localKeys[k].hasPrefixIgnoreCase("y") ||
_localKeys[k].hasPrefixIgnoreCase("t");
return;
}
// Check for ScummVM key
if (_settings.contains(k)) {
ret = _settings[k].hasPrefixIgnoreCase("y") ||
_settings[k].hasPrefixIgnoreCase("t");
return;
}
ret = defaultvalue;
}
void Configuration::pathFromValue(const Std::string &key, const Std::string &file, Common::Path &full_path) const {
Std::string tmp;
value(key, tmp);
full_path = Common::Path(tmp).joinInPlace(file);
}
bool Configuration::set(const Std::string &key, const Std::string &value) {
// Currently a value is written to the last writable tree with
// the correct root.
for (int i = _trees.size() - 1; i >= 0; --i) {
Shared::XMLTree *tree = _trees[i];
if (!(tree->isReadonly()) &&
tree->checkRoot(key)) {
tree->set(key, value);
return true;
}
}
assert(key.hasPrefix("config/"));
Std::string k = key.substr(7);
if (_localKeys.contains(k)) {
_localKeys[k] = value;
return true;
}
_settings[k] = value;
ConfMan.set(k, value);
_configChanged = true;
return true;
}
bool Configuration::set(const Std::string &key, const char *value) {
return set(key, Std::string(value));
}
bool Configuration::set(const Std::string &key, int value) {
// Currently a value is written to the last writable tree with
// the correct root.
for (int i = _trees.size() - 1; i >= 0; --i) {
Shared::XMLTree *tree = _trees[i];
if (!(tree->isReadonly()) &&
tree->checkRoot(key)) {
tree->set(key, value);
return true;
}
}
assert(key.hasPrefix("config/"));
Std::string k = key.substr(7);
if (_localKeys.contains(k)) {
_localKeys[k] = Common::String::format("%d", value);
return true;
}
_settings[k] = Common::String::format("%d", value);
ConfMan.setInt(k, value);
_configChanged = true;
return true;
}
bool Configuration::set(const Std::string &key, bool value) {
// Currently a value is written to the last writable tree with
// the correct root.
for (int i = _trees.size() - 1; i >= 0; --i) {
Shared::XMLTree *tree = _trees[i];
if (!(tree->isReadonly()) &&
tree->checkRoot(key)) {
tree->set(key, value);
return true;
}
}
assert(key.hasPrefix("config/"));
Std::string k = key.substr(7);
Common::String strValue = value ? "yes" : "no";
if (_localKeys.contains(k)) {
_localKeys[k] = strValue;
} else {
_settings[k] = strValue;
ConfMan.setBool(k, value);
_configChanged = true;
}
return true;
}
ConfigNode *Configuration::getNode(const Std::string &key) {
return new ConfigNode(*this, key);
}
void Configuration::getSubkeys(KeyTypeList &ktl, const Std::string &basekey) {
for (Shared::XMLTree *tree : _trees) {
Shared::XMLTree::KeyTypeList l;
tree->getSubkeys(l, basekey);
for (const auto &i : l) {
bool found = false;
for (auto &j : ktl) {
if (j.first == i.first) {
// already have this subkey, so just replace the value
j.second = i.second;
found = true;
}
}
if (!found) {
// new subkey
ktl.push_back(i);
}
}
}
}
void Configuration::load(GameId gameId, bool isEnhanced) {
// Load basic defaults for enhanced vs unehanced
if (isEnhanced)
setEnhancedDefaults(gameId);
else
setUnenhancedDefaults(gameId);
// nuvie.cfg in the game folder can supersede any ScummVM settings
if (Common::File::exists("nuvie.cfg"))
(void)readConfigFile("nuvie.cfg", "config");
// Load any further settings from scummvm.ini
const Common::ConfigManager::Domain &domain = *ConfMan.getActiveDomain();
Common::ConfigManager::Domain::const_iterator it;
for (it = domain.begin(); it != domain.end(); ++it) {
_settings[(*it)._key] = (*it)._value;
}
}
void Configuration::setCommonDefaults(GameId gameType) {
_settings["video/non_square_pixels"] = "no";
#ifdef TODO
_settings["audio/enabled"] = true;
_settings["audio/enable_music"] = true;
_settings["audio/enable_sfx"] = true;
_settings["audio/music_volume"] = 100;
_settings["audio/sfx_volume"] = 255;
#endif
_settings["audio/combat_changes_music"] = "yes";
_settings["audio/vehicles_change_music"] = "yes";
_settings["audio/conversations_stop_music"] = "no"; // original stopped music - maybe due to memory and disk swapping
_settings["audio/stop_music_on_group_change"] = "yes";
_settings["input/enable_doubleclick"] = "yes";
_settings["input/enabled_dragging"] = "yes";
_settings["input/look_on_left_click"] = "yes";
_settings["input/walk_with_left_button"] = "yes";
_settings["input/direction_selects_target"] = "yes";
_settings["general/dither_mode"] = "none";
_settings["general/enable_cursors"] = "yes";
_settings["general/party_formation"] = "standard";
// Only show the startup console if in ScummVM debug mode
_settings["general/show_console"] = gDebugLevel > 0 ? "yes" : "no";
_settings["cheats/enabled"] = "no";
_settings["cheats/enable_hackmove"] = "no";
_settings["cheats/min_brightness"] = "0";
_settings["cheats/party_all_the_time"] = "no";
// game specific settings
uint8 bg_color[] = { 218, 136, 216 }; // U6, MD, SE
uint8 border_color[] = { 220, 133, 219 }; // U6, MD, SE
int i = 0;
if (gameType == GAME_MARTIAN_DREAMS)
i = 1;
else if (gameType == GAME_SAVAGE_EMPIRE)
i = 2;
#ifdef TODO
_settings["language", "en";
_settings["music", "native";
_settings["sfx", "native";
if (i == 0) // U6
_settings["enable_speech", "yes";
#endif
_settings["skip_intro"] = "no";
_settings["show_eggs"] = "no";
if (i == 0) { // U6
_settings["show_stealing"] = "no";
_settings["roof_mode"] = "no";
}
_settings["use_new_dolls"] = "no";
_settings["cb_position"] = "default";
_settings["show_orig_style_cb"] = "default";
if (i == 0) // U6
_settings["cb_text_color"] = "115";
_settings["map_tile_lighting"] = i == 1 ? "no": "yes"; // MD has canals lit up so disable
_settings["custom_actor_tiles"] = "default";
_settings["converse_solid_bg"] = "no";
_settings["converse_bg_color"] =
Common::String::format("%d", bg_color[i]);
_settings["converse_width"] = "default";
_settings["converse_height"] = "default";
if (i == 0) { // U6
_settings["displayed_wind_dir"] = "from";
_settings["free_balloon_movement"] = "no";
}
_settings["game_specific_keys"] = "(default)";
_settings["newscroll/width"] = "30";
_settings["newscroll/height"] = "19";
_settings["newscroll/solid_bg"] = "no";
_settings["newscroll/bg_color"] =
Common::String::format("%d", bg_color[i]);
_settings["newscroll/border_color"] =
Common::String::format("%d", border_color[i]);
_settings["townsdir"] = "townsu6";
// _settings["newgamedata/name"] = "Avatar";
// _settings["newgamedata/gender"] = "0";
// _settings["newgamedata/portrait"] = "0";
// _settings["newgamedata/str"] = "15";
// _settings["newgamedata/dex"] = "15";
// _settings["newgamedata/int"] = "15";
}
void Configuration::setUnenhancedDefaults(GameId gameType) {
setCommonDefaults(gameType);
_settings["video/screen_width"] = "320";
_settings["video/screen_height"] = "200";
_settings["video/game_width"] = "320";
_settings["video/game_height"] = "200";
_settings["video/game_style"] = "original";
_settings["video/game_position"] = "center";
_settings["general/converse_gump"] = "default";
_settings["general/lighting"] = "original";
_settings["general/use_text_gumps"] = "no";
_settings["input/doubleclick_opens_containers"] = "no";
_settings["input/party_view_targeting"] = "no";
_settings["input/new_command_bar"] = "no";
_settings["input/interface"] = "normal";
}
void Configuration::setEnhancedDefaults(GameId gameType) {
setCommonDefaults(gameType);
_settings["video/screen_width"] = "640";
_settings["video/screen_height"] = "400";
_settings["video/game_width"] = "640";
_settings["video/game_height"] = "400";
_settings["video/game_style"] = "original+_full_map";
_settings["video/game_position"] = "center";
_settings["general/converse_gump"] = "yes";
_settings["general/lighting"] = "smooth";
_settings["general/use_text_gumps"] = "yes";
_settings["input/doubleclick_opens_containers"] = "yes";
_settings["input/party_view_targeting"] = "yes";
_settings["input/new_command_bar"] = "yes";
_settings["input/interface"] = "fullscreen";
}
} // End of namespace Nuvie
} // End of namespace Ultima

View File

@@ -0,0 +1,120 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef NUVIE_CONF_CONFIGURATION_H
#define NUVIE_CONF_CONFIGURATION_H
#include "ultima/shared/std/string.h"
#include "ultima/shared/std/containers.h"
#include "ultima/detection.h"
namespace Ultima {
namespace Shared {
class XMLTree;
} // End of namespace Shared
namespace Nuvie {
class ConfigNode;
#define NUVIE_CONF_READONLY true
#define NUVIE_CONF_READWRITE false
/**
* Configuration class.
*
* Configuration values are stored in one of two ways -either as a standalone
* nuvie.cfg file, or otherwise from the ScummVM domain for the added game.
*
* When the nuvie.cfg file is present, it's contents are stored as an XML tree
* (or a forest, technically). All values are stored as strings, but access
* functions for ints and bools are provided
* You should only store values in leaf nodes. (This isn't enforced everywhere,
* but contents of non-leaf nodes can disappear without warning)
*
* You can load multiple config files, which can be read-only.
* Each config file contains a single tree.
* Values in files loaded last override values in files loaded earlier.
* Values are written to the last-loaded writable config file with the right root.
* Because of this it's important to make sure the last-loaded config file with
* a given root is writable. (The idea is that you can load a system-wide config
* file first, and a user's config file after that.)
*/
class Configuration {
private:
Std::vector<Shared::XMLTree*> _trees;
Common::HashMap<Common::String, Common::String, Common::IgnoreCase_Hash,
Common::IgnoreCase_EqualTo> _localKeys;
Common::HashMap<Common::String, Common::String, Common::IgnoreCase_Hash,
Common::IgnoreCase_EqualTo> _settings;
Std::string _configFilename;
bool _configChanged;
// Sets default configurations common to both enhanced and unhenaced
void setCommonDefaults(GameId gameType);
// sets up unenhanced version defaults
void setUnenhancedDefaults(GameId gameType);
// sets up enhanced version defaults
void setEnhancedDefaults(GameId gameType);
public:
Configuration();
~Configuration();
// read config file. Multiple files may be read. Order is important.
bool readConfigFile(const Std::string &fname, const Std::string &root, bool readonly = true);
// Loads up the configuration settings
void load(GameId gameId, bool isEnhanced);
// write all (writable) config files
void write();
// clear everything
void clear();
// get value
void value(const Std::string &key, Std::string &ret, const char *defaultvalue = "") const;
void value(const Std::string &key, int &ret, int defaultvalue = 0) const;
void value(const Std::string &key, bool &ret, bool defaultvalue = false) const;
void pathFromValue(const Std::string &key, const Std::string &file, Common::Path &full_path) const;
// set value
bool set(const Std::string &key, const Std::string &value);
bool set(const Std::string &key, const char *value);
bool set(const Std::string &key, int value);
bool set(const Std::string &key, bool value);
// get node ref. (delete it afterwards)
ConfigNode *getNode(const Std::string &key);
typedef Common::Pair<Common::String, Common::String> KeyType;
typedef Common::Array<KeyType> KeyTypeList;
void getSubkeys(KeyTypeList &ktl, const Std::string &basekey);
};
} // End of namespace Nuvie
} // End of namespace Ultima
#endif

View File

@@ -0,0 +1,37 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/nuvie/conf/misc.h"
namespace Ultima {
namespace Nuvie {
Std::string readLine(Common::ReadStream *stream) {
Std::string line;
char c;
while (!stream->eos() && (c = stream->readByte()) != '\n')
line += c;
return line;
}
} // End of namespace Nuvie
} // End of namespace Ultima

View File

@@ -0,0 +1,38 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "ultima/shared/std/string.h"
#include "common/stream.h"
#ifndef NUVIE_CONF_MISC_H
#define NUVIE_CONF_MISC_H
namespace Ultima {
namespace Nuvie {
extern bool string_i_compare(const Std::string &s1, const Std::string &s2);
extern Std::string readLine(Common::ReadStream *stream);
} // End of namespace Nuvie
} // End of namespace Ultima
#endif