Skip to content

Commit f7c4c12

Browse files
author
Jaydenz
authored
Merge pull request #66
* there we fuckin go why was that being so dumb lmfao * forgot to push new songlist * Update song.h * github is weird sometimes * Merge branch 'Encore-Developers:indev' into indev * Merge branch 'Encore-Developers:indev' into indev * minor spelling mistake detected * Better Sorting and Preview Audio * Merge branch 'Encore-Developers:indev' into indev
1 parent e7b442f commit f7c4c12

File tree

8 files changed

+483
-302
lines changed

8 files changed

+483
-302
lines changed

Encore/lib/discord-rpc/windows/x64/discord_game_sdk.dll.lib renamed to Encore/lib/discord-rpc/windows/x64/discord_game_sdk.lib

File renamed without changes.

Encore/lib/discord-rpc/windows/x86/discord_game_sdk.dll.lib renamed to Encore/lib/discord-rpc/windows/x86/discord_game_sdk.lib

File renamed without changes.

Encore/src/menus/SongSelectMenu.cpp

Lines changed: 300 additions & 254 deletions
Large diffs are not rendered by default.

Encore/src/menus/SongSelectMenu.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,32 @@
55
#ifndef SONGSELECTMENU_H
66
#define SONGSELECTMENU_H
77
#include "OvershellMenu.h"
8+
#include <filesystem>
9+
#include <map>
810

911
class SongSelectMenu : public OvershellMenu {
1012
public:
1113
SongSelectMenu() = default;
12-
~SongSelectMenu() override = default;
14+
~SongSelectMenu() override;
1315
void KeyboardInputCallback(int key, int scancode, int action, int mods) override;
1416
void ControllerInputCallback(int joypadID, GLFWgamepadstate state) override;
1517
void Draw() override;
1618
void Load() override;
19+
void Unload();
20+
void UpdatePreviewVolume(double currentTime);
21+
22+
private:
23+
double previewStartTime = 0.0;
24+
float currentPreviewVolume = 0.0f;
25+
enum class PreviewState { FadeIn, Playing, FadeOut, Pause } previewState = PreviewState::FadeIn;
26+
const float fadeDuration = 2.5f;
27+
const float previewPlayDuration = 30.0f;
28+
const float pauseDuration = 2.5f;
29+
double phaseStartTime = 0.0;
30+
int pendingSongID = -1;
31+
double selectionTime = 0.0;
1732
};
1833

1934

2035

21-
#endif //SONGSELECTMENU_H
36+
#endif //SONGSELECTMENU_H

Encore/src/song/audio.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,12 @@ void Encore::AudioManager::StopPlayback(unsigned int handle) {
204204
CHECK_BASS_ERROR2();
205205
}
206206

