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