Initial commit
This commit is contained in:
140
src/FarmlandsGame.cpp
Normal file
140
src/FarmlandsGame.cpp
Normal 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
49
src/FarmlandsGame.h
Normal 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
7
src/Main.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
#include "FarmlandsGame.h"
|
||||
using namespace farmlands;
|
||||
|
||||
int main()
|
||||
{
|
||||
return FarmlandsGame().run();
|
||||
}
|
48
src/model/Level.cpp
Normal file
48
src/model/Level.cpp
Normal 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
45
src/model/Level.h
Normal 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
92
src/storage/LoadLevel.cpp
Normal 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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
120
src/storage/ResourceManager.cpp
Normal file
120
src/storage/ResourceManager.cpp
Normal 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 */
|
54
src/storage/ResourceManager.h
Normal file
54
src/storage/ResourceManager.h
Normal 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
28
src/storage/Resources.h
Normal 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_ */
|
Reference in New Issue
Block a user