|
@@ -1,70 +1,113 @@
|
|
|
#include <wrl.h>
|
|
|
#include <string>
|
|
|
#include <DXGI.h>
|
|
|
+#include <ppltasks.h>
|
|
|
|
|
|
-//#include <stdio.h>
|
|
|
-//#include <share.h>
|
|
|
-
|
|
|
-//static const char *
|
|
|
-//GetRootPath()
|
|
|
-//{
|
|
|
-// static char buf[1024] = "";
|
|
|
-// if (buf[0] == '\0')
|
|
|
-// {
|
|
|
-// Platform::String^ localfolder = Windows::Storage::ApplicationData::Current->LocalFolder->Path;
|
|
|
-// const char16 *begin = localfolder->Begin();
|
|
|
-// WideCharToMultiByte(CP_ACP, 0, begin, -1, buf, 1024, NULL, FALSE);
|
|
|
-// }
|
|
|
-// return buf;
|
|
|
-//}
|
|
|
-//
|
|
|
-//static const char *
|
|
|
-//GetInstallPath()
|
|
|
-//{
|
|
|
-// static char buf[1024] = "";
|
|
|
-// if (buf[0] == '\0')
|
|
|
-// {
|
|
|
-// Platform::String^ installfolder = Windows::ApplicationModel::Package::Current->InstalledLocation->Path;
|
|
|
-// const char16 *begin = installfolder->Begin();
|
|
|
-// WideCharToMultiByte(CP_ACP, 0, begin, -1, buf, 1024, NULL, FALSE);
|
|
|
-// }
|
|
|
-// return buf;
|
|
|
-//}
|
|
|
-//
|
|
|
-//extern "C" FILE *
|
|
|
-//MY_fopen(const char *path, const char *mode)
|
|
|
-//{
|
|
|
-// return fopen(path, mode);
|
|
|
-//
|
|
|
-// const char *p = GetRootPath();
|
|
|
-// char buf[1024];
|
|
|
-// _snprintf_s(buf, 1024, "%s\\%s", p, path);
|
|
|
-// FILE *fp = _fsopen(buf, mode, _SH_DENYNO);
|
|
|
-// if (fp == NULL)
|
|
|
-// {
|
|
|
-// p = GetInstallPath();
|
|
|
-// _snprintf_s(buf, 1024, "%s\\%s", p, path);
|
|
|
-// fp = _fsopen(buf, mode, _SH_DENYNO);
|
|
|
-// }
|
|
|
-// if (fp == NULL)
|
|
|
-// {
|
|
|
-// p = GetRootPath();
|
|
|
-// _snprintf_s(buf, 1024, "%s\\Shared\\%s", p, path);
|
|
|
-// fp = _fsopen(buf, mode, _SH_DENYNO);
|
|
|
-// }
|
|
|
-// return fp;
|
|
|
-//}
|
|
|
-
|
|
|
-static std::string g_savepath;
|
|
|
+#define PAL_PATH_NAME "SDLPAL"
|
|
|
+
|
|
|
+static std::string g_savepath, g_basepath;
|
|
|
+
|
|
|
+template<typename T>
|
|
|
+static bool WaitOnTask(T task, int64 wait_timeout)
|
|
|
+{
|
|
|
+ auto start = GetTickCount64();
|
|
|
+ while (!task.is_done() && (int64)(GetTickCount64() - start) <= wait_timeout)
|
|
|
+ Sleep(1);
|
|
|
+ return task.is_done();
|
|
|
+}
|
|
|
+
|
|
|
+static void ConvertString(Platform::String^ src, std::string& dst)
|
|
|
+{
|
|
|
+ int len = WideCharToMultiByte(CP_ACP, 0, src->Begin(), -1, nullptr, 0, nullptr, nullptr);
|
|
|
+ dst.resize(len - 1);
|
|
|
+ WideCharToMultiByte(CP_ACP, 0, src->Begin(), -1, (char*)dst.data(), len, nullptr, nullptr);
|
|
|
+}
|
|
|
+
|
|
|
+static bool CheckGamePath(Windows::Storage::StorageFolder^ root)
|
|
|
+{
|
|
|
+ Platform::String^ required_files[] = {
|
|
|
+ L"ABC.MKF", L"BALL.MKF", L"DATA.MKF", L"F.MKF", L"FBP.MKF",
|
|
|
+ L"FIRE.MKF", L"GOP.MKF", L"MAP.MKF", L"MGO.MKF", L"PAT.MKF",
|
|
|
+ L"RGM.MKF", L"RNG.MKF", L"SSS.MKF"
|
|
|
+ };
|
|
|
+ Platform::String^ optional_required_files[] = {
|
|
|
+ L"VOC.MKF", L"SOUNDS.MKF"
|
|
|
+ };
|
|
|
+ /* The words.dat & m.msg may be configurable in the future, so not check here */
|
|
|
+
|
|
|
+ /* Try to get the path */
|
|
|
+ auto foldertask = concurrency::create_task(root->GetFolderAsync(PAL_PATH_NAME));
|
|
|
+ if (!WaitOnTask(foldertask, 500)) return false; // Wait for 500ms max
|
|
|
+
|
|
|
+ try
|
|
|
+ {
|
|
|
+ /* Check the access right of necessary files */
|
|
|
+ auto folder = foldertask.get();
|
|
|
+ for (int i = 0; i < 13; i++)
|
|
|
+ {
|
|
|
+ auto filetask = concurrency::create_task(foldertask.get()->GetFileAsync(required_files[i]));
|
|
|
+ if (!WaitOnTask(filetask, 500) || _waccess_s(filetask.get()->Path->Begin(), 2)) return false;
|
|
|
+ }
|
|
|
+ for (int i = 0; i < 2; i++)
|
|
|
+ {
|
|
|
+ auto filetask = concurrency::create_task(foldertask.get()->GetFileAsync(optional_required_files[i]));
|
|
|
+ if (WaitOnTask(filetask, 500) && _waccess_s(filetask.get()->Path->Begin(), 2) == 0) return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch(Platform::Exception^)
|
|
|
+ { /* Accessing SD card failed, or required file is missing, or access is denied */ }
|
|
|
+ return false;
|
|
|
+}
|
|
|
+
|
|
|
+extern "C"
|
|
|
+LPCSTR UTIL_WP_BasePath(VOID)
|
|
|
+{
|
|
|
+ if (g_basepath.empty())
|
|
|
+ {
|
|
|
+ auto enumtask = concurrency::create_task(Windows::Storage::KnownFolders::RemovableDevices->GetFoldersAsync());
|
|
|
+ if (WaitOnTask(enumtask, 1000)) // Wait for 1000ms max
|
|
|
+ {
|
|
|
+ auto folderiter = enumtask.get()->First();
|
|
|
+ while (folderiter->HasCurrent)
|
|
|
+ {
|
|
|
+ if (CheckGamePath(folderiter->Current))
|
|
|
+ {
|
|
|
+ /* Folder examination succeeded */
|
|
|
+ auto folder = folderiter->Current->Path;
|
|
|
+ if (folder->End()[-1] != L'\\') folder += "\\";
|
|
|
+ folder += PAL_PATH_NAME "\\";
|
|
|
+ ConvertString(folder, g_basepath);
|
|
|
+
|
|
|
+ /* Check whether the folder is writable */
|
|
|
+ FILE* fp;
|
|
|
+ if (_wfopen_s(&fp, (folder + "sdlpal.rpg")->Begin(), L"w") == 0)
|
|
|
+ {
|
|
|
+ g_savepath = g_basepath;
|
|
|
+ fclose(fp);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ folderiter->MoveNext();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (g_basepath.empty())
|
|
|
+ {
|
|
|
+ g_basepath.assign("Assets\\Data\\");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return g_basepath.c_str();
|
|
|
+}
|
|
|
|
|
|
extern "C"
|
|
|
LPCSTR UTIL_WP_SavePath(VOID)
|
|
|
{
|
|
|
- auto localfolder = Windows::Storage::ApplicationData::Current->LocalFolder->Path;
|
|
|
- int len = WideCharToMultiByte(CP_ACP, 0, localfolder->Begin(), -1, nullptr, 0, nullptr, nullptr);
|
|
|
- g_savepath.resize(len);
|
|
|
- WideCharToMultiByte(CP_ACP, 0, localfolder->Begin(), -1, (char*)g_savepath.data(), len, nullptr, nullptr);
|
|
|
- const_cast<char*>(g_savepath.data())[len - 1] = '\\';
|
|
|
+ if (g_savepath.empty())
|
|
|
+ {
|
|
|
+ auto localfolder = Windows::Storage::ApplicationData::Current->LocalFolder->Path;
|
|
|
+ if (localfolder->End()[-1] != L'\\') localfolder += "\\";
|
|
|
+ ConvertString(localfolder, g_savepath);
|
|
|
+ }
|
|
|
return g_savepath.c_str();
|
|
|
}
|
|
|
|
|
@@ -98,4 +141,4 @@ UTIL_WP_GetScreenSize_exit:
|
|
|
if (pFactory) pFactory->Release();
|
|
|
|
|
|
return retval;
|
|
|
-}
|
|
|
+}
|