git repos / blockattack-game

blame: source/code/common.cpp

normal view · raw

89c4a3a6 sago007 2008-08-29 14:32 1
/*
c53e6443 sago007 2012-04-17 11:04 2
===========================================================================
c53e6443 sago007 2012-04-17 11:04 3
blockattack - Block Attack - Rise of the Blocks
c53e6443 sago007 2012-04-17 11:04 4
Copyright (C) 2005-2012 Poul Sander
c53e6443 sago007 2012-04-17 11:04 5
c53e6443 sago007 2012-04-17 11:04 6
This program is free software: you can redistribute it and/or modify
c53e6443 sago007 2012-04-17 11:04 7
it under the terms of the GNU General Public License as published by
c53e6443 sago007 2012-04-17 11:04 8
the Free Software Foundation, either version 2 of the License, or
c53e6443 sago007 2012-04-17 11:04 9
(at your option) any later version.
c53e6443 sago007 2012-04-17 11:04 10
c53e6443 sago007 2012-04-17 11:04 11
This program is distributed in the hope that it will be useful,
c53e6443 sago007 2012-04-17 11:04 12
but WITHOUT ANY WARRANTY; without even the implied warranty of
c53e6443 sago007 2012-04-17 11:04 13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
c53e6443 sago007 2012-04-17 11:04 14
GNU General Public License for more details.
c53e6443 sago007 2012-04-17 11:04 15
c53e6443 sago007 2012-04-17 11:04 16
You should have received a copy of the GNU General Public License
c53e6443 sago007 2012-04-17 11:04 17
along with this program.  If not, see http://www.gnu.org/licenses/
c53e6443 sago007 2012-04-17 11:04 18
c53e6443 sago007 2012-04-17 11:04 19
Source information and contacts persons can be found at
c53e6443 sago007 2012-04-17 11:04 20
http://blockattack.sf.net
c53e6443 sago007 2012-04-17 11:04 21
===========================================================================
89c4a3a6 sago007 2008-08-29 14:32 22
*/
89c4a3a6 sago007 2008-08-29 14:32 23
89c4a3a6 sago007 2008-08-29 14:32 24
#include "common.h"
769a41a0 sago007 2008-09-24 12:54 25
#include <sstream>
f306e3ca sago007 2015-12-04 21:16 26
#include <cstring>
769a41a0 sago007 2008-09-24 12:54 27
53001fa2 sago007 2015-11-08 15:13 28
using namespace std;
53001fa2 sago007 2015-11-08 15:13 29
using boost::format;
53001fa2 sago007 2015-11-08 15:13 30
444cec07 sago007 2012-05-05 16:42 31
static stringstream converter;
444cec07 sago007 2012-05-05 16:42 32
769a41a0 sago007 2008-09-24 12:54 33
//Function to convert numbers to string
ecef5838 sago007 2015-11-24 20:01 34
string itoa(int num) {
444cec07 sago007 2012-05-05 16:42 35
	converter.str(std::string());
444cec07 sago007 2012-05-05 16:42 36
	converter.clear();
c53e6443 sago007 2012-04-17 11:04 37
	converter << num;
c53e6443 sago007 2012-04-17 11:04 38
	return converter.str();
769a41a0 sago007 2008-09-24 12:54 39
}
769a41a0 sago007 2008-09-24 12:54 40
ecef5838 sago007 2015-11-24 20:01 41
string double2str(double num) {
444cec07 sago007 2012-05-05 16:42 42
	converter.str(std::string());
444cec07 sago007 2012-05-05 16:42 43
	converter.clear();
c53e6443 sago007 2012-04-17 11:04 44
	converter << num;
c53e6443 sago007 2012-04-17 11:04 45
	return converter.str();
c53e6443 sago007 2012-04-17 11:04 46
}
769a41a0 sago007 2008-09-24 12:54 47
f306e3ca sago007 2015-12-04 21:16 48
bool strequals(const char* a, const char* b) {
f306e3ca sago007 2015-12-04 21:16 49
	return strcmp(a,b) == 0;
f306e3ca sago007 2015-12-04 21:16 50
}
f306e3ca sago007 2015-12-04 21:16 51
d07b805e sago007 2009-01-27 13:15 52
/**
d07b805e sago007 2009-01-27 13:15 53
 * str2double parses a string and returns a double with the value of the string.
fcd5a134 sago007 2008-12-19 01:11 54
 * if the string is not a double then 0.0 is returned instead of throing an error
fcd5a134 sago007 2008-12-19 01:11 55
 * in that way this function will always return a useable value.
fcd5a134 sago007 2008-12-19 01:11 56
 */
