Added initial support for iOS

This commit is contained in:
Leon Styhre 2025-01-14 19:17:12 +01:00
parent 2af7267933
commit f3e2c837f2
20 changed files with 205 additions and 54 deletions

View file

@ -156,6 +156,9 @@ const std::string FileData::getROMDirectory()
{
#if defined(__ANDROID__)
return AndroidVariables::sROMDirectory;
#elif defined(__IOS__)
std::string dir {Utils::FileSystem::getHomePath() + "/Documents/ROMs"};
return dir;
#endif
const std::string& romDirSetting {Settings::getInstance()->getString("ROMDirectory")};
@ -187,6 +190,10 @@ const std::string FileData::getROMDirectory()
const std::string FileData::getMediaDirectory()
{
#if defined(__IOS__)
return Utils::FileSystem::getAppDataDirectory() + "/downloaded_media/";
#endif
const std::string& mediaDirSetting {Settings::getInstance()->getString("MediaDirectory")};
std::string mediaDirPath;

View file

@ -21,7 +21,7 @@
#include <windows.h>
#endif
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
#include "ConvertPDF.h"
#endif
@ -56,7 +56,7 @@ bool PDFViewer::startPDFViewer(FileData* game)
{
ViewController::getInstance()->pauseViewVideos();
#if !defined(__ANDROID__)
#if !defined(__ANDROID__) && !defined(__IOS__)
#if defined(_WIN64)
const std::string convertBinary {"/es-pdf-converter/es-pdf-convert.exe"};
#else
@ -305,7 +305,7 @@ bool PDFViewer::getDocumentInfo()
// Close process and thread handles.
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
#elif defined(__ANDROID__)
#elif defined(__ANDROID__) || defined(__IOS__)
if (ConvertPDF::processFile(mManualPath, "-fileinfo", 0, 0, 0, commandOutput) == -1)
return false;
#else
@ -449,7 +449,7 @@ void PDFViewer::convertPage(int pageNum)
CloseHandle(childStdoutRead);
WaitForSingleObject(pi.hThread, INFINITE);
WaitForSingleObject(pi.hProcess, INFINITE);
#elif (__ANDROID__)
#elif (__ANDROID__) || defined(__IOS__)
ConvertPDF::processFile(mManualPath, "-convert", pageNum,
static_cast<int>(mPages[pageNum].width),
static_cast<int>(mPages[pageNum].height), imageData);
@ -478,7 +478,7 @@ void PDFViewer::convertPage(int pageNum)
#if defined(_WIN64)
if (!processReturnValue || (static_cast<int>(imageDataSize) <
mPages[pageNum].width * mPages[pageNum].height * 4)) {
#elif defined(__ANDROID__)
#elif defined(__ANDROID__) || defined(__IOS__)
if (static_cast<int>(imageDataSize) < mPages[pageNum].width * mPages[pageNum].height * 4) {
#else
if (returnValue != 0 || (static_cast<int>(imageDataSize) <

View file

@ -44,6 +44,10 @@
#include "utils/PlatformUtilAndroid.h"
#endif
#if defined(__IOS__)
#include "InputOverlay.h"
#endif
#include <SDL2/SDL_events.h>
#include <algorithm>
@ -1332,7 +1336,7 @@ void GuiMenu::openInputDeviceOptions()
}
});
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
// Touch overlay size.
auto touchOverlaySize = std::make_shared<OptionListComponent<std::string>>(
getHelpStyle(), _("TOUCH OVERLAY SIZE"), false);
@ -1585,6 +1589,7 @@ void GuiMenu::openOtherOptions()
std::bind([this] { mWindow->pushGui(new GuiAlternativeEmulators); }));
s->addRow(alternativeEmulatorsRow);
#if !defined(__IOS__)
// Game media directory.
ComponentListRow rowMediaDir;
auto mediaDirectory = std::make_shared<TextComponent>(
@ -1626,6 +1631,7 @@ void GuiMenu::openOtherOptions()
}
});
s->addRow(rowMediaDir);
#endif
// Maximum VRAM.
auto maxVram = std::make_shared<SliderComponent>(128.0f, 2048.0f, 16.0f, "MiB");
@ -1663,6 +1669,7 @@ void GuiMenu::openOtherOptions()
});
#endif
#if !defined(__IOS__)
// Display/monitor.
auto displayIndex = std::make_shared<OptionListComponent<std::string>>(
getHelpStyle(), _("DISPLAY/MONITOR INDEX"), false);
@ -1683,6 +1690,7 @@ void GuiMenu::openOtherOptions()
s->setNeedsSaving();
}
});
#endif
// Screen contents rotation.
auto screenRotate = std::make_shared<OptionListComponent<std::string>>(
@ -1918,6 +1926,7 @@ void GuiMenu::openOtherOptions()
}
});
#if !defined(__IOS__)
// Custom event scripts, fired using Scripting::fireEvent().
auto customEventScripts = std::make_shared<SwitchComponent>();
customEventScripts->setState(Settings::getInstance()->getBool("CustomEventScripts"));
@ -1929,6 +1938,7 @@ void GuiMenu::openOtherOptions()
s->setNeedsSaving();
}
});
#endif
// Only show games included in the gamelist.xml files.
auto parseGamelistOnly = std::make_shared<SwitchComponent>();

