git repos / saland

commit fc0d6f9a

Poul Sander · 2018-10-20 16:46
fc0d6f9a29bc1f3f2f66cb921527603e872452a4 patch · browse files
parent 63c01ac9f60dd60886ba53d6e328232ac446708b

Copy common and os from Block Attack - Rise of the Blocks

Changed files

A src/common.cpp
A src/common.h
A src/os.cpp
A src/os.hpp
M src/saland.cpp before
diff --git a/src/common.cpp b/src/common.cpp new file mode 100644 index 0000000..49a98d2 --- /dev/null +++ b/src/common.cpp
@@ -0,0 +1,249 @@
+/*
+===========================================================================
+ * Saland Adventures
+Copyright (C) 2014-2018 Poul Sander
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see http://www.gnu.org/licenses/
+
+Source information and contacts persons can be found at
+https://github.com/sago007/saland
+===========================================================================
+*/
+
+#include "common.h"
+#include <sstream>
+#include <cstring>
+#include "os.hpp"
+#include "sago/SagoMiscSdl2.hpp"
+#include "sago/SagoMisc.hpp"
+#include <stdarg.h>
+
+
+bool strequals(const char* a, const char* b) {
+ return strcmp(a,b) == 0;
+}
+
+void dieOnNullptr(bool ptr, const char* msg) {
+ if (!ptr) {
+ sago::SagoFatalError(msg);
+ }
+}
+
+double str2double(const std::string& str2parse) {
+ try {
+ return std::stod(str2parse);
+ }
+ catch (...) {
+ return 0.0;
+ }
+}
+
+std::string SPrintStringF(const char* fmt, ...) {
+ std::string ret;
+ char buffer[1024];
+ va_list args;
+ va_start(args, fmt);
+ vsnprintf(buffer, sizeof(buffer), fmt, args);
+ ret = buffer;
+ va_end(args);
+ return ret;
+}
+
+const char* SPrintCF(const char* fmt, ...) {
+ static char buffer[1024];
+ va_list args;
+ va_start(args, fmt);
+ vsnprintf(buffer, sizeof(buffer), fmt, args);
+ va_end(args);
+ return buffer;
+}
+
+int str2int(const std::string& str2parse) {
+ try {
+ return std::stoi(str2parse);
+ }
+ catch (...) {
+ return 0;
+ }
+}
+
+/**
+ * Takes a number of milliseconds and returns the value in commonTime format.
+ */
+commonTime TimeHandler::ms2ct(unsigned int milliseconds) {
+ commonTime ct;
+ ct.days = 0;
+ unsigned int time = milliseconds;
+ ct.hours = time/(1000*60*60);
+ time = time % (1000*60*60);
+ ct.minutes = time/(1000*60);
+ time = time % (1000*60);
+ ct.seconds = time/1000;
+ return ct;
+}
+
+commonTime TimeHandler::getTime(const std::string& name) {
+ commonTime ct;
+ ct.days = Config::getInstance()->getInt(name+"Days");
+ ct.hours = Config::getInstance()->getInt(name+"Hours");
+ ct.minutes = Config::getInstance()->getInt(name+"Minutes");
+ ct.seconds = Config::getInstance()->getInt(name+"Seconds");
+ return ct;
+}
+
+/**
+ * Returns the total runtime with toAdd added but without writing it to config file.
+ * Used for stats
+ */
+commonTime TimeHandler::peekTime(const std::string& name, const commonTime& toAdd) {
+ commonTime ct = getTime(name);
+
+ ct.seconds +=toAdd.seconds;
+ ct.minutes +=ct.seconds/60;
+ ct.seconds = ct.seconds%60;
+
+ ct.minutes += toAdd.minutes;
+ ct.hours += ct.minutes/60;
+ ct.minutes = ct.minutes%60;
+
+ ct.hours += toAdd.hours;
+ ct.days += ct.hours/24;
+ ct.hours = ct.hours%24;
+
+ ct.days += toAdd.days;
+ return ct;
+}
+
+/**
+ * Same as peekTotalTime but writes the time to the config file.
+ * Should only be called only once! when the program shuts down
+ */
+commonTime TimeHandler::addTime(const std::string& name, const commonTime& toAdd) {
+ commonTime ct = peekTime(name,toAdd);
+
+ Config::getInstance()->setInt(name+"Days",ct.days);
+ Config::getInstance()->setInt(name+"Hours",ct.hours);
+ Config::getInstance()->setInt(name+"Minutes",ct.minutes);
+ Config::getInstance()->setInt(name+"Seconds",ct.seconds);
+ return ct;
+}
+
+Config* Config::instance = 0;
+
+Config::Config() {
+ configMap.clear();
+ load();
+ shuttingDown = 0; // Not shutting down
+}
+
+void Config::load() {
+ std::string filecontent = sago::GetFileContent("configFile");
+ std::stringstream inFile(filecontent);
+ std::string key;
+ std::string previuskey;
+ if (inFile) {
+ while (!inFile.eof()) {
+ inFile >> key;
+ if (key==previuskey) { //the last entry will be read 2 times if a linebreak is missing in the end
+ continue;
+ }
+ previuskey = key;
+ inFile.get(); //Read the space between the key and the content
+ std::string value;
+ std::getline(inFile, value);
+#if DEBUG
+ std::cerr << "Config read: " << key << " with:\"" << value << "\"" << "\n";
+#endif
+ configMap[key] = value;
+ }
+ }
+}
+
+Config* Config::getInstance() {
+ if (Config::instance==0) {
+ Config::instance = new Config();
+
+ }
+ return Config::instance;
+}
+
+void Config::save() {
+ std::stringstream outFile;
+ std::map<std::string,std::string>::iterator iter;
+ for (iter = configMap.begin(); iter != configMap.end(); ++iter) {
+ outFile << iter->first << " " << iter->second << "\n";
+ }
+ outFile << "\n"; //The last entry in the file will be read double if a linebreak is missing
+ //This is checked on load too in case a user changes it himself.
+ sago::WriteFileContent("configFile", outFile.str());
+}
+
+bool Config::exists(const std::string& varName) const {
+ //Using that find returns an iterator to the end of the map if not found
+ return configMap.find(varName) != configMap.end();
+}
+
+void Config::setDefault(const std::string& varName,const std::string& content) {
+ if (exists(varName)) {
+ return; //Already exists do not change
+ }
+ setString(varName,content);
+}
+
+void Config::setShuttingDown(long shuttingDown) {
+ this->shuttingDown = shuttingDown;
+}
+
+long Config::isShuttingDown() const {
+ return shuttingDown;
+}
+
+void Config::setString(const std::string& varName, const std::string& content) {
+ configMap[varName] = content;
+}
+
+void Config::setInt(const std::string& varName, int content) {
+ configMap[varName] = std::to_string(content);
+}
+
+void Config::setValue(const std::string& varName,double content) {
+ configMap[varName] = std::to_string(content);
+}
+
+std::string Config::getString(const std::string& varName) {
+ if (exists(varName)) {
+ return configMap[varName];
+ }
+ else {
+ return "";
+ }
+}
+
+int Config::getInt(const std::string& varName) {
+ if (exists(varName)) {
+ return str2int(configMap[varName]);
+ }
+ else {
+ return 0;
+ }
+}
+
+double Config::getValue(const std::string& varName) {
+ if (exists(varName)) {
+ return str2double(configMap[varName]);
+ }
+ else {
+ return 0.0;
+ }
+}
diff --git a/src/common.h b/src/common.h new file mode 100644 index 0000000..dc201f1 --- /dev/null +++ b/src/common.h
@@ -0,0 +1,205 @@
+/*
+===========================================================================
+ * Saland Adventures
+Copyright (C) 2014-2018 Poul Sander
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see http://www.gnu.org/licenses/
+
+Source information and contacts persons can be found at
+https://github.com/sago007/saland
+===========================================================================
+*/
+
+/*
+ *This is the common.h
+ *It contains some basic functions that nearly all multi platform games are going
+ *to need.
+ */
+
+#ifndef _COMMON_H
+#define _COMMON_H
+
+#include <string>
+#include <iostream>
+#include <map>
+#include <stdlib.h>
+#include <libintl.h>
+#include <ctime>
+
+
+#define _(String) gettext (String)
+
+struct commonTime
+{
+ unsigned int days = 0;
+ unsigned int hours = 0;
+ unsigned int minutes = 0;
+ unsigned int seconds = 0;
+};
+
+bool strequals(const char* a, const char* b);
+
+/**
+ * str2int parses a string and returns an int with the value of the string.
+ * if the string is not an int then 0 is returned instead of throwing an error
+ * in that way this function will always return a usable value.
+ */
+int str2int(const std::string &str2parse) __attribute__((const));
+
+void dieOnNullptr(bool, const char* msg);
+
+/**
+ * str2double parses a string and returns a double with the value of the string.
+ * if the string is not a double then 0.0 is returned instead of throwing an error
+ * in that way this function will always return a usable value.
+ */
+double str2double(const std::string &str2parse) __attribute__((const));
+
+/**
+ * Does the equivalent to snprintf but returns a C++ string
+ * @param fmt The format string
+ * @param ... Additional parameters for the place holders
+ * @return A string with the result
+ */
+std::string SPrintStringF(const char* fmt, ...) __attribute__ ((format (printf, 1, 2)));
+
+/**
+ * Prints to an internal C-buffer
+ * Because it uses an internal buffer the returned buffer is only valid until the next call
+ * The String is cut at 1024 chars (including the 0 terminator)
+ * @param fmt The format string
+ * @param ... Additional parameters for the place holders
+ * @return Pointer to an internal buffer
+ */
+const char* SPrintCF(const char* fmt, ...) __attribute__ ((format (printf, 1, 2)));
+
+class TimeHandler
+{
+public:
+ static commonTime ms2ct(unsigned int milliseconds);
+
+ static commonTime getTime(const std::string &name);
+
+ static commonTime peekTime(const std::string &name, const commonTime &toAdd);
+
+ static commonTime addTime(const std::string &name, const commonTime &toAdd);
+};
+
+#define MAX_VAR_LENGTH 1024
+
+/*This is the Config class it is a map to hold config variables.
+ *It is inspired by Quake 3's CVAR system although a lot simpler.
+ *All variables have keys "varName" that is used to access a variable.
+ *
+ *This class is a singleton
+ */
+class Config
+{
+private:
+ std::map<std::string, std::string> configMap;
+
+ static Config *instance;
+
+ void load();
+
+ /* tells if the user has requested a shutdown */
+ long shuttingDown = 0;
+
+ Config();
+
+
+public:
+ /*Config is a singleton.
+ *It is accessed like this:
+ *Config::getInstance()->method2call(parameters);
+ */
+ static Config* getInstance();
+
+ /*save()
+ *forces the config to be written to disk. This will also happened if the
+ *program terminates normally.
+ */
+ void save();
+
+ /*getString(varName)
+ *Looks in the config file and returns the string that matches the key "varName"
+ *Returns an empty string if varName does not exist.
+ */
+ std::string getString(const std::string &varName);
+
+ /*getInt(varName)
+ *Looks in the config file and returns the int that matches the key "varName"
+ *Returns "0" if varName does not exist or cannot be parsed.
+ */
+ int getInt(const std::string &varName);
+
+ /*getValue(varName)
+ *Looks in the config file and returns the double that matches the key "varName"
+ *Returns "0.0" if varName does not exist or cannot be parsed.
+ */
+ double getValue(const std::string &varName);
+
+ /*setString(varName,content)
+ *Sets the config variable with key "varName" to the value of "content"
+ */
+ void setString(const std::string &varName, const std::string &content);
+
+ /*setInt(varName,content)
+ *Sets the config variable with key "varName" to the value of "content"
+ */
+ void setInt(const std::string &varName, int content);
+
+ /**
+ * Sets a config variable to a given (double) value
+ * @param varName Name of the variable to set
+ * @param content Value to give the variable
+ */
+ void setValue(const std::string &varName,double content);
+
+ /**
+ * returns true if the key varName exists. This is used the first time 1.4.0
+ * starts so that it can see that it has to import configs from an earlier
+ * version.
+ * @param varName Name of the variable
+ * @return true if the variable exists
+ */
+ bool exists(const std::string &varName) const;
+
+ /*setDefault(varName,value)
+ *if the variable "varName" does not exist it will be created with value "value"
+ *if varName exists then this will have no effect
+ */
+ /**
+ * Set default value for a variable. If the variable "varName" does not exist it will be created with value "value"
+ * if varName exists then this will have no effect
+ * @param varName Name of the variable
+ * @param content The default value
+ */
+ void setDefault(const std::string &varName, const std::string &content);
+
+ /**
+ * Should be set if the user has requested the program to shutdown.
+ * @param shuttingDown value of shutdown command. 5 = default = shutdown but allow saving
+ */
+ void setShuttingDown(long shuttingDown = 5);
+
+ /**
+ * tells if the user wants to shutdown. This can be used if the exit button is pressed deeply in the program.
+ * @return
+ */
+ long isShuttingDown() const;
+};
+
+#endif /* _COMMON_H */
+
diff --git a/src/os.cpp b/src/os.cpp new file mode 100644 index 0000000..4f6cff3 --- /dev/null +++ b/src/os.cpp
@@ -0,0 +1,71 @@
+/*
+===========================================================================
+ * Saland Adventures
+Copyright (C) 2014-2018 Poul Sander
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see http://www.gnu.org/licenses/
+
+Source information and contacts persons can be found at
+https://github.com/sago007/saland
+===========================================================================
+*/
+
+#include "os.hpp"
+#include <iostream>
+#include <physfs.h>
+#include "sago/platform_folders.h"
+
+static sago::PlatformFolders pf;
+
+
+/*
+ *Files will be saved in:
+ * HOME/.local/share/"+GAMENAME (unix)
+ *or DOCUMENTS/My Games/GAMENAME (Windows)
+ */
+#define GAMENAME "saland_game"
+
+static std::string overrideSavePath = "";
+
+/**
+ * Returns the path to where all settings must be saved.
+ * On unix-like systems this is the home-folder under: ~/.local/share/GAMENAME
+ * In Windows it is My Documents/My Games
+ * Consider changing this for Vista that has a special save games folder
+ */
+std::string getPathToSaveFiles() {
+ if (overrideSavePath.length() > 0) {
+ return overrideSavePath;
+ }
+ return pf.getSaveGamesFolder1()+"/"+GAMENAME;
+}
+
+void setPathToSaveFiles(const std::string& path) {
+ overrideSavePath = path;
+}
+
+void OsCreateSaveFolder() {
+#if defined(__unix__)
+ std::string cmd = "mkdir -p '"+getPathToSaveFiles()+"/'";
+ int retcode = system(cmd.c_str());
+ if (retcode != 0) {
+ std::cerr << "Failed to create: " << getPathToSaveFiles()+"/" << "\n";
+ }
+#elif defined(_WIN32)
+ //Now for Windows NT/2k/xp/2k3 etc.
+ CreateDirectory(pf.getSaveGamesFolder1().c_str(), nullptr);
+ std::string tempA = getPathToSaveFiles();
+ CreateDirectory(tempA.c_str(),nullptr);
+#endif
+}
diff --git a/src/os.hpp b/src/os.hpp new file mode 100644 index 0000000..d1ea43c --- /dev/null +++ b/src/os.hpp
@@ -0,0 +1,37 @@
+/*
+===========================================================================
+ * Saland Adventures
+Copyright (C) 2014-2018 Poul Sander
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see http://www.gnu.org/licenses/
+
+Source information and contacts persons can be found at
+https://github.com/sago007/saland
+===========================================================================
+*/
+
+#if defined(_WIN32)
+#include "windows.h"
+#include "shlobj.h"
+#endif
+#include <string>
+
+std::string getPathToSaveFiles();
+#if defined(_WIN32)
+std::string getMyDocumentsPath();
+#endif
+
+void setPathToSaveFiles(const std::string& path);
+
+void OsCreateSaveFolder();
diff --git a/src/saland.cpp b/src/saland.cpp index d67f314..434381a 100644 --- a/src/saland.cpp +++ b/src/saland.cpp
@@ -1,7 +1,7 @@
/*
===========================================================================
* Saland Adventures
-Copyright (C) 2014-2017 Poul Sander
+Copyright (C) 2014-2018 Poul Sander
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -45,10 +45,9 @@ https://github.com/sago007/saland
#include "sagotmx/tmx_struct.h"
#include "sago/SagoTextBox.hpp"
-#if defined(_WIN32)
-#include <windows.h>
-#include <shlobj.h>
-#endif
+#include "common.h"
+#include "os.hpp"
+
#ifndef VERSIONNUMBER
#define VERSIONNUMBER "0.1.0"
@@ -68,14 +67,12 @@ public:
testBox.SetHolder(globalData.dataHolder);
testBox.SetFontSize(16);
}
-
+
virtual bool IsActive() override {
return isActive;
}
virtual void Draw(SDL_Renderer* target) override {
-
-
textField.SetText("Saland Adventures - The game that has a very long subtitle to test the outline");
textField.SetOutline(3, SDL_Color{255,165,0,255});
textField.Draw(target, 10, 10);
@@ -176,27 +173,6 @@ void runGame() {
}
-static sago::PlatformFolders pf;
-
-std::string getPathToSaveFiles() {
- return pf.getSaveGamesFolder1()+"/"+GAMENAME;
-}
-
-void OsCreateSaveFolder() {
-#if defined(__unix__)
- std::string cmd = "mkdir -p '"+getPathToSaveFiles()+"/'";
- int retcode = system(cmd.c_str());
- if (retcode != 0) {
- std::cerr << "Failed to create: " << getPathToSaveFiles()+"/" << "\n";
- }
-#elif defined(_WIN32)
- //Now for Windows NT/2k/xp/2k3 etc.
- std::string tempA = getPathToSaveFiles();
- CreateDirectory(tempA.c_str(),nullptr);
-#endif
-}
-
-
int main(int argc, char* argv[]) {
PHYSFS_init(argv[0]);
PHYSFS_addToSearchPath((std::string(PHYSFS_getBaseDir())+"/data").c_str(), 1);