Fix async loading bugs with loading from indexeddb store emscripten. Add emscripten debug and release scripts. Disable text entry whenever a menu is closed.

pull/35/head
sigonasr2 12 months ago
parent 9163eecd4a
commit e036302b58
  1. 6
      Adventures in Lestoria.sln
  2. 46
      Adventures in Lestoria/Adventures in Lestoria.vcxproj
  3. 2
      Adventures in Lestoria/LoadGameWindow.cpp
  4. 1
      Adventures in Lestoria/MainMenuWindow.cpp
  5. 1
      Adventures in Lestoria/Menu.cpp
  6. 1
      Adventures in Lestoria/Menu.h
  7. 185
      Adventures in Lestoria/SaveFile.cpp
  8. 2
      Adventures in Lestoria/Version.h
  9. 6
      Adventures in Lestoria/emscripten_debug_build.ps1
  10. 4
      CMakeLists.txt
  11. 2
      emscripten_build.ps1
  12. 3
      emscripten_debug_build.ps1

@ -9,6 +9,8 @@ Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Emscripten Debug|x64 = Emscripten Debug|x64
Emscripten Debug|x86 = Emscripten Debug|x86
Emscripten|x64 = Emscripten|x64
Emscripten|x86 = Emscripten|x86
Release Desktop|x64 = Release Desktop|x64
@ -21,6 +23,10 @@ Global
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Debug|x64.Build.0 = Debug|x64
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Debug|x86.ActiveCfg = Debug|Win32
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Debug|x86.Build.0 = Debug|Win32
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Emscripten Debug|x64.ActiveCfg = Emscripten Debug|x64
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Emscripten Debug|x64.Build.0 = Emscripten Debug|x64
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Emscripten Debug|x86.ActiveCfg = Emscripten Debug|Win32
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Emscripten Debug|x86.Build.0 = Emscripten Debug|Win32
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Emscripten|x64.ActiveCfg = Emscripten|x64
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Emscripten|x64.Build.0 = Emscripten|x64
{8E3067AF-CFE7-4B11-BC6B-B867C32753D7}.Emscripten|x86.ActiveCfg = Emscripten|Win32

@ -5,6 +5,14 @@
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Emscripten Debug|Win32">
<Configuration>Emscripten Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Emscripten Debug|x64">
<Configuration>Emscripten Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Emscripten|Win32">
<Configuration>Emscripten</Configuration>
<Platform>Win32</Platform>
@ -86,9 +94,15 @@
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Emscripten|Win32'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Emscripten Debug|Win32'" Label="Configuration">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Emscripten|x64'">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Emscripten Debug|x64'" Label="Configuration">
<PlatformToolset>v143</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
@ -286,6 +300,22 @@
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -File emscripten_build.ps1</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Emscripten Debug|Win32'">
<Link>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>$(CoreLibraryDependencies);%(AdditionalDependencies);discord_game_sdk.dll.lib</AdditionalDependencies>
</Link>
<ClCompile>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;</AdditionalIncludeDirectories>
</ClCompile>
<PostBuildEvent>
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File ../emscripten_debug_build.ps1</Command>
</PostBuildEvent>
<PreBuildEvent>
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -File emscripten_debug_build.ps1</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Emscripten|x64'">
<Link>
<SubSystem>Console</SubSystem>
@ -302,6 +332,22 @@
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -File emscripten_build.ps1</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Emscripten Debug|x64'">
<Link>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>$(CoreLibraryDependencies);%(AdditionalDependencies);discord_game_sdk.dll.lib</AdditionalDependencies>
</Link>
<ClCompile>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\AdventuresInLestoria\Adventures in Lestoria\discord-files;</AdditionalIncludeDirectories>
</ClCompile>
<PostBuildEvent>
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File ../emscripten_debug_build.ps1</Command>
</PostBuildEvent>
<PreBuildEvent>
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -File emscripten_debug_build.ps1</Command>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="Ability.h" />
<ClInclude Include="Animation.h" />