ecef5838 sago007 2015-11-24 20:01 57
double str2double(const string& str2parse) {
ecef5838 sago007 2015-11-24 20:01 58
	try {
444cec07 sago007 2012-05-05 16:42 59
		converter.clear();
444cec07 sago007 2012-05-05 16:42 60
		converter.str(str2parse);
c53e6443 sago007 2012-04-17 11:04 61
		double val = 0.0;
c53e6443 sago007 2012-04-17 11:04 62
		converter >> val;
c53e6443 sago007 2012-04-17 11:04 63
		return val;
c53e6443 sago007 2012-04-17 11:04 64
	}
ecef5838 sago007 2015-11-24 20:01 65
	catch (ios_base::failure& f) {
c53e6443 sago007 2012-04-17 11:04 66
		return 0.0;
c53e6443 sago007 2012-04-17 11:04 67
	}
769a41a0 sago007 2008-09-24 12:54 68
}
769a41a0 sago007 2008-09-24 12:54 69
d07b805e sago007 2009-01-27 13:15 70
/**
d07b805e sago007 2009-01-27 13:15 71
 * str2int parses a string and returns an int with the value of the string.
fcd5a134 sago007 2008-12-19 01:11 72
 * if the string is not an int then 0 is returned instead of throing an error
fcd5a134 sago007 2008-12-19 01:11 73
 * in that way this function will always return a useable value.
fcd5a134 sago007 2008-12-19 01:11 74
 */
ecef5838 sago007 2015-11-24 20:01 75
int str2int(const string& str2parse) {
ecef5838 sago007 2015-11-24 20:01 76
	try {
444cec07 sago007 2012-05-05 16:42 77
		converter.clear();
444cec07 sago007 2012-05-05 16:42 78
		converter.str(str2parse);
c53e6443 sago007 2012-04-17 11:04 79
		int val = 0;
c53e6443 sago007 2012-04-17 11:04 80
		converter >> val;
c53e6443 sago007 2012-04-17 11:04 81
		return val;
c53e6443 sago007 2012-04-17 11:04 82
	}
ecef5838 sago007 2015-11-24 20:01 83
	catch (ios_base::failure& f) {
c53e6443 sago007 2012-04-17 11:04 84
		return 0;
c53e6443 sago007 2012-04-17 11:04 85
	}
769a41a0 sago007 2008-09-24 12:54 86
}
89c4a3a6 sago007 2008-08-29 14:32 87
89c4a3a6 sago007 2008-08-29 14:32 88
#ifdef WIN32
89c4a3a6 sago007 2008-08-29 14:32 89
//Returns path to "my Documents" in windows:
ecef5838 sago007 2015-11-24 20:01 90
string getMyDocumentsPath() {
c53e6443 sago007 2012-04-17 11:04 91
	TCHAR pszPath[MAX_PATH];
acd79baf sago007 2015-11-22 19:37 92
	//if (SUCCEEDED(SHGetSpecialFolderPath(nullptr, pszPath, CSIDL_PERSONAL, FALSE))) {
ecef5838 sago007 2015-11-24 20:01 93
	if (SUCCEEDED(SHGetFolderPath(nullptr, CSIDL_PERSONAL, nullptr, 0, pszPath))) {
c53e6443 sago007 2012-04-17 11:04 94
		// pszPath is now the path that you want
724439a5 sago007 2008-09-11 15:52 95
#if DEBUG
c53e6443 sago007 2012-04-17 11:04 96
		cout << "MyDocuments Located: " << pszPath << endl;
89c4a3a6 sago007 2008-08-29 14:32 97
#endif
c53e6443 sago007 2012-04-17 11:04 98
		string theResult= pszPath;
c53e6443 sago007 2012-04-17 11:04 99
		return theResult;
c53e6443 sago007 2012-04-17 11:04 100
	}
ecef5838 sago007 2015-11-24 20:01 101
	else {
c53e6443 sago007 2012-04-17 11:04 102
		cout << "Warning: My Documents not found!" << endl;
c53e6443 sago007 2012-04-17 11:04 103
		string theResult ="";
c53e6443 sago007 2012-04-17 11:04 104
		return theResult;
c53e6443 sago007 2012-04-17 11:04 105
	}
89c4a3a6 sago007 2008-08-29 14:32 106
}
89c4a3a6 sago007 2008-08-29 14:32 107
89c4a3a6 sago007 2008-08-29 14:32 108
#endif
89c4a3a6 sago007 2008-08-29 14:32 109
d07b805e sago007 2009-01-27 13:15 110
/**
d07b805e sago007 2009-01-27 13:15 111
 * Returns the path to where all settings must be saved.
d07b805e sago007 2009-01-27 13:15 112
 * On unix-like systems this is the home-folder under: ~/.gamesaves/GAMENAME
d07b805e sago007 2009-01-27 13:15 113
 * In Windows it is My Documents/My Games
d07b805e sago007 2009-01-27 13:15 114
 * Consider changing this for Vista that has a special save games folder
d07b805e sago007 2009-01-27 13:15 115
 */
