Skip to content

Commit 899c9cf

Browse files
committed
Merge pull request #67 from Databean/main_refactor
Split up logic into more methods. Added and used make_resource
2 parents 50b5897 + dba9b61 commit 899c9cf

File tree

3 files changed

+95
-44
lines changed

3 files changed

+95
-44
lines changed

include/Util.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#include <utility>
55
#include <sstream>
6+
#include <memory>
7+
#include <stdexcept>
68

79
typedef std::pair<int, int> Coordinate;
810
typedef std::pair<float, float> ScreenCoordinate;
@@ -33,4 +35,23 @@ std::string toString(T t) {
3335
return stream.str();
3436
}
3537

38+
/**
39+
* Construct a resource unique_ptr, given a constructor, destructor, and arugments.
40+
* Intended for use with C-style constructor and destructor functions that operate on pointers.
41+
* From http://ericscottbarr.com/blog/2014/04/c-plus-plus-14-and-sdl2-managing-resources/
42+
* @param c The creator/initialization function.
43+
* @param d The destructor function
44+
* @param args The arguments to give to the constructor.
45+
* @return A unique pointer to the constructed resource.
46+
*/
47+
template<typename Creator, typename Destructor, typename... Arguments>
48+
auto make_resource(Creator c, Destructor d, Arguments&&... args)
49+
-> std::unique_ptr<typename std::decay<decltype(*c(std::forward<Arguments>(args)...))>::type, void(*)(typename std::decay<decltype(*c(std::forward<Arguments>(args)...))>::type*)>
50+
{
51+
auto r = c(std::forward<Arguments>(args)...);
52+
if (!r) { throw std::runtime_error {"Unable to create resource"}; }
53+
typedef typename std::decay<decltype(*r)>::type ResourceType;
54+
return std::unique_ptr<ResourceType, void(*)(ResourceType*)>(r, d);
55+
}
56+
3657
#endif

resources/graphics.conf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ font.path = resources/ComicNeue-Bold.ttf
33
font.size = 50
44

55
# General window settings
6+
screen.x=100
7+
screen.y=100
8+
69
screen.width = 1280
710
screen.height = 720
811

src/main.cpp

Lines changed: 71 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "Player.h"
1919
#include "GameView.h"
2020
#include "GameController.h"
21+
#include "Util.h"
2122

2223
using std::vector;
2324
using std::unique_ptr;
@@ -48,32 +49,63 @@ void updateViewport(int width, int height) {
4849
}
4950

