diff --git a/.cproject b/.cproject
index 0543afb..7f24998 100644
--- a/.cproject
+++ b/.cproject
@@ -7,9 +7,7 @@
-
-
@@ -18,7 +16,7 @@
-
+
@@ -66,6 +64,11 @@
+
+
+
+
+
diff --git a/.directory b/.directory
new file mode 100644
index 0000000..9591c9e
--- /dev/null
+++ b/.directory
@@ -0,0 +1,6 @@
+[Dolphin]
+Timestamp=2016,11,11,20,21,5
+Version=3
+
+[Settings]
+HiddenFilesShown=true
diff --git a/assets/levels/.directory b/assets/levels/.directory
new file mode 100644
index 0000000..605c359
--- /dev/null
+++ b/assets/levels/.directory
@@ -0,0 +1,6 @@
+[Dolphin]
+Timestamp=2016,11,26,16,53,1
+Version=3
+
+[Settings]
+HiddenFilesShown=true
diff --git a/assets/levels/Farm.level b/assets/levels/Farm.level
index 4b5b3a3..2c16e27 100644
--- a/assets/levels/Farm.level
+++ b/assets/levels/Farm.level
@@ -2,7 +2,7 @@
"cellWidth": 16,
"cellHeight": 16,
- "layerCount" : 10,
+ "layerCount" : 1,
"width" : 380,
"height" : 213,
diff --git a/assets/player/default.png b/assets/player/default.png
new file mode 100644
index 0000000..04fa9e4
Binary files /dev/null and b/assets/player/default.png differ
diff --git a/assets/ui/cursor.png b/assets/ui/cursor.png
new file mode 100644
index 0000000..60e8b22
Binary files /dev/null and b/assets/ui/cursor.png differ
diff --git a/assets_original/cursor.xcf b/assets_original/cursor.xcf
new file mode 100644
index 0000000..98496f1
Binary files /dev/null and b/assets_original/cursor.xcf differ
diff --git a/build/prepareAssets.py b/build/prepareAssets.py
index fdfa159..cd0dc09 100755
--- a/build/prepareAssets.py
+++ b/build/prepareAssets.py
@@ -113,6 +113,9 @@ if __name__ == '__main__':
RdirPrefix += "_"
for f in files:
+ if (f[0] == '.'):
+ continue
+
# Append to R
fResName = RdirPrefix + capitalize(os.path.splitext(f)[0])
r += " {0} = {1},\n".format(fResName, assetId)
diff --git a/src/FarmlandsGame.cpp b/src/FarmlandsGame.cpp
deleted file mode 100644
index 19b6671..0000000
--- a/src/FarmlandsGame.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * FarmlandsGame.cpp
- *
- * Created on: Nov 7, 2016
- * Author: tibi
- */
-
-#include "FarmlandsGame.h"
-#include
-
-#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.initialize(m_sdlRenderer);
- m_resourceManager.loadLevel(resources::R::Levels::Farm);
-
- return true;
-}
-
-void FarmlandsGame::onLogicUpdate()
-{
-
-}
-
-void FarmlandsGame::onRender()
-{
- SDL_RenderClear(m_sdlRenderer);
-
- SDL_Rect dest = { 0, 0, 0, 0};
- SDL_QueryTexture(m_resourceManager.texture(resources::R::Tilesets::Ground), NULL, NULL, &dest.w, &dest.h);
- dest.w *= 4;
- dest.h *= 4;
-
- SDL_RenderCopy(m_sdlRenderer, m_resourceManager.texture(resources::R::Tilesets::Ground), 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
deleted file mode 100644
index fe8f774..0000000
--- a/src/FarmlandsGame.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * FarmlandsGame.h
- *
- * Created on: Nov 7, 2016
- * Author: tibi
- */
-
-#ifndef FARMLANDSGAME_H_
-#define FARMLANDSGAME_H_
-
-#include "resources/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;
-
- resources::ResourceManager m_resourceManager;
- };
-}
-#endif /* FARMLANDSGAME_H_ */
diff --git a/src/GameState.h b/src/GameState.h
new file mode 100644
index 0000000..af1e1a1
--- /dev/null
+++ b/src/GameState.h
@@ -0,0 +1,68 @@
+/*
+ * GameState.h
+ *
+ * Created on: Nov 13, 2016
+ * Author: tibi
+ */
+
+#ifndef MODEL_GAMESTATE_H_
+#define MODEL_GAMESTATE_H_
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+namespace farmlands {
+
+ struct ViewportState
+ {
+ bool initialized;
+ int width, height;
+ };
+
+ struct Camera
+ {
+ float posX, posY;
+ float scale;
+ };
+
+ struct GuiState
+ {
+
+ };
+
+ struct GameState
+ {
+ // Resource layer
+ resources::ResourceManager resManager;
+
+ // Graphics layer
+ graphics::SdlRenderer sdlRenderer;
+ graphics::GuiRenderer guiRenderer;
+ graphics::GameRenderer gameRenderer;
+
+ // Gui
+ GuiState gui;
+
+ // Settings
+ model::GameConfig gameConfig;
+
+ // Current game
+ ViewportState viewport;
+ Camera camera;
+ model::Player player;
+ model::Level* currentLevel;
+
+ float elapsedTime;
+
+ };
+
+}
+
+#endif /* MODEL_GAMESTATE_H_ */
diff --git a/src/Main.cpp b/src/Main.cpp
index 17aefe8..71a0f0d 100644
--- a/src/Main.cpp
+++ b/src/Main.cpp
@@ -1,7 +1,8 @@
-#include "FarmlandsGame.h"
+#include
+
using namespace farmlands;
int main()
{
- return FarmlandsGame().run();
+ return controller::FarmlandsGame().run();
}
diff --git a/src/controller/FarmlandsGame.cpp b/src/controller/FarmlandsGame.cpp
new file mode 100644
index 0000000..6c9f4b1
--- /dev/null
+++ b/src/controller/FarmlandsGame.cpp
@@ -0,0 +1,126 @@
+/*
+ * FarmlandsGame.cpp
+ *
+ * Created on: Nov 7, 2016
+ * Author: tibi
+ */
+
+#include "FarmlandsGame.h"
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+namespace farmlands {
+namespace controller {
+
+FarmlandsGame::FarmlandsGame() :
+ m_running(true),
+ m_gameState(),
+ m_time(0),
+ m_guiController(),
+ m_playerController()
+{
+}
+
+bool FarmlandsGame::initialize()
+{
+ // Initialize game state
+ m_gameState.viewport.initialized = false;
+ m_gameState.camera.scale = 4;
+
+ // Initialize render system
+ if (!m_gameState.sdlRenderer.initialize(&m_gameState))
+ return false;
+
+ m_gameState.gameRenderer.initialize(&m_gameState);
+ m_gameState.guiRenderer.initialize(&m_gameState);
+
+ // Initialize controllers
+ m_guiController.initialize(&m_gameState);
+ m_playerController.initialize(&m_gameState);
+
+ // Initialize & load resources
+ m_gameState.resManager.initialize(&m_gameState);
+ m_gameState.resManager.loadGameAssets();
+ m_gameState.resManager.loadLevel(resources::R::Levels::Farm);
+ m_gameState.currentLevel = m_gameState.resManager.level(resources::R::Levels::Farm);
+
+ return true;
+}
+
+void FarmlandsGame::onUpdateLogic()
+{
+ m_playerController.updateLogic();
+}
+
+void FarmlandsGame::onRender()
+{
+ m_gameState.sdlRenderer.renderBegin();
+ m_gameState.gameRenderer.render();
+ m_gameState.guiRenderer.render();
+ m_gameState.sdlRenderer.renderEnd();
+}
+
+void FarmlandsGame::onEvent(SDL_Event& event)
+{
+ // Let controllers handle event
+ if (m_guiController.processEvent(event))
+ return;
+
+ if (m_playerController.processEvent(event))
+ return;
+
+ // Nobody? Handle global events
+ 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;
+}
+
+int FarmlandsGame::run()
+{
+ // Initialize game
+ if (!initialize())
+ return 1;
+
+ // Main loop
+ while(m_running)
+ {
+ // Update elapsed time
+ Uint32 now = SDL_GetTicks();
+ m_gameState.elapsedTime = (now - m_time) * 0.001f;
+ m_time = now;
+
+ SDL_Event event;
+ while (SDL_PollEvent(&event))
+ onEvent(event);
+
+ onUpdateLogic();
+ onRender();
+ }
+
+ // Cleanup
+ return 0;
+}
+
+}
+}
diff --git a/src/controller/FarmlandsGame.h b/src/controller/FarmlandsGame.h
new file mode 100644
index 0000000..33b665f
--- /dev/null
+++ b/src/controller/FarmlandsGame.h
@@ -0,0 +1,49 @@
+/*
+ * FarmlandsGame.h
+ *
+ * Created on: Nov 7, 2016
+ * Author: tibi
+ */
+
+#ifndef FARMLANDSGAME_H_
+#define FARMLANDSGAME_H_
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+namespace farmlands {
+namespace controller {
+
+ class FarmlandsGame {
+
+ public:
+ int run();
+ FarmlandsGame();
+
+ protected:
+ bool initialize();
+
+ void onUpdateLogic();
+ void onRender();
+ void onEvent(SDL_Event& event);
+
+ void stop();
+
+ private:
+ bool m_running;
+ GameState m_gameState;
+ Uint32 m_time;
+
+ GuiController m_guiController;
+ PlayerController m_playerController;
+ };
+
+}
+}
+#endif /* FARMLANDSGAME_H_ */
diff --git a/src/controller/GuiController.cpp b/src/controller/GuiController.cpp
new file mode 100644
index 0000000..bf77358
--- /dev/null
+++ b/src/controller/GuiController.cpp
@@ -0,0 +1,39 @@
+/*
+ * GuiController.cpp
+ *
+ * Created on: Nov 26, 2016
+ * Author: tibi
+ */
+
+#include
+
+#include
+
+namespace farmlands
+{
+namespace controller
+{
+
+GuiController::GuiController()
+ : m_gameState(nullptr)
+{
+}
+
+GuiController::~GuiController()
+{
+}
+
+void GuiController::initialize(GameState* gameState)
+{
+ assert(gameState != nullptr);
+
+ m_gameState = gameState;
+}
+
+bool GuiController::processEvent(SDL_Event& event)
+{
+ return false;
+}
+
+} /* namespace controller */
+} /* namespace farmlands */
diff --git a/src/controller/GuiController.h b/src/controller/GuiController.h
new file mode 100644
index 0000000..db87f17
--- /dev/null
+++ b/src/controller/GuiController.h
@@ -0,0 +1,43 @@
+/*
+ * GuiController.h
+ *
+ * Created on: Nov 26, 2016
+ * Author: tibi
+ */
+
+#ifndef CONTROLLER_GUICONTROLLER_H_
+#define CONTROLLER_GUICONTROLLER_H_
+
+#include
+
+namespace farmlands {
+
+// Forward declarations
+struct GameState;
+
+namespace controller {
+
+ class GuiController
+ {
+ public:
+ GuiController();
+ virtual ~GuiController();
+
+ /**
+ * Initializes game renderer
+ */
+ void initialize(GameState* gameState);
+
+ /**
+ * Processes an UI event
+ */
+ bool processEvent(SDL_Event& event);
+
+ private:
+ GameState* m_gameState;
+ };
+
+} /* namespace controller */
+} /* namespace farmlands */
+
+#endif /* CONTROLLER_GUICONTROLLER_H_ */
diff --git a/src/controller/PlayerController.cpp b/src/controller/PlayerController.cpp
new file mode 100644
index 0000000..b83a12c
--- /dev/null
+++ b/src/controller/PlayerController.cpp
@@ -0,0 +1,88 @@
+/*
+ * PlayerController.cpp
+ *
+ * Created on: Nov 27, 2016
+ * Author: tibi
+ */
+
+#include
+#include
+
+#include
+
+namespace farmlands
+{
+namespace controller
+{
+
+PlayerController::PlayerController()
+ : m_gameState(nullptr)
+{
+}
+
+PlayerController::~PlayerController()
+{
+}
+
+void PlayerController::initialize(GameState* gameState)
+{
+ assert(gameState != nullptr);
+ m_gameState = gameState;
+}
+
+bool PlayerController::processEvent(SDL_Event& event)
+{
+ return false;
+}
+
+void PlayerController::updateLogic()
+{
+ // Get keyboard status
+ const Uint8* keys = SDL_GetKeyboardState(NULL);
+ const SDL_Keymod mods = SDL_GetModState();
+
+ float deltaX = 0;
+ float deltaY = 0;
+
+ // Compute movement delta multiplier
+ float deltaMultiplier = 5.0f * m_gameState->elapsedTime; // Equivalent to units per second
+ if ((mods & KMOD_LSHIFT) || (mods & KMOD_RSHIFT))
+ deltaMultiplier *= 5;
+
+ // Handle scale changes (debugging only)
+ if (keys[SDL_SCANCODE_KP_MINUS])
+ m_gameState->camera.scale *= 1.0f - 0.05f * deltaMultiplier;
+ if (keys[SDL_SCANCODE_KP_PLUS])
+ m_gameState->camera.scale *= 1.0f + 0.05f * deltaMultiplier;
+
+ // Handle movement
+ if (keys[SDL_SCANCODE_UP])
+ deltaY -= 1;
+ if (keys[SDL_SCANCODE_DOWN])
+ deltaY += 1;
+ if (keys[SDL_SCANCODE_LEFT])
+ deltaX -= 1;
+ if (keys[SDL_SCANCODE_RIGHT])
+ deltaX += 1;
+
+ float newX = m_gameState->player.posX + deltaX * deltaMultiplier;
+ float newY = m_gameState->player.posY + deltaY * deltaMultiplier;
+
+ if (canMove(newX, newY))
+ {
+ m_gameState->player.posX = newX;
+ m_gameState->player.posY = newY;
+
+ m_gameState->camera.posX = m_gameState->player.posX;
+ m_gameState->camera.posY = m_gameState->player.posY - 1;
+ }
+}
+
+bool PlayerController::canMove(float x, float y)
+{
+ // TODO: check collisions & stuff. For now, nothing
+ return true;
+}
+
+} /* namespace controller */
+} /* namespace farmlands */
diff --git a/src/controller/PlayerController.h b/src/controller/PlayerController.h
new file mode 100644
index 0000000..d81712d
--- /dev/null
+++ b/src/controller/PlayerController.h
@@ -0,0 +1,52 @@
+/*
+ * PlayerController.h
+ *
+ * Created on: Nov 27, 2016
+ * Author: tibi
+ */
+
+#ifndef CONTROLLER_PLAYERCONTROLLER_H_
+#define CONTROLLER_PLAYERCONTROLLER_H_
+
+#include
+
+namespace farmlands {
+
+// Forward declarations
+struct GameState;
+
+namespace controller {
+
+ class PlayerController
+ {
+ public:
+ PlayerController();
+ virtual ~PlayerController();
+
+ /**
+ * Initializes game renderer
+ */
+ void initialize(GameState* gameState);
+
+ /**
+ * Processes an event.
+ *
+ * @returns true if the event was handled, or false otherwise.
+ */
+ bool processEvent(SDL_Event& event);
+
+ /**
+ * Called at the update logic step for every frame
+ */
+ void updateLogic();
+
+ private:
+ bool canMove(float x, float y);
+
+ GameState* m_gameState;
+ };
+
+} /* namespace controller */
+} /* namespace farmlands */
+
+#endif /* CONTROLLER_PLAYERCONTROLLER_H_ */
diff --git a/src/graphics/GameRenderer.cpp b/src/graphics/GameRenderer.cpp
new file mode 100644
index 0000000..e769c3f
--- /dev/null
+++ b/src/graphics/GameRenderer.cpp
@@ -0,0 +1,146 @@
+/*
+ * GameRenderer.cpp
+ *
+ * Created on: Nov 13, 2016
+ * Author: tibi
+ */
+#include
+#include
+#include