diff options
Diffstat (limited to 'source/data')
-rw-r--r-- | source/data/Config.cpp | 105 | ||||
-rw-r--r-- | source/data/Config.h | 136 | ||||
-rw-r--r-- | source/data/LevelReader.cpp | 54 | ||||
-rw-r--r-- | source/data/LevelReader.h | 71 |
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 |