ecef5838 sago007 2015-11-24 20:01 116
string getPathToSaveFiles() {
89c4a3a6 sago007 2008-08-29 14:32 117
#ifdef __unix__
c53e6443 sago007 2012-04-17 11:04 118
	return (string)getenv("HOME")+(string)"/.gamesaves/"+GAMENAME;
89c4a3a6 sago007 2008-08-29 14:32 119
#elif WIN32
c53e6443 sago007 2012-04-17 11:04 120
	return getMyDocumentsPath()+(string)"/My Games/"+GAMENAME;
89c4a3a6 sago007 2008-08-29 14:32 121
#else
c53e6443 sago007 2012-04-17 11:04 122
	return ".";
89c4a3a6 sago007 2008-08-29 14:32 123
#endif
89c4a3a6 sago007 2008-08-29 14:32 124
}
89c4a3a6 sago007 2008-08-29 14:32 125
d07b805e sago007 2009-01-27 13:15 126
/**
d07b805e sago007 2009-01-27 13:15 127
 * Takes a number of milliseconds and returns the value in commonTime format.
d07b805e sago007 2009-01-27 13:15 128
 */
ecef5838 sago007 2015-11-24 20:01 129
commonTime TimeHandler::ms2ct(unsigned int milliseconds) {
c53e6443 sago007 2012-04-17 11:04 130
	commonTime ct;
c53e6443 sago007 2012-04-17 11:04 131
	ct.days = 0;
c53e6443 sago007 2012-04-17 11:04 132
	unsigned int time = milliseconds;
c53e6443 sago007 2012-04-17 11:04 133
	ct.hours = time/(1000*60*60);
c53e6443 sago007 2012-04-17 11:04 134
	time = time % (1000*60*60);
c53e6443 sago007 2012-04-17 11:04 135
	ct.minutes = time/(1000*60);
c53e6443 sago007 2012-04-17 11:04 136
	time = time % (1000*60);
c53e6443 sago007 2012-04-17 11:04 137
	ct.seconds = time/1000;
c53e6443 sago007 2012-04-17 11:04 138
	return ct;
c09d0e4f sago007 2009-01-27 01:15 139
}
89c4a3a6 sago007 2008-08-29 14:32 140
ecef5838 sago007 2015-11-24 20:01 141
commonTime TimeHandler::getTime(const string& name) {
c53e6443 sago007 2012-04-17 11:04 142
	commonTime ct;
c53e6443 sago007 2012-04-17 11:04 143
	ct.days = Config::getInstance()->getInt(name+"Days");
c53e6443 sago007 2012-04-17 11:04 144
	ct.hours = Config::getInstance()->getInt(name+"Hours");
c53e6443 sago007 2012-04-17 11:04 145
	ct.minutes = Config::getInstance()->getInt(name+"Minutes");
c53e6443 sago007 2012-04-17 11:04 146
	ct.seconds = Config::getInstance()->getInt(name+"Seconds");
c53e6443 sago007 2012-04-17 11:04 147
	return ct;
89c4a3a6 sago007 2008-08-29 14:32 148
}
89c4a3a6 sago007 2008-08-29 14:32 149
d07b805e sago007 2009-01-27 13:15 150
/**
c53e6443 sago007 2012-04-17 11:04 151
 * Returns the total runtime with toAdd added but without writing it to config file.
d07b805e sago007 2009-01-27 13:15 152
 * Used for stats
c09d0e4f sago007 2009-01-27 01:15 153
 */