View file

@ -166,7 +166,7 @@ GuiThemeDownloader::GuiThemeDownloader(std::function<void()> updateCallback)
git_libgit2_init();
#if defined(__ANDROID__) && defined(USE_BUNDLED_CERTIFICATES)
#if (defined(__ANDROID__) || defined(__IOS__)) && defined(USE_BUNDLED_CERTIFICATES)
git_libgit2_opts(
GIT_OPT_SET_SSL_CERT_LOCATIONS,
ResourceManager::getInstance().getResourcePath(":/certificates/curl-ca-bundle.crt").c_str(),
@ -178,7 +178,7 @@ GuiThemeDownloader::GuiThemeDownloader(std::function<void()> updateCallback)
std::promise<bool>().swap(mPromise);
mFuture = mPromise.get_future();
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
mThemeDirectory = Utils::FileSystem::getInternalAppDataDirectory() + "/themes";
#else
const std::string defaultUserThemeDir {Utils::FileSystem::getAppDataDirectory() + "/themes"};

View file

@ -35,9 +35,13 @@
#include "views/ViewController.h"
#include <SDL2/SDL_events.h>
#include <SDL2/SDL_main.h>
#include <SDL2/SDL_timer.h>
// TODO: Not needed after moving to SDL3.
#if !defined(__IOS__)
#include <SDL2/SDL_main.h>
#endif
#if defined(__ANDROID__)
#include "utils/PlatformUtilAndroid.h"
#endif
@ -570,7 +574,7 @@ int main(int argc, char* argv[])
SDL_SetHint(SDL_HINT_APP_NAME, "ES-DE");
#if defined(__APPLE__)
#if defined(__APPLE__) && !defined(__IOS__)
// This is a workaround to disable the incredibly annoying save state functionality in
// macOS which forces a restore of the previous window state. The problem is that this
// removes the splash screen on startup and it may have other adverse effects as well.
@ -598,7 +602,7 @@ int main(int argc, char* argv[])
outputToConsole();
#endif
#if !defined(__ANDROID__)
#if !defined(__ANDROID__) && !defined(__IOS__)
{
std::vector<std::string> arguments;
for (int i {0}; i < argc; ++i)
@ -871,7 +875,7 @@ int main(int argc, char* argv[])
}
{
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
const std::string themeDir {Utils::FileSystem::getAppDataDirectory() + "/themes"};
if (!Utils::FileSystem::exists(themeDir)) {
LOG(LogInfo) << "Creating themes directory \"" << themeDir << "\"...";
@ -881,6 +885,7 @@ int main(int argc, char* argv[])
LOG(LogWarning) << "Couldn't create directory, permission problems?";
}
}
#if defined(__ANDROID__)
if (!Utils::FileSystem::exists(themeDir + "/.nomedia")) {
LOG(LogInfo) << "Creating \"no media\" file \"" << themeDir + "/.nomedia" << "\"...";
Utils::FileSystem::createEmptyFile(themeDir + "/.nomedia");
@ -888,6 +893,7 @@ int main(int argc, char* argv[])
LOG(LogWarning) << "Couldn't create file, permission problems?";
}
}
#endif
#else
// Create the themes folder in the application data directory (or elsewhere if the
// UserThemeDirectory setting has been defined).
@ -932,6 +938,7 @@ int main(int argc, char* argv[])
#endif
}
#if !defined(__IOS__)
{
// Create the scripts folder in the application data directory. This is only required
// for custom event scripts so it's also created as a convenience.
@ -949,6 +956,7 @@ int main(int argc, char* argv[])
}
}
}
#endif
{
// Create the screensavers and screensavers/custom_slideshow directories.
@ -1064,9 +1072,11 @@ int main(int argc, char* argv[])
return 1;
}
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
InputOverlay::getInstance().init();
#endif
#if defined(__ANDROID__)
LOG(LogDebug) << "Android API level: " << SDL_GetAndroidSDKVersion();
Utils::Platform::Android::printDeviceInfo();
int storageState {SDL_AndroidGetExternalStorageState()};
@ -1313,5 +1323,9 @@ int main(int argc, char* argv[])
FreeConsole();
#endif
#if defined(__IOS__)
exit(0);
#endif
return 0;
}

