// // settings.cc // // Store application settings // // Copyright (C) J. Belson 2000.02.27 // // $Author: jon $ : $Date: 2003/07/26 17:01:33 $ // #include #include #include #include #include #include "settings.h" using std::cout; using std::endl; #ifdef __BEOS__ #include #include const string settings:: settings_name = "LandscapePrefs"; #else const std::string settings::settings_name = ".landscape"; #endif using namespace std; /** * Constructor */ settings::settings() : pref_list() { // Load defaults for each setting category load_defaults_water(); load_defaults_atmospherics(); load_defaults_lighting(); load_defaults_sky(); load_defaults_clouds(); load_defaults_trees(); load_defaults_textures(); load_defaults_debug(); // Runtime only preferences set_bool(IMAGE_TO_SAVE, false); // Fractal defaults set_int(PREVIEW_HF_TYPE, HF_PERLIN2); set_int(PERLIN_ITERATIONS, 6); set_float(PERLIN_SCALE, 50); set_float(PERLIN_PERSISTENCE, 50); set_int(PERLIN2_OCTAVES, 6); set_float(PERLIN2_LACUNARITY, 2.0); set_float(PERLIN2_SCALE, 50.0); set_float(PERLIN2_FD, 0.95); set_float(MULTIFRACTAL_SCALE, 50.0); set_float(MULTIFRACTAL_FD, 0.95); set_float(MULTIFRACTAL_LACUNARITY, 2.0); set_int(MULTIFRACTAL_ITERATIONS, 6); set_int(SYNTHESIS_ITERATIONS, 8); set_float(SYNTHESIS_FD, 0.95); set_float(SUBDIVISION_FD, 0.95); set_int(PREVIEW_SEED, 0); set_float(RIDGED_SCALE, 50.0); set_float(RIDGED_FD, 0.95); set_float(RIDGED_LACUNARITY, 2.0); set_float(RIDGED_GAIN, 50.0); set_int(RIDGED_ITERATIONS, 6); // Render windows details set_int(RENDER_DETAIL, 7); set_bool(RENDER_BACKFACE_CULL, false); set_bool(RENDER_FRUSTRUM_CULL, true); // Preview window defaults set_int(PREVIEW_DETAIL, 7); // Windows set_bool(WINDOW_RENDER, false); set_bool(WINDOW_PREVIEW, false); set_bool(WINDOW_SETTINGS, false); set_int2(WINDOW_POS_MAIN, -1, -1); set_int2(WINDOW_POS_PREVIEW, -1, -1); set_int2(WINDOW_POS_PREVIEW_OUTPUT, -1, -1); set_int2(WINDOW_POS_RENDER, -1, -1); set_int2(WINDOW_POS_RENDER_OUTPUT, -1, -1); set_int2(WINDOW_POS_SETTINGS, -1, -1); #ifdef __BEOS__ BPath settings_path; find_directory(B_USER_SETTINGS_DIRECTORY, &settings_path, true); settings_path.Append(settings_name.c_str()); filename = settings_path.Path(); #else string home_dir = getenv("HOME"); filename = home_dir + "/" + settings_name; #endif cout << filename << endl; ifstream in(filename.c_str()); if (!in) { // Could not open settings file, so create one std::ofstream out(filename.c_str()); if (!out) { std::cerr << "Couldn't create default settings file." << std::endl; } else { std::cout << "Creating settings file" << endl; save_settings(out); } } else { std::cout << "Loading settings file \"" << filename << "\"" << std::endl; load_settings(in); } } /** * Destructor */ settings::~settings() { std::cout << "~settings\n"; std::ofstream out(filename.c_str()); if (!out) { std::cerr << "Couldn't create default settings file." << std::endl; } else { std::cout << "Saving settings" << std::endl; save_settings(out); } } /** * Check lookup was successful, else give error */ void settings::check(bool b, std::string name, std::string type) { if (!b) { std::cerr << "Failed to read \"" << name << "\" of type \"" << type << "\"\n"; assert(0); } } void settings::load_defaults_water(void) { // Water characteristics set_colour(WATER_COLOUR, fcolour(60/255.0, 100/255.0, 132/255.0)); set_float(WAVE_HEIGHT, 0.06); set_float(WAVE_SCALE, 0.96); set_float(WATER_REFLECTIVITY, 0.50); set_float(WATER_LEVEL, 0.0); } void settings::load_defaults_atmospherics(void) { // Atmospherics defaults set_colour(HAZE_COLOUR, fcolour(0.82, 0.84, 0.88)); set_float(HAZE_INTENSITY, 0.50); } void settings::load_defaults_lighting(void) { // Lighting set_colour(AMBIENT_COLOUR, fcolour(40/255.0, 40/255.0, 40/255.0)); set_colour(DIRECT_COLOUR, fcolour(175/255.0, 175/255.0, 175/255.0)); set_float(AMBIENT_INTENSITY, 0.2); set_float(DIRECT_INTENSITY, 0.7); set_float3(LIGHT_RAY_VECTOR, 0.0, -1.0, 0.0); } void settings::load_defaults_sky(void) { // Skydome set_colour(SKY_ZENITH_COLOUR, fcolour(90/255.0,125/255.0,180/255.0)); set_colour(SKY_HORIZON_COLOUR, fcolour(230/255.0,230/255.0,230/255.0)); set_bool(SKY_REALISTIC, true); } void settings::load_defaults_clouds(void) { // Cloud defaults set_colour(CLOUD_COLOUR, fcolour(0.9, 0.9, 0.9)); set_float(CLOUD_PERSISTENCE, 0.5); set_float(CLOUD_PRESENCE, 5.0); set_float(CLOUD_COVER, 0.0); set_float(CLOUD_SCALE, 0.1); set_int(CLOUD_SEED, rand()); } void settings::load_defaults_trees(void) { ; } void settings::load_defaults_textures(void) { ; } void settings::load_defaults_debug(void) { set_bool(DEBUG_SHOW_NORMALS, false); set_bool(DEBUG_SHOW_ENV_MAPS, false); set_bool(DEBUG_UNCONSTRAINED_CAMERA, false); } /** * get_* functions for 'name' * On exit : true for success, false for failure */ bool settings::get_float(string name, float* f) { bool ret_val = false; if (pref_list.find(name) != pref_list.end()) { pref p = pref_list[name]; if (p.type == eFLOAT) { *f = p.u.f; } ret_val = true; } check(ret_val, name, "float"); return ret_val; } /** * set_* functions for 'name' */ void settings::set_float(string name, float f) { map::iterator i = pref_list.find(name); if (i == pref_list.end()) { // 'name' not found, so add another item pref p; p.type = eFLOAT; p.u.f = f; pref_list[name] = p; } else { pref& p = i->second; p.u.f = f; } } bool settings::get_int(string name, int* i) { bool ret_val = false; if (pref_list.find(name) != pref_list.end()) { pref p = pref_list[name]; if (p.type == eINT) { *i = p.u.i; ret_val = true; } } check(ret_val, name, "int"); return ret_val; } void settings::set_bool(string name, bool b) { map::iterator i = pref_list.find(name); if (i == pref_list.end()) { // 'name' not found, so add another item pref p; p.type = eBOOL; p.u.b = b; pref_list[name] = p; } else { pref& p = i->second; p.u.b = b; } } bool settings::get_bool(string name, bool* b) { bool ret_val = false; if (pref_list.find(name) != pref_list.end()) { pref p = pref_list[name]; if (p.type == eBOOL) { *b = p.u.b; ret_val = true; } } check(ret_val, name, "bool"); return ret_val; } void settings::set_int(string name, int i) { map::iterator itr = pref_list.find(name); if (itr == pref_list.end()) { // 'name' not found, so add another item pref p; p.type = eINT; p.u.i = i; pref_list[name] = p; } else { pref& p = itr->second; p.u.i = i; } } bool settings::get_float3(std::string name, float* a, float* b, float* c) { bool ret_val = false; if (pref_list.find(name) != pref_list.end()) { pref p = pref_list[name]; if (p.type == eFLOAT3) { *a = p.u.f3.a; *b = p.u.f3.b; *c = p.u.f3.c; ret_val = true; } } check(ret_val, name, "float3"); return ret_val; } void settings::set_float3(std::string name, float a, float b, float c) { map::iterator i = pref_list.find(name); if (i == pref_list.end()) { // 'name' not found, so add another item pref p; p.type = eFLOAT3; p.u.f3.a = a; p.u.f3.b = b; p.u.f3.c = c; pref_list[name] = p; } else { pref& p = i->second; p.u.f3.a = a; p.u.f3.b = b; p.u.f3.c = c; } } bool settings::get_int2(std::string name, int* x, int* y) { bool ret_val = false; if (pref_list.find(name) != pref_list.end()) { pref p = pref_list[name]; if (p.type == eINT2) { *x = p.u.i3.a; *y = p.u.i3.b; ret_val = true; } } check(ret_val, name, "int2"); return ret_val; } void settings::set_int2(std::string name, int x, int y) { map::iterator i = pref_list.find(name); if (i == pref_list.end()) { // 'name' not found, so add another item pref p; p.type = eINT2; p.u.i3.a = x; p.u.i3.b = y; pref_list[name] = p; } else { pref& p = i->second; p.u.i3.a = x; p.u.i3.b = y; } } bool settings::get_int3(std::string name, int* x, int* y, int* z) { bool ret_val = false; if (pref_list.find(name) != pref_list.end()) { pref p = pref_list[name]; if (p.type == eINT3) { *x = p.u.i3.a; *y = p.u.i3.b; *z = p.u.i3.c; ret_val = true; } } check(ret_val, name, "int3"); return ret_val; } void settings::set_int3(std::string name, int x, int y, int z) { map::iterator i = pref_list.find(name); if (i == pref_list.end()) { // 'name' not found, so add another item pref p; p.type = eINT3; p.u.i3.a = x; p.u.i3.b = y; p.u.i3.c = z; pref_list[name] = p; } else { pref& p = i->second; p.u.i3.a = x; p.u.i3.b = y; p.u.i3.c = z; } } bool settings::get_colour(std::string name, fcolour* col) { bool ret_val = false; if (pref_list.find(name) != pref_list.end()) { pref p = pref_list[name]; if (p.type == eCOLOUR) { col->r = p.u.f3.a; col->g = p.u.f3.b; col->b = p.u.f3.c; ret_val = true; } } check(ret_val, name, "colour"); return ret_val; } void settings::set_colour(std::string name, const fcolour& col) { map::iterator i = pref_list.find(name); if (i == pref_list.end()) { // 'name' not found, so add another item pref p; p.type = eCOLOUR; p.u.f3.a = col.r; p.u.f3.b = col.g; p.u.f3.c = col.b; pref_list[name] = p; } else { pref& p = i->second; p.u.f3.a = col.r; p.u.f3.b = col.g; p.u.f3.c = col.b; } } /** * Load settings from stream */ void settings::load_settings(istream& str) { string name; int type; int i; float f; bool b; while (!str.eof()) { str >> type; str >> name; pref p; p.type = pref_type (type); switch (type) { case eINT: str >> i; set_int(name, i); break; case eFLOAT: str >> f; set_float(name, f); break; case eBOOL: str >> b; set_bool(name, b); break; case eINT2: { int a, b; str >> a; str >> b; set_int2(name, a, b); } break; case eINT3: { int a, b, c; str >> a; str >> b; str >> c; set_int3(name, a, b, c); } break; case eFLOAT3: { float a, b, c; str >> a; str >> b; str >> c; set_float3(name, a, b, c); } break; case eCOLOUR: { float r, g, b; str >> r; str >> g; str >> b; set_float3(name, r, g, b); } break; default: cerr << "Unknown setting type \"" << type << "\"" << endl; break; } str >> ws; } } /** * Save current settings */ void settings::save_settings(ostream& str) { map::iterator itr = pref_list.begin(); while (itr != pref_list.end()) { // Skip ones we don't want to save if (itr->first == PREVIEW_SEED || itr->first == IMAGE_TO_SAVE || itr->first == LIGHT_RAY_VECTOR) { itr++; continue; } pref p = itr->second; str << int (p.type) << " "; str << (itr->first) << " "; switch (p.type) { case eINT: str << p.u.i; break; case eFLOAT: str << p.u.f; break; case eBOOL: str << p.u.b; break; case eINT2: str << p.u.i3.a << " "; str << p.u.i3.b; break; case eINT3: str << p.u.i3.a << " "; str << p.u.i3.b << " "; str << p.u.i3.c; break; case eFLOAT3: str << p.u.f3.a << " "; str << p.u.f3.b << " "; str << p.u.f3.c; break; case eCOLOUR: str << p.u.f3.a << " "; str << p.u.f3.b << " "; str << p.u.f3.c; break; default: cerr << "Eek! Eek! Panic!" << endl; break; } str << endl; itr++; } } /** * Load app defaults for specified category */ void settings::load_defaults(pref_category cat) { switch (cat) { case catWATER: load_defaults_water(); break; case catATMOSPHERICS: load_defaults_atmospherics(); break; case catLIGHTING: load_defaults_lighting(); break; case catSKY: load_defaults_sky(); break; case catCLOUDS: load_defaults_clouds(); break; case catTREES: load_defaults_trees(); break; case catTEXTURES: load_defaults_textures(); break; case catDEBUG: load_defaults_debug(); break; } } /** * Return settings object, creating it if required */ settings* settings::get_instance(void) { //if (instance == 0) { // puts("Creating settings"); // instance = new settings(); //} static settings instance; return &instance; }