ecef5838 sago007 2015-11-24 20:01 154
commonTime TimeHandler::peekTime(const string& name, const commonTime& toAdd) {
c53e6443 sago007 2012-04-17 11:04 155
	commonTime ct = getTime(name);
c09d0e4f sago007 2009-01-27 01:15 156
c53e6443 sago007 2012-04-17 11:04 157
	ct.seconds +=toAdd.seconds;
c53e6443 sago007 2012-04-17 11:04 158
	ct.minutes +=ct.seconds/60;
c53e6443 sago007 2012-04-17 11:04 159
	ct.seconds = ct.seconds%60;
c09d0e4f sago007 2009-01-27 01:15 160
c53e6443 sago007 2012-04-17 11:04 161
	ct.minutes += toAdd.minutes;
c53e6443 sago007 2012-04-17 11:04 162
	ct.hours += ct.minutes/60;
c53e6443 sago007 2012-04-17 11:04 163
	ct.minutes = ct.minutes%60;
c09d0e4f sago007 2009-01-27 01:15 164
c53e6443 sago007 2012-04-17 11:04 165
	ct.hours += toAdd.hours;
c53e6443 sago007 2012-04-17 11:04 166
	ct.days += ct.hours/24;
c53e6443 sago007 2012-04-17 11:04 167
	ct.hours = ct.hours%24;
c09d0e4f sago007 2009-01-27 01:15 168
c53e6443 sago007 2012-04-17 11:04 169
	ct.days += toAdd.days;
c53e6443 sago007 2012-04-17 11:04 170
	return ct;
c09d0e4f sago007 2009-01-27 01:15 171
}
c09d0e4f sago007 2009-01-27 01:15 172
d07b805e sago007 2009-01-27 13:15 173
/**
c09d0e4f sago007 2009-01-27 01:15 174
 * Same as peekTotalTime but writes the time to the config file.
d07b805e sago007 2009-01-27 13:15 175
 * Should only be called only once! when the program shuts down
c09d0e4f sago007 2009-01-27 01:15 176
 */