View file

@ -67,6 +67,8 @@ public:
const std::string platformIdentifier {" P"};
#elif defined(__linux__)
const std::string platformIdentifier {" L"};
#elif defined(__IOS__)
const std::string platformIdentifier {" I"};
#elif defined(__APPLE__)
const std::string platformIdentifier {" M"};
#elif defined(_WIN64)

View file

@ -266,7 +266,7 @@ void ViewController::invalidSystemsFileDialog()
void ViewController::noGamesDialog()
{
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
mNoGamesErrorMessage = _("NO GAME FILES WERE FOUND, PLEASE PLACE YOUR GAMES IN "
"THE CONFIGURED ROM DIRECTORY. OPTIONALLY THE ROM "
"DIRECTORY STRUCTURE CAN BE GENERATED WHICH WILL "
@ -289,7 +289,7 @@ void ViewController::noGamesDialog()
mRomDirectory = FileData::getROMDirectory();
#endif
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
mNoGamesMessageBox = new GuiMsgBox(
HelpStyle(), mNoGamesErrorMessage + mRomDirectory,
#else
@ -404,7 +404,7 @@ void ViewController::noGamesDialog()
quit.type = SDL_QUIT;
SDL_PushEvent(&quit);
},
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
"", nullptr, nullptr, true, false,
(mRenderer->getIsVerticalOrientation() ?
0.90f :

View file

@ -30,6 +30,10 @@
#include "utils/PlatformUtilAndroid.h"
#endif
#if defined(__IOS__)
#define TOUCH_GUID_STRING "-3"
#endif
namespace
{
int SDL_USER_CECBUTTONDOWN {-1};
@ -38,7 +42,7 @@ namespace
InputManager::InputManager() noexcept
: mWindow {Window::getInstance()}
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
, mInputOverlay {InputOverlay::getInstance()}
#endif
, mKeyboardInputConfig {nullptr}
@ -92,7 +96,7 @@ void InputManager::init()
LOG(LogInfo) << "Added keyboard with default configuration";
}
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
mTouchInputConfig = std::make_unique<InputConfig>(DEVICE_TOUCH, "Touch", TOUCH_GUID_STRING);
loadTouchConfig();
#endif
@ -301,7 +305,7 @@ int InputManager::getNumConfiguredDevices()
if (mKeyboardInputConfig->isConfigured())
++num;
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
if (mTouchInputConfig->isConfigured())
++num;
#endif
@ -335,7 +339,7 @@ std::string InputManager::getDeviceGUIDString(int deviceId)
{
if (deviceId == DEVICE_KEYBOARD)
return KEYBOARD_GUID_STRING;
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
else if (deviceId == DEVICE_TOUCH)
return TOUCH_GUID_STRING;
#endif
@ -358,7 +362,7 @@ InputConfig* InputManager::getInputConfigByDevice(int device)
{
if (device == DEVICE_KEYBOARD)
return mKeyboardInputConfig.get();
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
else if (device == DEVICE_TOUCH)
return mTouchInputConfig.get();
#endif
@ -542,7 +546,7 @@ bool InputManager::parseEvent(const SDL_Event& event)
Input(DEVICE_KEYBOARD, TYPE_KEY, event.key.keysym.sym, 0, false));
return true;
}
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
case SDL_FINGERDOWN: {
if (!Settings::getInstance()->getBool("InputTouchOverlay"))
return false;
@ -736,7 +740,7 @@ void InputManager::loadDefaultControllerConfig(SDL_JoystickID deviceIndex)
void InputManager::loadTouchConfig()
{
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
InputConfig* cfg {mTouchInputConfig.get()};
if (cfg->isConfigured())

View file

@ -13,7 +13,7 @@
#include "CECInput.h"
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
#include "InputOverlay.h"
#endif
@ -68,7 +68,7 @@ private:
Window* mWindow;
CECInput mCECInput;
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
InputOverlay& mInputOverlay;
#endif

View file

@ -30,6 +30,9 @@ namespace Scripting
const std::string& arg3,
const std::string& arg4)
{
#if defined(__IOS__)
return;
#endif
if (!Settings::getInstance()->getBool("CustomEventScripts"))
return;

View file

@ -245,7 +245,7 @@ void Settings::setDefaults()
// Input device settings.
mStringMap["InputControllerType"] = {"xbox", "xbox"};
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
mStringMap["InputTouchOverlaySize"] = {"medium", "medium"};
mStringMap["InputTouchOverlayOpacity"] = {"normal", "normal"};
mIntMap["InputTouchOverlayFadeTime"] = {6, 6};
@ -263,7 +263,9 @@ void Settings::setDefaults()
mBoolMap["FavStarCustom"] = {false, false};
// Other settings.
#if !defined(__IOS__)
mStringMap["MediaDirectory"] = {"", ""};
#endif
#if defined(STEAM_DECK) || defined(RETRODECK)
mIntMap["MaxVRAM"] = {512, 512};
#elif defined(RASPBERRY_PI)
@ -274,7 +276,9 @@ void Settings::setDefaults()
#if !defined(USE_OPENGLES)
mIntMap["AntiAliasing"] = {0, 0};
#endif
#if !defined(__IOS__)
mIntMap["DisplayIndex"] = {1, 1};
#endif
mIntMap["ScreenRotate"] = {0, 0};
#if defined(__APPLE__)
mStringMap["KeyboardQuitShortcut"] = {"CmdQ", "CmdQ"};
@ -304,7 +308,9 @@ void Settings::setDefaults()
mBoolMap["AlternativeEmulatorPerGame"] = {true, true};
mBoolMap["ShowHiddenFiles"] = {true, true};
mBoolMap["ShowHiddenGames"] = {true, true};
#if !defined(__IOS__)
mBoolMap["CustomEventScripts"] = {false, false};
#endif
mBoolMap["ParseGamelistOnly"] = {false, false};
mBoolMap["MAMENameStripExtraInfo"] = {true, true};
#if defined(__unix__) && !defined(__ANDROID__)
@ -351,11 +357,11 @@ void Settings::setDefaults()
mBoolMap["LegacyGamelistFileLocation"] = {false, false};
mBoolMap["CreatePlaceholderSystemDirectories"] = {false, false};
mStringMap["OpenGLVersion"] = {"", ""};
#if !defined(__ANDROID__)
#if !defined(__ANDROID__) && !defined(__IOS__)
mStringMap["ROMDirectory"] = {"", ""};
#endif
mStringMap["UIMode_passkey"] = {"uuddlrlrba", "uuddlrlrba"};
#if !defined(__ANDROID__)
#if !defined(__ANDROID__) && !defined(__IOS__)
mStringMap["UserThemeDirectory"] = {"", ""};
#endif
mIntMap["LottieMaxFileCache"] = {150, 150};

View file

@ -21,6 +21,10 @@
#include <algorithm>
#include <pugixml.hpp>
#if defined(__IOS__)
#include "utils/PlatformUtilIOS.h"
#endif
// clang-format off
std::vector<std::string> ThemeData::sSupportedViews {
{"all"},
@ -770,6 +774,8 @@ void ThemeData::populateThemes()
#if defined(__ANDROID__)
const std::string userThemeDirectory {Utils::FileSystem::getInternalAppDataDirectory() +
"/themes"};
#elif defined(__IOS__)
const std::string userThemeDirectory;
#else
const std::string defaultUserThemeDir {Utils::FileSystem::getAppDataDirectory() + "/themes"};
const std::string userThemeDirSetting {Utils::FileSystem::expandHomePath(
@ -801,6 +807,10 @@ void ThemeData::populateThemes()
const std::vector<std::string> themePaths {Utils::FileSystem::getProgramDataPath() + "/themes",
Utils::FileSystem::getAppDataDirectory() + "/themes",
userThemeDirectory};
#elif defined(__IOS__)
const std::vector<std::string> themePaths {Utils::Platform::iOS::getPackagePath() + "themes",
Utils::FileSystem::getAppDataDirectory() +
"/themes"};
#elif defined(__APPLE__)
const std::vector<std::string> themePaths {
Utils::FileSystem::getExePath() + "/themes",

View file

@ -19,7 +19,7 @@
#include "resources/Font.h"
#include "utils/LocalizationUtil.h"
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
#include "InputOverlay.h"
#endif
@ -436,7 +436,7 @@ void Window::update(int deltaTime)
if (mScreensaver && mRenderScreensaver)
mScreensaver->update(deltaTime);
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
if (Settings::getInstance()->getBool("InputTouchOverlay"))
InputOverlay::getInstance().update(deltaTime);
#endif
@ -657,7 +657,7 @@ void Window::render()
if (mRenderScreensaver)
mScreensaver->renderScreensaver();
#if defined(__ANDROID__)
#if defined(__ANDROID__) || defined(__IOS__)
if (Settings::getInstance()->getBool("InputTouchOverlay"))
InputOverlay::getInstance().render(mRenderer->getIdentity());
#endif

View file

@ -69,6 +69,9 @@ bool Renderer::createWindow()
mInitialCursorState = (SDL_ShowCursor(0) != 0);
#if defined(__IOS__)
int displayIndex {0};
#else
int displayIndex {Settings::getInstance()->getInt("DisplayIndex")};
// Check that an invalid value has not been manually entered in the es_settings.xml file.
if (displayIndex != 1 && displayIndex != 2 && displayIndex != 3 && displayIndex != 4) {
@ -88,6 +91,7 @@ bool Renderer::createWindow()
else {
LOG(LogInfo) << "Using display: " << std::to_string(displayIndex + 1);
}
#endif
SDL_DisplayMode displayMode;
SDL_GetDesktopDisplayMode(displayIndex, &displayMode);
@ -217,6 +221,8 @@ bool Renderer::createWindow()
else
// If the resolution has been manually set from the command line, then keep the border.
windowFlags = SDL_WINDOW_OPENGL;
#elif defined(__IOS__)
windowFlags = SDL_WINDOW_FULLSCREEN | SDL_WINDOW_ALLOW_HIGHDPI | SDL_WINDOW_OPENGL;
#elif defined(__APPLE__)
// Not sure if this could be a useful setting.
// SDL_SetHint(SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES, "0");
@ -249,19 +255,22 @@ bool Renderer::createWindow()
mDisplayIndex = displayIndex;
#if defined(__APPLE__)
// The code below is required as the high DPI scaling on macOS is very bizarre and is
// measured in "points" rather than pixels (even though the naming convention sure looks
// like pixels). For example there could be a 1920x1080 entry in the OS display settings
// that actually corresponds to something like 3840x2160 pixels while at the same time
// there is a separate 1080p entry which corresponds to a "real" 1920x1080 resolution.
// The code below is required as the high DPI scaling on macOS and iOS is measured in "points"
// rather than pixels. For example there could be a 1920x1080 entry in the macOS display
// settings that actually corresponds to something like 3840x2160 pixels while at the same
// time there is a separate 1080p entry which corresponds to a "real" 1920x1080 resolution.
// Therefore the --resolution flag results in different things depending on whether a high
// DPI screen is used. E.g. 1280x720 on a 4K display would actually end up as 2560x1440
// which is incredibly strange. No point in struggling with this strangeness though,
// instead we simply indicate the physical pixel dimensions in parenthesis in the log
// file and make sure to double the window and screen sizes in case of a high DPI
// display so that the full application window is used for rendering.
// DPI screen is used. E.g. 1280x720 on a 4K display would actually end up as 2560x1440 pixels.
// The scale factor on macOS and iOS can be 1, 2 or 3 and we use this factor to calculate the
// actual physical pixel dimensions. We indicate these numbers inside parenthesis in the log
// file and we multiply the internal pixel resolution accordingly so that the full display
// or window size is always used for rendering.
int width {0};
#if defined(__IOS__)
SDL_GetWindowSizeInPixels(mSDLWindow, &width, nullptr);
#else
SDL_GL_GetDrawableSize(mSDLWindow, &width, nullptr);
#endif
int scaleFactor {static_cast<int>(width / mWindowWidth)};
LOG(LogInfo) << "Display resolution: " << std::to_string(displayMode.w) << "x"

View file

@ -14,9 +14,17 @@
#include <chrono>
#endif
#if defined(__IOS__)
#include <SDL2/SDL_syswm.h>
#endif
RendererOpenGL::RendererOpenGL() noexcept
: mShaderFBO1 {0}
, mShaderFBO2 {0}
, mFramebuffer {0}
#if defined(__IOS__)
, mColorbuffer {0}
#endif
, mVertexBuffer1 {0}
, mVertexBuffer2 {0}
, mSDLContext {nullptr}
@ -112,7 +120,7 @@ GLenum RendererOpenGL::convertTextureType(const TextureType type)
#else
case TextureType::BGRA: { return GL_BGRA; } break;
#endif
#if defined(__EMSCRIPTEN__) || defined(__ANDROID__)
#if defined(__EMSCRIPTEN__) || defined(__ANDROID__) || defined(__IOS__)
case TextureType::RED: { return GL_LUMINANCE; } break;
#else
case TextureType::RED: { return GL_RED; } break;
@ -251,6 +259,28 @@ bool RendererOpenGL::createContext()
#endif
#endif
#if defined(__IOS__)
SDL_SysWMinfo info {};
SDL_VERSION(&info.version);
UIWindow* uiWindow {nullptr};
if (SDL_GetWindowWMInfo(getSDLWindow(), &info) && info.subsystem == SDL_SYSWM_UIKIT)
uiWindow = (UIWindow*)info.info.uikit.window;
if (uiWindow) {
mFramebuffer = info.info.uikit.framebuffer;
mColorbuffer = info.info.uikit.colorbuffer;
}
GL_CHECK_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer));
GL_CHECK_ERROR(glBindRenderbuffer(GL_RENDERBUFFER, mColorbuffer));
GLenum status {glCheckFramebufferStatus(GL_FRAMEBUFFER)};
if (status != GL_FRAMEBUFFER_COMPLETE) {
LOG(LogError) << "Couldn't setup framebuffer: " << status;
}
#endif
GL_CHECK_ERROR(glClearColor(0.0f, 0.0f, 0.0f, 1.0f));
GL_CHECK_ERROR(glActiveTexture(GL_TEXTURE0));
GL_CHECK_ERROR(glEnable(GL_BLEND));
@ -306,7 +336,7 @@ bool RendererOpenGL::createContext()
GL_CHECK_ERROR(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
mPostProcTexture2, 0));
GL_CHECK_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0));
GL_CHECK_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer));
return true;
}
@ -379,7 +409,7 @@ void RendererOpenGL::setSwapInterval()
void RendererOpenGL::swapBuffers()
{
#if defined(__APPLE__)
#if defined(__APPLE__) && !defined(__IOS__)
// On macOS when running in the background, the OpenGL driver apparently does not swap
// the frames which leads to a very fast swap time. This makes ES-DE use a lot of CPU
// resources which slows down the games significantly on slower machines. By introducing
@ -444,8 +474,17 @@ unsigned int RendererOpenGL::createTexture(const unsigned int texUnit,
GL_UNSIGNED_BYTE, data));
}
else {
#if defined(__IOS__)
if (type == TextureType::RED)
GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, textureType, width, height, 0,
textureType, GL_UNSIGNED_BYTE, data));
else
GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, textureType,
GL_UNSIGNED_BYTE, data));
#else
GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, textureType, width, height, 0, textureType,
GL_UNSIGNED_BYTE, data));
#endif
}
#else
GL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, textureType,
@ -756,7 +795,7 @@ void RendererOpenGL::shaderPostprocessing(unsigned int shaders,
for (int p {0}; p < shaderPasses; ++p) {
if (!textureRGBA && i == shaderList.size() - 1 && p == shaderPasses - 1) {
GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0));
GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer));
if (offsetOrPadding)
setViewport(mViewport);
drawTriangleStrips(vertices, 4, BlendFactor::SRC_ALPHA,
@ -818,10 +857,10 @@ void RendererOpenGL::shaderPostprocessing(unsigned int shaders,
GL_CHECK_ERROR(
glReadPixels(0, 0, height, width, GL_BGRA, GL_UNSIGNED_BYTE, textureRGBA));
#endif
GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0));
GL_CHECK_ERROR(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mFramebuffer));
}
GL_CHECK_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0));
GL_CHECK_ERROR(glBindFramebuffer(GL_READ_FRAMEBUFFER, mFramebuffer));
if (offsetOrPadding)
setViewport(mViewport);

