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