@ -45,6 +45,8 @@ void Menu::InitializeLoadGameWindow(){
loadGameWindow->ADD("Game Files Label",MenuLabel)(geom2d::rect<float>{{-8,-12},{112,12}},"Load Game",1.0f,ComponentAttr::SHADOW|ComponentAttr::OUTLINE|ComponentAttr::BACKGROUND)END;
loadGameWindow->ADD("Game Files List",ScrollableWindowComponent)(geom2d::rect<float>{{-8,4},{112,116}})END;
loadGameWindow->ADD("Online Game Files List",ScrollableWindowComponent)(geom2d::rect<float>{{-8,4},{112,116}})END
->Enable(false);
loadGameWindow->ADD("Go Back Button",MenuComponent)(geom2d::rect<float>{{24,124},{48,12}},"Back",[](MenuFuncData menu){Menu::CloseMenu();return true;})END;

@ -69,7 +69,6 @@ void Menu::InitializeMainMenuWindow(){
Menu::OpenMenu(USER_ID);
}else{
SaveFile::UpdateSaveGameData();
Menu::OpenMenu(LOAD_GAME);
}
#else
SaveFile::UpdateSaveGameData();

@ -571,6 +571,7 @@ vf2d Menu::center(){
}
void Menu::CloseMenu(){
game->TextEntryEnable(false);
if(stack.size()>0){
stack.pop_back();
}else{

@ -185,7 +185,6 @@ public:
//X (0-2), Y (0-2) for specific 9-patch tile (tiled version).
static Renderable&GetPatchPart(int x,int y);
void RecalculateComponentCount();
void SetSelection(std::string_view button,const bool scroll=true,const bool reset=false); // Use the reset parameter when a window is opening up, as this will cause the window now to scroll to its previous target.
void SetSelection(std::weak_ptr<MenuComponent>button,const bool scroll=true,const bool reset=false); // Use the reset parameter when a window is opening up, as this will cause the window now to scroll to its previous target.
void SetSelection(std::variant<std::string,std::weak_ptr<MenuComponent>>button,const bool reset=false); // Use the reset parameter when a window is opening up, as this will cause the window now to scroll to its previous target.

@ -109,8 +109,9 @@ const void SaveFile::SaveGame(){
saveFile["Chapter"].SetInt(game->GetCurrentChapter());
saveFile["Save Name"].SetString(std::string(GetSaveFileName()));
saveFile["Game Time"].SetReal(game->GetRuntime());
utils::datafile::Write(saveFile,"save_file_path"_S+std::format("save.{:04}",saveFileID));
if(!onlineMode){
utils::datafile::Write(saveFile,"save_file_path"_S+std::format("save.{:04}",saveFileID));
}
utils::datafile metadata;
if(std::filesystem::exists("save_file_path"_S+"metadata.dat")){
utils::datafile::Read(metadata,"save_file_path"_S+"metadata.dat");
@ -120,13 +121,29 @@ const void SaveFile::SaveGame(){
metadata.GetProperty(std::format("save{}",saveFileID)).SetInt(game->GetPlayer()->Level(),2U);
metadata.GetProperty(std::format("save{}",saveFileID)).SetString(game->GetPlayer()->GetClassName(),3U);
metadata.GetProperty(std::format("save{}",saveFileID)).SetString(std::string(SaveFile::GetSaveFileName()),4U);
utils::datafile::Write(metadata,"save_file_path"_S+"metadata.dat");
if(!onlineMode){
utils::datafile::Write(metadata,"save_file_path"_S+"metadata.dat");
}
utils::datafile::INITIAL_SETUP_COMPLETE=true;
#ifdef __EMSCRIPTEN__
if(onlineMode){
std::function<void(std::string_view response)>RetryResponse;
RetryResponse=[&](std::string_view response){
if(response!="ERR"){
Server_SaveFile([](std::string_view response){
if(response=="ERR"){
std::cout<<"WARNING! Could not save data to server!"<<std::endl;
}
});
}else{
std::cout<<"WARNING! Could not save metadata to server!"<<std::endl;
}
};
Server_SaveMetadataFile(RetryResponse);
}else{
std::stringstream fileContents;
std::ifstream file("save_file_path"_S+std::format("save.{:04}",saveFileID)+"_online");
std::ifstream file("save_file_path"_S+std::format("save.{:04}",saveFileID));
while(file.good()){
int val=file.get();
if(val!=-1){
@ -134,26 +151,31 @@ const void SaveFile::SaveGame(){
}
}
std::string contents=fileContents.str();
emscripten_idb_async_store("/assets",("save_file_path"_S+std::format("save.{:04}",saveFileID)+"_online").c_str(),contents.data(),contents.length(),0,[](void*arg){
emscripten_idb_async_store("/assets",("save_file_path"_S+std::format("save.{:04}",saveFileID)).c_str(),contents.data(),contents.length(),0,[](void*arg){
std::cout<<"Successfully saved save file "<<saveFileID<<"!"<<std::endl;
},[](void*arg){
std::cout<<"Failed to save save file "<<saveFileID<<"!"<<std::endl;
});
file.close();
std::function<void(std::string_view response)>RetryResponse;
RetryResponse=[&](std::string_view response){
if(response!="ERR"){
Server_SaveFile([](std::string_view response){
if(response=="ERR"){
std::cout<<"WARNING! Could not save data to server!"<<std::endl;
}
});
}else{
std::cout<<"WARNING! Could not save metadata to server!"<<std::endl;
std::stringstream metafileContents;
std::ifstream metafile("save_file_path"_S+"metadata.dat");
while(metafile.good()){
int val=metafile.get();
if(val!=-1){
metafileContents<<char(val);
}
};
Server_SaveMetadataFile(RetryResponse);
}
std::string metaContents=metafileContents.str();
emscripten_idb_async_store("/assets",("save_file_path"_S+"metadata.dat").c_str(),metaContents.data(),metaContents.length(),0,[](void*arg){
std::cout<<"Successfully saved metafile!"<<std::endl;
},[](void*arg){
std::cout<<"Failed to save save metafile!"<<std::endl;
});
metafile.close();
}
#endif
}
@ -162,7 +184,10 @@ const void SaveFile::LoadGame(){
std::filesystem::create_directories("save_file_path"_S);
auto LoadFile=[&](){
utils::datafile loadFile;
if(std::filesystem::exists("save_file_path"_S+std::format("save.{:04}",saveFileID))){
std::string loadFilename="save_file_path"_S+std::format("save.{:04}",saveFileID);
if(std::filesystem::exists(loadFilename)){
utils::datafile::Read(loadFile,"save_file_path"_S+std::format("save.{:04}",saveFileID));
game->ResetGame();
for(auto&[key,data]:loadFile["Items"].GetOrderedKeys()){
@ -197,8 +222,8 @@ const void SaveFile::LoadGame(){
Unlock::UnlockArea(key);
if(data.GetValueCount()>1&&data.GetBool(1U)){
auto opt_cp=State_OverworldMap::ConnectionPointFromString(key);
if(!opt_cp.has_value())ERR(std::format("WARNING! Could not find connection point {}! THIS SHOULD NOT BE HAPPENING! Potential invalid unlock name.",key));
opt_cp.value()->SetVisited();
if(!opt_cp)ERR(std::format("WARNING! Could not find connection point {}! THIS SHOULD NOT BE HAPPENING! Potential invalid unlock name.",key))
else opt_cp.value()->SetVisited();
}
}
State_OverworldMap::SetStageMarker(loadFile["Overworld Map Location"].GetString());
@ -215,16 +240,32 @@ const void SaveFile::LoadGame(){
};
#ifdef __EMSCRIPTEN__
Server_GetFile([&](std::string_view response){
if(response!="ERR"){
if(onlineMode){
Server_GetFile([&](std::string_view response){
if(response!="ERR"){
std::ofstream file("save_file_path"_S+std::format("save.{:04}",saveFileID)+"_online");
file<<response;
file.close();
LoadFile();
}else{
std::cout<<"WARNING! Could not load save file!"<<std::endl;
}
});
}else{
emscripten_idb_async_load("/assets",("save_file_path"_S+std::format("save.{:04}",saveFileID)).c_str(),0,[](void*arg,void*data,int length){
std::cout<<"Loaded Save File "<<saveFileID<<" successfully!"<<std::endl;
std::string rawMetadata=(char*)data;
std::ofstream file("save_file_path"_S+std::format("save.{:04}",saveFileID));
file<<response;
for(int i=0;i<length;i++){
file<<rawMetadata[i];
}
file.close();
LoadFile();
}else{
std::cout<<"WARNING! Could not load save file!"<<std::endl;
}
});
LoadGame();
},[](void*arg){
std::cout<<"Failed to load Save File "<<saveFileID<<"!"<<std::endl;
});
}
#else
LoadFile();
#endif
@ -248,11 +289,17 @@ const void SaveFile::UpdateSaveGameData(){
auto gameFilesList=Component<ScrollableWindowComponent>(LOAD_GAME,"Game Files List");
gameFilesList->RemoveAllComponents();
const size_t saveFileCount=GetSaveFileCount();
utils::datafile metadata;
utils::datafile metadata,online_metadata;
if(!std::filesystem::exists("save_file_path"_S+"metadata.dat")){
utils::datafile::Write(metadata,"save_file_path"_S+"metadata.dat");
}
utils::datafile::Read(metadata,"save_file_path"_S+"metadata.dat");
if(!std::filesystem::exists("save_file_path"_S+"metadata.dat"+"_online")){
utils::datafile::Write(online_metadata,"save_file_path"_S+"metadata.dat"+"_online");
}
std::string saveGameFilename="save_file_path"_S+"metadata.dat";
std::string onlineSaveGameFilename="save_file_path"_S+"metadata.dat"+"_online";
utils::datafile::Read(metadata,saveGameFilename);
utils::datafile::Read(online_metadata,onlineSaveGameFilename);
float offsetY=0;
for(size_t i=0;i<saveFileCount;i++){
if(metadata.HasProperty(std::format("save{}",i))){
@ -266,43 +313,61 @@ const void SaveFile::UpdateSaveGameData(){
}
}
};
auto LoadOnlineMetadataFile=[](){
auto LoadMetadataFromDB=[](){
auto gameFilesList=Component<ScrollableWindowComponent>(LOAD_GAME,"Game Files List");
gameFilesList->RemoveAllComponents();
if(SaveFile::IsOnline()){
const size_t saveFileCount=GetSaveFileCount();
utils::datafile metadata;
if(!std::filesystem::exists("save_file_path"_S+"metadata.dat")){
utils::datafile::Write(metadata,"save_file_path"_S+"metadata.dat");
}
utils::datafile::Read(metadata,"save_file_path"_S+"metadata.dat");
float offsetY=0;
for(size_t i=0;i<saveFileCount;i++){
if(metadata.HasProperty(std::format("save{}",i))){
gameFilesList->ADD(std::format("Load File Button - Save {}",i),LoadFileButton)(geom2d::rect<float>{{0,offsetY},{gameFilesList->GetSize().x-13,48}},metadata[std::format("save{}",i)],i,[](MenuFuncData data){
std::weak_ptr<LoadFileButton>comp=DYNAMIC_POINTER_CAST<LoadFileButton>(data.component.lock());
saveFileID=comp.lock()->getSaveFileID();
SaveFile::LoadGame();
return true;
},ButtonAttr::NONE)END;
offsetY+=49;
#ifdef __EMSCRIPTEN__
emscripten_idb_async_load("/assets",("save_file_path"_S+"metadata.dat").c_str(),0,[](void*arg,void*data,int length){
std::cout<<"Loaded metadata successfully!"<<std::endl;
auto gameFilesList=Component<ScrollableWindowComponent>(LOAD_GAME,"Game Files List");
std::string rawMetadata=(char*)data;
std::ofstream file("save_file_path"_S+"metadata.dat");
for(int i=0;i<length;i++){
file<<rawMetadata[i];
}
}
}
file.close();
utils::datafile metadata;
utils::datafile::Read(metadata,"save_file_path"_S+"metadata.dat");
const size_t saveFileCount=metadata.GetKeys().size();
float offsetY=0;
for(size_t i=0;i<saveFileCount;i++){
if(metadata.HasProperty(std::format("save{}",i))){
gameFilesList->ADD(std::format("Load File Button - Save {}",i),LoadFileButton)(geom2d::rect<float>{{0,offsetY},{gameFilesList->GetSize().x-13,48}},metadata[std::format("save{}",i)],i,[](MenuFuncData data){
std::weak_ptr<LoadFileButton>comp=DYNAMIC_POINTER_CAST<LoadFileButton>(data.component.lock());
saveFileID=comp.lock()->getSaveFileID();
SaveFile::LoadGame();
return true;
},ButtonAttr::NONE)END;
offsetY+=49;
}
}
Menu::OpenMenu(LOAD_GAME);
},[](void*arg){
std::cout<<"Failed to load metadata!"<<std::endl;
});
#endif
};
LoadMetadataFile();
#ifndef __EMSCRIPTEN__
LoadMetadataFile();
#endif
#ifdef __EMSCRIPTEN__
Server_GetLoadInfo([&](std::string_view response){
if(response!="ERR"){
std::ofstream file("save_file_path"_S+"metadata.dat");
std::stringstream str;
file<<response;
file.close();
LoadMetadataFile();
}
});
if(onlineMode){
Server_GetLoadInfo([&](std::string_view response){
if(response!="ERR"){
std::ofstream file("save_file_path"_S+"metadata.dat"+"_online");
std::stringstream str;
file<<response;
file.close();
LoadMetadataFile();
}
});
}else{
LoadMetadataFromDB();
}
#endif
}

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0
#define VERSION_MINOR 3
#define VERSION_PATCH 0
#define VERSION_BUILD 6400
#define VERSION_BUILD 6401
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -0,0 +1,6 @@
$ErrorActionPreference = "Stop"
cd ..
./emscripten_debug_build.ps1
if ($LASTEXITCODE -eq 0) {
./emscripten_run.ps1
}

@ -326,8 +326,6 @@ if (EMSCRIPTEN)
-sEXPORTED_RUNTIME_METHODS=stringToNewUTF8
-std=c++20
--proxy-to-worker
-lidbfs.js
-O2
--preload-file ${SOURCE_DATA_DIR}@assets)
else()
target_link_options(
@ -342,8 +340,6 @@ if (EMSCRIPTEN)
-sEXPORTED_RUNTIME_METHODS=stringToNewUTF8
-std=c++20
--proxy-to-worker
-lidbfs.js
-O2
-sLLD_REPORT_UNDEFINED)
endif()

@ -1,3 +1,3 @@
clear
emcmake cmake .
emcmake cmake -DCMAKE_BUILD_TYPE=Release .
cmake --build . -j 8

@ -0,0 +1,3 @@
clear
emcmake cmake -DCMAKE_BUILD_TYPE=Debug .
cmake --build . -j 8
Loading…
Cancel
Save