View file

@ -13,7 +13,11 @@
#include "renderers/ShaderOpenGL.h"
#if defined(USE_OPENGLES)
#if defined(__IOS__)
#include <OpenGLES/ES3/gl.h>
#else
#include <GLES3/gl3.h>
#endif
#include <SDL2/SDL_opengles.h>
#else
#include <SDL2/SDL.h>
@ -78,6 +82,10 @@ private:
std::vector<std::shared_ptr<ShaderOpenGL>> mShaderProgramVector;
GLuint mShaderFBO1;
GLuint mShaderFBO2;
GLuint mFramebuffer;
#if defined(__IOS__)
GLuint mColorbuffer;
#endif
GLuint mVertexBuffer1;
GLuint mVertexBuffer2;

View file

@ -14,13 +14,21 @@
#include "renderers/Renderer.h"
#include "utils/MathUtil.h"
#if defined(__IOS__)
#define GLES_SILENCE_DEPRECATION
#endif
#if defined(_WIN64)
#include <GL/glew.h>
#endif
#include <SDL2/SDL.h>
#if defined(USE_OPENGLES)
#if defined(__IOS__)
#include <OpenGLES/ES3/gl.h>
#else
#include <GLES3/gl3.h>
#endif
#include <SDL2/SDL_opengles.h>
#else
#include <SDL2/SDL_opengl.h>

