Adapting music to web, fixing scripts, fixing bug in initial state

This commit is contained in:
Vladislav Khorev committed 2026-07-24 23:58:29 +03:00
1 parent c3f449b999
commit 5ecf5fb9d7
43 files changed
+875 -388

No files matched your search

+103 -27
View File
@@ -36,8 +36,10 @@ namespace FRG
#ifdef EMSCRIPTEN
const char* CONST_ZIP_FILE = "resources.zip";
const char* CONST_MUSIC_ZIP_FILE = "music.zip";
#else
const char* CONST_ZIP_FILE = "";
const char* CONST_MUSIC_ZIP_FILE = "";
#endif
float x = 0;
@@ -47,25 +49,29 @@ namespace FRG
#ifdef EMSCRIPTEN
Game* Game::s_instance = nullptr;
// Коллбэк успешной загрузки resources.zip
void Game::onResourcesZipLoaded(unsigned /*handle*/, void* /*userData*/, const char* /*filename*/) {
logger() << "Resources.zip loaded successfully--0" << std::endl;
logger() << "Resources.zip downloaded successfully to VFS" << std::endl;
// Синхронизируем MemFS -> IndexedDB, чтобы файл сохранился между сессиями браузера
FRG::emscriptenSyncFs();
if (s_instance) {
s_instance->resourcesDownloadProgress = 1.0f;
// Builds the loadSteps queue (cheap, no GL work); the actual loading
// happens one step per frame in Game::update() so the browser tab
// keeps repainting/responding instead of freezing for the whole load.
s_instance->setupPart2();
}
}
void Game::onResourcesZipError(unsigned /*handle*/, void* /*userData*/, int /*httpStatus*/) {
logger() << "Failed to download resources.zip" << std::endl;
void Game::onResourcesZipError(unsigned /*handle*/, void* /*userData*/, int httpStatus) {
logger() << "Failed to download resources.zip, HTTP status: " << httpStatus << std::endl;
// Можно обработать ошибку или предложить пользователю перезагрузить страницу
}
void Game::onResourcesZipProgress(unsigned /*handle*/, void* /*userData*/, int percentComplete) {
if (s_instance)
s_instance->resourcesDownloadProgress = percentComplete / 100.0f;
}
#endif
Location* Game::currentLocation() const {
@@ -133,12 +139,53 @@ namespace FRG
loadingMesh.RefreshVBO();
#ifdef EMSCRIPTEN
// Asynchronously download resources.zip; setupPart2() is called on completion.
// The loading screen stays visible until the download finishes.
s_instance = this;
logger() << "Load resurces step 1-" << std::endl;
emscripten_async_wget2("resources.zip", "resources.zip", "GET", nullptr, nullptr,
onResourcesZipLoaded, onResourcesZipError, onResourcesZipProgress);
std::string resPath = FRG::getPersistentResourcePath("resources.zip");
std::string musicPath = FRG::getPersistentResourcePath("music.zip");
// 1. Проверяем ресурсы (resources.zip)
if (FRG::isZipValid(resPath)) {
logger() << "[Load] Valid resources.zip found in IndexedDB cache: " << resPath << std::endl;
resourcesDownloadProgress = 1.0f;
// Архив уже есть и цел — переходим сразу к разбору/загрузке
setupPart2();
}
else {
logger() << "[Load] Resources.zip missing or corrupt. Downloading to: " << resPath << std::endl;
// Скачиваем сразу в постоянный путь /offline/resources.zip
emscripten_async_wget2(
"resources.zip", // URL на сервере
resPath.c_str(), // Назначение в VFS Emscripten
"GET",
nullptr,
nullptr,
onResourcesZipLoaded,
onResourcesZipError,
onResourcesZipProgress
);
}
/*
// 2. Проверяем музыку (music.zip)
if (FRG::isZipValid(musicPath)) {
logger() << "[Load] Valid music.zip found in IndexedDB cache." << std::endl;
}
else {
logger() << "[Load] Music.zip missing or corrupt. Downloading to: " << musicPath << std::endl;
emscripten_async_wget2(
"music.zip",
musicPath.c_str(),
"GET",
nullptr,
nullptr,
onMusicZipLoaded,
onMusicZipError,
onMusicZipProgress
);
}*/
#else
// Builds the loadSteps queue (cheap, no GL work); the actual loading
// happens one step per frame in Game::update() so the window keeps
@@ -299,12 +346,12 @@ namespace FRG
menuManager.onItemPickedUp(itemId);
const Item* item = ItemRegistry::instance().findById(itemId);
if (item) menuManager.showToast(menuManager.toastTextureItemAdded, item->name);
audioPlayer->playSoundAsync("audio/831642__ienba__generic-game-pick-up.ogg");
audioPlayer->playSoundAsync("resources/audio/831642__ienba__generic-game-pick-up.ogg");
};
gameState.inventory.onItemRemoved = [this](const std::string& itemId) {
const Item* item = ItemRegistry::instance().findById(itemId);
if (item) menuManager.showToast(menuManager.toastTextureItemRemoved, item->name);
audioPlayer->playSoundAsync("audio/831642__ienba__generic-game-pick-up.ogg");
audioPlayer->playSoundAsync("resources/audio/831642__ienba__generic-game-pick-up.ogg");
};
// Wire phone dialogue start function so MenuManager can trigger dialogues.
@@ -344,7 +391,8 @@ namespace FRG
performResetToInitialState();
gameState.currentLocationName = "location_dorm";
currentLocation()->scriptEngine.callLocationEnterCallback();
this->audioPlayer->crossFadeMusicAsync("audio/obshaga.ogg");
this->audioPlayer->crossFadeMusicAsync("music/obshaga.ogg");
menuManager.lastMusicTrack = "music/obshaga.ogg";
});
};
@@ -392,7 +440,8 @@ namespace FRG
loadSteps.push([this]() {
menuManager.loadSettings();
audioPlayer->crossFadeMusicAsync("audio/main menu final.ogg");
audioPlayer->crossFadeMusicAsync("music/main menu final.ogg");
menuManager.lastMusicTrack = "music/main menu final.ogg";
});
@@ -465,7 +514,21 @@ namespace FRG
void Game::performResetToInitialState() {
const std::string path = "resources/config/start_state.json";
const std::string content = FRG::readTextFile(path);
std::vector<char> fileData;
if (strlen(CONST_ZIP_FILE) > 0)
{
fileData = readFileFromZIP(path, CONST_ZIP_FILE);
}
else
{
fileData = readFile(path);
}
std::string content(fileData.begin(), fileData.end());
//const std::vector<char> contentVector = FRG::readFileFromZIP();
//const std::string content = FRG::readTextFile(path);
if (!content.empty()) {
try {
nlohmann::json root = nlohmann::json::parse(content);
@@ -485,10 +548,14 @@ namespace FRG
rearmDormOneShotCallbacks();
return;
} catch (const std::exception& e) {
std::cerr << "[reset] Failed to parse " << path << ": " << e.what()
logger() << "[reset] Failed to parse " << path << ": " << e.what()
<< " -- falling back to full rebuild" << std::endl;
}
}
else
{
logger() << "File " << path << " is empty -- falling back to full rebuild" << std::endl;
}
performFullReset();
}
@@ -616,10 +683,12 @@ namespace FRG
}
gameState.locations["uni_interior"]->requestDarklandsPlayBattleMusic = [this]() {
audioPlayer->crossFadeMusicFromPositionAsync("audio/bishkek fight.ogg");
audioPlayer->crossFadeMusicFromPositionAsync("music/bishkek fight.ogg");
menuManager.lastMusicTrack = "music/bishkek fight.ogg";
};
gameState.locations["uni_interior"]->requestDarklandsPlayNormalMusic = [this]() {
audioPlayer->crossFadeMusicFromPositionAsync("audio/bishkek fight calm.ogg");
audioPlayer->crossFadeMusicFromPositionAsync("music/bishkek fight calm.ogg");
menuManager.lastMusicTrack = "music/bishkek fight calm.ogg";
};
}
@@ -1679,7 +1748,7 @@ namespace FRG
return false;
}
audioPlayer->playSoundAsync("audio/459618__n-lerche__blow.ogg");
audioPlayer->playSoundAsync("resources/audio/459618__n-lerche__blow.ogg");
if (darklandsFlashActive) return false;
darklandsFlashActive = true;
darklandsFlashFadingIn = true;
@@ -1715,7 +1784,8 @@ namespace FRG
currentLocation()->scriptEngine.callTriggerNightEnterCallback();
}
audioPlayer->crossFadeMusicAsync("audio/bishkek night.ogg");
audioPlayer->crossFadeMusicAsync("music/bishkek night.ogg");
menuManager.lastMusicTrack = "music/bishkek night.ogg";
} else {
gameState.isDarklands = !gameState.isDarklands;
@@ -1725,11 +1795,13 @@ namespace FRG
if (gameState.isDarklands)
{
audioPlayer->crossFadeMusicAsync("audio/bishkek fight calm.ogg");
audioPlayer->crossFadeMusicAsync("music/bishkek fight calm.ogg");
menuManager.lastMusicTrack = "music/bishkek fight calm.ogg";
}
else
{
audioPlayer->crossFadeMusicAsync("audio/bishkek night.ogg");
audioPlayer->crossFadeMusicAsync("music/bishkek night.ogg");
menuManager.lastMusicTrack = "music/bishkek night.ogg";
}
if (currentLocation()) {
@@ -1845,20 +1917,24 @@ namespace FRG
if (gameState.isDarklands)
{
audioPlayer->crossFadeMusicAsync("audio/bishkek fight calm.ogg");
audioPlayer->crossFadeMusicAsync("music/bishkek fight calm.ogg");
menuManager.lastMusicTrack = "music/bishkek fight calm.ogg";
}
else if (gameState.isNight)
{
audioPlayer->crossFadeMusicAsync("audio/bishkek night.ogg");
audioPlayer->crossFadeMusicAsync("music/bishkek night.ogg");
menuManager.lastMusicTrack = "music/bishkek night.ogg";
}
else
{
if (gameState.currentLocationName == "location_dorm") {
audioPlayer->crossFadeMusicAsync("audio/obshaga.ogg");
audioPlayer->crossFadeMusicAsync("music/obshaga.ogg");
menuManager.lastMusicTrack = "music/obshaga.ogg";
}
else
{
audioPlayer->crossFadeMusicAsync("audio/bishkek univer day.ogg");
audioPlayer->crossFadeMusicAsync("music/bishkek univer day.ogg");
menuManager.lastMusicTrack = "music/bishkek univer day.ogg";
}
}
}