Update memoncpp to 0.2.0
This commit is contained in:
parent
c55da3a88d
commit
01ca4fa742
2
TODO.md
2
TODO.md
@ -41,9 +41,11 @@
|
|||||||
## TODO
|
## TODO
|
||||||
### Misc
|
### Misc
|
||||||
- Make Drawables lazily react to resolution changes
|
- Make Drawables lazily react to resolution changes
|
||||||
|
- Handle JCK and special characters
|
||||||
|
|
||||||
### Music Select Screen
|
### Music Select Screen
|
||||||
- Sound
|
- Sound
|
||||||
|
- Music Sample
|
||||||
- Fullscreen handling
|
- Fullscreen handling
|
||||||
- Song Panel click
|
- Song Panel click
|
||||||
- animation
|
- animation
|
||||||
|
@ -1,3 +1,13 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
88,dPYba,,adPYba, ,adPPYba, 88,dPYba,,adPYba, ,adPPYba, 8b,dPPYba,
|
||||||
|
88P' "88" "8a a8P_____88 88P' "88" "8a a8" "8a 88P' `"8a memoncpp
|
||||||
|
88 88 88 8PP""""""" 88 88 88 8b d8 88 88 v0.2.0
|
||||||
|
88 88 88 "8b, ,aa 88 88 88 "8a, ,a8" 88 88 https://github.com/Stepland/memoncpp
|
||||||
|
88 88 88 `"Ybbd8"' 88 88 88 `"YbbdP"' 88 88 https://github.com/Stepland/memon
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef MEMON_HPP_
|
#ifndef MEMON_HPP_
|
||||||
#define MEMON_HPP_
|
#define MEMON_HPP_
|
||||||
|
|
||||||
@ -144,53 +154,75 @@ namespace stepland {
|
|||||||
*/
|
*/
|
||||||
struct memon {
|
struct memon {
|
||||||
|
|
||||||
|
struct preview_loop {
|
||||||
|
float position;
|
||||||
|
float duration;
|
||||||
|
};
|
||||||
|
|
||||||
std::map<std::string,chart,compare_dif_names> charts;
|
std::map<std::string,chart,compare_dif_names> charts;
|
||||||
std::string song_title;
|
std::string song_title;
|
||||||
std::string artist;
|
std::string artist;
|
||||||
std::string music_path;
|
std::string music_path;
|
||||||
std::string album_cover_path;
|
std::string album_cover_path;
|
||||||
|
std::optional<preview_loop> preview;
|
||||||
float BPM;
|
float BPM;
|
||||||
float offset;
|
float offset;
|
||||||
|
|
||||||
friend std::istream& operator>>(std::istream& file, memon& m) {
|
friend std::istream& operator>>(std::istream& file, memon& m) {
|
||||||
nlohmann::json j;
|
nlohmann::json j;
|
||||||
file >> j;
|
file >> j;
|
||||||
if (j.find("version") != j.end()) {
|
// Basic checks
|
||||||
if (j.at("version").is_string()) {
|
if (j.find("version") == j.end()) {
|
||||||
|
m.load_from_memon_fallback(j);
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
if (not j.at("version").is_string()) {
|
||||||
|
throw std::invalid_argument("Unexpected version field : "+j.at("version").dump());
|
||||||
|
}
|
||||||
|
|
||||||
auto version = j.at("version").get<std::string>();
|
auto version = j.at("version").get<std::string>();
|
||||||
if (version == "0.1.0") {
|
if (version == "0.1.0") {
|
||||||
m.load_from_memon_v0_1_0(j);
|
m.load_from_memon_v0_1_0(j);
|
||||||
|
} else if (version == "0.2.0") {
|
||||||
|
m.load_from_memon_v0_2_0(j);
|
||||||
} else {
|
} else {
|
||||||
throw std::invalid_argument("Unsupported .memon version : "+version);
|
throw std::invalid_argument("Unsupported .memon version : "+version);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
throw std::invalid_argument("Unexpected version field : "+j.at("version").dump());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m.load_from_memon_fallback(j);
|
|
||||||
}
|
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Memon schema v0.1.0 :
|
* v0.2.0
|
||||||
* - "data" is now an object mapping a difficulty name to a chart,
|
* - "preview" as been added as an optional metadata key holding the song
|
||||||
* this way the difficulty names are guaranteed to be unique
|
* preview loop info, it's an object with two required fields :
|
||||||
* - "jacket path" is now "album cover path" because engrish much ?
|
* - "position" : time at which loop starts (in floating point seconds)
|
||||||
|
* - "length" : loop length (in floating point seconds)
|
||||||
*/
|
*/
|
||||||
void load_from_memon_v0_1_0(nlohmann::json memon_json) {
|
void load_from_memon_v0_2_0(nlohmann::json memon_json) {
|
||||||
|
|
||||||
auto metadata = memon_json.at("metadata");
|
auto metadata = memon_json.at("metadata");
|
||||||
if (not metadata.is_object()) {
|
if (not metadata.is_object()) {
|
||||||
throw std::invalid_argument("metadata fields is not an object");
|
throw std::invalid_argument("metadata fields is not an object");
|
||||||
}
|
}
|
||||||
|
|
||||||
this->song_title = metadata.value("song title","");
|
this->song_title = metadata.at("song title").get<std::string>();
|
||||||
this->artist = metadata.value("artist","");
|
this->artist = metadata.at("artist").get<std::string>();
|
||||||
this->music_path = metadata.value("music path","");
|
this->music_path = metadata.at("music path").get<std::string>();
|
||||||
this->album_cover_path = metadata.value("album cover path","");
|
this->album_cover_path = metadata.at("album cover path").get<std::string>();
|
||||||
this->BPM = metadata.value("BPM",120.0f);
|
this->BPM = metadata.at("BPM").get<float>();
|
||||||
this->offset = metadata.value("offset",0.0f);
|
this->offset = metadata.at("offset").get<float>();
|
||||||
|
|
||||||
|
// "preview" is optional in v0.2.0, it missing is NOT an error
|
||||||
|
if (metadata.find("preview") != metadata.end()) {
|
||||||
|
auto preview_json = metadata.at("preview");
|
||||||
|
float raw_position = preview_json.at("position").get<float>();
|
||||||
|
assert((raw_position >= 0.f));
|
||||||
|
float raw_duration = preview_json.at("duration").get<float>();
|
||||||
|
assert((raw_duration >= 0.f));
|
||||||
|
this->preview.emplace();
|
||||||
|
this->preview->position = raw_position;
|
||||||
|
this->preview->position = raw_duration;
|
||||||
|
}
|
||||||
|
|
||||||
if (not memon_json.at("data").is_object()) {
|
if (not memon_json.at("data").is_object()) {
|
||||||
throw std::invalid_argument("data field is not an object");
|
throw std::invalid_argument("data field is not an object");
|
||||||
@ -199,26 +231,15 @@ namespace stepland {
|
|||||||
for (auto& [dif_name, chart_json] : memon_json.at("data").items()) {
|
for (auto& [dif_name, chart_json] : memon_json.at("data").items()) {
|
||||||
|
|
||||||
chart new_chart;
|
chart new_chart;
|
||||||
new_chart.level = chart_json.value("level", 0);
|
new_chart.level = chart_json.at("level").get<int>();
|
||||||
new_chart.resolution = chart_json.at("resolution").get<int>();
|
new_chart.resolution = chart_json.at("resolution").get<int>();
|
||||||
|
assert((new_chart.resolution > 0));
|
||||||
|
|
||||||
if (not chart_json.at("notes").is_array()) {
|
if (not chart_json.at("notes").is_array()) {
|
||||||
throw std::invalid_argument(dif_name+" chart notes field has bad structure");
|
throw std::invalid_argument(dif_name+" chart notes field must be an array");
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& note : chart_json.at("notes")) {
|
for (auto& note : chart_json.at("notes")) {
|
||||||
if (
|
|
||||||
not (
|
|
||||||
note.is_object()
|
|
||||||
and note.find("n") != note.end()
|
|
||||||
and note.find("t") != note.end()
|
|
||||||
and note.find("l") != note.end()
|
|
||||||
and note.find("p") != note.end()
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
throw std::invalid_argument(dif_name+" chart has notes with bad structure");
|
|
||||||
}
|
|
||||||
|
|
||||||
new_chart.notes.emplace(
|
new_chart.notes.emplace(
|
||||||
note.at("n").get<int>(),
|
note.at("n").get<int>(),
|
||||||
note.at("t").get<int>(),
|
note.at("t").get<int>(),
|
||||||
@ -231,8 +252,55 @@ namespace stepland {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fallback memon parser
|
* v0.1.0
|
||||||
* Respects the old schema, with notable quirks :
|
* - "data" is now an object mapping a difficulty name to a chart,
|
||||||
|
* 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_json) {
|
||||||
|
|
||||||
|
auto metadata = memon_json.at("metadata");
|
||||||
|
if (not metadata.is_object()) {
|
||||||
|
throw std::invalid_argument("metadata fields is not an object");
|
||||||
|
}
|
||||||
|
|
||||||
|
this->song_title = metadata.at("song title").get<std::string>();
|
||||||
|
this->artist = metadata.at("artist").get<std::string>();
|
||||||
|
this->music_path = metadata.at("music path").get<std::string>();
|
||||||
|
this->album_cover_path = metadata.at("album cover path").get<std::string>();
|
||||||
|
this->BPM = metadata.at("BPM").get<float>();
|
||||||
|
this->offset = metadata.at("offset").get<float>();
|
||||||
|
|
||||||
|
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_json.at("data").items()) {
|
||||||
|
|
||||||
|
chart new_chart;
|
||||||
|
new_chart.level = chart_json.at("level").get<int>();
|
||||||
|
new_chart.resolution = chart_json.at("resolution").get<int>();
|
||||||
|
assert((new_chart.resolution > 0));
|
||||||
|
|
||||||
|
if (not chart_json.at("notes").is_array()) {
|
||||||
|
throw std::invalid_argument(dif_name+" chart notes field must be an array");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& note : chart_json.at("notes")) {
|
||||||
|
new_chart.notes.emplace(
|
||||||
|
note.at("n").get<int>(),
|
||||||
|
note.at("t").get<int>(),
|
||||||
|
note.at("l").get<int>(),
|
||||||
|
note.at("p").get<int>()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this->charts[dif_name] = new_chart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fallback parser
|
||||||
|
* Respects the old, unversionned schema, with notable quirks :
|
||||||
* - "data" is an array of charts, each with a difficulty name
|
* - "data" is an array of charts, each with a difficulty name
|
||||||
* - the album cover path field is named "jacket path"
|
* - the album cover path field is named "jacket path"
|
||||||
*/
|
*/
|
||||||
@ -243,10 +311,10 @@ namespace stepland {
|
|||||||
throw std::invalid_argument("metadata fields is not an object");
|
throw std::invalid_argument("metadata fields is not an object");
|
||||||
}
|
}
|
||||||
|
|
||||||
this->song_title = metadata.value("song title","");
|
this->song_title = metadata.at("song title").get<std::string>();
|
||||||
this->artist = metadata.value("artist","");
|
this->artist = metadata.at("artist").get<std::string>();
|
||||||
this->music_path = metadata.value("music path","");
|
this->music_path = metadata.at("music path").get<std::string>();
|
||||||
this->album_cover_path = metadata.value("jacket path","");
|
this->album_cover_path = metadata.at("jacket path").get<std::string>();
|
||||||
this->BPM = metadata.value("BPM",120.f);
|
this->BPM = metadata.value("BPM",120.f);
|
||||||
this->offset = metadata.value("offset",0.f);
|
this->offset = metadata.value("offset",0.f);
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user