View file

@ -16,6 +16,10 @@
#include <fstream>
#if defined(__IOS__)
#include "utils/PlatformUtilIOS.h"
#endif
ResourceManager& ResourceManager::getInstance()
{
static ResourceManager instance;
@ -32,14 +36,21 @@ std::string ResourceManager::getResourcePath(const std::string& path, bool termi
if (Utils::FileSystem::exists(testHome))
return testHome;
#if defined(__APPLE__)
#if defined(__IOS__)
const std::string iOSPackagePath {Utils::Platform::iOS::getPackagePath() + &path[2]};
if (Utils::FileSystem::exists(iOSPackagePath))
return iOSPackagePath;
#endif
#if defined(__APPLE__) && !defined(__IOS__)
// For macOS, check in the ../Resources directory relative to the executable directory.
std::string applePackagePath {Utils::FileSystem::getExePath() + "/../Resources/resources/" +
&path[2]};
if (Utils::FileSystem::exists(applePackagePath)) {
if (Utils::FileSystem::exists(applePackagePath))
return applePackagePath;
}
#elif (defined(__unix__) && !defined(APPIMAGE_BUILD)) || defined(__ANDROID__) || defined(__HAIKU__)
// Check in the program data directory.
std::string testDataPath {Utils::FileSystem::getProgramDataPath() + "/resources/" +
@ -71,10 +82,12 @@ std::string ResourceManager::getResourcePath(const std::string& path, bool termi
LOG(LogError) << "Program resource missing: " << path;
LOG(LogError) << "Tried to find the resource in the following locations:";
LOG(LogError) << testHome;
#if defined(__APPLE__)
#if defined(__IOS__)
LOG(LogError) << iOSPackagePath;
#elif defined(__APPLE__)
LOG(LogError) << applePackagePath;
#elif defined(__unix__) && !defined(APPIMAGE_BUILD)
LOG(LogError) << testDataPath;
LOG(LogError) << testDataPath;
#endif
#if !defined(__ANDROID__)
LOG(LogError) << testExePath;

View file

@ -260,7 +260,10 @@ namespace Utils
{
#if defined(__ANDROID__)
return getHomePath();
#else
#elif defined(__IOS__)
return getHomePath() + "/Documents/ES-DE";
#endif
if (FileSystemVariables::sAppDataDirectory.empty()) {
#if !defined(_WIN64)
if (getenv("ESDE_APPDATA_DIR") != nullptr) {
@ -282,7 +285,6 @@ namespace Utils
}
return FileSystemVariables::sAppDataDirectory;
#endif
}
std::string getInternalAppDataDirectory()

View file

@ -41,6 +41,9 @@ namespace Utils
{
int runRebootCommand()
{
#if defined(__IOS__)
return 0;
#else
#if defined(_WIN64)
return system("shutdown -r -t 0");
#elif defined(__APPLE__) || defined(__FreeBSD__)
@ -48,11 +51,15 @@ namespace Utils
return system("shutdown -r now");
#else
return system("shutdown --reboot now");
#endif
#endif
}
int runPoweroffCommand()
{
#if defined(__IOS__)
return 0;
#else
#if defined(_WIN64)
return system("shutdown -s -t 0");
#elif defined(__APPLE__)
@ -62,11 +69,15 @@ namespace Utils
return system("shutdown -p now");
#else
return system("shutdown --poweroff now");
#endif
#endif
}
int runSystemCommand(const std::string& cmd_utf8)
{
#if defined(__IOS__)
return 0;
#else
#if defined(_WIN64)
// On Windows we use _wsystem to support non-ASCII paths
// which requires converting from UTF-8 to a wstring.
@ -74,6 +85,7 @@ namespace Utils
return _wsystem(wchar_str.c_str());
#else
return system(cmd_utf8.c_str());
#endif
#endif
}
@ -102,7 +114,11 @@ namespace Utils
LOG(LogDebug)
<< "Platform::launchGameUnix(): Launching game while keeping ES-DE running "
"in the background, no command output will be written to the log file";
#if defined(__IOS__)
return 0;
#else
return system(command.c_str());
#endif
}
FILE* commandPipe;