1 // ==============================================================
2 //	This file is part of Glest Shared Library (www.glest.org)
3 //
4 //	Copyright (C) 2005 Matthias Braun <matze@braunis.de>
5 //
6 //	You can redistribute this code and/or modify it under
7 //	the terms of the GNU General Public License as published
8 //	by the Free Software Foundation; either version 2 of the
9 //	License, or (at your option) any later version
10 // ==============================================================
11 #ifndef _SHARED_PLATFORM_PLATFORMCOMMON_H_
12 #define _SHARED_PLATFORM_PLATFORMCOMMON_H_
13 
14 #ifdef WIN32
15 #include <windows.h>
16 #endif
17 
18 #include <string>
19 #include <vector>
20 #include <stdexcept>
21 #include <list>
22 
23 #include "data_types.h"
24 #include "checksum.h"
25 #include <utility>
26 #include <SDL.h>
27 #include <map>
28 //#include <chrono>
29 #include "leak_dumper.h"
30 
31 #if (defined WIN32) && !(defined snprintf)
32 #define snprintf _snprintf
33 #endif
34 
35 using std::string;
36 using std::vector;
37 using std::list;
38 using std::exception;
39 
40 using Shared::Platform::int64;
41 using Shared::Util::Checksum;
42 
43 namespace Shared { namespace PlatformCommon {
44 
45 #define STRINGIFY(x) #x
46 #define TOSTRING(x) STRINGIFY(x)
47 #define CODE_AT_LINE __FILE__ ":" TOSTRING(__LINE__)
48 #define CODE_AT_LINE_X(x) __FILE__ ":" TOSTRING(__LINE__) ":" TOSTRING(x)
49 
50 static const int IGNORE_CMD_RESULT_VALUE = -999999;
51 
52 // keycode constants (unfortunately designed after DirectInput and therefore not
53 // very specific)
54 // They also have to fit into a char. The positive numbers seem to be equal
55 // to ascii, for the rest we have to find sensefull mappings from SDL (which is
56 // alot more fine grained like left/right control instead of just control...)
57 const char vkAdd = -1;
58 const char vkSubtract = -2;
59 const char vkAlt = -3;
60 const char vkControl = -4;
61 const char vkShift = -5;
62 const char vkEscape = -6;
63 const char vkUp = -7;
64 const char vkLeft = -8;
65 const char vkRight = -9;
66 const char vkDown = -10;
67 const char vkReturn = -11;
68 const char vkBack = -12;
69 const char vkTab = -13;
70 const char vkF1 = -14;
71 const char vkF2 = -15;
72 const char vkF3 = -16;
73 const char vkF4 = -17;
74 const char vkF5 = -18;
75 const char vkF6 = -19;
76 const char vkF7 = -20;
77 const char vkF8 = -21;
78 const char vkF9 = -22;
79 const char vkF10 = -23;
80 const char vkF11 = -24;
81 const char vkF12 = -25;
82 const char vkDelete = -26;
83 const char vkPrint = -27;
84 const char vkPause = -29;
85 
86 class ShellCommandOutputCallbackInterface {
87 public:
~ShellCommandOutputCallbackInterface()88 	virtual ~ShellCommandOutputCallbackInterface() {}
89 
90 	virtual void * getShellCommandOutput_UserData(string cmd) = 0;
91     virtual void ShellCommandOutput_CallbackEvent(string cmd,char *output,void *userdata) = 0;
92 };
93 
94 //typedef std::chrono::time_point<std::chrono::system_clock> system_time_point;
95 tm threadsafe_localtime(const time_t &time);
96 // extracting std::time_t from std:chrono for "now"
97 time_t systemtime_now();
98 
99 
100 // =====================================================
101 //	class PerformanceTimer
102 // =====================================================
103 
104 class PerformanceTimer {
105 private:
106 	Uint32 lastTicks;
107 	Uint32 updateTicks;
108 
109 	int times;			// number of consecutive times
110 	int maxTimes;		// maximum number consecutive times
111 
112 public:
113 	void init(float fps, int maxTimes= -1);
114 
115 	bool isTime();
116 	void reset();
117 };
118 
119 // =====================================================
120 //	class Chrono
121 // =====================================================
122 
123 class Chrono {
124 private:
125 	Uint32 startCount;
126 	Uint32 accumCount;
127 	Uint32 freq;
128 	bool stopped;
129 
130 	Uint32 lastStartCount;
131 	Uint32 lastTickCount;
132 	int64  lastResult;
133 	int64 lastMultiplier;
134 	bool lastStopped;
135 
136 public:
137 	Chrono(bool autoStart=false);
138 	void start();
139 	void stop();
140 	void reset();
141 	int64 getMicros();
142 	int64 getMillis();
143 	int64 getSeconds();
144 
145 	bool isStarted() const;
146     static int64 getCurTicks();
147     static int64 getCurMillis();
148 
149 private:
150 	int64 queryCounter(int64 multiplier);
151 };
152 
153 // =====================================================
154 //	class ModeInfo
155 // =====================================================
156 class ModeInfo {
157 public:
158 	int width;
159 	int height;
160 	int depth;
161 
162 	ModeInfo(int width, int height, int depth);
163 
164 	bool operator< (const ModeInfo &j) const {
165 		if(this->width < j.width) {
166 			return true;
167 		}
168 		else if(this->width == j.width && this->height < j.height) {
169 			return true;
170 		}
171 		else if(this->width == j.width &&
172 				this->height == j.height &&
173 				this->depth < j.depth) {
174 			return true;
175 		}
176 
177 		return false;
178 	}
179 	string getString() const;
180 };
181 
182 // =====================================================
183 //	Misc
184 // =====================================================
185 void Tokenize(const string& str,vector<string>& tokens,const string& delimiters = " ");
186 bool isdir(const char *path);
187 bool fileExists(const string &path);
folderExists(const string & path)188 inline bool folderExists(const string &path) { return isdir(path.c_str()); }
189 
190 void findDirs(string path, vector<string> &results, bool errorOnNotFound,bool keepDuplicates);
191 void findDirs(const vector<string> &paths, vector<string> &results, bool errorOnNotFound=false,bool keepDuplicates=false);
192 void findAll(const vector<string> &paths, const string &fileFilter, vector<string> &results, bool cutExtension=false, bool errorOnNotFound=true,bool keepDuplicates=false);
193 void findAll(const string &path, vector<string> &results, bool cutExtension=false, bool errorOnNotFound=true);
194 vector<string> getFolderTreeContentsListRecursively(const string &path, const string &filterFileExt, bool includeFolders=false, vector<string> *recursiveMap=NULL);
195 
196 string getGameVersion();
197 string getGameGITVersion();
198 void setGameVersion(string version);
199 void setGameGITVersion(string git);
200 
201 string getCRCCacheFilePath();
202 void setCRCCacheFilePath(string path);
203 
204 std::pair<string,string> getFolderTreeContentsCheckSumCacheKey(vector<string> paths, string pathSearchString, const string &filterFileExt);
205 void clearFolderTreeContentsCheckSum(vector<string> paths, string pathSearchString, const string &filterFileExt);
206 uint32 getFolderTreeContentsCheckSumRecursively(vector<string> paths, string pathSearchString, const string &filterFileExt, Checksum *recursiveChecksum,bool forceNoCache=false);
207 time_t getFolderTreeContentsCheckSumRecursivelyLastGenerated(vector<string> paths, string pathSearchString, const string &filterFileExt);
208 
209 std::pair<string,string> getFolderTreeContentsCheckSumCacheKey(const string &path, const string &filterFileExt);
210 void clearFolderTreeContentsCheckSum(const string &path, const string &filterFileExt);
211 uint32 getFolderTreeContentsCheckSumRecursively(const string &path, const string &filterFileExt, Checksum *recursiveChecksum,bool forceNoCache=false);
212 
213 std::pair<string,string> getFolderTreeContentsCheckSumListCacheKey(vector<string> paths, string pathSearchString, const string &filterFileExt);
214 void clearFolderTreeContentsCheckSumList(vector<string> paths, string pathSearchString, const string &filterFileExt);
215 vector<std::pair<string,uint32> > getFolderTreeContentsCheckSumListRecursively(vector<string> paths, string pathSearchString, const string &filterFileExt, vector<std::pair<string,uint32> > *recursiveMap);
216 
217 std::pair<string,string> getFolderTreeContentsCheckSumListCacheKey(const string &path, const string &filterFileExt);
218 void clearFolderTreeContentsCheckSumList(const string &path, const string &filterFileExt);
219 vector<std::pair<string,uint32> > getFolderTreeContentsCheckSumListRecursively(const string &path, const string &filterFileExt, vector<std::pair<string,uint32> > *recursiveMap);
220 
221 void createDirectoryPaths(string  Path);
222 string extractFileFromDirectoryPath(string filename);
223 string extractDirectoryPathFromFile(string filename);
224 string extractLastDirectoryFromPath(string Path);
225 string extractExtension(const string& filename);
226 
227 void getFullscreenVideoModes(vector<ModeInfo> *modeinfos,bool isFullscreen);
228 void getFullscreenVideoInfo(int &colorBits,int &screenWidth,int &screenHeight,bool isFullscreen);
229 void changeVideoModeFullScreen(bool value);
230 void restoreVideoMode(SDL_Window *sdlWindow,bool exitingApp=false);
231 
232 bool StartsWith(const std::string &str, const std::string &key);
233 bool EndsWith(const string &str, const string& key);
234 
235 void endPathWithSlash(string &path, bool requireOSSlash=false);
236 void trimPathWithStartingSlash(string &path);
237 void updatePathClimbingParts(string &path,bool processPreviousDirTokenCheck=true);
238 string formatPath(string path);
239 
240 string replaceAllHTMLEntities(string& context);
241 string replaceAll(string& context, const string& from, const string& to);
242 vector<char> replaceAllBetweenTokens(vector<char>& context, const string &startToken, const string &endToken, const string &newText, bool removeTokens=true);
243 string replaceAllBetweenTokens(string& context, const string &startToken, const string &endToken, const string &newText, bool removeTokens=true);
244 bool removeFile(string file);
245 bool renameFile(string oldFile, string newFile);
246 void removeFolder(const string &path);
247 off_t getFileSize(string filename);
248 bool searchAndReplaceTextInFile(string fileName, string findText, string replaceText, bool simulateOnly);
249 void copyFileTo(string fromFileName, string toFileName);
250 
251 //int getScreenW();
252 //int getScreenH();
253 
254 void sleep(int millis);
255 
256 bool isCursorShowing();
257 void showCursor(bool b);
258 bool isKeyDown(int virtualKey);
259 //bool isKeyDown(SDLKey key);
260 string getCommandLine();
261 
262 string getUserHome();
263 
264 #define SPACES " "
265 
trim_at_delim(const string & s,const string & t)266 inline string trim_at_delim (const string & s, const string &t)  {
267   string d (s);
268   string::size_type i(d.find(t));
269   //printf("Searching for [%s] in [%s] got " MG_SIZE_T_SPECIFIER "\n",t.c_str(),d.c_str(),i);
270 
271   if (i == string::npos) {
272     return d;
273   }
274   else {
275 	  d = d.erase (i) ;
276 	  //printf("returning [%s]\n",d.c_str());
277 	  return d;
278   }
279 }
280 
281 inline string trim_right (const string & s, const string & t = SPACES)  {
282   string d (s);
283   string::size_type i (d.find_last_not_of (t));
284   if (i == string::npos)
285     return "";
286   else
287    return d.erase (d.find_last_not_of (t) + 1) ;
288 }  // end of trim_right
289 
290 inline string trim_left (const string & s, const string & t = SPACES) {
291   string d (s);
292   return d.erase (0, s.find_first_not_of (t)) ;
293 }  // end of trim_left
294 
295 inline string trim (const string & s, const string & t = SPACES) {
296   string d (s);
297   return trim_left (trim_right (d, t), t) ;
298 }  // end of trim
299 
300 string getFullFileArchiveExtractCommand(string fileArchiveExtractCommand,
301 		string fileArchiveExtractCommandParameters, string outputpath, string archivename);
302 string getFullFileArchiveCompressCommand(string fileArchiveCompressCommand,
303 		string fileArchiveCompressCommandParameters, string archivename, string archivefiles);
304 
305 bool executeShellCommand(string cmd,int expectedResult=IGNORE_CMD_RESULT_VALUE,ShellCommandOutputCallbackInterface *cb=NULL);
306 string executable_path(string exeName,bool includeExeNameInPath=false);
307 
308 void saveDataToFile(string filename, string data);
309 
310 bool valid_utf8_file(const char* file_name);
311 
312 string getFileTextContents(string path);
313 
314 string safeCharPtrCopy(const char *ptr, int maxLength=-1);
315 
316 class ValueCheckerVault {
317 
318 protected:
319 	std::map<const void *,uint32> vaultList;
320 
321 	void addItemToVault(const void *ptr,int value);
322 	void checkItemInVault(const void *ptr,int value) const;
323 
324 public:
325 
ValueCheckerVault()326 	ValueCheckerVault() {
327 		vaultList.clear();
328 	}
329 };
330 
331 
332 }}//end namespace
333 
334 #endif
335