341 lines
9.5 KiB
Plaintext
341 lines
9.5 KiB
Plaintext
#include "audio_paths.nvgt"
|
|
|
|
funcdef void learn_sounds_speak_callback(const string &in message, bool interrupt);
|
|
funcdef void learn_sounds_tick_callback();
|
|
funcdef void learn_sounds_setup_callback();
|
|
|
|
learn_sounds_speak_callback@ learnSoundsSpeakCallback = null;
|
|
learn_sounds_tick_callback@ learnSoundsTickCallback = null;
|
|
learn_sounds_setup_callback@ learnSoundsSetupCallback = null;
|
|
|
|
string[] learnSoundsSkipList;
|
|
string[] learnSoundsDescriptionPaths;
|
|
string[] learnSoundsDescriptionTexts;
|
|
|
|
string learnSoundsRootDir = "sounds";
|
|
string learnSoundsMenuSoundDir = "sounds/menu";
|
|
bool learnSoundsWrap = true;
|
|
bool learnSoundsPlaySelectSound = true;
|
|
bool learnSoundsSetupApplied = false;
|
|
|
|
sound learnSoundsPreviewSound;
|
|
sound learnSoundsMoveSound;
|
|
sound learnSoundsSelectSound;
|
|
|
|
void learn_sounds_set_speak_callback(learn_sounds_speak_callback@ callback) {
|
|
@learnSoundsSpeakCallback = @callback;
|
|
}
|
|
|
|
void learn_sounds_set_tick_callback(learn_sounds_tick_callback@ callback) {
|
|
@learnSoundsTickCallback = @callback;
|
|
}
|
|
|
|
void learn_sounds_set_setup_callback(learn_sounds_setup_callback@ callback) {
|
|
@learnSoundsSetupCallback = @callback;
|
|
learnSoundsSetupApplied = false;
|
|
}
|
|
|
|
void learn_sounds_set_root_dir(const string rootDir) {
|
|
learnSoundsRootDir = rootDir;
|
|
}
|
|
|
|
void learn_sounds_set_menu_sound_dir(const string menuSoundDir) {
|
|
learnSoundsMenuSoundDir = menuSoundDir;
|
|
}
|
|
|
|
void learn_sounds_set_wrap(bool wrap) {
|
|
learnSoundsWrap = wrap;
|
|
}
|
|
|
|
void learn_sounds_set_play_select_sound(bool playSelectSound) {
|
|
learnSoundsPlaySelectSound = playSelectSound;
|
|
}
|
|
|
|
void learn_sounds_clear_skip_entries() {
|
|
learnSoundsSkipList.resize(0);
|
|
}
|
|
|
|
void learn_sounds_add_skip_entry(const string entry) {
|
|
if (entry == "") {
|
|
return;
|
|
}
|
|
learnSoundsSkipList.insert_last(entry);
|
|
}
|
|
|
|
void learn_sounds_clear_descriptions() {
|
|
learnSoundsDescriptionPaths.resize(0);
|
|
learnSoundsDescriptionTexts.resize(0);
|
|
}
|
|
|
|
void learn_sounds_add_description(const string soundPath, const string description) {
|
|
if (soundPath == "") {
|
|
return;
|
|
}
|
|
learnSoundsDescriptionPaths.insert_last(soundPath);
|
|
learnSoundsDescriptionTexts.insert_last(description);
|
|
}
|
|
|
|
void learn_sounds_reset_configuration() {
|
|
learn_sounds_clear_skip_entries();
|
|
learn_sounds_clear_descriptions();
|
|
learnSoundsSetupApplied = false;
|
|
}
|
|
|
|
void learn_sounds_speak(const string &in message, bool interrupt) {
|
|
if (@learnSoundsSpeakCallback !is null) {
|
|
learnSoundsSpeakCallback(message, interrupt);
|
|
return;
|
|
}
|
|
screen_reader_speak(message, interrupt);
|
|
}
|
|
|
|
void learn_sounds_tick() {
|
|
if (@learnSoundsTickCallback !is null) {
|
|
learnSoundsTickCallback();
|
|
}
|
|
}
|
|
|
|
void learn_sounds_apply_setup_once() {
|
|
if (learnSoundsSetupApplied) {
|
|
return;
|
|
}
|
|
|
|
if (@learnSoundsSetupCallback !is null) {
|
|
learnSoundsSetupCallback();
|
|
}
|
|
|
|
learnSoundsSetupApplied = true;
|
|
}
|
|
|
|
string learn_sounds_normalize_path(const string&in path) {
|
|
return path.replace("\\", "/", true);
|
|
}
|
|
|
|
bool learn_sounds_is_directory_skip_entry(const string&in entry) {
|
|
if (entry.length() == 0) return false;
|
|
if (entry.substr(entry.length() - 1) == "/") return true;
|
|
return directory_exists(entry);
|
|
}
|
|
|
|
bool learn_sounds_should_skip_path(const string&in path) {
|
|
string normalizedPath = learn_sounds_normalize_path(path);
|
|
for (uint skipIndex = 0; skipIndex < learnSoundsSkipList.length(); skipIndex++) {
|
|
string entry = learn_sounds_normalize_path(learnSoundsSkipList[skipIndex]);
|
|
if (entry.length() == 0) continue;
|
|
|
|
bool isDirectory = learn_sounds_is_directory_skip_entry(entry);
|
|
if (isDirectory) {
|
|
if (entry.substr(entry.length() - 1) != "/") entry += "/";
|
|
if (normalizedPath.length() >= entry.length() &&
|
|
normalizedPath.substr(0, entry.length()) == entry) {
|
|
return true;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (normalizedPath == entry) return true;
|
|
|
|
if (entry.find_first("/") < 0 && entry.find_first("\\") < 0) {
|
|
if (normalizedPath.length() >= entry.length() + 1 &&
|
|
normalizedPath.substr(normalizedPath.length() - entry.length()) == entry) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
string learn_sounds_get_description(const string&in path) {
|
|
string normalizedPath = learn_sounds_normalize_path(path);
|
|
uint descriptionCount = learnSoundsDescriptionPaths.length();
|
|
if (learnSoundsDescriptionTexts.length() < descriptionCount) {
|
|
descriptionCount = learnSoundsDescriptionTexts.length();
|
|
}
|
|
|
|
for (uint descriptionIndex = 0; descriptionIndex < descriptionCount; descriptionIndex++) {
|
|
if (learn_sounds_normalize_path(learnSoundsDescriptionPaths[descriptionIndex]) == normalizedPath) {
|
|
return learnSoundsDescriptionTexts[descriptionIndex];
|
|
}
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
void learn_sounds_gather_files_recursive(const string&in basePath, string[]@ outFiles) {
|
|
string[]@ oggFiles = find_files(basePath + "/*.ogg");
|
|
if (@oggFiles !is null) {
|
|
for (uint fileIndex = 0; fileIndex < oggFiles.length(); fileIndex++) {
|
|
outFiles.insert_last(basePath + "/" + oggFiles[fileIndex]);
|
|
}
|
|
}
|
|
|
|
string[]@ oggUpperFiles = find_files(basePath + "/*.OGG");
|
|
if (@oggUpperFiles !is null) {
|
|
for (uint fileIndex = 0; fileIndex < oggUpperFiles.length(); fileIndex++) {
|
|
outFiles.insert_last(basePath + "/" + oggUpperFiles[fileIndex]);
|
|
}
|
|
}
|
|
|
|
string[]@ wavFiles = find_files(basePath + "/*.wav");
|
|
if (@wavFiles !is null) {
|
|
for (uint fileIndex = 0; fileIndex < wavFiles.length(); fileIndex++) {
|
|
outFiles.insert_last(basePath + "/" + wavFiles[fileIndex]);
|
|
}
|
|
}
|
|
|
|
string[]@ wavUpperFiles = find_files(basePath + "/*.WAV");
|
|
if (@wavUpperFiles !is null) {
|
|
for (uint fileIndex = 0; fileIndex < wavUpperFiles.length(); fileIndex++) {
|
|
outFiles.insert_last(basePath + "/" + wavUpperFiles[fileIndex]);
|
|
}
|
|
}
|
|
|
|
string[]@ folders = find_directories(basePath + "/*");
|
|
if (@folders !is null) {
|
|
for (uint folderIndex = 0; folderIndex < folders.length(); folderIndex++) {
|
|
learn_sounds_gather_files_recursive(basePath + "/" + folders[folderIndex], outFiles);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool learn_sounds_sort_case_insensitive(const string &in a, const string &in b) {
|
|
return a.lower() < b.lower();
|
|
}
|
|
|
|
string learn_sounds_collapse_spaces(const string&in text) {
|
|
string result = text;
|
|
while (result.find_first(" ") > -1) {
|
|
result = result.replace(" ", " ", true);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
string learn_sounds_label_from_path(const string&in soundPath) {
|
|
string normalizedPath = learn_sounds_normalize_path(soundPath);
|
|
int slashPos = normalizedPath.find_last_of("/");
|
|
string name = (slashPos >= 0) ? normalizedPath.substr(slashPos + 1) : normalizedPath;
|
|
|
|
string lowerName = name.lower();
|
|
if (lowerName.length() > 4 && lowerName.substr(lowerName.length() - 4) == ".ogg") {
|
|
name = name.substr(0, name.length() - 4);
|
|
} else if (lowerName.length() > 4 && lowerName.substr(lowerName.length() - 4) == ".wav") {
|
|
name = name.substr(0, name.length() - 4);
|
|
}
|
|
|
|
name = name.replace("_", " ", true);
|
|
name = name.replace("-", " ", true);
|
|
name = learn_sounds_collapse_spaces(name);
|
|
name = name.lower();
|
|
name.trim_whitespace_this();
|
|
|
|
if (name.length() == 0) return "Sound";
|
|
return name;
|
|
}
|
|
|
|
void learn_sounds_collect_entries(string[]@ labels, string[]@ soundPaths) {
|
|
labels.resize(0);
|
|
soundPaths.resize(0);
|
|
|
|
if (!directory_exists(learnSoundsRootDir)) {
|
|
return;
|
|
}
|
|
|
|
string[] discoveredFiles;
|
|
learn_sounds_gather_files_recursive(learnSoundsRootDir, discoveredFiles);
|
|
if (discoveredFiles.length() > 1) {
|
|
discoveredFiles.sort(learn_sounds_sort_case_insensitive);
|
|
}
|
|
|
|
for (uint fileIndex = 0; fileIndex < discoveredFiles.length(); fileIndex++) {
|
|
string soundPath = learn_sounds_normalize_path(discoveredFiles[fileIndex]);
|
|
if (learn_sounds_should_skip_path(soundPath)) {
|
|
continue;
|
|
}
|
|
|
|
string label = learn_sounds_label_from_path(soundPath);
|
|
string description = learn_sounds_get_description(soundPath);
|
|
if (description.length() > 0) {
|
|
label += " - " + description;
|
|
}
|
|
|
|
labels.insert_last(label);
|
|
soundPaths.insert_last(soundPath);
|
|
}
|
|
}
|
|
|
|
void learn_sounds_play_ui_sound(sound &inout soundObj, const string basePath) {
|
|
string soundPath = resolve_audio_path(basePath);
|
|
if (soundPath == "") {
|
|
return;
|
|
}
|
|
|
|
soundObj.close();
|
|
if (!soundObj.load(soundPath)) {
|
|
return;
|
|
}
|
|
soundObj.play();
|
|
}
|
|
|
|
void learn_sounds_run_menu() {
|
|
learn_sounds_apply_setup_once();
|
|
|
|
string[] labels;
|
|
string[] soundPaths;
|
|
learn_sounds_collect_entries(labels, soundPaths);
|
|
|
|
learn_sounds_speak("Learn sounds.", true);
|
|
if (labels.length() == 0) {
|
|
learn_sounds_speak("No sounds available.", true);
|
|
return;
|
|
}
|
|
|
|
int selection = 0;
|
|
learn_sounds_speak(labels[selection], true);
|
|
|
|
while (true) {
|
|
wait(5);
|
|
learn_sounds_tick();
|
|
|
|
if (key_pressed(KEY_ESCAPE)) {
|
|
learn_sounds_speak("Closed.", true);
|
|
return;
|
|
}
|
|
|
|
if (key_pressed(KEY_DOWN)) {
|
|
learn_sounds_play_ui_sound(learnSoundsMoveSound, learnSoundsMenuSoundDir + "/menu_move");
|
|
selection++;
|
|
if (selection >= int(labels.length())) {
|
|
selection = learnSoundsWrap ? 0 : int(labels.length()) - 1;
|
|
}
|
|
learn_sounds_speak(labels[selection], true);
|
|
}
|
|
|
|
if (key_pressed(KEY_UP)) {
|
|
learn_sounds_play_ui_sound(learnSoundsMoveSound, learnSoundsMenuSoundDir + "/menu_move");
|
|
selection--;
|
|
if (selection < 0) {
|
|
selection = learnSoundsWrap ? int(labels.length()) - 1 : 0;
|
|
}
|
|
learn_sounds_speak(labels[selection], true);
|
|
}
|
|
|
|
if (key_pressed(KEY_RETURN)) {
|
|
if (learnSoundsPlaySelectSound) {
|
|
learn_sounds_play_ui_sound(learnSoundsSelectSound, learnSoundsMenuSoundDir + "/menu_select");
|
|
}
|
|
string selectedPath = soundPaths[selection];
|
|
if (!file_exists(selectedPath)) {
|
|
learn_sounds_speak("Sound not found.", true);
|
|
continue;
|
|
}
|
|
|
|
learnSoundsPreviewSound.close();
|
|
if (!learnSoundsPreviewSound.load(selectedPath)) {
|
|
learn_sounds_speak("Unable to load sound.", true);
|
|
continue;
|
|
}
|
|
learnSoundsPreviewSound.play();
|
|
}
|
|
}
|
|
}
|