Initial commit

This commit is contained in:
2016-11-11 20:18:01 +02:00
commit 294fd6e2ac
14 changed files with 781 additions and 0 deletions

140
src/FarmlandsGame.cpp Normal file
View File

@ -0,0 +1,140 @@
/*
* FarmlandsGame.cpp
*
* Created on: Nov 7, 2016
* Author: tibi
*/
#include "FarmlandsGame.h"
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
#include <unistd.h>
#include <iostream>
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;
}
}

49
src/FarmlandsGame.h Normal file
View File

@ -0,0 +1,49 @@
/*
* FarmlandsGame.h
*
* Created on: Nov 7, 2016
* Author: tibi
*/
#ifndef FARMLANDSGAME_H_
#define FARMLANDSGAME_H_
#include "storage/ResourceManager.h"
#include <SDL2/SDL.h>
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_ */

7
src/Main.cpp Normal file
View File

@ -0,0 +1,7 @@
#include "FarmlandsGame.h"
using namespace farmlands;
int main()
{
return FarmlandsGame().run();
}

48
src/model/Level.cpp Normal file
View File

@ -0,0 +1,48 @@
/*
* Level.cpp
*
* Created on: Nov 11, 2016
* Author: tibi
*/
#include "Level.h"
#include <cassert>
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 */

45
src/model/Level.h Normal file
View File

@ -0,0 +1,45 @@
/*
* Level.h
*
* Created on: Nov 11, 2016
* Author: tibi
*/
#ifndef MODEL_LEVEL_H_
#define MODEL_LEVEL_H_
#include <cstdint>
#include <cstddef>
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_ */

92
src/storage/LoadLevel.cpp Normal file
View File

@ -0,0 +1,92 @@
/*
* LoadLevel.cpp
*
* Created on: Nov 11, 2016
* Author: tibi
*/
#include <model/Level.h>
#include <fstream>
#include <string>
#include <json.hpp>
using namespace farmlands::model;
using namespace nlohmann;
namespace farmlands {
namespace storage {
namespace {
void loadLevelCells(std::shared_ptr<Level> 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<Level> 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> 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;
}
}
}

View File

@ -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 */

View File

@ -0,0 +1,54 @@
/*
* ResourceManager.h
*
* Created on: Nov 7, 2016
* Author: tibi
*/
#ifndef STORAGE_RESOURCEMANAGER_H_
#define STORAGE_RESOURCEMANAGER_H_
#include <vector>
#include <map>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
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<FontId, TTF_Font*> m_fontCache;
std::map<std::string, int> m_fontIdCache;
std::vector<SDL_Surface*> m_surfaces;
std::vector<SDL_Texture*> m_textures;
};
} /* namespace storage */
} /* namespace farmlands */
#endif /* STORAGE_RESOURCEMANAGER_H_ */

28
src/storage/Resources.h Normal file
View File

@ -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_ */