From c7ef086d3dfd14c8ea97b62b1885ae36a02630ac Mon Sep 17 00:00:00 2001 From: Corentin Jabot Date: Sun, 20 Jun 2021 18:52:34 +0200 Subject: [PATCH] Migrate from SDL to SFML This simplifies the rendering code and remove all(!) pointers. There is a number of unresolved issues * Windows build ? * position delta computation: migrating to SFML seems to have modified the frame rate. --- lib/Board.cpp | 8 +-- lib/Board.hpp | 8 +-- lib/CMakeLists.txt | 17 ++--- lib/Canvas.cpp | 118 ++++++++++++++++++++++++---------- lib/Canvas.hpp | 34 +++++++--- lib/Game.cpp | 40 ++++-------- lib/Game.hpp | 4 +- lib/PacMan.cpp | 9 +-- lib/PacMan.hpp | 3 +- lib/PacManAnimation.cpp | 2 +- lib/PacManAnimation.hpp | 29 ++++----- lib/Pellets.hpp | 10 ++- lib/Position.hpp | 13 +++- lib/SDLWindow.cpp | 138 ---------------------------------------- lib/SDLWindow.hpp | 96 ---------------------------- lib/Sprite.cpp | 1 - lib/Sprite.hpp | 9 --- lib/SuperPellets.hpp | 11 ++-- src/CMakeLists.txt | 5 -- vcpkg.json | 4 +- 20 files changed, 176 insertions(+), 383 deletions(-) delete mode 100644 lib/SDLWindow.cpp delete mode 100644 lib/SDLWindow.hpp delete mode 100644 lib/Sprite.cpp delete mode 100644 lib/Sprite.hpp diff --git a/lib/Board.cpp b/lib/Board.cpp index 13afb3b..23cb6d1 100644 --- a/lib/Board.cpp +++ b/lib/Board.cpp @@ -67,8 +67,8 @@ bool Board::isWalkable(Position point, float position_delta, Direction direction } } -std::vector Board::initialPelletPositions() const { - std::vector positions; +std::vector Board::initialPelletPositions() const { + std::vector positions; for (uint8_t row = 0; row < ROWS; row++) { for (uint8_t column = 0; column < COLUMNS; column++) { if (board_state[row][column] == 1) @@ -78,8 +78,8 @@ std::vector Board::initialPelletPositions() const { return positions; } -std::vector Board::initialSuperPelletPositions() const { - std::vector positions; +std::vector Board::initialSuperPelletPositions() const { + std::vector positions; for (uint8_t row = 0; row < ROWS; row++) { for (uint8_t column = 0; column < COLUMNS; column++) { if (board_state[row][column] == 4) diff --git a/lib/Board.hpp b/lib/Board.hpp index 97c0d4b..2b6a9d8 100644 --- a/lib/Board.hpp +++ b/lib/Board.hpp @@ -1,9 +1,9 @@ #pragma once +#include + #include "Direction.hpp" #include "Position.hpp" - -#include #include #include @@ -16,9 +16,9 @@ public: [[nodiscard]] bool isWalkable(Position point, float d, Direction direction) const; - [[nodiscard]] std::vector initialPelletPositions() const; + [[nodiscard]] std::vector initialPelletPositions() const; - [[nodiscard]] std::vector initialSuperPelletPositions() const; + [[nodiscard]] std::vector initialSuperPelletPositions() const; static Position initialPacManPosition() { return { 14, 23 }; } diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index e9a1823..b805ba7 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,13 +1,10 @@ -find_package(sdl2-image CONFIG REQUIRED) -find_package(sdl2-ttf CONFIG REQUIRED) -find_package(fmt REQUIRED) -find_package(ZLIB REQUIRED) +find_package(SFML COMPONENTS COMPONENTS window graphics system CONFIG REQUIRED) + find_package(fmt REQUIRED) + find_package(OpenGL REQUIRED COMPONENTS OpenGL GLX) + file(GLOB_RECURSE sources CONFIGURE_DEPENDS "*.cpp") + add_library(libpacman ${ sources }) -file(GLOB_RECURSE sources CONFIGURE_DEPENDS "*.cpp") - -add_library(libpacman ${sources}) - -target_include_directories(libpacman PUBLIC .) -target_link_libraries(libpacman PUBLIC SDL2::SDL2-static SDL2::SDL2_image SDL2::SDL2_ttf fmt::fmt ZLIB::ZLIB) + target_include_directories(libpacman PUBLIC.) + target_link_libraries(libpacman PUBLIC fmt::fmt sfml - graphics sfml - window sfml - system OpenGL::OpenGL OpenGL::GLX) diff --git a/lib/Canvas.cpp b/lib/Canvas.cpp index 2c494b4..24968aa 100644 --- a/lib/Canvas.cpp +++ b/lib/Canvas.cpp @@ -1,15 +1,23 @@ #include "Canvas.hpp" -#include -#include + #include "PacMan.hpp" #include "Pellets.hpp" #include "SuperPellets.hpp" +#include +#include +#include Canvas::Canvas() - : window(windowDimensions()) {} + : window(sf::VideoMode(windowDimensions().width, windowDimensions().height), "Pacman", sf::Style::Titlebar | sf::Style::Close) { + window.setVerticalSyncEnabled(true); + + maze_texture = loadTexture("maze.png"); + sprites_texture = loadTexture("sprites32.png"); + game_font = loadFont("joystix.ttf"); +} void Canvas::update(const PacMan & pacMan, const Pellets & pellets, const SuperPellets & superPellets) { - window.clear(); + clear(); renderMaze(); renderPellets(pellets); @@ -17,62 +25,104 @@ void Canvas::update(const PacMan & pacMan, const Pellets & pellets, const SuperP renderPacMan(pacMan); renderScore(0); - window.render(); + render(); } -void Canvas::renderMaze() const { - SDL_Rect maze_translated = { LEFT_MARGIN, TOP_MARGIN, MAZE_WIDTH, MAZE_HEIGHT }; - Sprite maze = window.getBackground(); - window.renderSprite(maze, maze_translated); +void Canvas::clear() { + window.clear(sf::Color::Black); } -void Canvas::renderPellets(const Pellets & pellets) const { +void Canvas::render() { + window.display(); +} + +std::optional Canvas::pollEvent() { + sf::Event event; + if (window.pollEvent(event)) + return event; + return std::nullopt; +} + +void Canvas::renderMaze() { + Sprite maze(maze_texture); + maze.setPosition(LEFT_MARGIN, TOP_MARGIN); + window.draw(maze); +} + +void Canvas::renderPellets(const Pellets & pellets) { Sprite pellet = getSprite(pellets.currentSprite()); - std::vector pelletPositions = pellets.currentPositions(); + std::vector pelletPositions = pellets.currentPositions(); for (const auto & pos : pelletPositions) { renderSprite(pellet, pos); } } -void Canvas::renderSuperPellets(const SuperPellets & superPellets) const { +void Canvas::renderSuperPellets(const SuperPellets & superPellets) { Sprite pellet = getSprite(superPellets.currentSprite()); - std::vector superPelletPositions = superPellets.currentPositions(); + std::vector superPelletPositions = superPellets.currentPositions(); for (const auto & pos : superPelletPositions) { renderSprite(pellet, pos); } } -void Canvas::renderPacMan(const PacMan & pac_man) const { +void Canvas::renderPacMan(const PacMan & pac_man) { Sprite pacmanSprite = getSprite(pac_man.currentSprite()); const auto & pos = pac_man.position(); - renderSprite(pacmanSprite, SDL_Point{ int(pos.x), int(pos.y) }); + renderSprite(pacmanSprite, { int(pos.x), int(pos.y) }); } void Canvas::renderScore(int score) { - const int x = LEFT_MARGIN + MAZE_WIDTH + LEFT_MARGIN; - const int y = TOP_MARGIN * 2; - window.drawText("SCORE", {x, y}); - window.drawText(fmt::format("{}", score), {x, y + 20}); + const int x = LEFT_MARGIN + MAZE_WIDTH + LEFT_MARGIN; + const int y = TOP_MARGIN * 2; + + sf::Text text; + text.setPosition(x, y); + text.setFont(game_font); + text.setString(fmt::format("SCORE\n{}", score)); + text.setCharacterSize(20); + text.setFillColor(sf::Color::White); + window.draw(text); } -SDL_Rect Canvas::windowDimensions() const { +Rect Canvas::windowDimensions() const { return { 0, 0, LEFT_MARGIN + MAZE_WIDTH + SCORE_WIDTH, TOP_MARGIN + MAZE_HEIGHT + BOTTOM_MARGIN }; } -Sprite Canvas::getSprite(SDL_Point coordinate) const { - return window.getSprite( - { coordinate.x * DEFAULT_SPRITE_WIDTH, - coordinate.y * DEFAULT_SPRITE_HEIGHT, - DEFAULT_SPRITE_WIDTH, - DEFAULT_SPRITE_HEIGHT }); +Sprite Canvas::getSprite(PositionInt coordinate) const { + sf::Sprite sprite; + sprite.setTexture(sprites_texture); + sprite.setTextureRect(sf::IntRect{ coordinate.x * DEFAULT_SPRITE_WIDTH, + coordinate.y * DEFAULT_SPRITE_HEIGHT, + DEFAULT_SPRITE_WIDTH, + DEFAULT_SPRITE_HEIGHT }); + sprite.scale(0.5, 0.5); + return sprite; } -void Canvas::renderSprite(Sprite sprite, SDL_Point point) const { - SDL_Rect target = { - LEFT_MARGIN + int((point.x * DEFAULT_SPRITE_WIDTH - sprite.rect.w / 2) * TEXTURE_SCALE_FACTOR), - TOP_MARGIN + int((point.y * DEFAULT_SPRITE_WIDTH - sprite.rect.h / 2) * TEXTURE_SCALE_FACTOR), - sprite.rect.w, - sprite.rect.h - }; - window.renderSprite(sprite, target); +void Canvas::renderSprite(Sprite sprite, PositionInt pos) { + pos.x = LEFT_MARGIN + (pos.x * DEFAULT_SPRITE_WIDTH / 2); + pos.y = TOP_MARGIN + (pos.y * DEFAULT_SPRITE_HEIGHT / 2); + sprite.setPosition(pos.x, pos.y); + window.draw(sprite); +} + +static void exitFailure(const std::string & message) { + fmt::print("{}\n", message); + exit(1); +} + +sf::Texture Canvas::loadTexture(std::string_view path) { + sf::Texture texture; + if (!texture.loadFromFile(std::string{ path })) { + exitFailure(fmt::format("Failed to load image {}", path)); + } + return texture; +} + +sf::Font Canvas::loadFont(std::string_view path) { + sf::Font font; + if (!font.loadFromFile("joystix.ttf")) { + exitFailure(fmt::format("Failed to load font {}", path)); + } + return font; } diff --git a/lib/Canvas.hpp b/lib/Canvas.hpp index fee3d9f..4657306 100644 --- a/lib/Canvas.hpp +++ b/lib/Canvas.hpp @@ -1,6 +1,7 @@ #pragma once -#include "SDLWindow.hpp" +#include "Position.hpp" +#include class PacMan; class Pellets; @@ -10,6 +11,7 @@ class Canvas { public: Canvas(); void update(const PacMan & pacMan, const Pellets & pellets, const SuperPellets & superPellets); + std::optional pollEvent(); private: static constexpr int16_t LEFT_MARGIN = 40; @@ -20,16 +22,28 @@ private: static constexpr int16_t SCORE_WIDTH = 200; static constexpr int16_t DEFAULT_SPRITE_WIDTH = 32; static constexpr int16_t DEFAULT_SPRITE_HEIGHT = 32; - static constexpr float TEXTURE_SCALE_FACTOR = 0.5; - void renderMaze() const; - void renderPacMan(const PacMan & pac_man) const; - void renderPellets(const Pellets & pellets) const; - void renderSuperPellets(const SuperPellets & superPellets) const; - void renderSprite(Sprite sprite, SDL_Point point) const; + void clear(); + void render(); + void renderMaze(); + void renderPacMan(const PacMan & pac_man); + void renderPellets(const Pellets & pellets); + void renderSuperPellets(const SuperPellets & superPellets); + void renderSprite(Sprite sprite, PositionInt point); + void renderSprite(Sprite sprite, Rect target); + void renderScore(int score); - SDL_Rect windowDimensions() const; - Sprite getSprite(SDL_Point rect) const; - SDLWindow window; + Rect windowDimensions() const; + + void loadTextures(); + sf::Texture loadTexture(std::string_view path); + sf::Font loadFont(std::string_view path); + + Sprite getSprite(PositionInt rect) const; + + sf::RenderWindow window; + sf::Texture maze_texture; + sf::Texture sprites_texture; + sf::Font game_font; }; diff --git a/lib/Game.cpp b/lib/Game.cpp index 194db09..e99be4d 100644 --- a/lib/Game.cpp +++ b/lib/Game.cpp @@ -32,35 +32,17 @@ void Game::eatPellets() { } void Game::processEvents(InputState & inputState) { - SDL_Event event; - while (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_QUIT: - inputState.close = true; - break; - case SDL_KEYDOWN: - keyToggle(event, inputState, true); - break; - case SDL_KEYUP: - keyToggle(event, inputState, false); - break; - } - } -} -void Game::keyToggle(const SDL_Event & event, InputState & inputState, bool on) { - switch (event.key.keysym.sym) { - case SDLK_UP: - inputState.up = on; - break; - case SDLK_DOWN: - inputState.down = on; - break; - case SDLK_LEFT: - inputState.left = on; - break; - case SDLK_RIGHT: - inputState.right = on; - break; + auto event = canvas.pollEvent(); + if (event->type == sf::Event::Closed) { + inputState.close = true; + return; } + + inputState.down = inputState.up = inputState.left = inputState.right = false; + + inputState.down = sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Down); + inputState.up = sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Up); + inputState.left = sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Left); + inputState.right = sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Right); } diff --git a/lib/Game.hpp b/lib/Game.hpp index 6bf912f..f4e606d 100644 --- a/lib/Game.hpp +++ b/lib/Game.hpp @@ -23,9 +23,7 @@ private: void eatPellets(); - static void processEvents(InputState & inputState); - - static void keyToggle(const SDL_Event & event, InputState & inputState, bool on); + void processEvents(InputState & inputState); [[nodiscard]] static auto now(); }; diff --git a/lib/PacMan.cpp b/lib/PacMan.cpp index 09a2c1a..3cb1eff 100644 --- a/lib/PacMan.cpp +++ b/lib/PacMan.cpp @@ -1,9 +1,10 @@ #include "PacMan.hpp" +#include PacMan::PacMan(const Board & board) : pos(board.initialPacManPosition()) {} -SDL_Point PacMan::currentSprite() const { +PositionInt PacMan::currentSprite() const { return pacManAnimation.animationFrame(direction); } @@ -15,10 +16,10 @@ Position PacMan::positionInGrid() const { switch (direction) { case Direction::LEFT: case Direction::RIGHT: - return { floor(pos.x), round(pos.y) }; + return { std::floor(pos.x), std::round(pos.y) }; case Direction::UP: case Direction::DOWN: - return { floor(pos.x), round(pos.y) }; + return { std::floor(pos.x), std::round(pos.y) }; default: return pos; } @@ -47,7 +48,7 @@ void PacMan::updateAnimationPosition(std::chrono::milliseconds time_delta) { } void PacMan::updateMazePosition(std::chrono::milliseconds time_delta, const Board & board) { - float position_delta = time_delta.count() / 128.0; + float position_delta = time_delta.count() / 150.0; // Handle teleport if (pos.x >= COLUMNS - 1 && direction == Direction::RIGHT) { diff --git a/lib/PacMan.hpp b/lib/PacMan.hpp index 8a4e9bd..04b95bd 100644 --- a/lib/PacMan.hpp +++ b/lib/PacMan.hpp @@ -4,7 +4,6 @@ #include "PacManAnimation.hpp" #include "Position.hpp" -#include #include class Board; @@ -14,7 +13,7 @@ class PacMan { public: explicit PacMan(const Board & board); - [[nodiscard]] SDL_Point currentSprite() const; + [[nodiscard]] PositionInt currentSprite() const; [[nodiscard]] Position position() const; diff --git a/lib/PacManAnimation.cpp b/lib/PacManAnimation.cpp index 38606db..e2f845d 100644 --- a/lib/PacManAnimation.cpp +++ b/lib/PacManAnimation.cpp @@ -1,6 +1,6 @@ #include "PacManAnimation.hpp" -SDL_Point PacManAnimation::animationFrame(Direction direction) const { +PositionInt PacManAnimation::animationFrame(Direction direction) const { switch (direction) { case Direction::LEFT: return left_animation[animation_position]; diff --git a/lib/PacManAnimation.hpp b/lib/PacManAnimation.hpp index 5af50df..88afb3b 100644 --- a/lib/PacManAnimation.hpp +++ b/lib/PacManAnimation.hpp @@ -5,29 +5,28 @@ #include "InputState.hpp" #include "Position.hpp" -#include #include class PacManAnimation { public: - [[nodiscard]] SDL_Point animationFrame(Direction direction) const; + [[nodiscard]] PositionInt animationFrame(Direction direction) const; void updateAnimationPosition(std::chrono::milliseconds time_delta); private: uint8_t animation_position = 0; float animation_position_delta = 0.0; - const SDL_Point right_wide = { 0, 0 }; - const SDL_Point right_narrow = { 1, 0 }; - const SDL_Point closed = { 2, 0 }; - const SDL_Point left_narrow = { 3, 0 }; - const SDL_Point left_wide = { 4, 0 }; - const SDL_Point up_wide = { 5, 0 }; - const SDL_Point up_narrow = { 6, 0 }; - const SDL_Point down_wide = { 7, 0 }; - const SDL_Point down_narrow = { 8, 0 }; - const SDL_Point down_animation[4]{ down_wide, down_narrow, closed, down_narrow }; - const SDL_Point left_animation[4]{ left_wide, left_narrow, closed, left_narrow }; - const SDL_Point right_animation[4]{ right_wide, right_narrow, closed, right_narrow }; - const SDL_Point up_animation[4]{ up_wide, up_narrow, closed, up_narrow }; + const PositionInt right_wide = { 0, 0 }; + const PositionInt right_narrow = { 1, 0 }; + const PositionInt closed = { 2, 0 }; + const PositionInt left_narrow = { 3, 0 }; + const PositionInt left_wide = { 4, 0 }; + const PositionInt up_wide = { 5, 0 }; + const PositionInt up_narrow = { 6, 0 }; + const PositionInt down_wide = { 7, 0 }; + const PositionInt down_narrow = { 8, 0 }; + const PositionInt down_animation[4]{ down_wide, down_narrow, closed, down_narrow }; + const PositionInt left_animation[4]{ left_wide, left_narrow, closed, left_narrow }; + const PositionInt right_animation[4]{ right_wide, right_narrow, closed, right_narrow }; + const PositionInt up_animation[4]{ up_wide, up_narrow, closed, up_narrow }; }; diff --git a/lib/Pellets.hpp b/lib/Pellets.hpp index a6c348d..b224dd3 100644 --- a/lib/Pellets.hpp +++ b/lib/Pellets.hpp @@ -3,23 +3,21 @@ #include "Board.hpp" #include "Position.hpp" -#include - class Pellets { public: explicit Pellets(const Board & board); - [[nodiscard]] SDL_Point currentSprite() const { + [[nodiscard]] PositionInt currentSprite() const { return sprite; }; - [[nodiscard]] std::vector currentPositions() const { + [[nodiscard]] std::vector currentPositions() const { return positions; } bool eatPelletAtPosition(Position p); private: - const SDL_Point sprite = { 1, 9 }; - std::vector positions; + const PositionInt sprite = { 1, 9 }; + std::vector positions; }; diff --git a/lib/Position.hpp b/lib/Position.hpp index 5618d4b..b740945 100644 --- a/lib/Position.hpp +++ b/lib/Position.hpp @@ -1,12 +1,21 @@ #pragma once -#include +#include struct Position { float x; float y; }; -inline bool operator==(const SDL_Point & b, const Position & a) { +struct PositionInt { + int x; + int y; +}; + +using Rect = sf::Rect; + +using Sprite = sf::Sprite; + +inline bool operator==(const PositionInt & b, const Position & a) { return a.x == b.x && a.y == b.y; } diff --git a/lib/SDLWindow.cpp b/lib/SDLWindow.cpp deleted file mode 100644 index c3cbf15..0000000 --- a/lib/SDLWindow.cpp +++ /dev/null @@ -1,138 +0,0 @@ -#include "SDLWindow.hpp" - -#include -#include - -SDLWindow::SDLWindow(SDL_Rect windowGeometry) { - initSDL(); - initSDLImage(); - initSDLTTF(); - - createWindow(windowGeometry.w, windowGeometry.h); - createRenderer(); - createWindowSurface(); - setDrawColor(); - maze_texture = loadTexture("maze.png"); - sprite_texture = loadTexture("sprites32.png"); -} - -void SDLWindow::clear() { - SDL_RenderClear(renderer.get()); -} - -void SDLWindow::render() { - SDL_RenderPresent(renderer.get()); -} - -Sprite SDLWindow::getBackground() const { - auto [w, h] = textureSize(maze_texture.get()); - SDL_Rect maze_rect = { 0, 0, w, h }; - return { maze_texture.get(), maze_rect }; -} - -Sprite SDLWindow::getSprite(SDL_Rect rect) const { - return { sprite_texture.get(), rect }; -} - -void SDLWindow::renderSprite(Sprite sprite, SDL_Rect target) const { - if (SDL_RenderCopy(renderer.get(), sprite.texture, &sprite.rect, &target) < 0) - exitFailure("Failed to copy texture to renderer"); -} - -void SDLWindow::drawText(const std::string & text, SDL_Point position, SDL_Color textColor) const -{ - SDLSurfacePtr surface(TTF_RenderUTF8_Solid(font.get(), text.data(), textColor), SDL_Surface_Deleter{}); - SDLTexturePtr textTexture(SDL_CreateTextureFromSurface(renderer.get(), surface.get()), SDL_Texture_Deleter{}); - auto [w, h] = textureSize(textTexture.get()); - SDL_Rect textLocation = { position.x, position.y, w, h }; - SDL_RenderCopy(renderer.get(), textTexture.get(), NULL, &textLocation); -} - -void SDLWindow::initSDL() { - if (SDL_Init(SDL_INIT_EVERYTHING) < 0) - exitFailure("Failed to initialize the SDL2 library"); -} - -void SDLWindow::initSDLImage() { - int img_flags = IMG_INIT_PNG; - if (IMG_Init(img_flags) != img_flags) - exitImgFailure("Failed to init SDL_Image with png"); -} - -void SDLWindow::initSDLTTF() { - if(TTF_Init() != 0) { - exitFailure("Unable to setup font library"); - } - font.reset(TTF_OpenFont("joystix.ttf", 20)); - if(!font) { - exitFailure("Failed to copy texture to renderer"); - } -} - -void SDLWindow::createWindow(int width, int height) { - window = std::unique_ptr(SDL_CreateWindow( - "Pacman", - SDL_WINDOWPOS_CENTERED, - SDL_WINDOWPOS_CENTERED, - width, - height, - SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI)); - - if (!window) - exitFailure("Failed to create window"); -} - -void SDLWindow::createRenderer() { - renderer = std::unique_ptr(SDL_CreateRenderer( - window.get(), - -1, - SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC)); - - if (!renderer) - exitFailure("Failed to create renderer"); -} - -void SDLWindow::createWindowSurface() { - window_surface = std::unique_ptr(SDL_GetWindowSurface(window.get())); - if (!window_surface) - exitFailure("Failed to get the surface from the window"); -} - -void SDLWindow::setDrawColor() { - if (SDL_SetRenderDrawColor(renderer.get(), 0, 0, 0, SDL_ALPHA_OPAQUE) < 0) - exitFailure("Failed to set renderer color"); -} - -std::unique_ptr -SDLWindow::loadTexture(const std::string & path) { - auto surface = std::unique_ptr(IMG_Load(path.c_str())); - if (!surface) - exitImgFailure("Failed to load image"); - - auto texture = std::unique_ptr( - SDL_CreateTextureFromSurface(renderer.get(), surface.get())); - if (!texture) - exitFailure("Failed to create texture from surface"); - return texture; -} - -std::tuple SDLWindow::textureSize(SDL_Texture* texture) const -{ - int w, h; - if (SDL_QueryTexture(texture, nullptr, nullptr, &w, &h) != 0) { - exitFailure("Failed to get texture geometry"); - } - return {w, h}; -} - -void SDLWindow::exitFailure(const std::string & message) { - std::cerr << message << "\n"; - std::cerr << "SDL2 Error: " << SDL_GetError() << "\n"; - exit(1); -} - -void SDLWindow::exitImgFailure(const std::string & message) { - std::cerr << message << "\n"; - std::cerr << "SDL2_Image Error: " << IMG_GetError() << "\n"; - exit(1); -} diff --git a/lib/SDLWindow.hpp b/lib/SDLWindow.hpp deleted file mode 100644 index 8bbcad4..0000000 --- a/lib/SDLWindow.hpp +++ /dev/null @@ -1,96 +0,0 @@ -#pragma once - -#include "Sprite.hpp" -#include -#include -#include -#include - -struct SDL_Window_Deleter { - void operator()(SDL_Window * window) { - SDL_DestroyWindow(window); - } -}; - -struct SDL_Renderer_Deleter { - void operator()(SDL_Renderer * renderer) { - SDL_DestroyRenderer(renderer); - } -}; - -struct SDL_Surface_Deleter { - void operator()(SDL_Surface * surface) { - SDL_FreeSurface(surface); - } -}; - -struct SDL_Texture_Deleter { - void operator()(SDL_Texture * texture) { - SDL_DestroyTexture(texture); - } -}; - -struct SDL_Font_Deleter { - void operator()(TTF_Font* font) { - TTF_CloseFont(font); - } -}; - -using SDLTexturePtr = std::unique_ptr; -using SDLSurfacePtr = std::unique_ptr; - - -class PacMan; -class Pellets; -class SuperPellets; - -class SDLWindow { -public: - explicit SDLWindow(SDL_Rect windowGeometry); - - static constexpr auto White = SDL_Color{0xFF, 0xFF, 0xFF}; - - void clear(); - - void render(); - - Sprite getBackground() const; - Sprite getSprite(SDL_Rect rect) const; - void renderSprite(Sprite sprite, SDL_Rect target) const; - void drawText(const std::string &text, SDL_Point position, SDL_Color textColor = White) const; - -private: - static constexpr int16_t SCALE_FACTOR = 1; - - std::unique_ptr window; - std::unique_ptr renderer; - SDLSurfacePtr window_surface; - SDLTexturePtr maze_texture; - SDLTexturePtr sprite_texture; - std::unique_ptr font; - - void createWindow(int width, int height); - - void createRenderer(); - - void createWindowSurface(); - - static void initSDL(); - - static void initSDLImage(); - - void initSDLTTF(); - - void setDrawColor(); - - static void exitFailure(const std::string & message); - - static void exitImgFailure(const std::string & message); - - std::unique_ptr - loadTexture(const std::string & path); - - SDL_Rect windowDimensions() const; - - std::tuple textureSize(SDL_Texture* texture) const; -}; diff --git a/lib/Sprite.cpp b/lib/Sprite.cpp deleted file mode 100644 index 86523c6..0000000 --- a/lib/Sprite.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "Sprite.hpp" diff --git a/lib/Sprite.hpp b/lib/Sprite.hpp deleted file mode 100644 index 34e9373..0000000 --- a/lib/Sprite.hpp +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include -#include - -struct Sprite { - SDL_Texture * texture; - SDL_Rect rect; -}; diff --git a/lib/SuperPellets.hpp b/lib/SuperPellets.hpp index cb7176f..bda304f 100644 --- a/lib/SuperPellets.hpp +++ b/lib/SuperPellets.hpp @@ -2,24 +2,21 @@ #include "Board.hpp" #include "Position.hpp" - -#include - class SuperPellets { public: explicit SuperPellets(const Board & board); - [[nodiscard]] SDL_Point currentSprite() const { + [[nodiscard]] PositionInt currentSprite() const { return sprite; } - [[nodiscard]] std::vector currentPositions() const { + [[nodiscard]] std::vector currentPositions() const { return positions; } bool eatPelletAtPosition(Position p); private: - const SDL_Point sprite = { 0, 9 }; - std::vector positions; + const PositionInt sprite = { 0, 9 }; + std::vector positions; }; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index abdf99c..8f4f659 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,11 +2,6 @@ file(GLOB_RECURSE sources CONFIGURE_DEPENDS "*.cpp") add_executable(pacman ${sources}) target_link_libraries(pacman PUBLIC libpacman) -if(MSVC) - find_package(sdl2 CONFIG REQUIRED) - target_link_libraries(pacman PUBLIC SDL2::SDL2main) -endif() - set_target_properties(pacman PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" diff --git a/vcpkg.json b/vcpkg.json index 363dd6c..5941183 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -3,10 +3,8 @@ "name": "pacman", "version": "0.1", "dependencies": [ - "sdl2-image", - "sdl2-ttf", + "sfml", "fmt", - "zlib", "gtest" ] } \ No newline at end of file