Add in emscripten-specific branching menus and special load/save routines for online saving.

pull/28/head
sigonasr2 11 months ago
parent 2a900fa06e
commit 497db80b9b
  1. 7
      Crawler/Crawler.cpp
  2. 4
      Crawler/Crawler.vcxproj
  3. 3
      Crawler/Crawler.vcxproj.filters
  4. 4
      Crawler/MainMenuWindow.cpp
  5. 1
      Crawler/Menu.cpp
  6. 2
      Crawler/Menu.h
  7. 6
      Crawler/MenuLabel.h
  8. 8
      Crawler/SaveFile.cpp
  9. 46
      Crawler/UserIDMenu.cpp
  10. 2
      Crawler/Version.h
  11. 4
      Crawler/assets/config/configuration.txt
  12. 2
      Crawler/config.h
  13. 11
      Crawler/emscripten_build.ps1
  14. 18
      Crawler/olcPixelGameEngine.h
  15. 15
      Crawler/olcUTIL_DataFile.h

@ -239,8 +239,6 @@ bool Crawler::OnUserCreate(){
SetupDiscord(); SetupDiscord();
#endif #endif
SendRequest("index.html","");
return true; return true;
} }
@ -2569,3 +2567,8 @@ void Crawler::ResetGame(){
void Crawler::OnRequestCompleted(const std::string_view receivedData)const{ void Crawler::OnRequestCompleted(const std::string_view receivedData)const{
std::cout<<"Received in engine: "<<receivedData<<std::endl; std::cout<<"Received in engine: "<<receivedData<<std::endl;
} }
std::string operator ""_FS(const char*key,std::size_t len){
Crawler::OutputDebugInfo(key,len);
return DATA.GetProperty(std::string(key,len)).GetFullString();
}

@ -612,6 +612,10 @@
<ClCompile Include="Trapper.cpp" /> <ClCompile Include="Trapper.cpp" />
<ClCompile Include="Turret.cpp" /> <ClCompile Include="Turret.cpp" />
<ClCompile Include="Unlock.cpp" /> <ClCompile Include="Unlock.cpp" />
<ClCompile Include="UserIDMenu.cpp">
<SubType>
</SubType>
</ClCompile>
<ClCompile Include="VisualNovel.cpp" /> <ClCompile Include="VisualNovel.cpp" />
<ClCompile Include="Warrior.cpp" /> <ClCompile Include="Warrior.cpp" />
<ClCompile Include="util.cpp" /> <ClCompile Include="util.cpp" />

@ -674,6 +674,9 @@
<ClCompile Include="LoadGameWindow.cpp"> <ClCompile Include="LoadGameWindow.cpp">
<Filter>Source Files\Interface</Filter> <Filter>Source Files\Interface</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="UserIDMenu.cpp">
<Filter>Source Files\Interface</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="cpp.hint" /> <None Include="cpp.hint" />

@ -49,7 +49,11 @@ void Menu::InitializeMainMenuWindow(){
mainMenuWindow->ADD("New Game Button",MenuComponent)({{12,4},{72,24}},"New Game",[](MenuFuncData data){ mainMenuWindow->ADD("New Game Button",MenuComponent)({{12,4},{72,24}},"New Game",[](MenuFuncData data){
game->TextEntryEnable(true); game->TextEntryEnable(true);
#ifdef __EMSCRIPTEN__
Menu::OpenMenu(USER_ID);
#else
Menu::OpenMenu(SAVE_FILE_NAME); Menu::OpenMenu(SAVE_FILE_NAME);
#endif
return true; return true;
})END; })END;
mainMenuWindow->ADD("Load Game Button",MenuComponent)({{12,36},{72,24}},"Load Game",[](MenuFuncData data){ mainMenuWindow->ADD("Load Game Button",MenuComponent)({{12,36},{72,24}},"Load Game",[](MenuFuncData data){

@ -113,6 +113,7 @@ void Menu::InitializeMenus(){
InitializeConsumableCraftItemWindow(); InitializeConsumableCraftItemWindow();
InitializeSaveFileWindow(); InitializeSaveFileWindow();
InitializeLoadGameWindow(); InitializeLoadGameWindow();
InitializeUserIDWindow();
for(MenuType type=MenuType(int(MenuType::ENUM_START)+1);type<MenuType::ENUM_END;type=MenuType(int(type+1))){ for(MenuType type=MenuType(int(MenuType::ENUM_START)+1);type<MenuType::ENUM_END;type=MenuType(int(type+1))){
if(menus.count(type)==0){ if(menus.count(type)==0){

@ -79,6 +79,7 @@ enum MenuType{
CONSUMABLE_CRAFT_ITEM, CONSUMABLE_CRAFT_ITEM,
SAVE_FILE_NAME, SAVE_FILE_NAME,
LOAD_GAME, LOAD_GAME,
USER_ID,
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
/*DO NOT REMOVE!!*/ENUM_END//////////////////////////////// /*DO NOT REMOVE!!*/ENUM_END////////////////////////////////
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -104,6 +105,7 @@ class Menu:public IAttributable{
static void InitializeConsumableCraftItemWindow(); static void InitializeConsumableCraftItemWindow();
static void InitializeSaveFileWindow(); static void InitializeSaveFileWindow();
static void InitializeLoadGameWindow(); static void InitializeLoadGameWindow();
static void InitializeUserIDWindow();
friend class Crawler; friend class Crawler;
friend struct Player; friend struct Player;

@ -78,8 +78,8 @@ protected:
vf2d adjustedScale={scale,scale}; vf2d adjustedScale={scale,scale};
vf2d labelTextSize= vf2d labelTextSize=
proportional? proportional?
vf2d(game->GetWrappedTextSizeProp(label,rect.size.x,adjustedScale)): vf2d(game->GetWrappedTextSizeProp(label,rect.size.x-8,adjustedScale)):
vf2d(game->GetWrappedTextSize(label,rect.size.x,adjustedScale)); vf2d(game->GetWrappedTextSize(label,rect.size.x-8,adjustedScale));
if(fitToLabel){ if(fitToLabel){
labelTextSize= labelTextSize=
@ -93,7 +93,7 @@ protected:
} }
} }
vf2d drawPos=rect.middle()-vf2d{labelTextSize}/2; //Assume centered. vf2d drawPos=vf2d{-4.f,0.f}+rect.middle()-vf2d{labelTextSize}/2; //Assume centered.
if(!centered){ if(!centered){
drawPos=vf2d{rect.pos.x+2,rect.middle().y-labelTextSize.y/2}; //We should at least vertically align here. drawPos=vf2d{rect.pos.x+2,rect.middle().y-labelTextSize.y/2}; //We should at least vertically align here.
} }

@ -114,9 +114,16 @@ const void SaveFile::SaveGame(){
utils::datafile::Write(metadata,"save_file_path"_S+"metadata.dat"); utils::datafile::Write(metadata,"save_file_path"_S+"metadata.dat");
utils::datafile::INITIAL_SETUP_COMPLETE=true; utils::datafile::INITIAL_SETUP_COMPLETE=true;
#ifdef __EMSCRIPTEN__
Server_SaveFile();
#endif
} }
const void SaveFile::LoadGame(){ const void SaveFile::LoadGame(){
#ifdef __EMSCRIPTEN__
Server_GetFile();
#else
std::filesystem::create_directories("save_file_path"_S); std::filesystem::create_directories("save_file_path"_S);
utils::datafile loadFile; utils::datafile loadFile;
if(std::filesystem::exists("save_file_path"_S+std::format("save.{:04}",saveFileID))){ if(std::filesystem::exists("save_file_path"_S+std::format("save.{:04}",saveFileID))){
@ -163,6 +170,7 @@ const void SaveFile::LoadGame(){
}else{ }else{
std::cout<<std::format("WARNING! File {} does not exist for loading!","save_file_path"_S+std::format("save.{:04}",saveFileID))<<std::endl; std::cout<<std::format("WARNING! File {} does not exist for loading!","save_file_path"_S+std::format("save.{:04}",saveFileID))<<std::endl;
} }
#endif
} }
const std::string_view SaveFile::GetSaveFileName(){ const std::string_view SaveFile::GetSaveFileName(){

@ -0,0 +1,46 @@
#pragma region License
/*
License (OLC-3)
~~~~~~~~~~~~~~~
Copyright 2024 Joshua Sigona <sigonasr2@gmail.com>
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions or derivations of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions or derivative works in binary form must reproduce the above
copyright notice. This list of conditions and the following disclaimer must be
reproduced in the documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may
be used to endorse or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
Portions of this software are copyright © 2023 The FreeType
Project (www.freetype.org). Please see LICENSE_FT.txt for more information.
All rights reserved.
*/
#pragma endregion
#include "Menu.h"
#include "MenuLabel.h"
void Menu::InitializeUserIDWindow(){
Menu*userIDWindow=CreateMenu(USER_ID,CENTERED,vi2d{144,96});
userIDWindow->ADD("User ID Creation Explanation",MenuLabel)({{0,0},{144,96}},"user_id_message"_FS+"\n\n"+"user_id_message2"_FS,1.f,ComponentAttr::SHADOW|ComponentAttr::BACKGROUND|ComponentAttr::OUTLINE)END;
}

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0 #define VERSION_MAJOR 0
#define VERSION_MINOR 2 #define VERSION_MINOR 2
#define VERSION_PATCH 1 #define VERSION_PATCH 1
#define VERSION_BUILD 5283 #define VERSION_BUILD 5285
#define stringify(a) stringify_(a) #define stringify(a) stringify_(a)
#define stringify_(a) #a #define stringify_(a) #a

@ -118,3 +118,7 @@ water_reflection_time_step = 0.6
# the amount of scaling done to the water reflection. # the amount of scaling done to the water reflection.
water_reflection_scale_factor = 0.05 water_reflection_scale_factor = 0.05
# The message displayed to the user about ID creation.
user_id_message = You are playing the web build of this game. In order to save progress, we ask that you provide a unique username to identify your save data with.
user_id_message2 = Only game save data will be stored.

@ -51,6 +51,8 @@ utils::datafilefloatdata operator ""_f(const char*key,std::size_t len);
utils::datafiledoubledata operator ""_d(const char*key,std::size_t len); utils::datafiledoubledata operator ""_d(const char*key,std::size_t len);
//Read a string key from the config. //Read a string key from the config.
std::string operator ""_S(const char*key,std::size_t len); std::string operator ""_S(const char*key,std::size_t len);
//Read a full string key from the config.
std::string operator ""_FS(const char*key,std::size_t len);
//Read an integer key from the config. //Read an integer key from the config.
int operator ""_I(const char*key,std::size_t len); int operator ""_I(const char*key,std::size_t len);
//Read a float key from the config. //Read a float key from the config.

@ -1,3 +1,12 @@
cd .. cd ..
./emscripten_build.ps1 ./emscripten_build.ps1
./emscripten_run.ps1 if( -not $? )
{
$msg = $Error[0].Exception.Message
"$msg"
exit
}
else
{
./emscripten_run.ps1
}

@ -3718,13 +3718,13 @@ namespace olc
skip--; skip--;
continue; continue;
} }
if(c==' '||c=='\t'){ if(c==' '||c=='\t'||c=='\n'){
drawingMarker.x+=lettersWidth; drawingMarker.x+=lettersWidth;
lettersWidth=0; lettersWidth=0;
wrappingOccurred=false; wrappingOccurred=false;
} }
if(wrappingOccurred){ if(wrappingOccurred){
if(c!=' '&&c!='\t'){ if(c!=' '&&c!='\t'&&c!='\n'){
wrappingOccurred=false; wrappingOccurred=false;
maxWidth=std::max(maxWidth,drawingMarker.x); maxWidth=std::max(maxWidth,drawingMarker.x);
}else{ }else{
@ -3835,7 +3835,7 @@ namespace olc
skip--; skip--;
continue; continue;
} }
if(c==' '||c=='\t'){ if(c==' '||c=='\t'||c=='\n'){
for(PixelGameEngine::StringDecalData&letter:letters){ for(PixelGameEngine::StringDecalData&letter:letters){
DrawPartialSprite(vi2d(pos + drawingMarker), fontRenderable.Sprite(), vi2d(letter.sourcePos), vi2d(letter.sourceSize), scale, Sprite::Flip::NONE,letter.col); DrawPartialSprite(vi2d(pos + drawingMarker), fontRenderable.Sprite(), vi2d(letter.sourcePos), vi2d(letter.sourceSize), scale, Sprite::Flip::NONE,letter.col);
drawingMarker.x += 8.0f * scale; drawingMarker.x += 8.0f * scale;
@ -3844,7 +3844,7 @@ namespace olc
wrappingOccurred=false; wrappingOccurred=false;
} }
if(wrappingOccurred){ if(wrappingOccurred){
if(c!=' '&&c!='\t'){ if(c!=' '&&c!='\t'&&c!='\n'){
wrappingOccurred=false; wrappingOccurred=false;
}else{ }else{
continue; continue;
@ -3974,14 +3974,14 @@ namespace olc
skip--; skip--;
continue; continue;
} }
if(c==' '||c=='\t'){ if(c==' '||c=='\t'||c=='\n'){
drawingMarker.x+=lettersWidth; drawingMarker.x+=lettersWidth;
lettersWidth=0; lettersWidth=0;
wrappingOccurred=false; wrappingOccurred=false;
maxWidth=std::max(maxWidth,drawingMarker.x); maxWidth=std::max(maxWidth,drawingMarker.x);
} }
if(wrappingOccurred){ if(wrappingOccurred){
if(c!=' '&&c!='\t'){ if(c!=' '&&c!='\t'&&c!='\n'){
wrappingOccurred=false; wrappingOccurred=false;
}else{ }else{
continue; continue;
@ -4065,7 +4065,7 @@ namespace olc
skip--; skip--;
continue; continue;
} }
if(c==' '||c=='\t'){ if(c==' '||c=='\t'||c=='\n'){
for(PixelGameEngine::StringDecalData&letter:letters){ for(PixelGameEngine::StringDecalData&letter:letters){
DrawPartialSprite(vi2d(pos + drawingMarker), GetFontSprite(), vi2d(letter.sourcePos), vi2d(letter.sourceSize), scale,Sprite::Flip::NONE, letter.col); DrawPartialSprite(vi2d(pos + drawingMarker), GetFontSprite(), vi2d(letter.sourcePos), vi2d(letter.sourceSize), scale,Sprite::Flip::NONE, letter.col);
drawingMarker.x += float(vFontSpacing[letter.c - 32].y) * scale; drawingMarker.x += float(vFontSpacing[letter.c - 32].y) * scale;
@ -4074,7 +4074,7 @@ namespace olc
wrappingOccurred=false; wrappingOccurred=false;
} }
if(wrappingOccurred){ if(wrappingOccurred){
if(c!=' '&&c!='\t'){ if(c!=' '&&c!='\t'&&c!='\n'){
wrappingOccurred=false; wrappingOccurred=false;
}else{ }else{
continue; continue;
@ -7107,6 +7107,7 @@ namespace olc
EM_ASM({ EM_ASM({
requestResp="";
// olc_ApsectRatio // olc_ApsectRatio
// //
// Used by olc_ResizeHandler to calculate the viewport from the // Used by olc_ResizeHandler to calculate the viewport from the
@ -7347,7 +7348,6 @@ namespace olc
olc::Platform::ptrPGE->olc_CoreUpdate(); olc::Platform::ptrPGE->olc_CoreUpdate();
char*ptr=(char*)EM_ASM_PTR({ char*ptr=(char*)EM_ASM_PTR({
if(requestResp!==""){ if(requestResp!==""){
console.log("Request received: "+requestResp);
var newPtr=stringToNewUTF8(requestResp); var newPtr=stringToNewUTF8(requestResp);
requestResp=""; requestResp="";
return newPtr; return newPtr;

@ -61,8 +61,11 @@ David Barr, aka javidx9, <EFBFBD>OneLoneCoder 2019, 2020, 2021, 2022
#include <fstream> #include <fstream>
#include <stack> #include <stack>
#include <sstream> #include <sstream>
#include <numeric>
#include "Error.h" #include "Error.h"
using namespace std::literals;
int operator ""_I(const char*key,std::size_t len); int operator ""_I(const char*key,std::size_t len);
namespace olc::utils namespace olc::utils
@ -96,6 +99,18 @@ namespace olc::utils
} }
} }
// Retrieves the String Value of a Property, to include all values that are normally separated by the list separator.
inline const std::string GetFullString() const
{
return std::accumulate(m_vContent.begin(),m_vContent.end(),""s,[](std::string str,const std::string&data){
if(str.size()==0){
return std::move(str)+data;
}else{
return std::move(str)+","+data;
}
});
}
// Retrieves the Real Value of a Property (for a given index) or 0.0 // Retrieves the Real Value of a Property (for a given index) or 0.0
inline const double GetReal(const size_t nItem = 0) const inline const double GetReal(const size_t nItem = 0) const
{ {

Loading…
Cancel
Save