1 /*
2  * Copyright (C) 2015 Dmitry Marakasov <amdmi3@amdmi3.ru>
3  *
4  * This file is part of hoverboard-sdl.
5  *
6  * hoverboard-sdl is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * hoverboard-sdl is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with hoverboard-sdl.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifdef _WIN32
21 #	include <windows.h>
22 #endif
23 
24 #include <iostream>
25 #include <string>
26 #include <sstream>
27 #include <map>
28 
29 #include <SDL2/SDL.h>
30 
31 #include <SDL2pp/SDL.hh>
32 #include <SDL2pp/SDLTTF.hh>
33 #include <SDL2pp/Window.hh>
34 #include <SDL2pp/Renderer.hh>
35 #include <SDL2pp/Texture.hh>
36 
37 #include "game.hh"
38 
39 static const std::map<SDL_Keycode, int> teleport_slots = {
40 	{ SDLK_0, 0 },
41 	{ SDLK_1, 1 },
42 	{ SDLK_2, 2 },
43 	{ SDLK_3, 3 },
44 	{ SDLK_4, 4 },
45 	{ SDLK_5, 5 },
46 	{ SDLK_6, 6 },
47 	{ SDLK_7, 7 },
48 	{ SDLK_8, 8 },
49 	{ SDLK_9, 9 },
50 };
51 
main(int,char * [])52 int main(int, char*[]) try {
53 	// SDL stuff
54 	SDL2pp::SDL sdl(SDL_INIT_VIDEO);
55 	SDL2pp::SDLTTF sdlttf;
56 	SDL2pp::Window window("Hoverboard", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 740, 700, SDL_WINDOW_RESIZABLE);
57 
58 	// We use extracted large icon because otherwise SDL_image will
59 	// small (16x16) icon which looks too ugly
60 	SDL2pp::Surface icon(HOVERBOARD_DATADIR "/xkcd.png");
61 	window.SetIcon(icon);
62 
63 	SDL2pp::Renderer renderer(window, -1, SDL_RENDERER_ACCELERATED);
64 
65 	SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
66 
67 	Game game(renderer);
68 
69 	game.LoadState();
70 
71 	unsigned int prev_ticks = SDL_GetTicks();
72 
73 	// Main loop
74 	while (1) {
75 		unsigned int frame_ticks = SDL_GetTicks();
76 		unsigned int frame_delta = frame_ticks - prev_ticks;
77 		prev_ticks = frame_ticks;
78 
79 		// Process events
80 		SDL_Event event;
81 		while (SDL_PollEvent(&event)) {
82 			if (event.type == SDL_QUIT) {
83 				game.SaveState();
84 				return 0;
85 			} else if (event.type == SDL_KEYDOWN) {
86 				switch (event.key.keysym.sym) {
87 				case SDLK_ESCAPE: case SDLK_q:
88 					game.SaveState();
89 					return 0;
90 				case SDLK_LEFT: case SDLK_a: case SDLK_h:
91 					game.SetActionFlag(Game::LEFT);
92 					break;
93 				case SDLK_RIGHT: case SDLK_d: case SDLK_l:
94 					game.SetActionFlag(Game::RIGHT);
95 					break;
96 				case SDLK_UP: case SDLK_w: case SDLK_k:
97 					game.SetActionFlag(Game::UP);
98 					break;
99 				case SDLK_DOWN: case SDLK_s: case SDLK_j:
100 					game.SetActionFlag(Game::DOWN);
101 					break;
102 				case SDLK_TAB:
103 					game.ToggleMinimap();
104 					break;
105 				}
106 
107 				auto teleport_slot = teleport_slots.find(event.key.keysym.sym);
108 				if (teleport_slot != teleport_slots.end()) {
109 					if (SDL_GetModState() & KMOD_CTRL)
110 						game.SaveLocation(teleport_slot->second);
111 					else
112 						game.JumpToLocation(teleport_slot->second);
113 				}
114 			} else if (event.type == SDL_KEYUP) {
115 				switch (event.key.keysym.sym) {
116 				case SDLK_LEFT: case SDLK_a: case SDLK_h:
117 					game.ClearActionFlag(Game::LEFT);
118 					break;
119 				case SDLK_RIGHT: case SDLK_d: case SDLK_l:
120 					game.ClearActionFlag(Game::RIGHT);
121 					break;
122 				case SDLK_UP: case SDLK_w: case SDLK_k:
123 					game.ClearActionFlag(Game::UP);
124 					break;
125 				case SDLK_DOWN: case SDLK_s: case SDLK_j:
126 					game.ClearActionFlag(Game::DOWN);
127 					break;
128 				}
129 			}
130 		}
131 
132 		game.Update((float)frame_delta / 1000.0f, [&](int nloaded, int nmissing) {
133 				renderer.SetDrawColor(255, 255, 255);
134 				renderer.Clear();
135 
136 				game.RenderProgressbar(nloaded, nmissing);
137 
138 				renderer.Present();
139 			});
140 
141 		// Render
142 		renderer.SetDrawColor(255, 255, 255);
143 		renderer.Clear();
144 
145 		game.Render();
146 
147 		renderer.Present();
148 
149 		// Frame limiter
150 		SDL_Delay(5);
151 	}
152 
153 	return 0;
154 } catch (std::exception& e) {
155 #ifdef _WIN32
156 	MessageBox(nullptr, e.what(), "Error", MB_ICONERROR | MB_OK);
157 #else
158 	std::cerr << "Error: " << e.what() << std::endl;
159 #endif
160 	return 1;
161 } catch (...) {
162 #ifdef _WIN32
163 	MessageBox(nullptr, "Unknown error", "Error", MB_ICONERROR | MB_OK);
164 #else
165 	std::cerr << "Unknown error" << std::endl;
166 #endif
167 	return 1;
168 }
169 
170