forked from mirrors/principia
325 lines
9.5 KiB
C++
325 lines
9.5 KiB
C++
#include <tms/core/tms.h>
|
|
#include "settings.hh"
|
|
#include <cmath>
|
|
#include "game.hh"
|
|
|
|
#ifdef BUILD_VALGRIND
|
|
#include <valgrind/valgrind.h>
|
|
#endif
|
|
|
|
#include <errno.h>
|
|
|
|
struct shadow_res {int x; int y;};
|
|
|
|
_settings settings;
|
|
|
|
// Set all graphics settings to their lowest for e.g. emscripten or valgrind
|
|
static void apply_very_bad_settings()
|
|
{
|
|
settings["num_workers"]->v.i = 0;
|
|
settings["ao_map_res"]->v.i = 256;
|
|
settings["shadow_quality"]->v.u8 = 0;
|
|
settings["shadow_map_resx"]->v.i = 256;
|
|
settings["shadow_map_resy"]->v.i = 256;
|
|
settings["shadow_map_precision"]->v.i = 0;
|
|
settings["postprocess"]->v.b = false;
|
|
settings["debug"]->v.b = false;
|
|
settings["enable_shadows"]->v.b = false;
|
|
settings["enable_bloom"]->v.b = false;
|
|
settings["enable_ao"]->v.b = false;
|
|
settings["render_edev_labels"]->v.b = false;
|
|
settings["hide_tips"]->v.b = true;
|
|
}
|
|
|
|
#ifdef TMS_BACKEND_EMSCRIPTEN
|
|
#define ENABLE_SHADOWS_DEFAULT false
|
|
#define ENABLE_AO_DEFAULT false
|
|
#define WINDOW_RESIZABLE_DEFAULT true
|
|
#else
|
|
#define ENABLE_SHADOWS_DEFAULT true
|
|
#define ENABLE_AO_DEFAULT true
|
|
#define WINDOW_RESIZABLE_DEFAULT false
|
|
#endif
|
|
|
|
#ifdef TMS_BACKEND_MOBILE
|
|
#define AO_MAP_RES_DEFAULT 256
|
|
#else
|
|
#define AO_MAP_RES_DEFAULT 512
|
|
#endif
|
|
|
|
#ifdef TMS_USE_GLES
|
|
#define GAMMA_CORRECT_DEFAULT false
|
|
#else
|
|
#define GAMMA_CORRECT_DEFAULT -1
|
|
#endif
|
|
|
|
void
|
|
_settings::init()
|
|
{
|
|
this->_data.clear();
|
|
|
|
/** -Graphics **/
|
|
this->add("debug", S_BOOL, false);
|
|
|
|
// Shadows
|
|
this->add("enable_shadows", S_BOOL, ENABLE_SHADOWS_DEFAULT);
|
|
this->add("shadow_quality", S_UINT8, 1);
|
|
this->add("swap_shadow_map", S_BOOL, false);
|
|
this->add("shadow_map_depth_texture", S_BOOL, -1);
|
|
this->add("shadow_map_precision", S_BOOL, -1);
|
|
// XXX: see git history
|
|
this->add("shadow_map_resx", S_INT32, 1280);
|
|
this->add("shadow_map_resy", S_INT32, 720);
|
|
|
|
// AO
|
|
this->add("enable_ao", S_BOOL, ENABLE_AO_DEFAULT);
|
|
this->add("ao_map_res", S_INT32, AO_MAP_RES_DEFAULT);
|
|
this->add("swap_ao_map", S_BOOL, true);
|
|
this->add("shadow_ao_combine", S_BOOL, 0);
|
|
|
|
// Postprocessing
|
|
this->add("postprocess", S_BOOL, false);
|
|
this->add("enable_bloom", S_BOOL, false);
|
|
this->add("discard_framebuffer",S_BOOL, -1);
|
|
this->add("gamma_correct", S_BOOL, GAMMA_CORRECT_DEFAULT);
|
|
|
|
// VSync
|
|
this->add("vsync", S_BOOL, true);
|
|
|
|
// Windowing settings
|
|
this->add("window_width", S_INT32, _tms.window_width);
|
|
this->add("window_height", S_INT32, _tms.window_height);
|
|
this->add("window_maximized", S_BOOL, false);
|
|
this->add("window_fullscreen", S_BOOL, false);
|
|
this->add("window_resizable", S_BOOL, WINDOW_RESIZABLE_DEFAULT);
|
|
this->add("autosave_screensize",S_BOOL, true);
|
|
|
|
// UI
|
|
this->add("uiscale", S_FLOAT, 1.3f);
|
|
this->add("render_gui", S_BOOL, true);
|
|
this->add("render_edev_labels", S_BOOL, true);
|
|
|
|
this->add("fv", S_INT32, 2); /* settings file version */
|
|
this->add("jail_cursor", S_BOOL, false);
|
|
this->add("smooth_cam", S_BOOL, false);
|
|
this->add("cam_speed_modifier", S_FLOAT, 1.f);
|
|
this->add("smooth_zoom", S_BOOL, false);
|
|
this->add("zoom_speed", S_FLOAT, 1.f);
|
|
this->add("smooth_menu", S_BOOL, true);
|
|
this->add("border_scroll_enabled", S_BOOL, true);
|
|
this->add("border_scroll_speed", S_FLOAT, 1.f);
|
|
this->add("menu_speed", S_FLOAT, 1.f);
|
|
this->add("always_reload_data", S_BOOL, false);
|
|
/* TODO: Add setting for enabling or disabling menu sliding */
|
|
|
|
/** -Player **/
|
|
this->add("widget_control_sensitivity", S_FLOAT, 1.5f);
|
|
this->add("rc_lock_cursor", S_BOOL, false);
|
|
this->add("control_type", S_UINT8, 1);
|
|
|
|
/** -Audio **/
|
|
this->add("volume", S_FLOAT, 1.0f, true);
|
|
this->add("muted", S_BOOL, false);
|
|
|
|
/** -Debug **/
|
|
this->add("display_object_id", S_BOOL, false);
|
|
this->add("display_grapher_value", S_BOOL, false);
|
|
this->add("display_wireless_frequency", S_BOOL, true);
|
|
|
|
this->add("emulate_touch", S_BOOL, false);
|
|
|
|
#ifdef TMS_BACKEND_MOBILE
|
|
this->add("touch_controls", S_BOOL, true);
|
|
#else
|
|
this->add("touch_controls", S_BOOL, false);
|
|
#endif
|
|
|
|
this->add("tutorial", S_UINT32, 0);
|
|
this->add("display_fps", S_UINT8, 0);
|
|
|
|
this->add("num_workers", S_UINT8, SDL_GetCPUCount());
|
|
tms_infof("num workers (real): %d", SDL_GetCPUCount());
|
|
|
|
this->add("dna_sandbox_back", S_BOOL, false);
|
|
this->add("hide_tips", S_BOOL, false);
|
|
this->add("first_adventure", S_BOOL, true);
|
|
|
|
this->add("score_ask_before_submitting", S_BOOL, false);
|
|
this->add("score_automatically_submit", S_BOOL, true);
|
|
|
|
this->add("has_opened_classic_puzzles", S_BOOL, false);
|
|
|
|
sprintf(this->filename, "%s/settings.ini", tms_storage_path());
|
|
FILE *fh;
|
|
|
|
if ((fh = fopen(this->filename, "r")) == NULL) {
|
|
if (errno == ENOENT) {
|
|
tms_infof("file doesn't exist, create it!");
|
|
this->save();
|
|
} else {
|
|
/* todo: is the dir Principia created before this is called? */
|
|
tms_infof("another error occured, no permissinos to the dir/file?");
|
|
}
|
|
} else {
|
|
fclose(fh);
|
|
}
|
|
}
|
|
|
|
bool
|
|
_settings::load(void)
|
|
{
|
|
FILE *fh = fopen(this->filename, "r");
|
|
|
|
if (!fh) {
|
|
tms_errorf("Unable to open settings file for reading.");
|
|
return false;
|
|
}
|
|
|
|
char buf[256];
|
|
|
|
while (fgets(buf, 256, fh) != NULL) {
|
|
if (strchr(buf, '=') == NULL) continue;
|
|
size_t sz = strlen(buf);
|
|
char key[64];
|
|
char val[64];
|
|
int k = 0;
|
|
|
|
bool on_key = true;
|
|
|
|
for (int i = 0; i < sz; ++i) {
|
|
if (buf[i] == '\n' || buf[i] == ' ') continue;
|
|
|
|
if (k == 62) {
|
|
if (on_key) {
|
|
key[k++] = '\0';
|
|
k = 0;
|
|
on_key = false;
|
|
}
|
|
else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (buf[i] == '=') {
|
|
if (on_key) key[k++] = '\0';
|
|
k = 0;
|
|
on_key = false;
|
|
continue;
|
|
}
|
|
|
|
if (on_key) {
|
|
key[k++] = buf[i];
|
|
} else {
|
|
val[k++] = buf[i];
|
|
}
|
|
}
|
|
|
|
val[k] = '\0';
|
|
|
|
std::map<const char*, setting*>::iterator it = this->_data.find(key);
|
|
if (it != this->_data.end()) {
|
|
switch (it->second->type) {
|
|
case S_INT8:
|
|
it->second->v.i = (int8_t)strtol(val, NULL, 10);
|
|
break;
|
|
case S_INT32:
|
|
it->second->v.i = (int32_t)strtol(val, NULL, 10);
|
|
break;
|
|
case S_UINT8:
|
|
it->second->v.u8 = (uint8_t)strtoul(val, NULL, 10);
|
|
break;
|
|
case S_UINT32:
|
|
it->second->v.u32 = (uint32_t)strtoul(val, NULL, 10);
|
|
break;
|
|
case S_FLOAT:
|
|
if (it->second->clamp) {
|
|
it->second->v.f = tclampf(atof(val), 0.f, 1.f);
|
|
} else {
|
|
it->second->v.f = atof(val);
|
|
}
|
|
break;
|
|
case S_BOOL:
|
|
it->second->v.b = (int8_t)strtol(val, NULL, 10);
|
|
break;
|
|
default:
|
|
tms_fatalf("Unknown setting type: %d", it->second->type);
|
|
break;
|
|
}
|
|
} else {
|
|
tms_warnf("Unknown settings key: %s", key);
|
|
}
|
|
}
|
|
|
|
fclose(fh);
|
|
|
|
tms_infof("num workers (user): %d", settings["num_workers"]->v.i);
|
|
|
|
#ifdef BUILD_VALGRIND
|
|
if (RUNNING_ON_VALGRIND) {
|
|
tms_debugf("Running on valgrind, forcing settings to bad!");
|
|
apply_very_bad_settings();
|
|
}
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
_settings::save(void)
|
|
{
|
|
#ifdef BUILD_VALGRIND
|
|
// don't save the shitty valgrind settings file
|
|
if (RUNNING_ON_VALGRIND) return true;
|
|
#endif
|
|
|
|
FILE *fh = fopen(this->filename, "w+");
|
|
|
|
if (!fh) {
|
|
tms_errorf("An error occured when attempting to open settings file.");
|
|
return false;
|
|
}
|
|
|
|
for (std::map<const char*, setting*>::iterator it = this->_data.begin();
|
|
it != this->_data.end(); ++it) {
|
|
switch (it->second->type) {
|
|
case S_INT8:
|
|
fprintf(fh, "%s=%d\n", it->first, it->second->v.i8);
|
|
break;
|
|
case S_INT32:
|
|
fprintf(fh, "%s=%d\n", it->first, it->second->v.i);
|
|
break;
|
|
case S_UINT8:
|
|
fprintf(fh, "%s=%u\n", it->first, it->second->v.u8);
|
|
break;
|
|
case S_UINT32:
|
|
fprintf(fh, "%s=%u\n", it->first, it->second->v.u32);
|
|
break;
|
|
case S_FLOAT:
|
|
fprintf(fh, "%s=%f\n", it->first, it->second->v.f);
|
|
break;
|
|
case S_BOOL:
|
|
fprintf(fh, "%s=%d\n", it->first, it->second->v.b);
|
|
break;
|
|
default:
|
|
tms_fatalf("Unknown setting type: %d", it->second->type);
|
|
break;
|
|
}
|
|
}
|
|
|
|
fclose(fh);
|
|
|
|
return true;
|
|
}
|
|
|
|
void
|
|
_settings::clean(void)
|
|
{
|
|
}
|
|
|
|
_settings::~_settings()
|
|
{
|
|
for (std::map<const char*, setting*>::iterator it = this->_data.begin();
|
|
it != this->_data.end(); ++it) {
|
|
delete it->second;
|
|
}
|
|
}
|