summaryrefslogtreecommitdiff
path: root/source/data
diff options
context:
space:
mode:
Diffstat (limited to 'source/data')
-rw-r--r--source/data/Config.cpp105
-rw-r--r--source/data/Config.h136
-rw-r--r--source/data/LevelReader.cpp54
-rw-r--r--source/data/LevelReader.h71
4 files changed, 366 insertions, 0 deletions
diff --git a/source/data/Config.cpp b/source/data/Config.cpp
new file mode 100644
index 0000000..6cdda2f
--- /dev/null
+++ b/source/data/Config.cpp
@@ -0,0 +1,105 @@
+#include "Config.h"
+
+const string Config::SCREEN_WIDTH_KEY("screen_width");
+const string Config::SCREEN_HEIGHT_KEY("screen_height");
+const string Config::FULLSCREEN_KEY("fullscreen");
+
+const string Config::SCREEN_WIDTH_DEFAULT("800");
+const string Config::SCREEN_HEIGHT_DEFAULT("600");
+const string Config::FULLSCREEN_DEFAULT("false");
+
+
+Config::Config(const string& filename)
+ :_screenWidth(0),
+ _screenHeight(0)
+{
+ ifstream inStream(filename.c_str(), fstream::in);
+
+ map<string, string> readValues;
+ map<string, string> unfoundValues;
+ readFile(inStream, readValues);
+ fillValues(readValues, unfoundValues);
+
+ inStream.close();
+
+ ofstream outStream(filename.c_str(), fstream::app);
+
+ writeUnfoundValues(outStream, unfoundValues);
+
+ outStream.close();
+}
+
+unsigned int Config::screenWidth() const
+{
+ return _screenWidth;
+}
+unsigned int Config::screenHeight() const
+{
+ return _screenHeight;
+}
+bool Config::fullscreen() const
+{
+ return _fullscreen;
+}
+
+void Config::readFile(ifstream& file, map<string,string>& map)
+{
+ if (!file.is_open()) return;
+
+ string nextEntry;
+ while(!file.eof())
+ {
+ file >> nextEntry;
+
+ string::size_type equalsIndex = nextEntry.find("=",0);
+ if (equalsIndex!=string::npos)
+ {
+ string key = nextEntry.substr(0,equalsIndex);
+ string value = nextEntry.substr(equalsIndex+1);
+
+ map[key] = value;
+ }
+ }
+}
+
+void Config::fillValues(const map<string, string>& readValues, map<string, string>& unfoundValues)
+{
+ setScreenWidth(extractValue(readValues, unfoundValues, SCREEN_WIDTH_KEY, SCREEN_WIDTH_DEFAULT));
+ setScreenHeight(extractValue(readValues, unfoundValues, SCREEN_HEIGHT_KEY, SCREEN_HEIGHT_DEFAULT));
+ setFullscreen(extractValue(readValues, unfoundValues, FULLSCREEN_KEY, FULLSCREEN_DEFAULT));
+}
+
+string Config::extractValue(const map<string, string>& readValues, map<string, string>& unfoundValues, const string& key, const string& defaultValue)
+{
+ map<string, string>::const_iterator findIter = readValues.find(key);
+ if (findIter != readValues.end())
+ {
+ return findIter->second;
+ }
+ else
+ {
+ unfoundValues[key] = defaultValue;
+ return defaultValue;
+ }
+}
+
+void Config::writeUnfoundValues(ofstream& file, const map<string, string>& unfoundValues)
+{
+ for (map<string, string>::const_iterator iter = unfoundValues.begin(); iter!=unfoundValues.end(); ++iter)
+ {
+ file << iter->first << "=" << iter->second << endl;
+ }
+}
+
+void Config::setScreenWidth(const string& screenWidthStr)
+{
+ _screenWidth = atoi(screenWidthStr.c_str());
+}
+void Config::setScreenHeight(const string& screenHeightStr)
+{
+ _screenHeight = atoi(screenHeightStr.c_str());
+}
+void Config::setFullscreen(const string& fullscreenStr)
+{
+ _fullscreen = fullscreenStr=="true";
+}
diff --git a/source/data/Config.h b/source/data/Config.h
new file mode 100644
index 0000000..8fdf5aa
--- /dev/null
+++ b/source/data/Config.h
@@ -0,0 +1,136 @@
+#ifndef CONFIG_H
+#define CONFIG_H
+
+#include <cstdlib>
+#include <string>
+#include <fstream>
+#include <map>
+using namespace std;
+
+/**
+* @brief Object for handling user settings loaded from a file.
+*
+* These settings are currently all related to the screen (resolution and windowed or fullscreen).
+* If custom controls are implemented in a later release, they will be loaded here. If a setting exists
+* but is not found in the config file, it is set to a default value and written to the file.
+*
+* @author Justin Wernick
+* @author David Schneider
+*/
+class Config
+{
+ public:
+ /**
+ * @brief Constructs a Config object from a file with the given path.
+ *
+ * Opens the file and reads all of the settings in the file. The read settings are
+ * bound to the settings that have keys defined in the class. And settings missing from
+ * the file are set to default values, and the default values are written to the file.
+ *
+ * @param [in] filename The path of the file in which the settings are stored.
+ */
+ Config(const string& filename);
+
+ //Assignment and copy operations are handled by the compiler generated versions
+
+ /**
+ * @brief Function for accessing the screen width setting in pixels.
+ *
+ * @return The desired width of the screen in pixels.
+ */
+ unsigned int screenWidth() const;
+
+ /**
+ * @brief Function for accessing the screen height setting in pixels.
+ *
+ * @return The desired height of the screen in pixels.
+ */
+ unsigned int screenHeight() const;
+
+ /**
+ * @brief Function for accessing whether the game should be displayed in fullscreen or windowed mode.
+ *
+ * @return The desired fullscreen setting. A result of true means fullscreen mode, while a result of false means windowed mode.
+ */
+ bool fullscreen() const;
+
+ private:
+ /**
+ * @brief Reads all of the settings defined in a file into a map.
+ *
+ * Reads each line that is in the format "key=value" in a file into a map.
+ * Lines that do not contain a '=' are ignored.
+ *
+ * @param [in] file An opened filestream object at the beginning of the file to be read. After the function call, file will be at the end of the file.
+ * @param [out] map The map that is populated with settings.
+ */
+ void readFile(ifstream& file, map<string,string>& map);
+
+ /**
+ * @brief Initialises the Config option's parameters to those in the readValues map.
+ *
+ * Parameters with a key that does not appear in readValues are initialised to a default value.
+ * The default value, and its key, are then added to the unfoundValues map.
+ *
+ * @param [in] readValues A map containing all of the settings read in from a config file.
+ * @param [out] unfoundValues A map that is populated with and settings not found in readValues.
+ */
+ void fillValues(const map<string, string>& readValues, map<string, string>& unfoundValues);
+
+ /**
+ * @brief Helper function for fillValues. Finds the value for a single key.
+ *
+ * If the given key does not appear, it is added to the unfoundValues map with the given default
+ *
+ * @param [in] readValues A map containing all of the settings read in from a config file.
+ * @param [out] unfoundValues A map that is populated with and settings not found in readValues.
+ * @param [in] key The key of the setting to be found in readValues.
+ * @param [in] defaultValue The value to return and add to unfoundValues if the setting is not found in readValues.
+ *
+ * @return The value corresponding to the requested key.
+ */
+ string extractValue(const map<string, string>& readValues, map<string, string>& unfoundValues, const string& key, const string& defaultValue);
+
+ /**
+ * @brief Writes settings that were not found in the file to the file with default values.
+ *
+ * @param [in] file The opened filestream to which the key=value pairs are written.
+ * @param [in] unfoundValues The map of key value pairs to be written to the file.
+ */
+ void writeUnfoundValues(ofstream& file, const map<string, string>& unfoundValues);
+
+ /**
+ * @brief Initializes the screen width in pixels from a given string.
+ *
+ * @param [in] screenWidthStr A string representing the desired screen width, read from a file.
+ */
+ void setScreenWidth(const string& screenWidthStr);
+
+ /**
+ * @brief Initializes the screen height in pixels from a given string.
+ *
+ * @param [in] screenHeightStr A string representing the desired screen height, read from a file.
+ */
+ void setScreenHeight(const string& screenHeightStr);
+
+ /**
+ * @brief Initializes the fullscreen setting from a given string.
+ *
+ * @param [in] fullscreenStr A string representing whether the screen should be in fullscreen mode ("true") or windowed mode (anything else).
+ */
+ void setFullscreen(const string& fullscreenStr);
+
+ unsigned int _screenWidth; ///< The desired width of the screen in pixels.
+ unsigned int _screenHeight; ///< The desired height of the screen in pixels.
+ bool _fullscreen; ///< The desired fullscreen or windowed setting.
+
+ static const string SCREEN_WIDTH_KEY; ///< The key for the screen width setting, initialized to "screen_width".
+ static const string SCREEN_HEIGHT_KEY; ///< The key for the screen height setting, initialized to "screen_height".
+ static const string FULLSCREEN_KEY; ///< The key for the fullscreen setting, initialized to "fullscreen".
+
+ static const string SCREEN_WIDTH_DEFAULT; ///< The default value for the screen width setting, initialized to 800.
+ static const string SCREEN_HEIGHT_DEFAULT; ///< The default value for the screen height setting, initialized to 600.
+ static const string FULLSCREEN_DEFAULT; ///< The default value for the fullscreen setting, initialized to false.
+};
+
+#endif // CONFIG_H
diff --git a/source/data/LevelReader.cpp b/source/data/LevelReader.cpp
new file mode 100644
index 0000000..e5364d8
--- /dev/null
+++ b/source/data/LevelReader.cpp
@@ -0,0 +1,54 @@
+#include "LevelReader.h"
+
+LevelReader::LevelReader(string filename)
+ :_filename(filename)
+{}
+
+void LevelReader::readLevel(Maze& maze, list<PlayerCar>& players, list<EnemyCar>& enemies, list<Checkpoint>& checkpoints, list<Rock>& rocks)
+{
+ ifstream file(_filename.c_str());
+ if (!file)
+ {
+ al_show_native_message_box(NULL, "Fatal error", "Fatal error", "The requested level file could not be opened.", NULL, ALLEGRO_MESSAGEBOX_ERROR);
+ throw FileOpenError();
+ }
+
+ int maxX = 0;
+ int maxY = 0;
+
+ string line;
+ char element;
+ int y = 0;
+ vector <pair<int, int> > walls;
+
+ while (!file.eof())
+ {
+ getline (file, line);
+
+ for (int x = 0; x < static_cast<int>(line.length()); ++x)
+ {
+ element = line.at(x);
+ switch (element)
+ {
+ case PLAYER_CHAR: players.push_back(PlayerCar(x,y));
+ break;
+ case ENEMY_CHAR: enemies.push_back (EnemyCar(x,y));
+ break;
+ case CHECKPOINT_CHAR: checkpoints.push_back(Checkpoint(x,y));
+ break;
+ case ROCK_CHAR: rocks.push_back(Rock(x,y));
+ break;
+ case WALL_CHAR: walls.push_back (make_pair(x,y));
+ break;
+ }
+ if (maxX < x) maxX = x;
+ if (maxY < y) maxY = y;
+ }
+
+ ++y;
+ }
+
+ maze.generateMaze (walls, maxX, maxY);
+
+ file.close();
+}
diff --git a/source/data/LevelReader.h b/source/data/LevelReader.h
new file mode 100644
index 0000000..293d820
--- /dev/null
+++ b/source/data/LevelReader.h
@@ -0,0 +1,71 @@
+#ifndef MAZEREADER_H
+#define MAZEREADER_H
+
+#include <vector>
+#include <list>
+#include <string>
+#include <fstream>
+using namespace std;
+
+#include <allegro5/allegro_native_dialog.h>
+
+#include "../logic/Maze.h"
+#include "../logic/PlayerCar.h"
+#include "../logic/EnemyCar.h"
+#include "../logic/Checkpoint.h"
+#include "../logic/Rock.h"
+
+/**
+* @brief An exception that is thrown if the file selected for opening does not exist.
+*
+* This should never be thrown, since the Allegro native file dialog is being used to select
+* this file, and it only allows one to select existing files.
+*
+* @author Justin Wernick
+* @author David Schneider
+*/
+class FileOpenError{};
+
+/**
+* @brief Reads the game objects from a text file and calls relevant constructors.
+*
+* @author Justin Wernick
+* @author David Schneider
+*/
+class LevelReader
+{
+ public:
+ /**
+ * @brief Constructor that stores the path of the file containing the level to be read with the readLevel function.
+ *
+ * @param [in] filename The path of the file containing the level.
+ */
+ LevelReader(string filename);
+
+ //Assignment and copy operations are handled by the compiler generated versions
+
+ /**
+ * @brief Function to read the chosen file into the data structures used in the game.
+ *
+ * Each character in the file is iterated through, and added to the appropriate data structure if it matches
+ * one of the defined constants. Lists should be cleared prior to calling this function.
+ *
+ * @param [out] maze Object representing the walls, populated with a vector of x,y pairs.
+ * @param [out] players List representing the player(s) in the game.
+ * @param [out] enemies List representing the enemies in the game.
+ * @param [out] checkpoints List representing the checkpoints in the game.
+ * @param [out] rocks List representing the rocks in the game.
+ */
+ void readLevel(Maze& maze, list<PlayerCar>& players, list<EnemyCar>& enemies, list<Checkpoint>& checkpoints, list<Rock>& rocks);
+
+ private:
+ static const char PLAYER_CHAR = '@'; ///< Character represented a PlayerCar in the level file.
+ static const char ENEMY_CHAR = 'X'; ///< Character represented an EnemyCar in the level file.
+ static const char CHECKPOINT_CHAR = 'P'; ///< Character represented a Checkpoint in the level file.
+ static const char ROCK_CHAR = 'O'; ///< Character represented a Rock in the level file.
+ static const char WALL_CHAR = '#'; ///< Character represented a solid part of the maze in the level file.
+
+ string _filename; ///< Path of the file containing the level.
+};
+
+#endif // MAZEREADER_H