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