From ac500158664d52fd05154feab7c17527cd0e452c Mon Sep 17 00:00:00 2001 From: Stepland <16676308+Stepland@users.noreply.github.com> Date: Wed, 23 Oct 2019 23:39:10 +0200 Subject: [PATCH] Implement JacketPack --- meson.build | 20 +++++++++++++++-- src/Main.cpp | 13 +++++++++-- src/Model/Chart.hpp | 16 +++++++++++++- src/Model/MusicList.cpp | 3 +++ src/Model/MusicList.hpp | 6 +++++ src/Screens/Gameplay.hpp | 2 +- src/Screens/MusicSelect.hpp | 8 +++++-- src/Textures/JacketPack.cpp | 44 +++++++++++++++++++++++++++++++++++++ src/Textures/JacketPack.hpp | 34 ++++++++++++++++++++++++++++ 9 files changed, 138 insertions(+), 8 deletions(-) create mode 100644 src/Model/MusicList.cpp create mode 100644 src/Textures/JacketPack.cpp create mode 100644 src/Textures/JacketPack.hpp diff --git a/meson.build b/meson.build index 2417da2..e54e073 100644 --- a/meson.build +++ b/meson.build @@ -10,8 +10,24 @@ foreach module : ['system', 'window', 'graphics', 'audio'] sfml += [dependency('sfml-'+module, version : '>=2.5.1')] endforeach +cpp = meson.get_compiler('cpp') +filesystem = cpp.find_library('stdc++fs') + +sources = [ + 'src/Main.cpp', + 'src/Model/Chart.hpp', + 'src/Model/MusicList.hpp', + 'src/Model/MusicList.cpp', + 'src/Model/Score.hpp', + 'src/Screens/Gameplay.hpp', + 'src/Screens/MusicSelect.hpp', + 'src/Screens/Result.hpp', + 'src/Textures/TexturePack.hpp', + 'src/Textures/TexturePack.cpp', +] + executable( 'jujube', - 'src/Main.cpp', - dependencies: sfml + sources, + dependencies: [sfml, filesystem] ) \ No newline at end of file diff --git a/src/Main.cpp b/src/Main.cpp index fd77307..befca54 100644 --- a/src/Main.cpp +++ b/src/Main.cpp @@ -9,15 +9,24 @@ #include "Screens/Result.hpp" int main(int argc, char const *argv[]) { + sf::RenderWindow window(sf::VideoMode(800,600), "jujube"); window.setVerticalSyncEnabled(true); + Screen::MusicSelect music_select; + while (true) { - Chart& selected_chart = music_select.display(window); + + Chart& selected_chart = music_select.select_chart(window); + Screen::Gameplay gameplay(selected_chart); - Score score = gameplay.display(window); + Score score = gameplay.play_chart(window); + Screen::Result result(score); result.display(window); + } + return 0; + } diff --git a/src/Model/Chart.hpp b/src/Model/Chart.hpp index d19e954..e68c52b 100644 --- a/src/Model/Chart.hpp +++ b/src/Model/Chart.hpp @@ -1,6 +1,20 @@ #pragma once +#include + class Chart { public: Chart(); -}; \ No newline at end of file +}; + +class ChartMetadata { +public: + ChartMetadata( + std::string title, + std::string artist + ); +private: + std::string title; + std::string artist; + +} \ No newline at end of file diff --git a/src/Model/MusicList.cpp b/src/Model/MusicList.cpp new file mode 100644 index 0000000..43bdfef --- /dev/null +++ b/src/Model/MusicList.cpp @@ -0,0 +1,3 @@ +#include "MusicList.hpp" + +MusicList::MusicList() \ No newline at end of file diff --git a/src/Model/MusicList.hpp b/src/Model/MusicList.hpp index eef979d..1d8de77 100644 --- a/src/Model/MusicList.hpp +++ b/src/Model/MusicList.hpp @@ -1,6 +1,12 @@ #pragma once +#include + +#include "../Textures/JacketPack.hpp" + class MusicList { public: MusicList(); +private: + Textures::JacketPack jacket_previews; }; diff --git a/src/Screens/Gameplay.hpp b/src/Screens/Gameplay.hpp index dba414f..cb86132 100644 --- a/src/Screens/Gameplay.hpp +++ b/src/Screens/Gameplay.hpp @@ -9,7 +9,7 @@ namespace Screen { const Chart& chart; public: explicit Gameplay(const Chart& selected_chart); - Score display(sf::Window& window) const; + Score play_chart(sf::Window& window) const; }; }; diff --git a/src/Screens/MusicSelect.hpp b/src/Screens/MusicSelect.hpp index dfc8743..ade9fbf 100644 --- a/src/Screens/MusicSelect.hpp +++ b/src/Screens/MusicSelect.hpp @@ -5,10 +5,14 @@ #include "../Model/Chart.hpp" namespace Screen { + /* + The music select screen is created only once and loads a cache of available songs + in the music_list attribute + */ class MusicSelect { MusicList music_list; public: - MusicSelect(); - Chart& display(sf::Window& window) const; + MusicSelect() = default; + Chart& select_chart(sf::Window& window) const; }; }; diff --git a/src/Textures/JacketPack.cpp b/src/Textures/JacketPack.cpp new file mode 100644 index 0000000..f47f824 --- /dev/null +++ b/src/Textures/JacketPack.cpp @@ -0,0 +1,44 @@ +#include "JacketPack.hpp" + +#include +#include +#include + +sf::Sprite Textures::JacketPack::operator[](const std::string& path) const{ + auto location = get_detailed_location(locations.at(path)); + sf::IntRect rect(location.column, location.row, 128, 128); + sf::Sprite jacket; + jacket.setTexture(textures.at(location.texture_index)->getTexture()); + jacket.setTextureRect(rect); + return jacket; +} + +void Textures::JacketPack::push_back(const std::filesystem::path& jacket) { + + sf::Texture jacket_texture; + if (!jacket_texture.loadFromFile(jacket)) { + std::stringstream ss; + ss << "Unable to load jacket image : " << jacket; + throw std::runtime_error(ss.str()); + } else { + locations[jacket] = next_location; + } + auto size = jacket_texture.getSize(); + auto location = get_detailed_location(next_location); + sf::Sprite new_jacket; + new_jacket.setTexture(jacket_texture); + new_jacket.setScale(128.0f/size.x, 128.0f/size.y); + new_jacket.setPosition(128.0f * location.column, 128.0f * location.row); + if (location.column == 0 and location.row == 0) { + // first jacket means it's a new texture + textures.push_back(std::make_shared()); + textures.back()->create(1024, 1024); + } + textures.at(location.texture_index)->draw(new_jacket); + textures.at(location.texture_index)->display(); + next_location++; +} + +Textures::DetailedLocation Textures::get_detailed_location(unsigned int location) { + return {location / 64, (location % 64) / 8, location % 8}; +} diff --git a/src/Textures/JacketPack.hpp b/src/Textures/JacketPack.hpp new file mode 100644 index 0000000..540f382 --- /dev/null +++ b/src/Textures/JacketPack.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include + +namespace Textures { + + /* + A JacketPack stores 128x128 jacket previews in 1024x1024 textures + */ + class JacketPack { + public: + JacketPack() = default; + sf::Sprite operator[](const std::string& path) const; + void push_back(const std::filesystem::path& jacket); + //private: + std::unordered_map locations; + std::vector> textures; + unsigned int next_location = 0; + }; + + struct DetailedLocation { + unsigned int texture_index; + unsigned int row; + unsigned int column; + }; + + DetailedLocation get_detailed_location(unsigned int location); +}