207+
void Encore::AudioManager::SetAudioStreamPosition(unsigned int handle, double time) {
208+
int positionBytes = BASS_ChannelSeconds2Bytes(handle, time);
209+
BASS_ChannelSetPosition(handle, positionBytes, BASS_POS_BYTE);
210+
CHECK_BASS_ERROR2();
211+
}
212+
207213
void Encore::AudioManager::loadSample(const std::string &path, const std::string &name) {
208214
HSAMPLE sample = BASS_SampleLoad(false, path.c_str(), 0, 0, 1, 0);
209215
if (sample) {

Encore/src/song/audio.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ namespace Encore {
3535
void UpdateAudioStreamVolumes();
3636
AudioStream* GetAudioStreamByInstrument(int instrument);
3737
static void SetAudioStreamVolume(unsigned int handle, float volume);
38+
static void SetAudioStreamPosition(unsigned int handle, double time);
3839
static void BeginPlayback(unsigned int handle);
3940
static void StopPlayback(unsigned int handle);
4041

Encore/src/song/song.h

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ class Song {
194194
bool ini = false;
195195
smf::MidiFile midiFile;
196196
void LoadAudioINI(std::filesystem::path songPath);
197-
197+
float previewStartTime = 0.0f;
198198
void LoadAudio(std::filesystem::path jsonPath) {
199199
std::ifstream ifs(jsonPath);
200200

@@ -406,6 +406,36 @@ class Song {
406406
}
407407
}
408408
}
409+
if (document.HasMember("preview_start_time") && document["preview_start_time"].IsInt()) {
410+
previewStartTime = static_cast<float>(document["preview_start_time"].GetInt());
411+
}
412+
}
413+
if (document.HasMember("stems") && document["stems"].IsObject()) {
414+
for (auto &path : document["stems"].GetObject()) {
415+
std::string stem = std::string(path.name.GetString());
416+
int partIndex = -1;
417+
if (stem == "drums") partIndex = PartDrums;
418+
else if (stem == "bass") partIndex = PartBass;
419+
else if (stem == "lead") partIndex = PartGuitar;
420+
else if (stem == "vocals") partIndex = PartVocals;
421+
else if (stem == "backing") partIndex = 5;
422+
423+
if (path.value.IsString()) {
424+
std::filesystem::path stemPath = jsonPath.parent_path() / path.value.GetString();
425+
if (std::filesystem::exists(stemPath)) {
426+
stemsPath.push_back({ stemPath.string(), partIndex });
427+
}
428+
} else if (path.value.IsArray()) {
429+
for (auto &path2 : path.value.GetArray()) {
430+
if (path2.IsString()) {
431+
std::filesystem::path stemPath = jsonPath.parent_path() / path2.GetString();
432+
if (std::filesystem::exists(stemPath)) {
433+
stemsPath.push_back({ stemPath.string(), partIndex });
434+
}
435+
}
436+
}
437+
}
438+
}
409439
}
410440
if (charters.empty()) {
411441
charters.push_back("Unknown Charter");

Encore/src/song/songlist.cpp

Lines changed: 128 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@
33

44
#include <set>
55

6+
#include <algorithm>
7+
#include <nlohmann/json.hpp>
8+
#include <fstream>
69
#include "util/binary.h"
710

11+
using json = nlohmann::json;
812
// sorting
913
void SongList::Clear() {
1014
listMenuEntries.clear();
@@ -86,7 +90,6 @@ void SongList::sortList(SortType sortType) {
8690
std::sort(songs.begin(), songs.end(), sortSource);
8791
break;
8892
case SortType::Length:
89-
std::sort(songs.begin(), songs.end(), sortTitle);
9093
std::sort(songs.begin(), songs.end(), sortLen);
9194
break;
9295
case SortType::Year:
@@ -99,7 +102,11 @@ void SongList::sortList(SortType sortType) {
99102
}
100103

101104
void SongList::sortList(SortType sortType, int &selectedSong) {
102-
Song &curSong = songs[selectedSong];
105+
Song curSong;
106+
bool hasCurrentSong = selectedSong >= 0 && selectedSong < songs.size();
107+
if (hasCurrentSong) {
108+
curSong = songs[selectedSong];
109+
}
103110
selectedSong = 0;
104111
switch (sortType) {
105112
case SortType::Title:
@@ -114,7 +121,6 @@ void SongList::sortList(SortType sortType, int &selectedSong) {
114121
std::sort(songs.begin(), songs.end(), sortSource);
115122
break;
116123
case SortType::Length:
117-
std::sort(songs.begin(), songs.end(), sortTitle);
118124
std::sort(songs.begin(), songs.end(), sortLen);
119125
break;
120126
case SortType::Year:
@@ -123,10 +129,12 @@ void SongList::sortList(SortType sortType, int &selectedSong) {
123129
break;
124130
default:;
125131
}
126-
for (int i = 0; i < songs.size(); i++) {
127-
if (songs[i].artist == curSong.artist && songs[i].title == curSong.title) {
128-
selectedSong = i;
129-
break;
132+
if (hasCurrentSong) {
133+
for (size_t i = 0; i < songs.size(); i++) {
134+
if (songs[i].artist == curSong.artist && songs[i].title == curSong.title) {
135+
selectedSong = i;
136+
break;
137+
}
130138
}
131139
}
132140
listMenuEntries = GenerateSongEntriesWithHeaders(songs, sortType);
@@ -180,82 +188,157 @@ void SongList::ScanSongs(const std::vector<std::filesystem::path> &songsFolder)
180188
}
181189

182190
directoryCount++;
183-
if (std::filesystem::exists(entry.path() / "info.json")) {
184-
Song song;
185-
song.LoadSong(entry.path() / "info.json");
186-
songs.push_back(std::move(song));
187-
songCount++;
191+
Song song;
192+
std::filesystem::path infoPath = entry.path() / "info.json";
193+
if (std::filesystem::exists(infoPath)) {
194+
song.LoadSong(infoPath);
195+
try {
196+
json infoData;
197+
std::ifstream infoFile(infoPath);
198+
infoFile >> infoData;
199+
infoFile.close();
200+
201+
if (infoData.contains("source") && infoData["source"].is_string()) {
202+
song.source = infoData["source"].get<std::string>();
203+
if (song.source.empty()) {
204+
song.source = "Unknown Source";
205+
}
206+
} else {
207+
song.source = "Unknown Source";
208+
}
209+
210+
if (infoData.contains("release_year") && infoData["release_year"].is_string()) {
211+
song.releaseYear = infoData["release_year"].get<std::string>();
212+
if (song.releaseYear.empty()) {
213+
song.releaseYear = "Unknown Year";
214+
}
215+
} else {
216+
song.releaseYear = "Unknown Year";
217+
}
218+
219+
if (infoData.contains("preview_start_time") && infoData["preview_start_time"].is_number_integer()) {
220+
song.previewStartTime = infoData["preview_start_time"].get<int>();
221+
} else {
222+
song.previewStartTime = 3000;
223+
}
224+
225+
} catch (const std::exception& e) {
226+
song.source = "Unknown Source";
227+
song.releaseYear = "Unknown Year";
228+
song.previewStartTime = 500;
229+
}
188230
} else if (std::filesystem::exists(entry.path() / "song.ini")) {
189-
Song song;
190-
191231
song.songInfoPath = (entry.path() / "song.ini").string();
192232
song.songDir = entry.path().string();
193233
song.LoadSongIni(entry.path());
194234
song.ini = true;
195-
songs.push_back(std::move(song));
196-
songCount++;
235+
if (std::filesystem::exists(infoPath)) {
236+
try {
237+
json infoData;
238+
std::ifstream infoFile(infoPath);
239+
infoFile >> infoData;
240+
infoFile.close();
241+
242+
if (infoData.contains("source") && infoData["source"].is_string()) {
243+
song.source = infoData["source"].get<std::string>();
244+
if (song.source.empty()) {
245+
song.source = "Unknown Source";
246+
}
247+
} else {
248+
song.source = "Unknown Source";
249+
}
250+
251+
if (infoData.contains("release_year") && infoData["release_year"].is_string()) {
252+
song.releaseYear = infoData["release_year"].get<std::string>();
253+
if (song.releaseYear.empty()) {
254+
song.releaseYear = "Unknown Year";
255+
}
256+
} else {
257+
song.releaseYear = "Unknown Year";
258+
}
259+
260+
if (infoData.contains("preview_start_time") && infoData["preview_start_time"].is_number_integer()) {
261+
song.previewStartTime = infoData["preview_start_time"].get<int>();
262+
} else {
263+
song.previewStartTime = 500;
264+
}
265+
266+
Encore::EncoreLog(LOG_INFO, TextFormat("CACHE: Read metadata for INI song %s - %s from %s", song.title.c_str(), song.artist.c_str(), infoPath.string().c_str()));
267+
} catch (const std::exception& e) {
268+
Encore::EncoreLog(LOG_ERROR, TextFormat("CACHE: Failed to read metadata for INI song %s - %s from %s: %s", song.title.c_str(), song.artist.c_str(), infoPath.string().c_str(), e.what()));
269+
song.source = "Unknown Source";
270+
song.releaseYear = "Unknown Year";
271+
song.previewStartTime = 500;
272+
}
273+
} else {
274+
song.source = "Unknown Source";
275+
song.releaseYear = "Unknown Year";
276+
song.previewStartTime = 500;
277+
Encore::EncoreLog(LOG_INFO, TextFormat("CACHE: No info.json for INI song %s - %s, using default metadata", song.title.c_str(), song.artist.c_str()));
278+
}
279+
} else {
280+
continue;
197281
}
282+
283+
songs.push_back(std::move(song));
284+
songCount++;
198285
}
199286
}
200287

201288
Encore::EncoreLog(LOG_INFO, "CACHE: Rewriting song cache");
202289
WriteCache();
203290
}
204291

292+
std::string GetLengthHeader(int length) {
293+
if (length < 60) return "< 1:00";
294+
if (length < 120) return "1:00-2:00";
295+
if (length < 180) return "2:00-3:00";
296+
if (length < 240) return "3:00-4:00";
297+
if (length < 300) return "4:00-5:00";
298+
return "5:00+";
299+
}
300+
205301
std::vector<ListMenuEntry> SongList::GenerateSongEntriesWithHeaders(
206302
const std::vector<Song> &songs, SortType sortType
207303
) {
208304
std::vector<ListMenuEntry> songEntries;
209305
std::string currentHeader = "";
210306
int pos = 0;
211-
for (int i = 0; i < songs.size(); i++) {
307+
for (size_t i = 0; i < songs.size(); i++) {
212308
const Song &song = songs[i];
309+
std::string header;
213310
switch (sortType) {
214311
case SortType::Title: {
215312
std::string title = removeArticle(TextToLower(song.title.c_str()));
216-
if (toupper(title[0]) != currentHeader[0]) {
217-
currentHeader = toupper(title[0]);
218-
songEntries.emplace_back(true, 0, currentHeader, false);
219-
pos++;
220-
}
313+
header = title.empty() ? "#" : std::string(1, toupper(title[0]));
221314
break;
222315
}
223316
case SortType::Artist: {
224317
std::string artist = removeArticle(song.artist);
225-
if (artist != currentHeader) {
226-
currentHeader = song.artist;
227-
songEntries.emplace_back(true, 0, currentHeader, false);
228-
pos++;
229-
}
318+
header = artist.empty() ? "#" : artist;
230319
break;
231320
}
232321
case SortType::Source: {
233322
std::string source = removeArticle(song.source);
234-
if (source != currentHeader) {
235-
currentHeader = song.source;
236-
songEntries.emplace_back(true, 0, currentHeader, false);
237-
pos++;
238-
}
323+
header = source.empty() ? "Unknown" : source;
239324
break;
240325
}
241326
case SortType::Length: {
242-
if (std::to_string(song.length) != currentHeader) {
243-
currentHeader = std::to_string(song.length);
244-
songEntries.emplace_back(true, 0, currentHeader, false);
245-
pos++;
246-
}
327+
header = GetLengthHeader(song.length);
247328
break;
248329
}
249330
case SortType::Year: {
250-
std::string year = removeArticle(song.releaseYear);
251-
if (year != currentHeader) {
252-
currentHeader = song.releaseYear;
253-
songEntries.emplace_back(true, 0, currentHeader, false);
254-
pos++;
255-
}
331+
header = song.releaseYear.empty() ? "Unknown Year" : song.releaseYear;
256332
break;
257333
}
258-
default:;
334+
default:
335+
header = "#";
336+
break;
337+
}
338+
if (header != currentHeader) {
339+
currentHeader = header;
340+
songEntries.emplace_back(true, 0, currentHeader, false);
341+
pos++;
259342
}
260343
songEntries.emplace_back(false, i, "", false);
261344
pos++;
@@ -404,4 +487,4 @@ void SongList::LoadCache(const std::vector<std::filesystem::path> &songsFolder)
404487

405488
// ScanSongs(songsFolder);
406489
sortList(SortType::Title);
407-
}
490+
}

0 commit comments

Comments
 (0)