commit 294fd6e2ac7285be1a3888410f50a6246409b8de Author: Tiberiu Chibici Date: Fri Nov 11 20:18:01 2016 +0200 Initial commit diff --git a/.cproject b/.cproject new file mode 100644 index 0000000..90e6cee --- /dev/null +++ b/.cproject @@ -0,0 +1,165 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eb56f33 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +RemoteSystemsTempFiles +.metadata +.settings +import +Debug +Release diff --git a/.project b/.project new file mode 100644 index 0000000..fd9d8fe --- /dev/null +++ b/.project @@ -0,0 +1,27 @@ + + + Farmlands + + + + + + org.eclipse.cdt.managedbuilder.core.genmakebuilder + clean,full,incremental, + + + + + org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder + full,incremental, + + + + + + org.eclipse.cdt.core.cnature + org.eclipse.cdt.core.ccnature + org.eclipse.cdt.managedbuilder.core.managedBuildNature + org.eclipse.cdt.managedbuilder.core.ScannerConfigNature + + diff --git a/assets/fonts/DejaVuSans.ttf b/assets/fonts/DejaVuSans.ttf new file mode 100644 index 0000000..39a60f4 Binary files /dev/null and b/assets/fonts/DejaVuSans.ttf differ diff --git a/assets/tilesets/ground.png b/assets/tilesets/ground.png new file mode 100644 index 0000000..0dac8fd Binary files /dev/null and b/assets/tilesets/ground.png differ diff --git a/src/FarmlandsGame.cpp b/src/FarmlandsGame.cpp new file mode 100644 index 0000000..fee82cb --- /dev/null +++ b/src/FarmlandsGame.cpp @@ -0,0 +1,140 @@ +/* + * FarmlandsGame.cpp + * + * Created on: Nov 7, 2016 + * Author: tibi + */ + +#include "FarmlandsGame.h" +#include +#include +#include +#include +#include + +namespace farmlands +{ + +FarmlandsGame::FarmlandsGame() : + m_running(true), + m_sdlWindow(nullptr), + m_sdlRenderer(nullptr) +{ +} + +bool FarmlandsGame::initialize() +{ + if (SDL_Init(SDL_INIT_VIDEO) != 0) { + std::cerr << "Failed to initialize SDL!\n"; + return false; + } + + int imgFlags = IMG_INIT_PNG; + if (IMG_Init(IMG_INIT_PNG) != imgFlags) { + std::cerr << "Failed to initialize SDL_image!\n"; + return false; + } + + if (TTF_Init() != 0) { + std::cerr << "Failed to initialize SDL_ttf!\n"; + return false; + } + + m_sdlWindow = SDL_CreateWindow("Farmlands", 0, 0, 1024, 768, SDL_WINDOW_SHOWN); + if (!m_sdlWindow) { + std::cerr << "Failed to create main window!\n"; + return false; + } + + m_sdlRenderer = SDL_CreateRenderer(m_sdlWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); + if (!m_sdlRenderer) { + std::cerr << "Failed to create renderer!\n"; + return false; + } + + // Load resources + m_resourceManager.loadGame(m_sdlRenderer); + + return true; +} + +void FarmlandsGame::onLogicUpdate() +{ + +} + +void FarmlandsGame::onRender() +{ + SDL_RenderClear(m_sdlRenderer); + + SDL_Rect dest = { 0, 0, 0, 0}; + SDL_QueryTexture(m_resourceManager.texture(0), NULL, NULL, &dest.w, &dest.h); + dest.w *= 2; + + SDL_RenderCopy(m_sdlRenderer, m_resourceManager.texture(0), nullptr, &dest); + // Render loading screen + + SDL_Delay(10); + + SDL_RenderPresent(m_sdlRenderer); +} + +void FarmlandsGame::onEvent(SDL_Event& event) +{ + switch(event.type) + { + case SDL_QUIT: + stop(); + break; + + case SDL_KEYDOWN: + if (event.key.keysym.scancode == SDL_Scancode::SDL_SCANCODE_ESCAPE) + stop(); + break; + case SDL_WINDOWEVENT_RESIZED: + break; + } +} + +void FarmlandsGame::stop() +{ + m_running = false; +} + +void FarmlandsGame::dispose() +{ + if (m_sdlRenderer) + SDL_DestroyRenderer(m_sdlRenderer); + + if (m_sdlWindow) + SDL_DestroyWindow(m_sdlWindow); + + SDL_Quit(); +} + +int FarmlandsGame::run() +{ + // Initialize game + if (!initialize()) + { + dispose(); + return 1; + } + + // Main loop + while(m_running) + { + SDL_Event event; + while (SDL_PollEvent(&event)) + onEvent(event); + + onLogicUpdate(); + onRender(); + } + + // Cleanup + dispose(); + return 0; +} + +} diff --git a/src/FarmlandsGame.h b/src/FarmlandsGame.h new file mode 100644 index 0000000..c18db35 --- /dev/null +++ b/src/FarmlandsGame.h @@ -0,0 +1,49 @@ +/* + * FarmlandsGame.h + * + * Created on: Nov 7, 2016 + * Author: tibi + */ + +#ifndef FARMLANDSGAME_H_ +#define FARMLANDSGAME_H_ + +#include "storage/ResourceManager.h" + +#include + +namespace farmlands +{ + enum GameState + { + Splash, + MainMenu, + Playing + }; + + class FarmlandsGame { + + public: + int run(); + FarmlandsGame(); + + protected: + bool initialize(); + + void onLogicUpdate(); + void onRender(); + void onEvent(SDL_Event& event); + + void stop(); + void dispose(); + + private: + bool m_running; + SDL_Window* m_sdlWindow; + SDL_Renderer* m_sdlRenderer; + enum GameState m_state; + + storage::ResourceManager m_resourceManager; + }; +} +#endif /* FARMLANDSGAME_H_ */ diff --git a/src/Main.cpp b/src/Main.cpp new file mode 100644 index 0000000..17aefe8 --- /dev/null +++ b/src/Main.cpp @@ -0,0 +1,7 @@ +#include "FarmlandsGame.h" +using namespace farmlands; + +int main() +{ + return FarmlandsGame().run(); +} diff --git a/src/model/Level.cpp b/src/model/Level.cpp new file mode 100644 index 0000000..b6ec10f --- /dev/null +++ b/src/model/Level.cpp @@ -0,0 +1,48 @@ +/* + * Level.cpp + * + * Created on: Nov 11, 2016 + * Author: tibi + */ + +#include "Level.h" +#include + +namespace farmlands { +namespace model { + +Level::Level(size_t layerCount, size_t rowCount, size_t columnCount) + : m_cells(new Cell[layerCount * rowCount * columnCount]), + m_layers(layerCount), + m_rows(rowCount), + m_columns(columnCount) +{ +} + +Level::~Level() +{ + delete[] m_cells; +} + + +Cell Level::cell(size_t layer, size_t row, size_t col) const +{ + assert(layer < m_layers); + assert(row < m_rows); + assert(col < m_columns); + + return m_cells[layer * m_rows * m_columns + row * m_columns + col]; +} + +void Level::setCell(size_t layer, size_t row, size_t col, Cell value) +{ + assert(layer < m_layers); + assert(row < m_rows); + assert(col < m_columns); + + m_cells[layer * m_rows * m_columns + row * m_columns + col] = value; +} + + +} /* namespace model */ +} /* namespace farmlands */ diff --git a/src/model/Level.h b/src/model/Level.h new file mode 100644 index 0000000..f5fe12b --- /dev/null +++ b/src/model/Level.h @@ -0,0 +1,45 @@ +/* + * Level.h + * + * Created on: Nov 11, 2016 + * Author: tibi + */ + +#ifndef MODEL_LEVEL_H_ +#define MODEL_LEVEL_H_ + +#include +#include + +namespace farmlands { +namespace model { + + typedef int16_t Cell; + + class Level + { + public: + Level(size_t layerCount, size_t rowCount, size_t columnCount); + Level(const Level&) = delete; + Level& operator= (const Level&) = delete; + + virtual ~Level(); + + inline size_t layerCount() const { return m_layers; } + inline size_t rowCount() const { return m_rows; } + inline size_t columnCount() const { return m_columns; } + + Cell cell(size_t layer, size_t row, size_t col) const; + void setCell(size_t layer, size_t row, size_t col, Cell value); + + private: + Cell* m_cells; + size_t m_layers; + size_t m_rows; + size_t m_columns; + }; + +} /* namespace model */ +} /* namespace farmlands */ + +#endif /* MODEL_LEVEL_H_ */ diff --git a/src/storage/LoadLevel.cpp b/src/storage/LoadLevel.cpp new file mode 100644 index 0000000..db8c242 --- /dev/null +++ b/src/storage/LoadLevel.cpp @@ -0,0 +1,92 @@ +/* + * LoadLevel.cpp + * + * Created on: Nov 11, 2016 + * Author: tibi + */ + +#include + +#include +#include +#include + +using namespace farmlands::model; +using namespace nlohmann; + +namespace farmlands { +namespace storage { + +namespace { + + void loadLevelCells(std::shared_ptr level, size_t layer, std::string cellsFileName) + { + char buffer[1024 * 10]; + + // Open file + std::ifstream in(cellsFileName); + if (!in) + throw 0; // TODO: replace with exception type + + // Read CSV file line by line + for (size_t row = 0; row < level->rowCount(); row++) + { + in.getline(buffer, sizeof(buffer)); + + if (in.eof()) + throw 0; // TODO: replace with exception type + + // Separated by comma (or maybe semicolon) + char* nextNum = strtok(buffer, ",;"); + for (size_t col = 0; col < level->columnCount() && nextNum != NULL; col++) + { + Cell cell = (Cell)strtol(nextNum, NULL, 10); + level->setCell(layer, row, col, cell); + + nextNum = strtok(NULL, ",;"); + } + } + + in.close(); + } +} + + std::shared_ptr loadLevel(std::string fileName) + { + // Open file + std::ifstream levelIn(fileName); + if (!levelIn) + throw 0; // TODO: replace with exception type + + // Parse file + json levelJs; + levelIn>>levelJs; + + size_t layerCount = levelJs.value("layerCount", 0u); + size_t rowCount = levelJs.value("height", 0u); + size_t colCount = levelJs.value("width", 0u); + + size_t cellWidth = levelJs.value("cellWidth", 0u); + size_t cellHeight = levelJs.value("cellHeight", 0u); + + std::shared_ptr level(new Level(layerCount, rowCount, colCount)); + + // Read layers + json layersJs = levelJs["layers"]; + size_t layer = 0; + + for (auto it = layersJs.begin(); it != layersJs.end(); it++, layer++) + { + std::string cellsFileName = it->value("cellsFile", std::string()); + loadLevelCells(level, layer, cellsFileName); + + std::string textureFileName = it->value("textureFile", std::string()); + } + return level; + } + +} +} + + + diff --git a/src/storage/ResourceManager.cpp b/src/storage/ResourceManager.cpp new file mode 100644 index 0000000..f1261f4 --- /dev/null +++ b/src/storage/ResourceManager.cpp @@ -0,0 +1,120 @@ +/* + * ResourceManager.cpp + * + * Created on: Nov 7, 2016 + * Author: tibi + */ + +#include "ResourceManager.h" +#include "Resources.h" + +#define FONTID(id,size) (id * 1000 + size) +#define FONTID_SIZE(fontid) (fontid % 1000) +#define FONTID_ID(fontid) (fontid / 1000) + +namespace farmlands +{ +namespace storage +{ + +ResourceManager::ResourceManager() +{ +} + +ResourceManager::~ResourceManager() +{ +} + +void ResourceManager::loadMainMenu() +{ +} + +void ResourceManager::loadGame(SDL_Renderer* renderer) +{ + loadTextures(renderer); +} + +void ResourceManager::loadTextures(SDL_Renderer* renderer) +{ + for (size_t i = 0; i < sizeof(Resources_Textures) / sizeof(Resources_Textures[0]); i++) + { + SDL_Surface* surface = IMG_Load(Resources_Textures[i]); + m_surfaces.push_back(surface); + + SDL_Texture* texture = SDL_CreateTextureFromSurface(renderer, surface); + m_textures.push_back(texture); + } +} + +TTF_Font* ResourceManager::font(const char* name, int pointSize) +{ + int id = fontId(name); + + return font(id, pointSize); +} + +TTF_Font* ResourceManager::font(int id, int pointSize) +{ + // Open from cache + auto it = m_fontCache.find(FONTID(id, pointSize)); + if (it != m_fontCache.end()) + return it->second; + + // Open font + TTF_Font* font = TTF_OpenFont(Resources_Fonts[id], pointSize); + m_fontCache.emplace(FONTID(id, pointSize), font); + + return font; +} + +int ResourceManager::fontId(const char* name) +{ + // Find in cache + auto it = m_fontIdCache.find(std::string(name)); + if (it != m_fontIdCache.end()) + return it->second; + + for (size_t i = 0; i < sizeof(Resources_Fonts) / sizeof(Resources_Fonts[0]); i++) + { + // Extract name from file name + std::string fontName = Resources_Fonts[i]; + size_t nameStart = fontName.find_last_of('/'); + + if (nameStart == std::string::npos) + nameStart = 0; + else + ++nameStart; + + size_t nameEnd = fontName.find_last_of('.'); + size_t nameLen = (nameEnd != std::string::npos) ? nameEnd - nameStart : std::string::npos; + + fontName = fontName.substr(nameStart, nameLen); + + // Found? + if (fontName == name) { + m_fontIdCache.emplace(fontName, i); + return i; + } + } + + return -1; +} + +SDL_Texture* ResourceManager::texture(const char* name) +{ + return NULL; +} + +SDL_Texture* ResourceManager::texture(int id) +{ + return m_textures[id]; +} + +int ResourceManager::textureId(const char* name) +{ + return -1; +} + + +} /* namespace storage */ +} /* namespace farmlands */ diff --git a/src/storage/ResourceManager.h b/src/storage/ResourceManager.h new file mode 100644 index 0000000..8ec02ac --- /dev/null +++ b/src/storage/ResourceManager.h @@ -0,0 +1,54 @@ +/* + * ResourceManager.h + * + * Created on: Nov 7, 2016 + * Author: tibi + */ + +#ifndef STORAGE_RESOURCEMANAGER_H_ +#define STORAGE_RESOURCEMANAGER_H_ + +#include +#include + +#include +#include +#include + +namespace farmlands +{ +namespace storage +{ + class ResourceManager + { + public: + ResourceManager(); + virtual ~ResourceManager(); + + void loadMainMenu(); + void loadGame(SDL_Renderer* renderer); + + TTF_Font* font(const char* name, int pointSize); + TTF_Font* font(int id, int pointSize); + int fontId(const char* name); + + SDL_Texture* texture(const char* name); + SDL_Texture* texture(int id); + int textureId(const char* name); + + private: + void loadTextures(SDL_Renderer* renderer); + + typedef int FontId; + + std::map m_fontCache; + std::map m_fontIdCache; + + std::vector m_surfaces; + std::vector m_textures; + }; + +} /* namespace storage */ +} /* namespace farmlands */ + +#endif /* STORAGE_RESOURCEMANAGER_H_ */ diff --git a/src/storage/Resources.h b/src/storage/Resources.h new file mode 100644 index 0000000..517d3bd --- /dev/null +++ b/src/storage/Resources.h @@ -0,0 +1,28 @@ +/* + * Resources.h + * + * Created on: Nov 7, 2016 + * Author: tibi + */ + +#ifndef STORAGE_RESOURCES_H_ +#define STORAGE_RESOURCES_H_ + +namespace farmlands { +namespace storage { + + const char* const Resources_Fonts[] = + { + "assets/fonts/DejaVuSans.ttf", + }; + + const char* const Resources_MainMenu_Textures[] = { }; + const char* const Resources_Textures[] = + { + "assets/tilesets/ground.png" + }; + +} +} + +#endif /* STORAGE_RESOURCES_H_ */