IT BUILDS
This commit is contained in:
parent
97d5f1493a
commit
73a02bf924
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#ifndef MEMON_HPP_
|
||||
#define MEMON_HPP_
|
||||
|
||||
#include <cassert>
|
||||
#include <set>
|
||||
@ -168,6 +169,7 @@ namespace stepland {
|
||||
} else {
|
||||
m.load_from_memon_fallback(j);
|
||||
}
|
||||
return file;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -176,9 +178,9 @@ namespace stepland {
|
||||
* this way the difficulty names are guaranteed to be unique
|
||||
* - "jacket path" is now "album cover path" because engrish much ?
|
||||
*/
|
||||
void load_from_memon_v0_1_0(nlohmann::json memon) {
|
||||
void load_from_memon_v0_1_0(nlohmann::json memon_json) {
|
||||
|
||||
auto metadata = memon.at("metadata");
|
||||
auto metadata = memon_json.at("metadata");
|
||||
if (not metadata.is_object()) {
|
||||
throw std::invalid_argument("metadata fields is not an object");
|
||||
}
|
||||
@ -190,11 +192,11 @@ namespace stepland {
|
||||
this->BPM = metadata.value("BPM",120.0f);
|
||||
this->offset = metadata.value("offset",0.0f);
|
||||
|
||||
if (not memon.at("data").is_object()) {
|
||||
if (not memon_json.at("data").is_object()) {
|
||||
throw std::invalid_argument("data field is not an object");
|
||||
}
|
||||
|
||||
for (auto& [dif_name, chart_json] : memon.at("data").items()) {
|
||||
for (auto& [dif_name, chart_json] : memon_json.at("data").items()) {
|
||||
|
||||
chart new_chart;
|
||||
new_chart.level = chart_json.value("level", 0);
|
||||
@ -234,9 +236,9 @@ namespace stepland {
|
||||
* - "data" is an array of charts, each with a difficulty name
|
||||
* - the album cover path field is named "jacket path"
|
||||
*/
|
||||
void load_from_memon_fallback(nlohmann::json memon) {
|
||||
void load_from_memon_fallback(nlohmann::json memon_json) {
|
||||
|
||||
auto metadata = memon.at("metadata");
|
||||
auto metadata = memon_json.at("metadata");
|
||||
if (not metadata.is_object()) {
|
||||
throw std::invalid_argument("metadata fields is not an object");
|
||||
}
|
||||
@ -248,11 +250,11 @@ namespace stepland {
|
||||
this->BPM = metadata.value("BPM",120.f);
|
||||
this->offset = metadata.value("offset",0.f);
|
||||
|
||||
if (not memon.at("data").is_array()) {
|
||||
if (not memon_json.at("data").is_array()) {
|
||||
throw std::invalid_argument("data field is not an array");
|
||||
}
|
||||
|
||||
for (auto& chart_json : memon.at("data")) {
|
||||
for (auto& chart_json : memon_json.at("data")) {
|
||||
chart new_chart;
|
||||
new_chart.level = chart_json.value("level", 0);
|
||||
new_chart.resolution = chart_json.at("resolution").get<int>();
|
||||
@ -289,4 +291,6 @@ namespace stepland {
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* MEMON_HPP_ */
|
||||
|
@ -41,5 +41,12 @@ executable(
|
||||
'jujube',
|
||||
sources,
|
||||
dependencies: [sfml, filesystem],
|
||||
include_directories : include_directories('include')
|
||||
include_directories : include_directories('include'),
|
||||
cpp_args : [
|
||||
'-Wall',
|
||||
'-Wextra',
|
||||
'-Wshadow',
|
||||
'-Wnon-virtual-dtor',
|
||||
'-pedantic'
|
||||
]
|
||||
)
|
@ -1,73 +1,83 @@
|
||||
#include "Note.hpp"
|
||||
|
||||
namespace Data {
|
||||
|
||||
Note::Note(
|
||||
unsigned int t_position,
|
||||
sf::Time t_timing,
|
||||
sf::Time t_length,
|
||||
unsigned int t_tail_position
|
||||
) :
|
||||
position(t_position),
|
||||
timing(t_timing),
|
||||
length(t_length),
|
||||
tail_position(t_tail_position)
|
||||
{
|
||||
if (t_position > 15) {
|
||||
throw std::out_of_range(
|
||||
"Tried creating a note with invalid position : "
|
||||
+std::to_string(t_position)
|
||||
);
|
||||
}
|
||||
|
||||
Data::Note::Note(
|
||||
unsigned int t_position,
|
||||
sf::Time t_timing,
|
||||
sf::Time t_length,
|
||||
unsigned int t_tail_position
|
||||
) :
|
||||
position(t_position),
|
||||
timing(t_timing),
|
||||
length(t_length),
|
||||
tail_position(t_tail_position)
|
||||
{
|
||||
if (t_position > 15) {
|
||||
throw std::out_of_range("Tried creating a note with invalid position : "+std::to_string(t_position));
|
||||
}
|
||||
|
||||
if (t_length.asMicroseconds() < 0) {
|
||||
throw std::out_of_range("Tried creating a long note with negative length : "+std::to_string(t_length.asSeconds)+ "s");
|
||||
|
||||
}
|
||||
if (t_length.asMicroseconds() > 0) {
|
||||
if (t_tail_position > 5) {
|
||||
throw std::out_of_range("Tried creating a long note with invalid tail position : "+std::to_string(t_tail_position));
|
||||
if (t_length.asMicroseconds() < 0) {
|
||||
throw std::out_of_range(
|
||||
"Tried creating a long note with negative length : "
|
||||
+std::to_string(t_length.asSeconds())+"s"
|
||||
);
|
||||
}
|
||||
if (t_length.asMicroseconds() > 0) {
|
||||
if (t_tail_position > 5) {
|
||||
throw std::out_of_range(
|
||||
"Tried creating a long note with invalid tail position : "
|
||||
+std::to_string(t_tail_position)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Data::Note::operator==(const Data::Note &rhs) const {
|
||||
return timing == rhs.timing && position == rhs.position;
|
||||
}
|
||||
|
||||
bool Data::Note::operator!=(const Data::Note &rhs) const {
|
||||
return !(rhs == *this);
|
||||
}
|
||||
|
||||
bool Data::Note::operator<(const Data::Note &rhs) const {
|
||||
if (timing < rhs.timing) {
|
||||
return true;
|
||||
bool Note::operator==(const Note &rhs) const {
|
||||
return timing == rhs.timing && position == rhs.position;
|
||||
}
|
||||
if (rhs.timing < timing) {
|
||||
return false;
|
||||
|
||||
bool Note::operator!=(const Note &rhs) const {
|
||||
return !(rhs == *this);
|
||||
}
|
||||
return position < rhs.position;
|
||||
}
|
||||
|
||||
bool Data::Note::operator>(const Data::Note &rhs) const {
|
||||
return rhs < *this;
|
||||
}
|
||||
bool Note::operator<(const Note &rhs) const {
|
||||
if (timing < rhs.timing) {
|
||||
return true;
|
||||
}
|
||||
if (rhs.timing < timing) {
|
||||
return false;
|
||||
}
|
||||
return position < rhs.position;
|
||||
}
|
||||
|
||||
bool Data::Note::operator<=(const Data::Note &rhs) const {
|
||||
return !(rhs < *this);
|
||||
}
|
||||
bool Note::operator>(const Note &rhs) const {
|
||||
return rhs < *this;
|
||||
}
|
||||
|
||||
bool Data::Note::operator>=(const Data::Note &rhs) const {
|
||||
return !(*this < rhs);
|
||||
}
|
||||
const unsigned int Data::Note::getPosition() const {
|
||||
return position;
|
||||
}
|
||||
bool Note::operator<=(const Note &rhs) const {
|
||||
return !(rhs < *this);
|
||||
}
|
||||
|
||||
const sf::Time& Data::Note::getTiming() const {
|
||||
return timing;
|
||||
}
|
||||
bool Note::operator>=(const Note &rhs) const {
|
||||
return !(*this < rhs);
|
||||
}
|
||||
unsigned int Note::getPosition() const {
|
||||
return position;
|
||||
}
|
||||
|
||||
const sf::Time& Data::Note::getLength() const {
|
||||
return length;
|
||||
}
|
||||
const sf::Time& Note::getTiming() const {
|
||||
return timing;
|
||||
}
|
||||
|
||||
const unsigned int Data::Note::getTailPosition() const {
|
||||
return tail_position;
|
||||
const sf::Time& Note::getLength() const {
|
||||
return length;
|
||||
}
|
||||
|
||||
unsigned int Note::getTailPosition() const {
|
||||
return tail_position;
|
||||
}
|
||||
}
|
||||
|
@ -14,10 +14,10 @@ namespace Data {
|
||||
bool operator<=(const Note &rhs) const;
|
||||
bool operator>=(const Note &rhs) const;
|
||||
|
||||
const unsigned int getPosition() const;
|
||||
unsigned int getPosition() const;
|
||||
const sf::Time& getTiming() const;
|
||||
const sf::Time& getLength() const;
|
||||
const unsigned int getTailPosition() const;
|
||||
unsigned int getTailPosition() const;
|
||||
|
||||
private:
|
||||
|
||||
@ -27,4 +27,4 @@ namespace Data {
|
||||
const unsigned int tail_position = 0;
|
||||
|
||||
};
|
||||
};
|
||||
}
|
@ -49,7 +49,7 @@ namespace Data {
|
||||
fs::begin(folder),
|
||||
fs::end(folder),
|
||||
[](const fs::directory_entry& de) {
|
||||
de.path().extension() == ".memo" or
|
||||
return de.path().extension() == ".memo" or
|
||||
de.path().extension() == ".memon";
|
||||
}
|
||||
)
|
||||
@ -93,14 +93,14 @@ namespace Data {
|
||||
// .memo ?
|
||||
auto memo_files = getMemoFiles(song_folder);
|
||||
if (not memo_files.empty()) {
|
||||
throw std::exception("jujube does not support .memo files for now ...");
|
||||
throw std::invalid_argument("jujube does not support .memo files for now ...");
|
||||
} else {
|
||||
throw std::invalid_argument("No valid file found in song folder");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<fs::path>& getMemoFiles(fs::path song_folder) {
|
||||
const std::vector<fs::path> getMemoFiles(fs::path song_folder) {
|
||||
std::vector<fs::path> res;
|
||||
for (const auto& p : fs::directory_iterator(song_folder)) {
|
||||
if (p.path().extension() == ".memo") {
|
||||
@ -110,7 +110,7 @@ namespace Data {
|
||||
return res;
|
||||
}
|
||||
|
||||
const std::vector<fs::path>& getMemonFiles(fs::path song_folder) {
|
||||
const std::vector<fs::path> getMemonFiles(fs::path song_folder) {
|
||||
std::vector<fs::path> res;
|
||||
for (const auto& p : fs::directory_iterator(song_folder)) {
|
||||
if (p.path().extension() == ".memon") {
|
||||
|
@ -46,6 +46,6 @@ namespace Data {
|
||||
// .memon files also accepted
|
||||
const std::vector<fs::path> getSongFolders();
|
||||
std::list<fs::path> recursiveSongSearch(fs::path song_or_pack);
|
||||
const std::vector<fs::path>& getMemoFiles(fs::path song_folder);
|
||||
const std::vector<fs::path>& getMemonFiles(fs::path song_folder);
|
||||
const std::vector<fs::path> getMemoFiles(fs::path song_folder);
|
||||
const std::vector<fs::path> getMemonFiles(fs::path song_folder);
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ sf::Sprite Textures::CoverAltas::at(const fs::path& path) const {
|
||||
index = 0;
|
||||
}
|
||||
|
||||
auto location = get_detailed_location(path_to_index.at(path));
|
||||
auto location = get_detailed_location(index);
|
||||
sf::IntRect rect(location.column*256, location.row*256, 256, 256);
|
||||
sf::Sprite cover;
|
||||
cover.setTexture(textures.at(location.texture_index)->getTexture());
|
||||
|
@ -18,7 +18,7 @@ namespace std {
|
||||
return std::hash<std::string>()(p.string());
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
namespace Textures {
|
||||
|
||||
@ -50,4 +50,4 @@ namespace Textures {
|
||||
};
|
||||
|
||||
DetailedLocation get_detailed_location(unsigned int location);
|
||||
};
|
||||
}
|
||||
|
@ -37,9 +37,14 @@ void MusicSelect::Screen::select_chart(sf::RenderWindow& window) {
|
||||
// drawing the ribbon
|
||||
for (size_t panel = 0; panel < 12; panel++) {
|
||||
ribbon.at(panel)->draw(
|
||||
*this,
|
||||
resources,
|
||||
window,
|
||||
sf::FloatRect((panel%4)*150.f, (panel/4)*150.f, 150.f, 150.f)
|
||||
sf::FloatRect(
|
||||
(panel%4)*150.f,
|
||||
(panel/4)*150.f,
|
||||
150.f,
|
||||
150.f
|
||||
)
|
||||
);
|
||||
}
|
||||
window.display();
|
||||
@ -47,10 +52,4 @@ void MusicSelect::Screen::select_chart(sf::RenderWindow& window) {
|
||||
}
|
||||
|
||||
void MusicSelect::Screen::handle_key(const sf::Event::KeyEvent& key_event) {
|
||||
auto panel = key_mapping.key_to_button(key_event.code);
|
||||
if (panel) {
|
||||
if (Button::B2 <= *panel and *panel <= Button::B12) {
|
||||
ribbon.at()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,4 +33,4 @@ namespace MusicSelect {
|
||||
KeyMapping key_mapping;
|
||||
void handle_key(const sf::Event::KeyEvent& key_event);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
@ -4,6 +4,10 @@
|
||||
|
||||
#include "MusicSelect.hpp"
|
||||
|
||||
void MusicSelect::CategoryPanel::click(Screen& screen) {
|
||||
|
||||
}
|
||||
|
||||
void MusicSelect::CategoryPanel::draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) {
|
||||
sf::RectangleShape frame{{area.width*0.9f, area.height*0.9f}};
|
||||
frame.setFillColor(sf::Color::Black);
|
||||
@ -27,12 +31,22 @@ void MusicSelect::CategoryPanel::draw(Resources& resources, sf::RenderTarget& ta
|
||||
label_text.setString(this->label);
|
||||
label_text.setCharacterSize(24U);
|
||||
label_text.setFillColor(sf::Color::White);
|
||||
auto bounds = label_text.getLocalBounds();
|
||||
label_text.setOrigin(bounds.width / 2.f, bounds.height / 2.f);
|
||||
if (bounds.height > bounds.width) {
|
||||
label_text.setScale(area.height*0.8f / bounds.height, area.height*0.8f / bounds.height);
|
||||
auto text_bounds = label_text.getLocalBounds();
|
||||
label_text.setOrigin(text_bounds.width / 2.f, text_bounds.height / 2.f);
|
||||
if (text_bounds.height > text_bounds.width) {
|
||||
label_text.setScale(area.height*0.8f / text_bounds.height, area.height*0.8f / text_bounds.height);
|
||||
} else {
|
||||
label_text.setScale(area.width*0.8f / bounds.width, area.width*0.8f / bounds.width);
|
||||
label_text.setScale(area.width*0.8f / text_bounds.width, area.width*0.8f / text_bounds.width);
|
||||
}
|
||||
label_text.setPosition(area.left + area.width / 2.f, area.top + area.height / 2.f);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MusicSelect::SongPanel::click(Screen& screen) {
|
||||
|
||||
}
|
||||
|
||||
void MusicSelect::SongPanel::draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) {
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <SFML/Graphics.hpp>
|
||||
#include <SFML/Window.hpp>
|
||||
|
||||
#include "../../Data/SongList.hpp"
|
||||
#include "Resources.hpp"
|
||||
|
||||
namespace MusicSelect {
|
||||
@ -28,7 +29,7 @@ namespace MusicSelect {
|
||||
|
||||
class CategoryPanel final : public Panel {
|
||||
public:
|
||||
CategoryPanel(const std::string& t_label) : label(t_label) {};
|
||||
explicit CategoryPanel(const std::string& t_label) : label(t_label) {};
|
||||
void click(Screen& screen) override;
|
||||
void draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) override;
|
||||
private:
|
||||
@ -37,7 +38,7 @@ namespace MusicSelect {
|
||||
|
||||
class SongPanel final : public Panel {
|
||||
public:
|
||||
SongPanel(const Data::Song& t_song) : song(t_song) {};
|
||||
explicit SongPanel(const Data::Song& t_song) : song(t_song) {};
|
||||
void click(Screen& screen) override;
|
||||
void draw(Resources& resources, sf::RenderTarget& target, sf::FloatRect area) override;
|
||||
private:
|
||||
|
@ -8,7 +8,7 @@
|
||||
MusicSelect::Ribbon MusicSelect::Ribbon::title_sort(const Data::SongList& song_list) {
|
||||
std::map<char,std::vector<Data::Song>> categories;
|
||||
for (const auto& song : song_list.songs) {
|
||||
if (song.title.size > 0) {
|
||||
if (song.title.size() > 0) {
|
||||
char letter = song.title[0];
|
||||
if ('A' <= letter and letter <= 'Z') {
|
||||
categories[letter].push_back(song);
|
||||
@ -22,22 +22,25 @@ MusicSelect::Ribbon MusicSelect::Ribbon::title_sort(const Data::SongList& song_l
|
||||
}
|
||||
}
|
||||
Ribbon ribbon;
|
||||
for (const auto& [letter, songs] : categories) {
|
||||
std::vector<std::unique_ptr<Panel>> panels = {std::make_unique<CategoryPanel>(letter)};
|
||||
for (auto& [letter, songs] : categories) {
|
||||
std::vector<std::unique_ptr<Panel>> panels;
|
||||
panels.emplace_back(
|
||||
std::make_unique<CategoryPanel>(
|
||||
std::string(1, letter)
|
||||
)
|
||||
);
|
||||
std::sort(songs.begin(), songs.end(), Data::Song::sort_by_title);
|
||||
for (const auto& song : songs) {
|
||||
panels.push_back(std::make_unique<SongPanel>(song));
|
||||
}
|
||||
while (panels.size % 3 != 0) {
|
||||
while (panels.size() % 3 != 0) {
|
||||
panels.push_back(std::make_unique<EmptyPanel>());
|
||||
}
|
||||
for (size_t i = 0; i < panels.size; i += 3) {
|
||||
std::array<std::unique_ptr<Panel>,3> column = {
|
||||
std::move(panels[i]),
|
||||
std::move(panels[i+1]),
|
||||
std::move(panels[i+2])
|
||||
};
|
||||
ribbon.layout.push_back(column);
|
||||
for (size_t i = 0; i < panels.size(); i += 3) {
|
||||
ribbon.layout.emplace_back();
|
||||
for (size_t j = 0; j < 3; j++) {
|
||||
ribbon.layout.back()[j] = std::move(panels[i+j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ribbon;
|
||||
|
@ -8,7 +8,7 @@ namespace MusicSelect {
|
||||
// It can be sorted in a number of ways
|
||||
class Ribbon {
|
||||
public:
|
||||
Ribbon();
|
||||
Ribbon() = default;
|
||||
static Ribbon title_sort(const Data::SongList& song_list);
|
||||
static Ribbon test_sort();
|
||||
const auto& get_layout() {return layout;};
|
||||
|
Loading…
x
Reference in New Issue
Block a user