1 /* This file is part of the Marble Marcher (https://github.com/HackerPoet/MarbleMarcher).
2 * Copyright(C) 2018 CodeParade
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program.If not, see <http://www.gnu.org/licenses/>.
16 */
17 #pragma once
18 #include <fstream>
19 #include <sstream>
20 #include <SFML/Graphics.hpp>
21 #include <filesystem>
22 #include <array>
23 #include <AntTweakBar.h>
24 namespace fs = std::filesystem;
25 
26 #if defined(unix) || defined(__unix__) || defined(__unix)
27 #include <sys/stat.h>
28 #include <unistd.h>
29 #include <sys/types.h>
30 #include <pwd.h>
31 #endif
32 
33 const int num_of_keys = 20;
34 enum KEYS {
35 	UP, DOWN, LEFT, RIGHT, VIEWUP, VIEWDOWN, VIEWLEFT, VIEWRIGHT,
36 	PAUSE, RESTART, SCREENSHOT, ZOOM_IN, ZOOM_OUT,
37 	JOYSTICK_MOVE_AXIS_X, JOYSTICK_MOVE_AXIS_Y, JOYSTICK_VIEW_AXIS_X, JOYSTICK_VIEW_AXIS_Y,
38 	JOYSTICK_EXIT, JOYSTICK_SCREENSHOT, JOYSTICK_RESTART
39 };
40 
41 struct MainSettings
42 {
43 	int rendering_resolution;
44 	int screenshot_resolution;
45 	int MRRM_scale;
46 	int shadow_resolution;
47 	int bloom_resolution;
48 	int language;
49 
50 	bool shadows;
51 	bool refl_refr;
52 	bool fog;
53 
54 	float bloom_intensity;
55 	float bloom_radius;
56 	float gamma;
57 	float FOV;
58 
59 	float music_volume;
60 	float fx_volume;
61 	float mouse_sensitivity;
62 	float wheel_sensitivity;
63 
64 	bool loop_level;
65 
66 	float motion_blur;
67 	float exposure;
68 	int shader_config;
69 
70 	bool fullscreen;
71 	bool VSYNC;
72 	int marble_type;
73 	bool play_next;
74 
75 	float gamma_material;
76 	float gamma_sky;
77 	float gamma_camera;
78 
79 	bool cross_eye;
80 	float eye_separation;
81 	float auto_exposure_speed;
82 	float auto_exposure_target;
83 	bool touch_mode;
84 
85 	std::array<int, num_of_keys> control_mapping;
86 
87 	//cheeets
88 	bool speed_regulation;
89 	int fps_limit;
90 
91 	bool screenshot_preview;
92 	float preview_time;
93 	float gamepad_deadzone;
94 
95 	float DOF_max, DOF_focus;
96 	int screenshot_samples;
97 	bool fractal_glow;
98 	bool flag_glow;
99 };
100 
101 extern TwEnumVal resolutions[];
102 static const std::array<int, num_of_keys> default_control_mapping =
103 { sf::Keyboard::W, sf::Keyboard::S, sf::Keyboard::A, sf::Keyboard::D,
104   sf::Keyboard::Up, sf::Keyboard::Down, sf::Keyboard::Left, sf::Keyboard::Right,
105   sf::Keyboard::P, sf::Keyboard::R, sf::Keyboard::F5, sf::Keyboard::Num1, sf::Keyboard::Num2,
106 	1, 2, 3, 4, 1, 2, 3};
107 //an incomprehensible wall of default parameters
108 static const MainSettings default_settings =
109 {
110 	6, 10, 6, 3, 5, 0, true, true, true, 0.08, 10, 2.2, 70, 20, 20, 0.005, 0.2, false,
111 	0.005, 0.45, 0, false, true, 0, true, 0.5, 0.75, 2.2, false, -0.02, 0.2, 0.55,
112 	false, default_control_mapping, true, 60, true, 1.f, 0.1f, 22.f, 4.5f, 30, false, true
113 };
114 
115 class AllSettings
116 {
117 public:
AllSettings()118 	AllSettings()
119 	{
120 		stg = default_settings;
121 	}
122 
AllSettings(std::string settings_file)123 	AllSettings(std::string settings_file)
124 	{
125 		Load(settings_file);
126 	}
127 
Load(std::string settings_file)128 	bool Load(std::string settings_file)
129 	{
130 		if (!LoadFromFile(settings_file))
131 		{
132 			stg = default_settings;
133 			first_start = true;
134 			return true;
135 		}
136 		first_start = false;
137 		return false;
138 	}
139 
RestoreDefaults()140 	void RestoreDefaults()
141 	{
142 		stg = default_settings;
143 	}
144 
LoadFromFile(std::string settings_file)145 	bool LoadFromFile(std::string settings_file)
146 	{
147 		filename = settings_file;
148 		if (!fs::exists(settings_file))
149 		{
150 			return false;
151 		}
152 
153 		int cfg_size = fs::file_size(settings_file);
154 		int MainSettings_size = sizeof(MainSettings);
155 
156 		if (cfg_size != MainSettings_size)
157 		{
158 			return false;
159 		}
160 
161 		std::ifstream cfg_file(settings_file, std::ios_base::in | std::ios_base::binary);
162 
163 		cfg_file.seekg(0);
164 		cfg_file.read(reinterpret_cast<char *>(&stg), sizeof(MainSettings));
165 
166 		cfg_file.close();
167 		return true;
168 	}
169 
SaveToFile(std::string settings_file)170 	void SaveToFile(std::string settings_file)
171 	{
172 		std::ofstream cfg_file(settings_file, std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
173 
174 		cfg_file.write(reinterpret_cast<char *>(&stg), sizeof(MainSettings));
175 
176 		cfg_file.close();
177 	}
178 
179 	//Returns relative path or if on unix, returns config directory
GetConfigPath()180 	std::string GetConfigPath(){
181 		#if defined(__APPLE__)
182 		return "assets";
183 		#elif defined(unix) || defined(__unix__) || defined(__unix)
184 			char* userdir;
185 			if ((userdir = getenv("HOME")) == NULL) {
186 				userdir = getpwuid(getuid())->pw_dir;
187 			}
188 			std::string path = std::string(userdir) + "/.config/marblemarcher";
189 			mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
190 			return path;
191 			delete userdir;
192 		#else
193 		return "assets";
194 		#endif
195 	}
196 
197 	MainSettings stg;
198 	std::string filename;
199 
200 	bool first_start;
201 
~AllSettings()202 	~AllSettings()
203 	{
204 		SaveToFile(filename);
205 	}
206 };
207 
208 extern AllSettings SETTINGS;