ecef5838 sago007 2015-11-24 20:01 177
commonTime TimeHandler::addTime(const string& name, const commonTime& toAdd) {
c53e6443 sago007 2012-04-17 11:04 178
	commonTime ct = peekTime(name,toAdd);
c53e6443 sago007 2012-04-17 11:04 179
c53e6443 sago007 2012-04-17 11:04 180
	Config::getInstance()->setInt(name+"Days",ct.days);
c53e6443 sago007 2012-04-17 11:04 181
	Config::getInstance()->setInt(name+"Hours",ct.hours);
c53e6443 sago007 2012-04-17 11:04 182
	Config::getInstance()->setInt(name+"Minutes",ct.minutes);
c53e6443 sago007 2012-04-17 11:04 183
	Config::getInstance()->setInt(name+"Seconds",ct.seconds);
c53e6443 sago007 2012-04-17 11:04 184
	return ct;
89c4a3a6 sago007 2008-08-29 14:32 185
}
769a41a0 sago007 2008-09-24 12:54 186
769a41a0 sago007 2008-09-24 12:54 187
Config* Config::instance = 0;
769a41a0 sago007 2008-09-24 12:54 188
ecef5838 sago007 2015-11-24 20:01 189
Config::Config() {
c53e6443 sago007 2012-04-17 11:04 190
	configMap.clear();
c53e6443 sago007 2012-04-17 11:04 191
	load();
c53e6443 sago007 2012-04-17 11:04 192
	shuttingDown = 0; // Not shutting down
769a41a0 sago007 2008-09-24 12:54 193
}
769a41a0 sago007 2008-09-24 12:54 194
ecef5838 sago007 2015-11-24 20:01 195
void Config::load() {
c53e6443 sago007 2012-04-17 11:04 196
	string filename = getPathToSaveFiles()+"/configFile";
c53e6443 sago007 2012-04-17 11:04 197
	ifstream inFile(filename.c_str());
c53e6443 sago007 2012-04-17 11:04 198
	string key;
c53e6443 sago007 2012-04-17 11:04 199
	string previuskey;
c53e6443 sago007 2012-04-17 11:04 200
	char value[MAX_VAR_LENGTH];
ecef5838 sago007 2015-11-24 20:01 201
	if (inFile) {
ecef5838 sago007 2015-11-24 20:01 202
		while (!inFile.eof()) {
c53e6443 sago007 2012-04-17 11:04 203
			inFile >> key;
ecef5838 sago007 2015-11-24 20:01 204
			if (key==previuskey) { //the last entry will be read 2 times if a linebreak is missing in the end
c53e6443 sago007 2012-04-17 11:04 205
				continue;
acd79baf sago007 2015-11-22 19:37 206
			}
c53e6443 sago007 2012-04-17 11:04 207
			previuskey = key;
c53e6443 sago007 2012-04-17 11:04 208
			inFile.get(); //Read the space between the key and the content
c53e6443 sago007 2012-04-17 11:04 209
			inFile.getline(value,MAX_VAR_LENGTH);
c53e6443 sago007 2012-04-17 11:04 210
#if DEBUG
c53e6443 sago007 2012-04-17 11:04 211
			cout << "Config "<< "read: " << key << " with:\"" << value << "\"" << endl;
c53e6443 sago007 2012-04-17 11:04 212
#endif
c53e6443 sago007 2012-04-17 11:04 213
			configMap[key] = (string)value;
c53e6443 sago007 2012-04-17 11:04 214
		}
c53e6443 sago007 2012-04-17 11:04 215
		inFile.close();
c53e6443 sago007 2012-04-17 11:04 216
	}
769a41a0 sago007 2008-09-24 12:54 217
}
769a41a0 sago007 2008-09-24 12:54 218
ecef5838 sago007 2015-11-24 20:01 219
Config* Config::getInstance() {
ecef5838 sago007 2015-11-24 20:01 220
	if (Config::instance==0) {
c53e6443 sago007 2012-04-17 11:04 221
		Config::instance = new Config();
c53e6443 sago007 2012-04-17 11:04 222
c53e6443 sago007 2012-04-17 11:04 223
	}
c53e6443 sago007 2012-04-17 11:04 224
	return Config::instance;
769a41a0 sago007 2008-09-24 12:54 225
}
769a41a0 sago007 2008-09-24 12:54 226
ecef5838 sago007 2015-11-24 20:01 227
void Config::save() {
c53e6443 sago007 2012-04-17 11:04 228
	string filename = getPathToSaveFiles()+"/configFile";
c53e6443 sago007 2012-04-17 11:04 229
	ofstream outFile(filename.c_str(),ios::trunc);
c53e6443 sago007 2012-04-17 11:04 230
ecef5838 sago007 2015-11-24 20:01 231
	if (outFile) {
c53e6443 sago007 2012-04-17 11:04 232
		map<string,string>::iterator iter;
ecef5838 sago007 2015-11-24 20:01 233
		for (iter = configMap.begin(); iter != configMap.end(); iter++) {
c53e6443 sago007 2012-04-17 11:04 234
			outFile << iter->first << " " << iter->second << endl;
c53e6443 sago007 2012-04-17 11:04 235
		}
c53e6443 sago007 2012-04-17 11:04 236
		outFile << "\n"; //The last entry in the file will be read double if a linebreak is missing
c53e6443 sago007 2012-04-17 11:04 237
		//This is checked on load too in case a user changes it himself.
c53e6443 sago007 2012-04-17 11:04 238
	}
c53e6443 sago007 2012-04-17 11:04 239
	outFile.close();
769a41a0 sago007 2008-09-24 12:54 240
}
769a41a0 sago007 2008-09-24 12:54 241
ecef5838 sago007 2015-11-24 20:01 242
bool Config::exists(const string& varName) const {
c53e6443 sago007 2012-04-17 11:04 243
	//Using that find returns an iterator to the end of the map if not found
c53e6443 sago007 2012-04-17 11:04 244
	return configMap.find(varName) != configMap.end();
769a41a0 sago007 2008-09-24 12:54 245
}
769a41a0 sago007 2008-09-24 12:54 246
ecef5838 sago007 2015-11-24 20:01 247
void Config::setDefault(const string& varName,const string& content) {
ecef5838 sago007 2015-11-24 20:01 248
	if (exists(varName)) {
acd79baf sago007 2015-11-22 19:37 249
		return;    //Already exists do not change
acd79baf sago007 2015-11-22 19:37 250
	}
c53e6443 sago007 2012-04-17 11:04 251
	setString(varName,content);
42f8ed5f sago007 2009-03-05 11:47 252
}
42f8ed5f sago007 2009-03-05 11:47 253
ecef5838 sago007 2015-11-24 20:01 254
void Config::setShuttingDown(long shuttingDown) {
c53e6443 sago007 2012-04-17 11:04 255
	this->shuttingDown = shuttingDown;
cc3ef158 sago007 2011-07-03 16:13 256
}
cc3ef158 sago007 2011-07-03 16:13 257
ecef5838 sago007 2015-11-24 20:01 258
long Config::isShuttingDown() const {
c53e6443 sago007 2012-04-17 11:04 259
	return shuttingDown;
cc3ef158 sago007 2011-07-03 16:13 260
}
cc3ef158 sago007 2011-07-03 16:13 261
ecef5838 sago007 2015-11-24 20:01 262
void Config::setString(const string& varName, const string& content) {
c53e6443 sago007 2012-04-17 11:04 263
	configMap[varName] = content;
769a41a0 sago007 2008-09-24 12:54 264
}
769a41a0 sago007 2008-09-24 12:54 265
ecef5838 sago007 2015-11-24 20:01 266
void Config::setInt(const string& varName, int content) {
c53e6443 sago007 2012-04-17 11:04 267
	configMap[varName] = itoa(content);
769a41a0 sago007 2008-09-24 12:54 268
}
769a41a0 sago007 2008-09-24 12:54 269
ecef5838 sago007 2015-11-24 20:01 270
void Config::setValue(const string& varName,double content) {
c53e6443 sago007 2012-04-17 11:04 271
	configMap[varName] = double2str(content);
769a41a0 sago007 2008-09-24 12:54 272
}
769a41a0 sago007 2008-09-24 12:54 273
ecef5838 sago007 2015-11-24 20:01 274
string Config::getString(const string& varName) {
ecef5838 sago007 2015-11-24 20:01 275
	if (exists(varName)) {
c53e6443 sago007 2012-04-17 11:04 276
		return configMap[varName];
c53e6443 sago007 2012-04-17 11:04 277
	}
acd79baf sago007 2015-11-22 19:37 278
	else {
c53e6443 sago007 2012-04-17 11:04 279
		return "";
acd79baf sago007 2015-11-22 19:37 280
	}
769a41a0 sago007 2008-09-24 12:54 281
}
769a41a0 sago007 2008-09-24 12:54 282
ecef5838 sago007 2015-11-24 20:01 283
int Config::getInt(const string& varName) {
ecef5838 sago007 2015-11-24 20:01 284
	if (exists(varName)) {
c53e6443 sago007 2012-04-17 11:04 285
		return str2int(configMap[varName]);
c53e6443 sago007 2012-04-17 11:04 286
	}
acd79baf sago007 2015-11-22 19:37 287
	else {
c53e6443 sago007 2012-04-17 11:04 288
		return 0;
acd79baf sago007 2015-11-22 19:37 289
	}
769a41a0 sago007 2008-09-24 12:54 290
}
769a41a0 sago007 2008-09-24 12:54 291
ecef5838 sago007 2015-11-24 20:01 292
double Config::getValue(const string& varName) {
ecef5838 sago007 2015-11-24 20:01 293
	if (exists(varName)) {
c53e6443 sago007 2012-04-17 11:04 294
		return str2double(configMap[varName]);
c53e6443 sago007 2012-04-17 11:04 295
	}
acd79baf sago007 2015-11-22 19:37 296
	else {
c53e6443 sago007 2012-04-17 11:04 297
		return 0.0;
acd79baf sago007 2015-11-22 19:37 298
	}
769a41a0 sago007 2008-09-24 12:54 299
}
1970-01-01 00:00 300