diff --git a/html5/build_release.bat b/html5/build_release.bat
index 720c720..61eada2 100644
--- a/html5/build_release.bat
+++ b/html5/build_release.bat
@@ -1,5 +1,5 @@
:Set below to DEBUG=1 for debug mode builds - slower but way easier to see problems. Disables the ASYNC stuff as that doesn't seem to play
-:well with the rest
+:well with the rest. It uses Emscripten default html setup which doesn't allow uploading/downloading though.
SET DEBUG=0
@@ -9,8 +9,10 @@ SET DEBUG=0
SET USE_HTML5_CUSTOM_MAIN=1
:If 1, this is used:
-SET CUSTOM_TEMPLATE=CustomMain4-3AspectRatioTemplate.html
-:SET CUSTOM_TEMPLATE=CustomMainFullTemplate.html
+
+SET CUSTOM_TEMPLATE=..\..\shared\html5\templates\CustomMain4-3AspectRatioTemplate.html
+:SET CUSTOM_TEMPLATE=..\..\shared\html5\templates\CustomMain3-2AspectRatioTemplate.html
+:SET CUSTOM_TEMPLATE=..\..\shared\html5\templates\CustomMainFullTemplate.html
set CURPATH=%cd%
diff --git a/source/App.cpp b/source/App.cpp
index 3faf77c..69726ef 100644
--- a/source/App.cpp
+++ b/source/App.cpp
@@ -231,6 +231,12 @@ bool App::GetForceAspectRatio()
bool App::UseClassicEscapeMenu()
{
+
+ if (GetEmulatedPlatformID() == PLATFORM_ID_HTML5)
+ {
+ return true;
+ }
+
if (IsDesktop())
{
return true;
@@ -362,7 +368,11 @@ bool App::Init()
#ifdef PLATFORM_HTML5
- string crap = JLIB_GetURL();
+
+ char *pStringTemp = JLIB_GetURL();
+
+ string crap = pStringTemp;
+ free(pStringTemp); //emscripten thing, trust me
int n = crap.find_last_of('?');
if (n == string::npos)
@@ -924,12 +934,13 @@ void App::SaveAllData()
if (GetDinkGameState() == DINK_GAME_STATE_PLAYING)
{
// SaveState(GetSavePath()+"state.dat");
- SaveState(g_dglo.m_savePath+"continue_state.dat");
+ SaveState(g_dglo.m_savePath+"continue_state.dat", false);
WriteLastPathSaved(g_dglo.m_savePath); //so we know what to reload
}
//GetAudioManager()->StopMusic();
SaveSettings();
+ SyncPersistentData();
}
void App::OnEnterBackground()
@@ -1042,6 +1053,55 @@ const char * GetBundleName()
void App::OnMessage( Message &m )
{
m_adManager.OnMessage(m); //gives the AdManager a way to handle messages
+
+
+ if (m.GetClass() == MESSAGE_CLASS_GUI)
+ {
+ if (m.GetType() == MESSAGE_TYPE_HTML5_GOT_UPLOAD)
+ {
+ LogMsg("Got uploaded file %s", m.GetStringParm().c_str());
+ string fName = m.GetStringParm();
+
+
+ size_t index = fName.find_last_of('_');
+ size_t periodPos = fName.find_last_of('.');
+
+ if (periodPos == string::npos || GetFileExtension(fName) != "dat") return;
+
+ string dmodName = "";
+
+ if (index != string::npos)
+ {
+ //yeah, it has one
+ dmodName = fName.substr(index + 1, periodPos - (index + 1));
+ }
+
+ //ok, ready to copy it. But figure out where, and what the filename should be
+ string destPath = GetSavePath() + "dink/";
+ string destFile = fName;
+
+ //modify if needed for a dmod
+
+ if (!dmodName.empty())
+ {
+ destPath = GetDMODRootPath() + dmodName + "/";
+ destFile = fName.substr(0, index);
+ destFile += fName.substr(periodPos, fName.size() - periodPos);
+ }
+
+ LogMsg("Importing %s to %s", (GetSavePath() + fName).c_str(), (destPath + destFile).c_str());
+
+ /*
+ InitDinkPaths(GetBaseAppPath(), "dink", dmoddir);
+ GameCreate(pBG->GetParent(), 0, "", "Loading " + dmodName);
+ GameCreate(pMenu->GetParent(), 0, g_dglo.m_savePath + "continue_state.dat");
+ Entity *pMenu = DinkQuitGame();
+ PopUpCreate(pMenu, "Error loading save state. Probably an older version, sorry.", "", "cancel", "Continue", "", "", true);
+ */
+
+ }
+ }
+
BaseApp::OnMessage(m);
}
diff --git a/source/Component/CursorComponent.cpp b/source/Component/CursorComponent.cpp
index 3af8578..fe39798 100644
--- a/source/Component/CursorComponent.cpp
+++ b/source/Component/CursorComponent.cpp
@@ -72,7 +72,7 @@ void CursorComponent::OnInput( VariantList *pVList )
- if (IsDesktop())
+ if (IsDesktop() || GetEmulatedPlatformID() == PLATFORM_ID_HTML5)
{
//controls for a real mouse
diff --git a/source/GUI/GameMenu.cpp b/source/GUI/GameMenu.cpp
index 1c1704f..cbc66a6 100644
--- a/source/GUI/GameMenu.cpp
+++ b/source/GUI/GameMenu.cpp
@@ -1101,7 +1101,7 @@ void OnAutoSave(VariantList *pVList)
)
{
SaveAutoSave();
-
+ SyncPersistentData();
//reschedule this function to run again in a bit
GetMessageManager()->CallEntityFunction(pVList->Get(0).GetEntity(), AUTO_SAVE_MS, "OnAutoSave", pVList);
return;
diff --git a/source/GUI/MainMenu.cpp b/source/GUI/MainMenu.cpp
index 4f047ac..60ad9b7 100644
--- a/source/GUI/MainMenu.cpp
+++ b/source/GUI/MainMenu.cpp
@@ -640,7 +640,6 @@ Entity * MainMenuCreate( Entity *pParentEnt, bool bFadeIn )
#endif
-
if (!g_bDidVersionCheck && IsDesktop())
{
g_bDidVersionCheck = true;
diff --git a/source/GUI/OptionsMenu.cpp b/source/GUI/OptionsMenu.cpp
index 986eedf..7e4637f 100644
--- a/source/GUI/OptionsMenu.cpp
+++ b/source/GUI/OptionsMenu.cpp
@@ -373,9 +373,6 @@ void OptionsMenuAddScrollContent(Entity *pParent)
pEnt = CreateTextButtonEntity(pBG, "vid_hd", startX, y, "1920X1080");
pEnt->GetShared()->GetFunction("OnButtonSelected")->sig_function.connect(&OptionsMenuOnSelect);
y += spacerY;
-
-
-
}
//control method
diff --git a/source/GUI/PauseMenu.cpp b/source/GUI/PauseMenu.cpp
index 6355d7e..6ce892d 100644
--- a/source/GUI/PauseMenu.cpp
+++ b/source/GUI/PauseMenu.cpp
@@ -10,6 +10,20 @@
#include "PopUpMenu.h"
#include "Entity/SelectButtonWithCustomInputComponent.h"
+
+#if defined _DEBUG || defined PLATFORM_HTML5
+
+const bool G_ALLOW_SAVE_EXPORTING = true;
+
+#else
+const bool G_ALLOW_SAVE_EXPORTING = false;
+#endif
+
+#ifdef PLATFORM_HTML5
+#include "HTML5Utils.h"
+#endif
+
+
void PlayMenuMusic()
{
@@ -103,7 +117,7 @@ void PauseEnd(Entity *pMenu)
GetMessageManager()->CallEntityFunction(pMenu, 500, "OnDelete", NULL);
GetBaseApp()->SetGameTickPause(false);
- SyncPersistentData();
+ //SyncPersistentData();
}
@@ -179,12 +193,13 @@ void PauseMenuOnSelect(VariantList *pVList) //0=vec2 point of click, 1=entity se
{
//slide it off the screen and then kill the whole menu tree
RemoveFocusIfNeeded(pMenu);
- SaveState(g_dglo.m_savePath+"continue_state.dat");
+ SaveState(g_dglo.m_savePath+"continue_state.dat", false);
WriteLastPathSaved("");
//kill our state.dat if it existed, not needed now, this can exist if an iphone goes into suspend, but then is resumed
RemoveFile(GetSavePath()+"state.dat", false);
//SlideScreen(pEntClicked->GetParent()->GetParent(), false);
DinkQuitGame();
+ SyncPersistentData();
}
if (pEntClicked->GetName() == "Debug")
@@ -214,6 +229,37 @@ void PauseMenuOnSelect(VariantList *pVList) //0=vec2 point of click, 1=entity se
}
+ if (pEntClicked->GetName() == "ExportQuickSave")
+ {
+ //SaveStateWithExtra(false);
+ //UpdatePauseButtons(pMenu);
+
+ GetAudioManager()->Play("audio/quick_save.wav");
+ SaveState(DinkGetSavePath() + "quicksave.dat");
+
+ string prepend = g_dglo.m_dmodGameDir;
+
+ if (prepend.empty()) prepend = "dink";
+#ifdef PLATFORM_HTML5
+
+ HTMLDownloadFileFromFileSystem(DinkGetSavePath() + "quicksave.dat", prepend + "_quicksave.dat");
+#endif
+ PauseEnd(pMenu);
+ ShowQuickMessage("Download started");
+
+ }
+
+ if (pEntClicked->GetName() == "ImportQuickSave")
+ {
+
+#ifdef PLATFORM_HTML5
+ HTMLUploadFileToFileSystem();
+// HTMLDownloadFileFromFileSystem(DinkGetSavePath() + "quicksave.dat", g_dglo.m_dmodGameDir + "_quicksave.dat");
+#endif
+ PauseEnd(pMenu);
+
+ }
+
if (pEntClicked->GetName() == "QuickLoad")
{
LogMsg("loading state");
@@ -361,11 +407,53 @@ Entity * PauseMenuCreate(Entity *pParentEnt)
pButtonEntity->GetShared()->GetFunction("OnButtonSelected")->sig_function.connect(&PauseMenuOnSelect);
pButtonEntity->GetVar("alignment")->Set(uint32(ALIGNMENT_CENTER));
+ if (G_ALLOW_SAVE_EXPORTING)
+ {
+ Entity *pButton;
+ CL_Vec2f vEntSize = GetSize2DEntity(pButtonEntity);
+ CL_Vec2f vEntPos = GetPos2DEntity(pButtonEntity);
+
+ float spacer = 80;
+ pButton = CreateTextButtonEntity(pBG, "ExportQuickSave", vEntPos.x, (vEntPos.y + vEntSize.y/2) +spacer, "(Export Quicksave to file)", true);
+ SetAlignmentEntity(pButton, ALIGNMENT_DOWN_CENTER);
+ pButton->GetShared()->GetFunction("OnButtonSelected")->sig_function.connect(&PauseMenuOnSelect);
+
+ //next button
+// pButton = CreateTextButtonEntity(pBG, "ExportNormalSave", vEntPos.x, (vEntPos.y + vEntSize.y / 2) + spacer+spacer, "(Export last save slot save)", true);
+// SetAlignmentEntity(pButton, ALIGNMENT_DOWN_CENTER);
+// pButton->GetShared()->GetFunction("OnButtonSelected")->sig_function.connect(&PauseMenuOnSelect);
+
+
+ }
+
pButtonEntity = CreateOverlayButtonEntity(pBG , "QuickLoad", ReplaceWithLargeInFileName("interface/iphone/button_quickload.rttex"), iPhoneMapX(395), GetScreenSizeYf()/2);
pButtonEntity->GetShared()->GetFunction("OnButtonSelected")->sig_function.connect(&PauseMenuOnSelect);
pButtonEntity->GetVar("alignment")->Set(uint32(ALIGNMENT_CENTER));
+
+ if (G_ALLOW_SAVE_EXPORTING)
+ {
+ Entity *pButton;
+
+ CL_Vec2f vEntSize = GetSize2DEntity(pButtonEntity);
+ CL_Vec2f vEntPos = GetPos2DEntity(pButtonEntity);
+
+ float spacer = 80;
+ pButton = CreateTextButtonEntity(pBG, "ImportQuickSave", vEntPos.x, (vEntPos.y + vEntSize.y / 2) + spacer, "(Import Quicksave file)", true);
+ SetAlignmentEntity(pButton, ALIGNMENT_DOWN_CENTER);
+ pButton->GetShared()->GetFunction("OnButtonSelected")->sig_function.connect(&PauseMenuOnSelect);
+ SetButtonStyleEntity(pButton, Button2DComponent::BUTTON_STYLE_CLICK_ON_TOUCH); //to get around HTML5 rules on uploading, required because it's only
+ //allowed when initiated by a user click
+//
+// //next button
+// pButton = CreateTextButtonEntity(pBG, "ImportNormalSave", vEntPos.x, (vEntPos.y + vEntSize.y / 2) + spacer + spacer, "(Import save slot file)", true);
+// SetAlignmentEntity(pButton, ALIGNMENT_DOWN_CENTER);
+// pButton->GetShared()->GetFunction("OnButtonSelected")->sig_function.connect(&PauseMenuOnSelect);
+
+
+ }
+
UpdatePauseButtons(pBG);
pButtonEntity = CreateTextButtonEntity(pTextBG, "Map", x, y, "VIEW MAP", false); y += ySpacer;
@@ -414,11 +502,12 @@ Entity * PauseMenuCreate(Entity *pParentEnt)
SetButtonClickSound(pButtonEntity, ""); //no sound
EntityComponent *pKeys = AddHotKeyToButton(pButtonEntity, VIRTUAL_KEY_BACK);
+
//work around problem of it instantly closing
pKeys->GetVar("disabled")->Set(uint32(1));
GetMessageManager()->SetComponentVariable(pKeys, 500, "disabled", uint32(0)); //enable it again
- if (IsDesktop())
+ if (IsDesktop() || GetEmulatedPlatformID() == PLATFORM_ID_HTML5)
{
EntityComponent *pKeys = AddHotKeyToButton(pButtonEntity, VIRTUAL_KEY_F1);
//work around problem of it instantly closing
@@ -426,6 +515,8 @@ Entity * PauseMenuCreate(Entity *pParentEnt)
GetMessageManager()->SetComponentVariable(pKeys, 500, "disabled", uint32(0)); //enable it again
}
+
+
/*
pKeys = AddHotKeyToButton(pButtonEntity, VIRTUAL_KEY_PROPERTIES);
//work around problem of it instantly closing
diff --git a/source/dink/dink.cpp b/source/dink/dink.cpp
index cbb655c..ce399d6 100644
--- a/source/dink/dink.cpp
+++ b/source/dink/dink.cpp
@@ -950,7 +950,7 @@ void load_map(const int num)
FILE * fp;
int holdme,lsize;
- LogMsg("Loading map %d...",num);
+ //LogMsg("Loading map %d...",num);
g_dglos.m_bRenderBackgroundOnLoad = true;
StreamingInstance *pFile = GetFileManager()->GetStreaming(GetFileLocationString(g_dglos.current_map), NULL, false);
@@ -5059,7 +5059,7 @@ bool PlayMidi(const char *sFileName)
g_dglo.m_lastMusicPath = sFileName;
GetAudioManager()->Play(GetFileLocationString(fName), true, true, false);
- LogMsg("Playing music %s", sFileName);
+ //LogMsg("Playing music %s", sFileName);
return true;
}
@@ -7950,13 +7950,14 @@ pass:
LogMsg("Was told to kill game, so doing it like a good boy.");
g_sprite[1].freeze = 0;
- SaveState(g_dglo.m_savePath+"continue_state.dat");
+ SaveState(g_dglo.m_savePath+"continue_state.dat", false);
WriteLastPathSaved("");
//kill our state.dat if it existed, not needed now, this can exist if an iphone goes into suspend, but then is resumed
RemoveFile(GetSavePath()+"state.dat", false);
DinkQuitGame();
+ SyncPersistentData();
//uncomment below if you want this to actually work
//PostMessage(g_hWndMain, WM_CLOSE, 0, 0);
@@ -17564,7 +17565,7 @@ bool LoadScriptState(FILE *fp)
}
-bool SaveState(string const &path)
+bool SaveState(string const &path, bool bSyncSaves)
{
LogMsg("Saving %s (inside %s which is off of %s)", path.c_str(), g_dglo.m_gameDir.c_str(), g_dglo.m_savePath.c_str());
CreateDirectoryRecursively(g_dglo.m_savePath, g_dglo.m_gameDir);
@@ -17607,7 +17608,8 @@ bool SaveState(string const &path)
fclose(fp);
- SyncPersistentData();
+ if (bSyncSaves)
+ SyncPersistentData();
return bOk; //success
}
@@ -17983,7 +17985,7 @@ void DinkOnForeground()
bForceReinit = true;
#endif
#ifdef PLATFORM_HTML5
- //bForceReinit = true;
+ bForceReinit = true;
#endif
if (IsDesktop() || GetEmulatedPlatformID() == PLATFORM_ID_ANDROID || bForceReinit) //xoom needs this too after a suspend/resume from hitting the power button
diff --git a/source/dink/dink.h b/source/dink/dink.h
index d6b5aad..67c7b0d 100644
--- a/source/dink/dink.h
+++ b/source/dink/dink.h
@@ -206,7 +206,7 @@ struct sequence
byte m_spaceAllowed;
byte m_bFrameSetUsed;
byte m_bIsAnim;
- byte m_bDidFileScan;
+ byte m_bDidFileScan;
};
@@ -751,7 +751,7 @@ bool DinkLoadPlayerScript(const string fileName);
void DinkUnloadUnusedGraphicsByUsageTime(unsigned int timeMS);
bool LoadState(string const &path, bool bLoadPathsOnly);
-bool SaveState(string const &path);
+bool SaveState(string const &path, bool bSyncSaves = true);
eDinkGameState GetDinkGameState();
void SetDinkGameState(eDinkGameState state);
void DinkModStrength(int mod);
diff --git a/windows_vs2017/winRTDink.vcxproj b/windows_vs2017/winRTDink.vcxproj
index b9d80cb..87a2bee 100644
--- a/windows_vs2017/winRTDink.vcxproj
+++ b/windows_vs2017/winRTDink.vcxproj
@@ -3905,6 +3905,28 @@
+
+ NotUsing
+ NotUsing
+ NotUsing
+ NotUsing
+ NotUsing
+ NotUsing
+ NotUsing
+ NotUsing
+ NotUsing
+
+
+ NotUsing
+ NotUsing
+ NotUsing
+ NotUsing
+ NotUsing
+ NotUsing
+ NotUsing
+ NotUsing
+ NotUsing
+
@@ -4303,6 +4325,8 @@
+
+
diff --git a/windows_vs2017/winRTDink.vcxproj.filters b/windows_vs2017/winRTDink.vcxproj.filters
index d823dd5..82be186 100644
--- a/windows_vs2017/winRTDink.vcxproj.filters
+++ b/windows_vs2017/winRTDink.vcxproj.filters
@@ -835,6 +835,12 @@
shared\Renderer\libpng
+
+ shared\util
+
+
+ shared\util
+
@@ -1404,6 +1410,12 @@
shared\html5
+
+ shared\util
+
+
+ shared\util
+