mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-01-17 22:55:38 +00:00
(Android) Added experimental support for running in multi-window mode
This commit is contained in:
parent
697c3fb74f
commit
b26da9d80d
|
@ -596,6 +596,13 @@ bool SystemData::loadConfig()
|
|||
sStartupExitSignal = true;
|
||||
return true;
|
||||
}
|
||||
#if defined(__ANDROID__)
|
||||
if (event.type == SDL_WINDOWEVENT &&
|
||||
event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||
ViewController::getInstance()->setWindowSizeChanged(
|
||||
static_cast<int>(event.window.data1), static_cast<int>(event.window.data2));
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
std::string name;
|
||||
|
|
|
@ -503,6 +503,15 @@ void applicationLoop()
|
|||
if (SDL_PollEvent(&event)) {
|
||||
do {
|
||||
#if defined(__ANDROID__)
|
||||
if (event.type == SDL_WINDOWEVENT &&
|
||||
event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||
// This covers switching to/from multi-window mode. Note that the reload
|
||||
// mechanism is rather ungraceful as it just forcekills any open windows, which
|
||||
// is problematic if the scraper or theme downloader is running for instance.
|
||||
ViewController::getInstance()->setWindowSizeChanged(
|
||||
static_cast<int>(event.window.data1), static_cast<int>(event.window.data2));
|
||||
ViewController::getInstance()->checkWindowSizeChanged();
|
||||
}
|
||||
// Prevent that button presses get registered immediately when entering the
|
||||
// foreground (which most commonly mean we're returning from a game).
|
||||
// Also perform some other tasks on resume such as resetting timers.
|
||||
|
@ -1101,7 +1110,16 @@ int main(int argc, char* argv[])
|
|||
if (Settings::getInstance()->getBool("SplashScreen"))
|
||||
window->renderSplashScreen(Window::SplashScreenState::SCANNING, 0.0f);
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
while (SDL_PollEvent(&event)) {
|
||||
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||
ViewController::getInstance()->setWindowSizeChanged(
|
||||
static_cast<int>(event.window.data1), static_cast<int>(event.window.data2));
|
||||
}
|
||||
};
|
||||
#else
|
||||
while (SDL_PollEvent(&event)) {};
|
||||
#endif
|
||||
|
||||
#if defined(_WIN64)
|
||||
// Hide taskbar if the setting for this is enabled.
|
||||
|
@ -1249,6 +1267,11 @@ int main(int argc, char* argv[])
|
|||
|
||||
// Main application loop.
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
// If the window size changed during startup then we need to resize and reload.
|
||||
ViewController::getInstance()->checkWindowSizeChanged();
|
||||
#endif
|
||||
|
||||
if (!SystemData::sStartupExitSignal) {
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
emscripten_set_main_loop(&applicationLoop, 0, 1);
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "views/ViewController.h"
|
||||
|
||||
#include "ApplicationUpdater.h"
|
||||
#include "AudioManager.h"
|
||||
#include "CollectionSystemsManager.h"
|
||||
#include "FileFilterIndex.h"
|
||||
#include "InputManager.h"
|
||||
|
@ -35,6 +36,10 @@
|
|||
#include "views/GamelistView.h"
|
||||
#include "views/SystemView.h"
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#include "utils/PlatformUtilAndroid.h"
|
||||
#endif
|
||||
|
||||
ViewController::ViewController() noexcept
|
||||
: mRenderer {Renderer::getInstance()}
|
||||
, mNoGamesMessageBox {nullptr}
|
||||
|
@ -49,6 +54,8 @@ ViewController::ViewController() noexcept
|
|||
, mFadeOpacity {0}
|
||||
, mCancelledTransition {false}
|
||||
, mNextSystem {false}
|
||||
, mWindowChangedWidth {0}
|
||||
, mWindowChangedHeight {0}
|
||||
{
|
||||
mState.viewing = ViewMode::NOTHING;
|
||||
mState.previouslyViewed = ViewMode::NOTHING;
|
||||
|
@ -1373,6 +1380,13 @@ void ViewController::preload()
|
|||
SystemData::sStartupExitSignal = true;
|
||||
return;
|
||||
}
|
||||
#if defined(__ANDROID__)
|
||||
if (event.type == SDL_WINDOWEVENT &&
|
||||
event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||
setWindowSizeChanged(static_cast<int>(event.window.data1),
|
||||
static_cast<int>(event.window.data2));
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
const std::string entryType {(*it)->isCustomCollection() ? "custom collection" : "system"};
|
||||
|
@ -1551,6 +1565,71 @@ void ViewController::reloadAll()
|
|||
updateHelpPrompts();
|
||||
}
|
||||
|
||||
void ViewController::setWindowSizeChanged(const int width, const int height)
|
||||
{
|
||||
#if defined(__ANDROID__)
|
||||
const std::pair<int, int> windowSize {Utils::Platform::Android::getWindowSize()};
|
||||
|
||||
if (windowSize.first == static_cast<int>(mRenderer->getScreenWidth()) &&
|
||||
windowSize.second == static_cast<int>(mRenderer->getScreenHeight())) {
|
||||
mWindowChangedWidth = 0;
|
||||
mWindowChangedHeight = 0;
|
||||
}
|
||||
else {
|
||||
mWindowChangedWidth = windowSize.first;
|
||||
mWindowChangedHeight = windowSize.second;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ViewController::checkWindowSizeChanged()
|
||||
{
|
||||
if (mWindowChangedWidth == 0 || mWindowChangedHeight == 0)
|
||||
return;
|
||||
|
||||
LOG(LogInfo) << "Window size has changed from " << mRenderer->getScreenWidth() << "x"
|
||||
<< mRenderer->getScreenHeight() << " to " << mWindowChangedWidth << "x"
|
||||
<< mWindowChangedHeight << ", reloading...";
|
||||
|
||||
mWindowChangedWidth = 0;
|
||||
mWindowChangedHeight = 0;
|
||||
|
||||
mWindow->stopInfoPopup();
|
||||
|
||||
if (mState.viewing != ViewController::ViewMode::NOTHING) {
|
||||
mWindow->stopScreensaver();
|
||||
mWindow->stopMediaViewer();
|
||||
mWindow->stopPDFViewer();
|
||||
}
|
||||
|
||||
// This is done quite ungracefully, essentially forcekilling all open windows.
|
||||
while (mWindow->getGuiStackSize() > 1)
|
||||
mWindow->removeGui(mWindow->peekGui());
|
||||
|
||||
AudioManager::getInstance().deinit();
|
||||
mWindow->deinit();
|
||||
SDL_Delay(20);
|
||||
AudioManager::getInstance().init();
|
||||
mWindow->init(true);
|
||||
|
||||
mWindow->setLaunchedGame(false);
|
||||
mWindow->invalidateCachedBackground();
|
||||
mWindow->renderSplashScreen(Window::SplashScreenState::RELOADING, 0.0f);
|
||||
|
||||
if (mState.viewing != ViewController::ViewMode::NOTHING) {
|
||||
reloadAll();
|
||||
goToStart(false);
|
||||
resetCamera();
|
||||
}
|
||||
else {
|
||||
noGamesDialog();
|
||||
}
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
InputOverlay::getInstance().init();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ViewController::rescanROMDirectory()
|
||||
{
|
||||
mWindow->setBlockInput(true);
|
||||
|
|
|
@ -56,6 +56,10 @@ public:
|
|||
// Reload everything with a theme, used when the "Theme" setting changes.
|
||||
void reloadAll();
|
||||
|
||||
// On window size changes we need to deinit/init the application, reload the systems etc.
|
||||
void setWindowSizeChanged(const int width, const int height);
|
||||
void checkWindowSizeChanged();
|
||||
|
||||
// Rescan the ROM directory for any changes to games and systems.
|
||||
void rescanROMDirectory();
|
||||
|
||||
|
@ -199,6 +203,8 @@ private:
|
|||
float mFadeOpacity;
|
||||
bool mCancelledTransition; // Needed only for the Fade transition style.
|
||||
bool mNextSystem;
|
||||
int mWindowChangedWidth;
|
||||
int mWindowChangedHeight;
|
||||
};
|
||||
|
||||
#endif // ES_APP_VIEWS_VIEW_CONTROLLER_H
|
||||
|
|
|
@ -107,7 +107,7 @@ GuiComponent* Window::peekGui()
|
|||
return mGuiStack.back();
|
||||
}
|
||||
|
||||
bool Window::init()
|
||||
bool Window::init(bool resized)
|
||||
{
|
||||
if (!mRenderer->init()) {
|
||||
LOG(LogError) << "Renderer failed to initialize.";
|
||||
|
@ -133,6 +133,9 @@ bool Window::init()
|
|||
mDefaultFonts.push_back(Font::get(FONT_SIZE_LARGE_FIXED));
|
||||
}
|
||||
|
||||
if (resized)
|
||||
Font::updateFontSizes();
|
||||
|
||||
if (mRenderer->getIsVerticalOrientation())
|
||||
mSplash->setResize(mRenderer->getScreenWidth() * 0.8f, 0.0f);
|
||||
else
|
||||
|
|
|
@ -93,7 +93,7 @@ public:
|
|||
int getGuiStackSize() { return static_cast<int>(mGuiStack.size()); }
|
||||
bool isBackgroundDimmed();
|
||||
|
||||
bool init();
|
||||
bool init(bool resized = false);
|
||||
void deinit();
|
||||
|
||||
void input(InputConfig* config, Input input);
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
#include "renderers/ShaderOpenGL.h"
|
||||
#include "resources/ResourceManager.h"
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
#include "utils/PlatformUtilAndroid.h"
|
||||
#endif
|
||||
|
||||
#if defined(_WIN64)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
@ -101,12 +105,26 @@ bool Renderer::createWindow()
|
|||
displayMode.h = displayBounds.h;
|
||||
#endif
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
const std::pair<int, int> windowSize {Utils::Platform::Android::getWindowSize()};
|
||||
|
||||
if (windowSize.first != 0 && windowSize.second != 0) {
|
||||
sScreenWidth = windowSize.first;
|
||||
sScreenHeight = windowSize.second;
|
||||
}
|
||||
else {
|
||||
sScreenWidth = displayMode.w;
|
||||
sScreenHeight = displayMode.h;
|
||||
}
|
||||
#else
|
||||
sScreenWidth = Settings::getInstance()->getInt("ScreenWidth") ?
|
||||
Settings::getInstance()->getInt("ScreenWidth") :
|
||||
displayMode.w;
|
||||
sScreenHeight = Settings::getInstance()->getInt("ScreenHeight") ?
|
||||
Settings::getInstance()->getInt("ScreenHeight") :
|
||||
displayMode.h;
|
||||
#endif
|
||||
|
||||
mScreenOffsetX = glm::clamp((Settings::getInstance()->getInt("ScreenOffsetX") ?
|
||||
Settings::getInstance()->getInt("ScreenOffsetX") :
|
||||
0),
|
||||
|
@ -228,6 +246,8 @@ bool Renderer::createWindow()
|
|||
return false;
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -183,6 +183,7 @@ public:
|
|||
const glm::mat4& getProjectionMatrix() { return mProjectionMatrix; }
|
||||
const glm::mat4& getProjectionMatrixNormal() { return mProjectionMatrixNormal; }
|
||||
SDL_Window* getSDLWindow() { return mSDLWindow; }
|
||||
const int getDisplayIndex() { return mDisplayIndex; }
|
||||
const int getScreenRotation() { return mScreenRotation; }
|
||||
static const bool getIsVerticalOrientation() { return sIsVerticalOrientation; }
|
||||
static const float getScreenWidth() { return static_cast<float>(sScreenWidth); }
|
||||
|
@ -249,6 +250,7 @@ private:
|
|||
|
||||
static inline int sScreenWidth {0};
|
||||
static inline int sScreenHeight {0};
|
||||
int mDisplayIndex {0};
|
||||
int mScreenRotation {0};
|
||||
bool mInitialCursorState {true};
|
||||
static inline bool sIsVerticalOrientation {false};
|
||||
|
|
|
@ -118,6 +118,16 @@ std::shared_ptr<Font> Font::get(float size, const std::string& path)
|
|||
return font;
|
||||
}
|
||||
|
||||
void Font::updateFontSizes()
|
||||
{
|
||||
getMiniFont(true);
|
||||
getSmallFont(true);
|
||||
getMediumFont(true);
|
||||
getMediumFixedFont(true);
|
||||
getLargeFont(true);
|
||||
getLargeFixedFont(true);
|
||||
}
|
||||
|
||||
glm::vec2 Font::sizeText(std::string text, float lineSpacing)
|
||||
{
|
||||
if (text == "")
|
||||
|
|
|
@ -37,46 +37,65 @@ class Font : public IReloadable
|
|||
public:
|
||||
virtual ~Font();
|
||||
static std::shared_ptr<Font> get(float size, const std::string& path = getDefaultPath());
|
||||
static float getMiniFont()
|
||||
static float getMiniFont(bool forceUpdate = false)
|
||||
{
|
||||
static float sMiniFont {0.030f *
|
||||
std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth())};
|
||||
if (forceUpdate)
|
||||
sMiniFont = 0.030f * std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth());
|
||||
return sMiniFont;
|
||||
}
|
||||
static float getSmallFont()
|
||||
static float getSmallFont(bool forceUpdate = false)
|
||||
{
|
||||
static float sSmallFont {0.035f *
|
||||
std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth())};
|
||||
if (forceUpdate)
|
||||
sSmallFont = 0.035f * std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth());
|
||||
return sSmallFont;
|
||||
}
|
||||
static float getMediumFont()
|
||||
static float getMediumFont(bool forceUpdate = false)
|
||||
{
|
||||
static float sMediumFont {
|
||||
(Renderer::getIsVerticalOrientation() ? 0.040f : 0.045f) *
|
||||
std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth())};
|
||||
if (forceUpdate)
|
||||
sMediumFont = (Renderer::getIsVerticalOrientation() ? 0.040f : 0.045f) *
|
||||
std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth());
|
||||
return sMediumFont;
|
||||
}
|
||||
static float getMediumFixedFont()
|
||||
static float getMediumFixedFont(bool forceUpdate = false)
|
||||
{
|
||||
// Fixed size regardless of screen orientation.
|
||||
static float sMediumFixedFont {
|
||||
0.045f * std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth())};
|
||||
if (forceUpdate)
|
||||
sMediumFixedFont =
|
||||
0.045f * std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth());
|
||||
return sMediumFixedFont;
|
||||
}
|
||||
static float getLargeFont()
|
||||
static float getLargeFont(bool forceUpdate = false)
|
||||
{
|
||||
static float sLargeFont {(Renderer::getIsVerticalOrientation() ? 0.080f : 0.085f) *
|
||||
std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth())};
|
||||
if (forceUpdate)
|
||||
sLargeFont = (Renderer::getIsVerticalOrientation() ? 0.080f : 0.085f) *
|
||||
std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth());
|
||||
return sLargeFont;
|
||||
}
|
||||
static float getLargeFixedFont()
|
||||
static float getLargeFixedFont(bool forceUpdate = false)
|
||||
{
|
||||
// Fixed size regardless of screen orientation.
|
||||
static float sLargeFixedFont {
|
||||
0.085f * std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth())};
|
||||
if (forceUpdate)
|
||||
sLargeFixedFont =
|
||||
0.085f * std::min(Renderer::getScreenHeight(), Renderer::getScreenWidth());
|
||||
return sLargeFixedFont;
|
||||
}
|
||||
|
||||
// Needed for when the application window has been resized.
|
||||
static void updateFontSizes();
|
||||
|
||||
// Returns the size of shaped text without applying any wrapping or abbreviations.
|
||||
glm::vec2 sizeText(std::string text, float lineSpacing = 1.5f);
|
||||
|
||||
|
|
Loading…
Reference in a new issue