WinRTUtil.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #include "pch.h"
  2. #include <wrl.h>
  3. #include <string>
  4. #include <DXGI.h>
  5. #include <ppltasks.h>
  6. #include "../SDLPal.Common/AsyncHelper.h"
  7. #include "../SDLPal.Common/StringHelper.h"
  8. #include "../../main.h"
  9. #include "SDL.h"
  10. #include "SDL_endian.h"
  11. static std::string g_basepath, g_configpath;
  12. extern HANDLE g_eventHandle;
  13. extern "C"
  14. LPCSTR UTIL_BasePath(VOID)
  15. {
  16. if (g_basepath.empty())
  17. {
  18. auto mru_list = Windows::Storage::AccessCache::StorageApplicationPermissions::MostRecentlyUsedList;
  19. for each (auto entry in mru_list->Entries)
  20. {
  21. if (dynamic_cast<Windows::Storage::StorageFolder^>(AWait(mru_list->GetItemAsync(entry.Token), g_eventHandle)) != nullptr)
  22. {
  23. auto localfolder = entry.Metadata;
  24. if (localfolder->End()[-1] != L'\\') localfolder += "\\";
  25. ConvertString(localfolder, g_basepath);
  26. break;
  27. }
  28. }
  29. }
  30. return g_basepath.c_str();
  31. }
  32. extern "C"
  33. LPCSTR UTIL_SavePath(VOID)
  34. {
  35. return UTIL_BasePath();
  36. }
  37. extern "C"
  38. LPCSTR UTIL_ConfigPath(VOID)
  39. {
  40. if (g_configpath.empty())
  41. {
  42. auto localfolder = Windows::Storage::ApplicationData::Current->LocalFolder->Path;
  43. if (localfolder->End()[-1] != L'\\') localfolder += "\\";
  44. ConvertString(localfolder, g_configpath);
  45. }
  46. return g_configpath.c_str();
  47. }
  48. extern "C"
  49. LPCSTR UTIL_ScreenShotPath(VOID)
  50. {
  51. return gConfig.pszGamePath;
  52. }
  53. extern "C"
  54. BOOL UTIL_GetScreenSize(DWORD *pdwScreenWidth, DWORD *pdwScreenHeight)
  55. {
  56. DXGI_OUTPUT_DESC desc;
  57. IDXGIFactory1* pFactory = nullptr;
  58. IDXGIAdapter1* pAdapter = nullptr;
  59. IDXGIOutput* pOutput = nullptr;
  60. DWORD retval = FALSE;
  61. #if NTDDI_VERSION >= NTDDI_WIN10
  62. if (Windows::System::Profile::AnalyticsInfo::VersionInfo->DeviceFamily != L"Windows.Mobile") return FALSE;
  63. #endif
  64. if (!pdwScreenWidth || !pdwScreenHeight) return FALSE;
  65. if (FAILED(CreateDXGIFactory1(IID_IDXGIFactory1, (void**)&pFactory))) goto UTIL_WP_GetScreenSize_exit;
  66. if (FAILED(pFactory->EnumAdapters1(0, &pAdapter))) goto UTIL_WP_GetScreenSize_exit;
  67. if (FAILED(pAdapter->EnumOutputs(0, &pOutput))) goto UTIL_WP_GetScreenSize_exit;
  68. if (SUCCEEDED(pOutput->GetDesc(&desc)))
  69. {
  70. #if (NTDDI_VERSION < NTDDI_WIN10) && (WINAPI_FAMILY != WINAPI_FAMILY_PHONE_APP)
  71. *pdwScreenWidth = (desc.DesktopCoordinates.right - desc.DesktopCoordinates.left);
  72. *pdwScreenHeight = (desc.DesktopCoordinates.bottom - desc.DesktopCoordinates.top);
  73. #else
  74. *pdwScreenWidth = (desc.DesktopCoordinates.bottom - desc.DesktopCoordinates.top);
  75. *pdwScreenHeight = (desc.DesktopCoordinates.right - desc.DesktopCoordinates.left);
  76. #endif
  77. retval = TRUE;
  78. }
  79. UTIL_WP_GetScreenSize_exit:
  80. if (pOutput) pOutput->Release();
  81. if (pAdapter) pAdapter->Release();
  82. if (pFactory) pFactory->Release();
  83. return retval;
  84. }
  85. extern "C"
  86. BOOL UTIL_IsAbsolutePath(LPCSTR lpszFileName)
  87. {
  88. char szDrive[_MAX_DRIVE], szDir[_MAX_DIR], szFname[_MAX_FNAME], szExt[_MAX_EXT];
  89. if (_splitpath_s(lpszFileName, szDrive, szDir, szFname, szExt) == 0)
  90. return (strlen(szDrive) > 0 && (szDir[0] == '\\' || szDir[0] == '/'));
  91. else
  92. return FALSE;
  93. }
  94. extern "C"
  95. BOOL UTIL_TouchEnabled(VOID)
  96. {
  97. return (ref new Windows::Devices::Input::TouchCapabilities())->TouchPresent;
  98. }
  99. static Windows::Storage::StorageFile^ g_running_file = nullptr;
  100. static void CreateRunningFile()
  101. {
  102. // Create the 'running' file for crash detection.
  103. try { g_running_file = AWait(Windows::Storage::ApplicationData::Current->LocalFolder->CreateFileAsync("running", Windows::Storage::CreationCollisionOption::OpenIfExists), g_eventHandle); }
  104. catch (Platform::Exception^) {}
  105. }
  106. static void DeleteRunningFile()
  107. {
  108. // Delete the 'running' file on normal exit.
  109. try { if (g_running_file) AWait(g_running_file->DeleteAsync()); g_running_file = nullptr; }
  110. catch (Platform::Exception^) {}
  111. }
  112. static int SDLCALL WinRT_EventFilter(void *userdata, SDL_Event * event)
  113. {
  114. switch (event->type)
  115. {
  116. case SDL_APP_DIDENTERFOREGROUND:
  117. CreateRunningFile();
  118. break;
  119. case SDL_APP_DIDENTERBACKGROUND:
  120. case SDL_APP_TERMINATING:
  121. // Enter background or exiting, treat as normal exit
  122. DeleteRunningFile();
  123. break;
  124. }
  125. return 0;
  126. }
  127. static int input_event_filter(const SDL_Event *lpEvent, PALINPUTSTATE *state)
  128. {
  129. if (lpEvent->type == SDL_KEYDOWN &&
  130. lpEvent->key.keysym.sym == SDLK_AC_BACK &&
  131. !gpGlobals->fInMainGame)
  132. {
  133. PAL_Shutdown(0);
  134. }
  135. return 0;
  136. }
  137. extern "C"
  138. INT UTIL_Platform_Init(int argc, char* argv[])
  139. {
  140. // Defaults log to debug output
  141. UTIL_LogAddOutputCallback([](LOGLEVEL, const char* str, const char*)->void {
  142. OutputDebugStringA(str);
  143. }, PAL_DEFAULT_LOGLEVEL);
  144. CreateRunningFile();
  145. SDL_SetHint(SDL_HINT_ORIENTATIONS, "LandscapeRight");
  146. SDL_SetHint(SDL_HINT_WINRT_HANDLE_BACK_BUTTON, "1");
  147. SDL_AddEventWatch(WinRT_EventFilter, nullptr);
  148. return 0;
  149. }
  150. extern "C"
  151. VOID UTIL_Platform_Quit(VOID)
  152. {
  153. DeleteRunningFile();
  154. }