comparison Applications/Sdl/SdlEngine.cpp @ 51:b340879da9bd

reorganization
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 27 Apr 2017 14:50:20 +0200
parents Framework/Applications/Sdl/SdlEngine.cpp@28956ed68280
children c2dc924f1a63 ea377c770ef4
comparison
equal deleted inserted replaced
49:c45f368de5c0 51:b340879da9bd
1 /**
2 * Stone of Orthanc
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017 Osimis, Belgium
6 *
7 * This program is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU Affero General Public License
9 * as published by the Free Software Foundation, either version 3 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Affero General Public License for more details.
16 *
17 * You should have received a copy of the GNU Affero General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/
20
21
22 #include "SdlEngine.h"
23
24 #if ORTHANC_ENABLE_SDL == 1
25
26 #include "../../../Resources/Orthanc/Core/Logging.h"
27
28 #include <SDL.h>
29
30 namespace OrthancStone
31 {
32 void SdlEngine::RenderFrame()
33 {
34 if (!viewportChanged_)
35 {
36 return;
37 }
38
39 viewportChanged_ = false;
40
41 if (buffering_.RenderOffscreen(viewport_))
42 {
43 // Do not notify twice when a new frame was rendered, to avoid
44 // spoiling the SDL event queue
45 SDL_Event event;
46 SDL_memset(&event, 0, sizeof(event));
47 event.type = refreshEvent_;
48 event.user.code = 0;
49 event.user.data1 = 0;
50 event.user.data2 = 0;
51 SDL_PushEvent(&event);
52 }
53 }
54
55
56 void SdlEngine::RenderThread(SdlEngine* that)
57 {
58 for (;;)
59 {
60 that->renderFrame_.Wait();
61
62 if (that->continue_)
63 {
64 that->RenderFrame();
65 }
66 else
67 {
68 return;
69 }
70 }
71 }
72
73
74 KeyboardModifiers SdlEngine::GetKeyboardModifiers(const uint8_t* keyboardState,
75 const int scancodeCount)
76 {
77 int result = KeyboardModifiers_None;
78
79 if (keyboardState != NULL)
80 {
81 if (SDL_SCANCODE_LSHIFT < scancodeCount &&
82 keyboardState[SDL_SCANCODE_LSHIFT])
83 {
84 result |= KeyboardModifiers_Shift;
85 }
86
87 if (SDL_SCANCODE_RSHIFT < scancodeCount &&
88 keyboardState[SDL_SCANCODE_RSHIFT])
89 {
90 result |= KeyboardModifiers_Shift;
91 }
92
93 if (SDL_SCANCODE_LCTRL < scancodeCount &&
94 keyboardState[SDL_SCANCODE_LCTRL])
95 {
96 result |= KeyboardModifiers_Control;
97 }
98
99 if (SDL_SCANCODE_RCTRL < scancodeCount &&
100 keyboardState[SDL_SCANCODE_RCTRL])
101 {
102 result |= KeyboardModifiers_Control;
103 }
104
105 if (SDL_SCANCODE_LALT < scancodeCount &&
106 keyboardState[SDL_SCANCODE_LALT])
107 {
108 result |= KeyboardModifiers_Alt;
109 }
110
111 if (SDL_SCANCODE_RALT < scancodeCount &&
112 keyboardState[SDL_SCANCODE_RALT])
113 {
114 result |= KeyboardModifiers_Alt;
115 }
116 }
117
118 return static_cast<KeyboardModifiers>(result);
119 }
120
121
122 void SdlEngine::SetSize(unsigned int width,
123 unsigned int height)
124 {
125 buffering_.SetSize(width, height, viewport_);
126 viewportChanged_ = true;
127 Refresh();
128 }
129
130
131 void SdlEngine::Stop()
132 {
133 if (continue_)
134 {
135 continue_ = false;
136 renderFrame_.Signal(); // Unlock the render thread
137 renderThread_.join();
138 }
139 }
140
141
142 void SdlEngine::Refresh()
143 {
144 renderFrame_.Signal();
145 }
146
147
148 SdlEngine::SdlEngine(SdlWindow& window,
149 IViewport& viewport) :
150 window_(window),
151 viewport_(viewport),
152 continue_(true)
153 {
154 refreshEvent_ = SDL_RegisterEvents(1);
155
156 SetSize(window_.GetWidth(), window_.GetHeight());
157
158 viewport_.Register(*this);
159
160 renderThread_ = boost::thread(RenderThread, this);
161 }
162
163
164 SdlEngine::~SdlEngine()
165 {
166 Stop();
167
168 viewport_.Unregister(*this);
169 }
170
171
172 void SdlEngine::Run()
173 {
174 int scancodeCount = 0;
175 const uint8_t* keyboardState = SDL_GetKeyboardState(&scancodeCount);
176
177 bool stop = false;
178 while (!stop)
179 {
180 Refresh();
181
182 SDL_Event event;
183
184 while (SDL_PollEvent(&event))
185 {
186 if (event.type == SDL_QUIT)
187 {
188 stop = true;
189 break;
190 }
191 else if (event.type == refreshEvent_)
192 {
193 buffering_.SwapToScreen(window_);
194 }
195 else if (event.type == SDL_MOUSEBUTTONDOWN)
196 {
197 KeyboardModifiers modifiers = GetKeyboardModifiers(keyboardState, scancodeCount);
198
199 switch (event.button.button)
200 {
201 case SDL_BUTTON_LEFT:
202 viewport_.MouseDown(MouseButton_Left, event.button.x, event.button.y, modifiers);
203 break;
204
205 case SDL_BUTTON_RIGHT:
206 viewport_.MouseDown(MouseButton_Right, event.button.x, event.button.y, modifiers);
207 break;
208
209 case SDL_BUTTON_MIDDLE:
210 viewport_.MouseDown(MouseButton_Middle, event.button.x, event.button.y, modifiers);
211 break;
212
213 default:
214 break;
215 }
216 }
217 else if (event.type == SDL_MOUSEMOTION)
218 {
219 viewport_.MouseMove(event.button.x, event.button.y);
220 }
221 else if (event.type == SDL_MOUSEBUTTONUP)
222 {
223 viewport_.MouseUp();
224 }
225 else if (event.type == SDL_WINDOWEVENT)
226 {
227 switch (event.window.event)
228 {
229 case SDL_WINDOWEVENT_LEAVE:
230 viewport_.MouseLeave();
231 break;
232
233 case SDL_WINDOWEVENT_ENTER:
234 viewport_.MouseEnter();
235 break;
236
237 case SDL_WINDOWEVENT_SIZE_CHANGED:
238 SetSize(event.window.data1, event.window.data2);
239 break;
240
241 default:
242 break;
243 }
244 }
245 else if (event.type == SDL_MOUSEWHEEL)
246 {
247 KeyboardModifiers modifiers = GetKeyboardModifiers(keyboardState, scancodeCount);
248
249 int x, y;
250 SDL_GetMouseState(&x, &y);
251
252 if (event.wheel.y > 0)
253 {
254 viewport_.MouseWheel(MouseWheelDirection_Up, x, y, modifiers);
255 }
256 else if (event.wheel.y < 0)
257 {
258 viewport_.MouseWheel(MouseWheelDirection_Down, x, y, modifiers);
259 }
260 }
261 else if (event.type == SDL_KEYDOWN)
262 {
263 KeyboardModifiers modifiers = GetKeyboardModifiers(keyboardState, scancodeCount);
264
265 switch (event.key.keysym.sym)
266 {
267 case SDLK_a: viewport_.KeyPressed('a', modifiers); break;
268 case SDLK_b: viewport_.KeyPressed('b', modifiers); break;
269 case SDLK_c: viewport_.KeyPressed('c', modifiers); break;
270 case SDLK_d: viewport_.KeyPressed('d', modifiers); break;
271 case SDLK_e: viewport_.KeyPressed('e', modifiers); break;
272 case SDLK_f: window_.ToggleMaximize(); break;
273 case SDLK_g: viewport_.KeyPressed('g', modifiers); break;
274 case SDLK_h: viewport_.KeyPressed('h', modifiers); break;
275 case SDLK_i: viewport_.KeyPressed('i', modifiers); break;
276 case SDLK_j: viewport_.KeyPressed('j', modifiers); break;
277 case SDLK_k: viewport_.KeyPressed('k', modifiers); break;
278 case SDLK_l: viewport_.KeyPressed('l', modifiers); break;
279 case SDLK_m: viewport_.KeyPressed('m', modifiers); break;
280 case SDLK_n: viewport_.KeyPressed('n', modifiers); break;
281 case SDLK_o: viewport_.KeyPressed('o', modifiers); break;
282 case SDLK_p: viewport_.KeyPressed('p', modifiers); break;
283 case SDLK_q: stop = true; break;
284 case SDLK_r: viewport_.KeyPressed('r', modifiers); break;
285 case SDLK_s: viewport_.KeyPressed('s', modifiers); break;
286 case SDLK_t: viewport_.KeyPressed('t', modifiers); break;
287 case SDLK_u: viewport_.KeyPressed('u', modifiers); break;
288 case SDLK_v: viewport_.KeyPressed('v', modifiers); break;
289 case SDLK_w: viewport_.KeyPressed('w', modifiers); break;
290 case SDLK_x: viewport_.KeyPressed('x', modifiers); break;
291 case SDLK_y: viewport_.KeyPressed('y', modifiers); break;
292 case SDLK_z: viewport_.KeyPressed('z', modifiers); break;
293
294 default:
295 break;
296 }
297 }
298 }
299
300 SDL_Delay(10); // Necessary for mouse wheel events to work
301 }
302
303 Stop();
304 }
305
306
307 void SdlEngine::GlobalInitialize()
308 {
309 SDL_Init(SDL_INIT_VIDEO);
310 }
311
312
313 void SdlEngine::GlobalFinalize()
314 {
315 SDL_Quit();
316 }
317 }
318
319 #endif