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 <Renderer.h>
19 #include <fstream>
20 #include <vector>
21 #include <Eigen/Dense>
22 #include <SFML/Audio.hpp>
23 #include <filesystem>
24 #include <map>
25 #include <algorithm>
26 
27 #ifdef _WIN32
28 #include <Windows.h>
29 #define ERROR_MSG(x) MessageBox(nullptr, TEXT(x), TEXT("ERROR"), MB_OK);
30 #else
31 #include <iostream>
32 #define ERROR_MSG(x) std::cerr << x << std::endl;
33 #endif
34 
35 namespace fs = std::filesystem;
36 
37 static const int num_levels = 24;
38 static const int num_fractal_params = 9;
39 typedef Eigen::Matrix<float, num_fractal_params, 1> FractalParams;
40 
41 struct LevelF
42 {
43 	int FractalIterations;
44 	float FractalParams[9];
45 	float PBR_roughness;	 //Fractal roughness
46 	float PBR_metal;         //Fractal metalicity
47 
48 	float marble_rad;        //Radius of the marble
49 	float start_look_x;      //Camera direction on start
50 	float orbit_dist;        //Distance to orbit
51 	float start_pos[3];      //Starting position of the marble
52 	float end_pos[3];        //Ending goal flag position
53 	float kill_y;            //Below this height player is killed
54 	bool planet;             //True if gravity should be like a planet
55 	char txt[255];           //Title
56 	char desc[255];			 //Description
57 	float anim_1;            //Animation amount for angle1 parameter
58 	float anim_2;            //Animation amount for angle2 parameter
59 	float anim_3;            //Animation amount for offset_y parameter
60 	float light_dir[3];	     //Sun light direction
61 	float light_col[3];      //Sun light color
62 	float background_col[3];
63 
64 	int level_id;	     	 //level identifier
65 	int link_level;			 //Play what level after finish
66 	char use_music[255];     //what track to use
67 
68 	float ground_force;
69 	float air_force;
70 	float ground_friction;
71 	float air_friction;
72 	float gravity;
73 	float ground_ratio;
74 
75 	float gravity_dir[3];
76 
77 	//Advanced Animation
78 	float FractalParamsAmp[9];
79 	float FractalParamsFrq[9];
80 };
81 
82 class Level {
83 public:
Level()84   Level() {}
85   Level(float s, float a1, float a2,
86         const Eigen::Vector3f& v,
87         const Eigen::Vector3f& c,
88         float rad,
89         float look_x,
90         float orbit_d,
91         const Eigen::Vector3f& start,
92         const Eigen::Vector3f& end,
93         float kill,
94         bool planet,
95         const char* desc,
96         float an1=0.0f, float an2=0.0f, float an3=0.0f);
97 
98   void LoadFromFile(fs::path path);
99   void SaveToFile(std::string file, int ID, int Link);
100 
101   void LoadLevelF(LevelF lvl);
102   LevelF GetLevelF();
103 
104   int FractalIter;			 //Fractal iterations
105   FractalParams params;      //Fractal parameters
106 
107   float PBR_roughness;		 //Fractal roughness
108   float PBR_metal;           //Fractal metalicity
109 
110   float marble_rad;          //Radius of the marble
111   float start_look_x;        //Camera direction on start
112   float orbit_dist;          //Distance to orbit
113   Eigen::Vector3f start_pos; //Starting position of the marble
114   Eigen::Vector3f end_pos;   //Ending goal flag position
115   float kill_y;              //Below this height player is killed
116   bool planet;               //True if gravity should be like a planet
117   std::string txt;           //Title
118   std::string desc;			 //Description
119   float anim_1;              //Animation amount for angle1 parameter
120   float anim_2;              //Animation amount for angle2 parameter
121   float anim_3;              //Animation amount for offset_y parameter
122   Eigen::Vector3f light_dir; //Sun light direction
123   Eigen::Vector3f light_col; //Sun light color
124 
125   int level_id;				 //level identifier
126   int link_level;			 //Play what level after finish
127   std::string use_music;     //what track to use
128 
129   Eigen::Vector3f background_col;
130 
131   float ground_force;
132   float air_force;
133   float ground_friction;
134   float air_friction;
135   float gravity;
136   float ground_ratio;
137 
138   Eigen::Vector3f gravity_dir;
139 
140   //Advanced Animation
141   FractalParams FractalParamsAmp;
142   FractalParams FractalParamsFrq;
143 };
144 
145 extern Level all_levels[num_levels];
146 extern Level default_level;
147 
148 std::vector<fs::path> GetFilesInFolder(std::string folder, std::string filetype);
149 
150 struct Score
151 {
152 	int level_id = 0;
153 	int played_num = 0;
154 	float best_time = 0.f;
155 	float all_time = 0.f;
156 	float last_time = 0.f;
157 };
158 
159 class All_Levels
160 {
161 public:
All_Levels()162 	All_Levels() {}
163 
164 	void LoadLevelsFromFolder(std::string folder);
165 	void LoadMusicFromFolder(std::string folder);
166 
167 	bool LevelExists(int ID);
168 	Level GetLevel(int ID);
169 	int GetLevelNum();
170 	std::map<int, std::string> getLevelNames();
171 	std::map<int, std::string> getLevelDesc();
172 	std::vector<int> getLevelIds();
173 	std::map<int, Score> getLevelScores();
174 	sf::Music* GetLevelMusic(int ID);
175 
176 	sf::Music * GetMusic(std::string music);
177 
178 	void RecreateMissing();
179 
180 	void ReloadLevels();
181 
182 	void LoadLevelFromFile(fs::path file);
183 	void LoadScoresFromFile(std::string file);
184 	float GetBest(int lvl);
185 	void SaveScoresToFile(const std::string& file);
186 
187 	bool UpdateScore(int lvl, float time);
188 	void DeleteLevel(int lvl);
189 	sf::Music* GetMusicByID(int ID);
190 
191 	void StopAllMusic();
192 
193 	std::vector<std::string> GetMusicNames();
194 
195 private:
196 	std::map<int, Level> level_map;
197 	std::map<int, Score> score_map;
198 	std::map<int, int> level_id_map;
199 	std::map<int, std::string> level_names;
200 	std::map<int, std::string> level_descriptions;
201 	std::vector<int> level_ids;
202 
203 	std::map<std::string, sf::Music*> music_map;
204 	std::vector<std::string> music_names;
205 
206 	std::string lvl_folder;
207 
208 	int level_num;
209 };
210 
211 std::string ConvertSpaces2_(std::string text);
212