mirror of
https://gitlab.com/square-game-liberation-front/F.E.I.S.git
synced 2024-11-15 03:27:41 +01:00
Remove old fumen and chart files
This commit is contained in:
parent
ddb0b1112a
commit
019e9be178
@ -1,93 +0,0 @@
|
||||
#include "chart.hpp"
|
||||
|
||||
int Chart::getResolution() const {
|
||||
return resolution;
|
||||
}
|
||||
|
||||
void Chart::setResolution(int resolution) {
|
||||
if (resolution <= 0) {
|
||||
throw std::invalid_argument("Can't set a resolution of " + std::to_string(resolution));
|
||||
} else {
|
||||
this->resolution = resolution;
|
||||
}
|
||||
}
|
||||
|
||||
Chart::Chart(const std::string& dif, int level, int resolution) :
|
||||
dif_name(dif),
|
||||
level(level),
|
||||
Notes(),
|
||||
resolution(resolution)
|
||||
{
|
||||
if (resolution <= 0) {
|
||||
throw std::invalid_argument("Can't set a resolution of " + std::to_string(resolution));
|
||||
}
|
||||
}
|
||||
|
||||
bool Chart::operator==(const Chart& rhs) const {
|
||||
return dif_name == rhs.dif_name && level == rhs.level && Notes == rhs.Notes
|
||||
&& resolution == rhs.resolution;
|
||||
}
|
||||
|
||||
bool Chart::operator!=(const Chart& rhs) const {
|
||||
return !(rhs == *this);
|
||||
}
|
||||
|
||||
bool Chart::is_colliding(const Note& note, int ticks_threshold) {
|
||||
int lower_bound = std::max(0, note.getTiming() - ticks_threshold);
|
||||
int upper_bound = note.getTiming() + ticks_threshold;
|
||||
|
||||
auto lower_note = Notes.lower_bound(Note(0, lower_bound));
|
||||
auto upper_note = Notes.upper_bound(Note(15, upper_bound));
|
||||
|
||||
if (lower_note != Notes.end()) {
|
||||
for (auto other_note = lower_note;
|
||||
other_note != Notes.end() and other_note != upper_note;
|
||||
++other_note) {
|
||||
if (other_note->getPos() == note.getPos()
|
||||
and other_note->getTiming() != note.getTiming()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function does not take long notes into account and just gives back
|
||||
* anything with a timing value between the two arguments, inclusive
|
||||
*/
|
||||
std::set<Note> Chart::getNotesBetween(int start_timing, int end_timing) const {
|
||||
std::set<Note> res = {};
|
||||
|
||||
auto lower_bound = Notes.lower_bound(Note(0, start_timing));
|
||||
auto upper_bound = Notes.upper_bound(Note(15, end_timing));
|
||||
|
||||
for (auto& note_it = lower_bound; note_it != upper_bound; ++note_it) {
|
||||
res.insert(*note_it);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Takes long notes into account, gives back any note that would be visible
|
||||
* between the two arguments, LN tails included
|
||||
*/
|
||||
std::set<Note> Chart::getVisibleNotesBetween(int start_timing, int end_timing) const {
|
||||
auto res = getNotesBetween(start_timing, end_timing);
|
||||
|
||||
auto note_it = Notes.upper_bound(Note(0, start_timing));
|
||||
std::set<Note>::reverse_iterator rev_note_it(note_it);
|
||||
|
||||
for (; rev_note_it != Notes.rend(); ++rev_note_it) {
|
||||
if (rev_note_it->getLength() != 0) {
|
||||
int end_tick = rev_note_it->getTiming() + rev_note_it->getLength();
|
||||
if (end_tick >= start_timing and end_tick <= end_timing) {
|
||||
res.insert(*rev_note_it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "note.hpp"
|
||||
|
||||
/*
|
||||
* Holds the notes, the difficulty name and the level
|
||||
*/
|
||||
class Chart {
|
||||
public:
|
||||
Chart(const std::string& dif = "Edit", int level = 1, int resolution = 240);
|
||||
|
||||
int getResolution() const;
|
||||
void setResolution(int resolution);
|
||||
|
||||
std::string dif_name;
|
||||
int level;
|
||||
std::set<Note> Notes;
|
||||
|
||||
std::set<Note> getNotesBetween(int start_timing, int end_timing) const;
|
||||
std::set<Note> getVisibleNotesBetween(int start_timing, int end_timing) const;
|
||||
|
||||
bool is_colliding(const Note& note, int ticks_threshold);
|
||||
|
||||
bool operator==(const Chart& rhs) const;
|
||||
|
||||
bool operator!=(const Chart& rhs) const;
|
||||
|
||||
private:
|
||||
int resolution;
|
||||
};
|
151
src/fumen.cpp
151
src/fumen.cpp
@ -1,151 +0,0 @@
|
||||
#include "fumen.hpp"
|
||||
|
||||
Fumen::Fumen(
|
||||
const std::filesystem::path& path,
|
||||
const std::string& songTitle,
|
||||
const std::string& artist,
|
||||
const std::string& musicPath,
|
||||
const std::string& albumCoverPath,
|
||||
float BPM,
|
||||
float offset) :
|
||||
path(path),
|
||||
songTitle(songTitle),
|
||||
artist(artist),
|
||||
musicPath(musicPath),
|
||||
albumCoverPath(albumCoverPath),
|
||||
BPM(BPM),
|
||||
offset(offset) {}
|
||||
|
||||
bool cmpDifName::operator()(const std::string& a, const std::string& b) const {
|
||||
if (dif_names.find(a) != dif_names.end()) {
|
||||
if (dif_names.find(b) != dif_names.end()) {
|
||||
return dif_names.find(a)->second < dif_names.find(b)->second;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (dif_names.find(b) != dif_names.end()) {
|
||||
return false;
|
||||
} else {
|
||||
return a < b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Selects a version-specific parsing function according to what's indicated in
|
||||
* the file
|
||||
*/
|
||||
void Fumen::loadFromMemon(std::filesystem::path path) {
|
||||
nlohmann::json j;
|
||||
std::ifstream fichier(path);
|
||||
|
||||
fichier >> j;
|
||||
|
||||
if (j.find("version") != j.end() and j.at("version").is_string()) {
|
||||
if (j.at("version").get<std::string>() == "0.1.0") {
|
||||
this->loadFromMemon_v0_1_0(j);
|
||||
} else {
|
||||
this->loadFromMemon_fallback(j);
|
||||
}
|
||||
} else {
|
||||
this->loadFromMemon_fallback(j);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Memon schema v0.1.0 :
|
||||
* - "data" is an object mapping a difficulty name to a chart, this way we
|
||||
* get the dif. name uniqueness for free
|
||||
* - "jacket path" is now "album cover path" because why tf not
|
||||
*/
|
||||
void Fumen::loadFromMemon_v0_1_0(nlohmann::json memon) {
|
||||
this->songTitle = memon.at("metadata").value("song title", "");
|
||||
this->artist = memon.at("metadata").value("artist", "");
|
||||
this->musicPath = memon.at("metadata").value("music path", "");
|
||||
this->albumCoverPath = memon.at("metadata").value("album cover path", "");
|
||||
this->BPM = memon.at("metadata").value("BPM", 120.f);
|
||||
this->offset = memon.at("metadata").value("offset", 0.f);
|
||||
for (auto& [dif_name, chart_json] : memon.at("data").items()) {
|
||||
Chart chart(dif_name, chart_json.value("level", 0), chart_json.at("resolution"));
|
||||
for (auto& note : chart_json.at("notes")) {
|
||||
chart.Notes.emplace(note.at("n"), note.at("t"), note.at("l"), note.at("p"));
|
||||
}
|
||||
this->Charts.insert(std::pair<std::string, Chart>(chart.dif_name, chart));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Fallback memon parser
|
||||
* Respects the old schema, with notable quirks :
|
||||
* - "data" is an array of charts
|
||||
* - the album cover path field is named "jacket path"
|
||||
* ("jaquette" made sense in French but is a bit far-fetched in English
|
||||
* unfortunately)
|
||||
*/
|
||||
void Fumen::loadFromMemon_fallback(nlohmann::json j) {
|
||||
this->songTitle = j.at("metadata").value("song title", "");
|
||||
this->artist = j.at("metadata").value("artist", "");
|
||||
this->musicPath = j.at("metadata").value("music path", "");
|
||||
this->albumCoverPath = j.at("metadata").value("jacket path", "");
|
||||
this->BPM = j.at("metadata").value("BPM", 120.f);
|
||||
this->offset = j.at("metadata").value("offset", 0.f);
|
||||
for (auto& chart_json : j.at("data")) {
|
||||
Chart chart(
|
||||
chart_json.at("dif_name"),
|
||||
chart_json.value("level", 0),
|
||||
chart_json.at("resolution"));
|
||||
for (auto& note : chart_json.at("notes")) {
|
||||
chart.Notes.emplace(note.at("n"), note.at("t"), note.at("l"), note.at("p"));
|
||||
}
|
||||
this->Charts.insert(std::pair<std::string, Chart>(chart.dif_name, chart));
|
||||
}
|
||||
}
|
||||
|
||||
void Fumen::saveAsMemon(std::filesystem::path path) {
|
||||
std::ofstream fichier(path);
|
||||
using json = nlohmann::json;
|
||||
json j = {
|
||||
{"version", "0.1.0"},
|
||||
{"metadata",
|
||||
{{"song title", this->songTitle},
|
||||
{"artist", this->artist},
|
||||
{"music path", this->musicPath},
|
||||
{"album cover path", this->albumCoverPath},
|
||||
{"BPM", this->BPM},
|
||||
{"offset", this->offset}}},
|
||||
{"data", json::object()}};
|
||||
for (auto& tuple : this->Charts) {
|
||||
json chart_json = {
|
||||
{"level", tuple.second.level},
|
||||
{"resolution", tuple.second.getResolution()},
|
||||
{"notes", json::array()}};
|
||||
for (auto& note : tuple.second.Notes) {
|
||||
json note_json = {
|
||||
{"n", note.getPos()},
|
||||
{"t", note.getTiming()},
|
||||
{"l", note.getLength()},
|
||||
{"p", note.getTail_pos()}};
|
||||
chart_json["notes"].push_back(note_json);
|
||||
}
|
||||
j["data"].emplace(tuple.second.dif_name, chart_json);
|
||||
}
|
||||
|
||||
fichier << j.dump(4) << std::endl;
|
||||
fichier.close();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns how long the chart is in seconds as a float, from beat 0 to the last
|
||||
* note
|
||||
*/
|
||||
float Fumen::get_chart_runtime(Chart c) {
|
||||
if (!c.Notes.empty()) {
|
||||
Note last_note = *c.Notes.rbegin();
|
||||
auto beats = static_cast<float>(last_note.getTiming()) / c.getResolution();
|
||||
auto minutes = beats / this->BPM;
|
||||
return minutes * 60.f;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <json.hpp>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include "chart.hpp"
|
||||
#include "note.hpp"
|
||||
|
||||
/*
|
||||
* Difficulty name ordering : BSC > ADV > EXT > anything else in lexicographical
|
||||
* order
|
||||
*/
|
||||
struct cmpDifName {
|
||||
std::map<std::string, int> dif_names;
|
||||
|
||||
cmpDifName() { dif_names = {{"BSC", 1}, {"ADV", 2}, {"EXT", 3}}; }
|
||||
bool operator()(const std::string& a, const std::string& b) const;
|
||||
};
|
||||
|
||||
/*
|
||||
* Represents a .memon file : several charts and some metadata
|
||||
*/
|
||||
class Fumen {
|
||||
public:
|
||||
explicit Fumen(
|
||||
const std::filesystem::path& path,
|
||||
const std::string& songTitle = "",
|
||||
const std::string& artist = "",
|
||||
const std::string& musicPath = "",
|
||||
const std::string& albumCoverPath = "",
|
||||
float BPM = 120,
|
||||
float offset = 0);
|
||||
|
||||
void loadFromMemon(std::filesystem::path path);
|
||||
void loadFromMemon_v0_1_0(nlohmann::json j);
|
||||
void loadFromMemon_fallback(nlohmann::json j);
|
||||
|
||||
void saveAsMemon(std::filesystem::path path);
|
||||
|
||||
void autoLoadFromMemon() { loadFromMemon(path); };
|
||||
void autoSaveAsMemon() { saveAsMemon(path); };
|
||||
|
||||
std::map<std::string, Chart, cmpDifName> Charts;
|
||||
std::filesystem::path path;
|
||||
std::string songTitle;
|
||||
std::string artist;
|
||||
std::string musicPath;
|
||||
std::string albumCoverPath;
|
||||
float BPM;
|
||||
float offset;
|
||||
|
||||
float get_chart_runtime(Chart c);
|
||||
};
|
@ -7,13 +7,11 @@ sources += files(
|
||||
'better_notes.cpp',
|
||||
'better_song.cpp',
|
||||
'better_timing.cpp',
|
||||
'chart.cpp',
|
||||
'chart_state.cpp',
|
||||
'clipboard.cpp',
|
||||
'config.cpp',
|
||||
'editor_state.cpp',
|
||||
'file_dialogs.cpp',
|
||||
'fumen.cpp',
|
||||
'history_item.cpp',
|
||||
'imgui_extras.cpp',
|
||||
'json_decimal_handling.cpp',
|
||||
|
Loading…
Reference in New Issue
Block a user