5051
/**
51-
* Main. Initializes SDL and the model, view, and controller. Also has the main game loop.
52+
* Run the game loop until the game exits.
53+
* @param displayWindow The window the game is being drawn in.
54+
* @param view The view of the game being drawn.
5255
*/
53-
int main(int argc, char *argv[]) {
54-
55-
if(TTF_Init()==-1) {
56-
std::cout << "Error in TTF_Init: " << TTF_GetError() << std::endl;
57-
return 2;
56+
void gameLoop(SDL_Window& displayWindow, GameView& view) {
57+
bool running = true;
58+
while(running) {
59+
SDL_Event event;
60+
while(SDL_PollEvent(&event)) {
61+
running = view.acceptInput(event);
62+
}
63+
64+
view.render();
65+
66+
SDL_GL_SwapWindow(&displayWindow);
67+
SDL_Delay(100);
5868
}
59-
60-
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE);
61-
SDL_Window* displayWindow;
62-
SDL_Renderer* displayRenderer;
69+
}
70+
71+
/**
72+
* Check the renderer created by SDL is valid for our purposes (uses accelerated graphics).
73+
* @param displayRenderer The renderer being used for the game.
74+
* @return If the renderer is valid.
75+
*/
76+
bool checkRenderer(SDL_Renderer& displayRenderer) {
6377
SDL_RendererInfo displayRendererInfo;
64-
SDL_CreateWindowAndRenderer(getGraphicsConfig()["screen.width"], getGraphicsConfig()["screen.height"], SDL_WINDOW_OPENGL, &displayWindow, &displayRenderer);
65-
SDL_GetRendererInfo(displayRenderer, &displayRendererInfo);
66-
/*TODO: Check that we have OpenGL */
67-
if ((displayRendererInfo.flags & SDL_RENDERER_ACCELERATED) == 0 ||
68-
(displayRendererInfo.flags & SDL_RENDERER_TARGETTEXTURE) == 0) {
69-
std::cout << "Unable to create a window using accelerated graphics." << std::endl;
70-
return 0;
78+
SDL_GetRendererInfo(&displayRenderer, &displayRendererInfo);
79+
return (displayRendererInfo.flags & SDL_RENDERER_ACCELERATED) && (displayRendererInfo.flags & SDL_RENDERER_TARGETTEXTURE);
80+
}
81+
82+
/**
83+
* Initialize the game objects, and run the game loop.
84+
*/
85+
void game() {
86+
auto displayWindow = make_resource(SDL_CreateWindow, SDL_DestroyWindow,
87+
"Wars of Catan",
88+
(float)getGraphicsConfig()["screen.x"],
89+
(float)getGraphicsConfig()["screen.y"],
90+
(float)getGraphicsConfig()["screen.width"],
91+
(float)getGraphicsConfig()["screen.height"],
92+
SDL_WINDOW_OPENGL);
93+
94+
auto displayRenderer = make_resource(SDL_CreateRenderer, SDL_DestroyRenderer,
95+
displayWindow.get(),
96+
-1,
97+
SDL_RENDERER_ACCELERATED);
98+
99+
if(checkRenderer(*displayRenderer)) {}
100+
else {
101+
std::cerr << "Unable to create a rendering window using accelerated graphics." << std::endl;
102+
return;
71103
}
72104

73-
SDL_GLContext glContext = SDL_GL_CreateContext(displayWindow);
105+
SDL_GLContext glContext = SDL_GL_CreateContext(displayWindow.get());
74106

75107
initOpenGL();
76-
108+
77109
updateViewport(getGraphicsConfig()["screen.width"], getGraphicsConfig()["screen.height"]);
78110

79111
GameBoard model({"Southern Tribes", "Western Watch", "North Guard", "East Raiders"});
@@ -82,32 +114,27 @@ int main(int argc, char *argv[]) {
82114

83115
model.initializeGame();
84116

85-
// Player& firstPlayer = model.getPlayer(0);
86-
//
87-
// model.PlaceSettlement(Coordinate{0, 0}, firstPlayer);
88-
// model.PlaceRoad(Coordinate{0, 0}, Coordinate{1, 0}, firstPlayer);
89-
// model.PlaceRoad(Coordinate{1, 0}, Coordinate{1, 1}, firstPlayer);
90-
// model.PlaceRoad(Coordinate{1, 1}, Coordinate{0, 2}, firstPlayer);
91-
// model.PlaceSettlement(Coordinate{0, 2}, firstPlayer);
92-
// model.UpgradeSettlement(Coordinate{0, 2});
93-
//
94-
bool running = true;
95-
while(running) {
96-
SDL_Event event;
97-
while(SDL_PollEvent(&event)) {
98-
running = view.acceptInput(event);
99-
}
100-
101-
view.render();
102-
103-
SDL_GL_SwapWindow(displayWindow);
104-
SDL_Delay(100);
105-
}
117+
gameLoop(*displayWindow, view);
106118

107119
SDL_GL_DeleteContext(glContext);
108-
SDL_DestroyWindow(displayWindow);
109-
SDL_DestroyRenderer(displayRenderer);
110-
SDL_Quit();
120+
}
121+
122+
/**
123+
* Main. Initializes SDL and the model, view, and controller. Also has the main game loop.
124+
*/
125+
int main(int argc, char *argv[]) {
111126

112-
return 0;
127+
if(TTF_Init()==-1) {
128+
std::cerr << "Error in TTF_Init: " << TTF_GetError() << std::endl;
129+
return 2;
130+
}
131+
132+
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) {
133+
std::cerr << "Error in SDL_Init: " << SDL_GetError() << std::endl;
134+
return -1;
135+
}
136+
137+
game();
138+
139+
SDL_Quit();
113140
}

0 commit comments

Comments
 (0)