18#include "IWindow2.hpp"
30#include <unordered_map>
53 SdlWindow(int32_t screenWidth, int32_t screenHeight, std::string title) {
54 _window = SDL_CreateWindow(title.c_str(),
55 SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
56 screenWidth, screenHeight,
57 SDL_WINDOW_SHOWN | SDL_WINDOW_ALLOW_HIGHDPI);
61 _renderer = SDL_CreateRenderer(_window, -1, SDL_RENDERER_ACCELERATED);
64 SDL_SetRenderDrawBlendMode(_renderer, SDL_BLENDMODE_BLEND);
69 SDL_RenderSetLogicalSize(_renderer, screenWidth, screenHeight);
72 _id = SDL_GetWindowID(_window);
73 registry()[_id] =
this;
74 _lastTicks = SDL_GetTicks();
81 registry().erase(_id);
82 if (!_cursor && !shown()) {
84 SDL_ShowCursor(SDL_ENABLE);
87 SDL_DestroyRenderer(_renderer);
89 SDL_DestroyWindow(_window);
93 bool isOpen()
override {
return _open && _window !=
nullptr; }
95 void close()
override { _open =
false; }
100 SDL_GetWindowPosition(_window, &x, &y);
101 return {
static_cast<double>(x),
static_cast<double>(y)};
105 SDL_SetWindowPosition(_window,
static_cast<int>(position.x),
static_cast<int>(position.y));
111 SDL_GetWindowSize(_window, &w, &h);
112 return {
static_cast<double>(w),
static_cast<double>(h)};
116 SDL_SetWindowSize(_window,
static_cast<int>(size.x),
static_cast<int>(size.y));
118 SDL_RenderSetLogicalSize(_renderer,
static_cast<int>(size.x),
static_cast<int>(size.y));
149 return !_events.empty();
153 for (
const SDL_Event &event : _events) {
154 if (event.type == SDL_QUIT ||
155 (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE) ||
156 (
event.type == SDL_KEYDOWN &&
event.key.keysym.scancode == SDL_SCANCODE_ESCAPE)) {
167 SDL_SetRenderDrawColor(_renderer, 0, 0, 0, 255);
168 SDL_RenderClear(_renderer);
173 SDL_RenderPresent(_renderer);
175 const uint32_t now = SDL_GetTicks();
177 _delta =
static_cast<int32_t
>(now - _lastTicks);
182 if (_frameLimit > 0) {
183 const int32_t budget = 1000 / _frameLimit;
185 if (_delta < budget) {
186 SDL_Delay(
static_cast<uint32_t
>(budget - _delta));
191 _lastTicks = SDL_GetTicks();
195 void drawPoly(graphic::IPolygon *polygon)
override;
196 void drawSprite(graphic::ISprite *sprite)
override;
197 void drawText(graphic::IText *text)
override;
205 static std::unordered_map<uint32_t, SdlWindow *> ®istry() {
206 static std::unordered_map<uint32_t, SdlWindow *> windows;
224 applyCursor(SDL_GetMouseFocus());
226 while (SDL_PollEvent(&event)) {
227 const uint32_t target = windowOf(event);
230 for (
auto &[
id, window] : registry())
235 const auto found = registry().find(target);
237 if (found == registry().end())
239 found->second->push(event);
254 static void applyCursor(SDL_Window *focused) {
258 const auto found = registry().find(SDL_GetWindowID(focused));
260 if (found == registry().end())
263 const bool wanted = found->second->_cursor;
265 if (wanted == shown())
268 SDL_ShowCursor(wanted ? SDL_ENABLE : SDL_DISABLE);
272 static bool &shown() {
273 static bool visible =
true;
279 static uint32_t windowOf(
const SDL_Event &event) {
280 switch (event.type) {
281 case SDL_WINDOWEVENT:
return event.window.windowID;
283 case SDL_KEYUP:
return event.key.windowID;
284 case SDL_MOUSEBUTTONDOWN:
285 case SDL_MOUSEBUTTONUP:
return event.button.windowID;
286 case SDL_MOUSEMOTION:
return event.motion.windowID;
287 case SDL_MOUSEWHEEL:
return event.wheel.windowID;
288 case SDL_TEXTINPUT:
return event.text.windowID;
302 void push(
const SDL_Event &event) {
303 if (_events.size() >= MAX_EVENTS)
304 _events.erase(_events.begin());
305 _events.push_back(event);
317 void feedEvent(
const SDL_Event &event) {
318 switch (event.type) {
320 if (!event.key.repeat)
321 _keysDown[
event.key.keysym.scancode] =
true;
324 _keysDown[
event.key.keysym.scancode] =
false;
326 case SDL_MOUSEBUTTONDOWN:
327 _mouseDown[
event.button.button] =
true;
329 case SDL_MOUSEBUTTONUP:
330 _mouseDown[
event.button.button] =
false;
332 case SDL_MOUSEMOTION:
333 _mousePosition = {
static_cast<double>(
event.motion.x),
static_cast<double>(event.motion.y)};
335 case SDL_WINDOWEVENT:
337 if (event.window.event == SDL_WINDOWEVENT_FOCUS_LOST) {
338 _keysDown.fill(
false);
339 _mouseDown.fill(
false);
348 static constexpr size_t MAX_EVENTS = 1024;
350 SDL_Window *_window =
nullptr;
351 SDL_Renderer *_renderer =
nullptr;
358 std::vector<SDL_Event> _events;
360 uint32_t _lastTicks = 0;
362 int32_t _frameLimit = 0;
364 std::array<bool, SDL_NUM_SCANCODES> _keysDown{};
365 std::array<bool, 8> _mouseDown{};
366 Vector2f _mousePosition{0, 0};
372 if (!_renderer || sdlPolygon->_vertices.empty())
379 const float x =
static_cast<float>(sdlPolygon->_position.x);
380 const float y =
static_cast<float>(sdlPolygon->_position.y);
382 for (
size_t i = 0; i < sdlPolygon->_vertices.size(); i++) {
383 sdlPolygon->_screen[i] = sdlPolygon->_vertices[i];
384 sdlPolygon->_screen[i].position.x += x;
385 sdlPolygon->_screen[i].position.y += y;
388 SDL_RenderGeometry(_renderer,
nullptr,
389 sdlPolygon->_screen.data(),
static_cast<int>(sdlPolygon->_screen.size()),
395 SDL_Texture *texture = sdlSprite->_texture.
handle(_renderer);
400 const SDL_Rect source{
401 static_cast<int>(sdlSprite->_crop.x),
static_cast<int>(sdlSprite->_crop.y),
402 static_cast<int>(sdlSprite->_crop.w),
static_cast<int>(sdlSprite->_crop.h)};
403 const SDL_Rect destination{
404 static_cast<int>(sdlSprite->_position.x),
static_cast<int>(sdlSprite->_position.y),
405 static_cast<int>(sdlSprite->_size.x),
static_cast<int>(sdlSprite->_size.y)};
407 SDL_RenderCopyEx(_renderer, texture, &source, &destination,
408 sdlSprite->_rotation,
nullptr, SDL_FLIP_NONE);
413 SDL_Texture *texture = sdlText->handle(_renderer);
418 const SDL_Rect destination{
419 static_cast<int>(sdlText->_position.x),
static_cast<int>(sdlText->_position.y),
420 sdlText->_width, sdlText->_height};
422 SDL_RenderCopyEx(_renderer, texture,
nullptr, &destination,
423 sdlText->_rotation,
nullptr, SDL_FLIP_NONE);
436template <
typename Match>
437static bool anyEvent(
const std::vector<SDL_Event> &events, uint32_t type, Match match) {
438 for (
const SDL_Event &event : events)
439 if (event.type == type && match(event))
445 std::vector<Keys> keys;
447 for (
const auto &[key, code] : _keys)
448 if (_window._keysDown[code])
454 const SDL_Scancode code = _keys.at(key);
456 return anyEvent(_window._events, SDL_KEYDOWN,
457 [code](
const SDL_Event &event) { return event.key.keysym.scancode == code && !event.key.repeat; });
461 const SDL_Scancode code = _keys.at(key);
463 return anyEvent(_window._events, SDL_KEYUP,
464 [code](
const SDL_Event &event) { return event.key.keysym.scancode == code; });
471 const uint8_t button = _buttons.at(key);
473 return anyEvent(_window._events, SDL_MOUSEBUTTONDOWN,
474 [button](
const SDL_Event &event) { return event.button.button == button; });
478 const uint8_t button = _buttons.at(key);
480 return anyEvent(_window._events, SDL_MOUSEBUTTONUP,
481 [button](
const SDL_Event &event) { return event.button.button == button; });
490 _window._mousePosition = position;
491 SDL_WarpMouseInWindow(_window._window,
static_cast<int>(position.x),
static_cast<int>(position.y));
498 for (
const SDL_Event &event : _window._events)
499 if (event.type == SDL_MOUSEWHEEL)
500 delta +=
event.wheel.preciseY;
505 const SDL_GameControllerButton raw = _buttons.at(button);
507 return anyEvent(_window._events, SDL_CONTROLLERBUTTONDOWN,
508 [raw](
const SDL_Event &event) { return event.cbutton.button == raw; });
512 const SDL_GameControllerButton raw = _buttons.at(button);
514 return anyEvent(_window._events, SDL_CONTROLLERBUTTONUP,
515 [raw](
const SDL_Event &event) { return event.cbutton.button == raw; });
La manette numero _index, ouverte a la construction.
Definition SdlGamepad.hpp:31
Le clavier d'UNE fenetre.
Definition SdlKeyboard.hpp:33
Definition SdlMouse.hpp:24
Un contour quelconque, decoupe en triangles une fois pour toutes.
Definition SdlPolygon.hpp:35
Une vue sur une texture : decoupe, position, taille, rotation.
Definition SdlSprite.hpp:29
Une chaine rendue en texture, refaite quand elle change.
Definition SdlText.hpp:37
SDL_Texture * handle(SDL_Renderer *renderer) const
La texture pour CE renderer, fabriquee au besoin.
Definition SdlTexture.hpp:64
Une fenetre SDL et son renderer, implemente IWindow2.
Definition SdlWindow.hpp:50
~SdlWindow()
Definition SdlWindow.hpp:77
Vector2f getPosition() override
Definition SdlWindow.hpp:97
void eventClose() override
Definition SdlWindow.hpp:152
SdlWindow(int32_t screenWidth, int32_t screenHeight, std::string title)
Definition SdlWindow.hpp:53
bool pollEvent() override
Vide la file SDL une fois, puis rend l'etat de CETTE fenetre.
Definition SdlWindow.hpp:147
void setPosition(Vector2f position) override
Definition SdlWindow.hpp:104
void setFrameLimit(int32_t limit) override
Definition SdlWindow.hpp:121
void setSize(Vector2f size) override
Definition SdlWindow.hpp:115
void beginDraw() override
Definition SdlWindow.hpp:164
void endDraw() override
Definition SdlWindow.hpp:171
int32_t getDelta() override
Definition SdlWindow.hpp:139
Vector2f getSize() override
Definition SdlWindow.hpp:108
void close() override
Definition SdlWindow.hpp:95
void setMouseVisibility(bool visible) override
Cache ou montre le pointeur SUR CETTE FENETRE.
Definition SdlWindow.hpp:137
bool isOpen() override
Definition SdlWindow.hpp:93
bool isKeyPressed(Keys key) const override
Definition SdlWindow.hpp:453
void drawText(graphic::IText *text) override
Definition SdlWindow.hpp:411
bool isKeyDown(Keys key) const override
Definition SdlWindow.hpp:467
bool isButtonPressed(Buttons key) const override
Definition SdlWindow.hpp:470
void drawSprite(graphic::ISprite *sprite) override
Definition SdlWindow.hpp:393
void setPosition(Vector2f position) override
Definition SdlWindow.hpp:489
bool isButtonDown(Buttons key) const override
Definition SdlWindow.hpp:484
bool isKeyUp(Keys key) const override
Definition SdlWindow.hpp:468
void drawPoly(graphic::IPolygon *polygon) override
Definition SdlWindow.hpp:369
float GetMouseWheelMove() const override
Definition SdlWindow.hpp:494
bool isButtonReleased(Buttons key) const override
Definition SdlWindow.hpp:477
bool isButtonUp(Buttons key) const override
Definition SdlWindow.hpp:485
bool isButtonReleased(Button button) const override
Definition SdlWindow.hpp:511
bool isKeyReleased(Keys key) const override
Definition SdlWindow.hpp:460
bool isButtonPressed(Button button) const override
Definition SdlWindow.hpp:504
Vector2f getPosition() const override
Definition SdlWindow.hpp:487
std::vector< Keys > whichKeyDown() const override
Definition SdlWindow.hpp:444