]> git.localhorst.tv Git - space.git/blob - src/app/Application.cpp
9f78eaeb592b2660d7a9264cbe748dfc4004148e
[space.git] / src / app / Application.cpp
1 #include "Application.h"
2
3 #include "../graphics/Canvas.h"
4 #include "../graphics/Color.h"
5
6
7 namespace space {
8
9 Application::Application(Canvas &c)
10 : canvas(c)
11 , univ(Vector<int>(10, 10), Vector<int>(10, 10), Vector<int>(10, 10))
12 , focus(Vector<float>(500, 500), 500)
13 , cam(c.Size(), focus.Pos())
14 , controlled(univ.AddShip(Ship()))
15 , linGauge(
16         Vector<int>(15, 100),
17         Vector<int>(10, 10),
18         Color(0xFF, 0xFF, 0xFF),
19         Color(0x00, 0x00, 0x00),
20         Color(0x00, 0xFF, 0x00),
21         Color(0xFF, 0x00, 0x00))
22 , rotGauge(
23         Vector<int>(15, 100),
24         Vector<int>(27, 10),
25         Color(0xFF, 0xFF, 0xFF),
26         Color(0x00, 0x00, 0x00),
27         Color(0x33, 0x33, 0xFF),
28         Color(0x00, 0x00, 0xFF))
29 , autopilot(*controlled, focus.Pos())
30 , apEnabled(false)
31 , last(SDL_GetTicks())
32 , running(false)
33 , paused(false) {
34         univ.AddResource(Resource("Liquid Hydrogen", 70));
35         univ.AddResource(Resource("Liquid Qxygen", 1141));
36         univ.AddResource(Resource("Water", 999));
37 }
38
39
40 void Application::Run() {
41         running = true;
42         while (running) {
43                 Uint32 now = SDL_GetTicks();
44                 int delta = now - last;
45                 Loop(delta);
46                 last = now;
47         }
48 }
49
50
51 void Application::Loop(int delta) {
52         HandleEvents();
53         if (delta == 0) {
54                 SDL_Delay(1);
55                 return;
56         }
57
58         if (!paused) {
59                 Update(delta);
60         }
61         Render();
62         canvas.Present();
63 }
64
65
66 void Application::HandleEvents() {
67         SDL_Event event;
68         while (SDL_PollEvent(&event)) {
69                 switch (event.type) {
70                         case SDL_QUIT:
71                                 running = false;
72                                 break;
73                         case SDL_WINDOWEVENT:
74                                 if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
75                                         cam.Resize(event.window.data1, event.window.data2);
76                                 }
77                                 break;
78                         case SDL_KEYDOWN:
79                                 if (!event.key.repeat) {
80                                         OnKeyDown(event.key);
81                                 }
82                                 break;
83                         case SDL_KEYUP:
84                                 if (!event.key.repeat) {
85                                         OnKeyUp(event.key);
86                                 }
87                                 break;
88                         default:
89                                 // skip event
90                                 break;
91                 }
92         }
93 }
94
95 void Application::OnKeyDown(const SDL_KeyboardEvent &e) {
96         switch (e.keysym.sym) {
97                 case SDLK_UP:
98                         focus.MoveUp();
99                         break;
100                 case SDLK_DOWN:
101                         focus.MoveDown();
102                         break;
103                 case SDLK_LEFT:
104                         focus.MoveLeft();
105                         break;
106                 case SDLK_RIGHT:
107                         focus.MoveRight();
108                         break;
109                 case SDLK_w:
110                         control.y -= 1;
111                         break;
112                 case SDLK_s:
113                         control.y += 1;
114                         break;
115                 case SDLK_a:
116                         control.x -= 1;
117                         break;
118                 case SDLK_d:
119                         control.x += 1;
120                         break;
121                 case SDLK_z:
122                         cam.StartZoom();
123                         break;
124                 case SDLK_x:
125                         cam.StartShrink();
126                         break;
127                 case SDLK_c:
128                         apEnabled = !apEnabled;
129                         break;
130                 case SDLK_p:
131                         paused = !paused;
132                         break;
133                 default:
134                         break;
135         }
136 }
137
138 void Application::OnKeyUp(const SDL_KeyboardEvent &e) {
139         switch (e.keysym.sym) {
140                 case SDLK_UP:
141                         focus.StopUp();
142                         break;
143                 case SDLK_DOWN:
144                         focus.StopDown();
145                         break;
146                 case SDLK_LEFT:
147                         focus.StopLeft();
148                         break;
149                 case SDLK_RIGHT:
150                         focus.StopRight();
151                         break;
152                 case SDLK_w:
153                         control.y += 1;
154                         break;
155                 case SDLK_s:
156                         control.y -= 1;
157                         break;
158                 case SDLK_a:
159                         control.x += 1;
160                         break;
161                 case SDLK_d:
162                         control.x -= 1;
163                         break;
164                 case SDLK_z:
165                         cam.StopZoom();
166                         break;
167                 case SDLK_x:
168                         cam.StopShrink();
169                         break;
170                 default:
171                         break;
172         }
173 }
174
175
176 void Application::Update(int dt) {
177         const float delta = dt / 1e3;
178         if (apEnabled) {
179                 autopilot.Update(delta);
180         } else {
181                 controlled->rotThrottle = control.x;
182                 controlled->linThrottle = -control.y;
183         }
184         cam.Update(delta);
185         univ.Update(delta);
186         focus.SetSpeed(500 / cam.Zoom());
187         focus.Update(delta);
188 }
189
190
191 void Application::Render() {
192         constexpr Color background(0x00, 0x00, 0x00);
193         constexpr Color univGrid(0xEE, 0xEE, 0xEE);
194         constexpr Color secGrid(0x77, 0x77, 0x77);
195         constexpr Color entityColor(0x00, 0xAA, 0xAA);
196         constexpr Color focusColor(0xFA, 0xFA, 0x00);
197
198         canvas.SetColor(background);
199         canvas.Fill();
200
201         canvas.Grid2(
202                 cam.ToScreen(Vector<float>(0, 0)),
203                 cam.ToScale(univ.size * univ.secSize * univ.areaSize),
204                 cam.ToScale(univ.areaSize),
205                 univ.secSize,
206                 secGrid,
207                 univGrid);
208
209         canvas.SetColor(focusColor);
210         canvas.Cross(cam.ToScreen(focus.Pos()), 15);
211
212         canvas.SetColor(entityColor);
213         for (const Ship &s : univ.Ships()) {
214                 const Vector<float> direction = s.Dir();
215                 const Vector<int> position = cam.ToScreen(s.pos);
216                 const Vector<int> nose = position + Vector<int>(direction * 15.0f);
217                 const Vector<int> left = position + Vector<int>((Rotate90(direction) * 8.0f) - (direction * 4.0f));
218                 const Vector<int> right = position + Vector<int>((Rotate270(direction) * 8.0f) - (direction * 4.0f));
219                 canvas.Line(position, nose);
220                 canvas.Quad(nose, left, position, right);
221         }
222
223         autopilot.Render(canvas, cam);
224
225         linGauge.Render(canvas, controlled->linThrottle);
226         rotGauge.Render(canvas, controlled->rotThrottle);
227 }
228
229 }