diff --git a/android/AndroidManifest.template.xml b/android/AndroidManifest.template.xml index 68ce6bbdc..c84b868c1 100644 --- a/android/AndroidManifest.template.xml +++ b/android/AndroidManifest.template.xml @@ -40,6 +40,7 @@ android:allowBackup="true" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:hardwareAccelerated="true" + @ANDROID_PROPERTIES@ > 1) - { - prefs.Set("Scale", scale); - SDL_SetWindowSize(sdl_window, WINDOWW * scale, WINDOWH * scale); - showLargeScreenDialog = true; - } - } - StopTextInput(); auto &engine = ui::Engine::Ref(); engine.g = new Graphics(); engine.Scale = scale; engine.GraveExitsConsole = graveExitsConsole; - engine.SetResizable(resizable); - engine.Fullscreen = fullscreen; - engine.SetAltFullscreen(altFullscreen); - engine.SetForceIntegerScaling(forceIntegerScaling); + engine.SetWindowFrameOps(currentFrameOps); engine.MomentumScroll = momentumScroll; engine.ShowAvatars = showAvatars; engine.Begin(); engine.SetFastQuit(prefs.Get("FastQuit", true)); + engine.TouchUI = prefs.Get("TouchUI", DEFAULT_TOUCH_UI); + + if (Client::Ref().IsFirstRun() && FORCE_WINDOW_FRAME_OPS == forceWindowFrameOpsNone) + { + scale = GuessBestScale(); + if (scale > 1) + { + prefs.Set("Scale", scale); + showLargeScreenDialog = true; + } + } + + SDLSetScreen(scale, { + prefs.Get("Resizable", false), + prefs.Get("Fullscreen", false), + prefs.Get("AltFullscreen", false), + prefs.Get("ForceIntegerScaling", true), + }, vsyncHint); bool enableBluescreen = USE_BLUESCREEN && !true_arg(arguments["disable-bluescreen"]); if (enableBluescreen) diff --git a/src/PowderToyFontEditor.cpp b/src/PowderToyFontEditor.cpp index f84f9f23b..a2c1be11b 100644 --- a/src/PowderToyFontEditor.cpp +++ b/src/PowderToyFontEditor.cpp @@ -51,10 +51,6 @@ int main(int argc, char * argv[]) scale = buf; } } - resizable = false; - fullscreen = false; - altFullscreen = false; - forceIntegerScaling = true; // TODO: maybe bind the maximum allowed scale to screen size somehow if(scale < 1 || scale > 10) @@ -69,10 +65,7 @@ int main(int argc, char * argv[]) auto &engine = ui::Engine::Ref(); engine.g = new Graphics(); engine.Scale = scale; - engine.SetResizable(resizable); - engine.Fullscreen = fullscreen; - engine.SetAltFullscreen(altFullscreen); - engine.SetForceIntegerScaling(forceIntegerScaling); + engine.SetWindowFrameOps({ false, false, false, false }); engine.Begin(); engine.SetFastQuit(true); diff --git a/src/PowderToySDL.cpp b/src/PowderToySDL.cpp index 2c77c5a20..34127d00e 100644 --- a/src/PowderToySDL.cpp +++ b/src/PowderToySDL.cpp @@ -13,11 +13,8 @@ SDL_Window *sdl_window = NULL; SDL_Renderer *sdl_renderer = NULL; SDL_Texture *sdl_texture = NULL; int scale = 1; -bool fullscreen = false; -bool altFullscreen = false; -bool forceIntegerScaling = true; bool vsyncHint = false; -bool resizable = false; +WindowFrameOps currentFrameOps = { false, false, false, false }; bool momentumScroll = true; bool showAvatars = true; uint64_t lastTick = 0; @@ -91,7 +88,7 @@ void blit(pixel *vid) { SDL_UpdateTexture(sdl_texture, NULL, vid, WINDOWW * sizeof (Uint32)); // need to clear the renderer if there are black edges (fullscreen, or resizable window) - if (fullscreen || resizable) + if (currentFrameOps.fullscreen || currentFrameOps.resizable) SDL_RenderClear(sdl_renderer); SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL); SDL_RenderPresent(sdl_renderer); @@ -144,22 +141,36 @@ void SDLClose() SDL_Quit(); } -void SDLSetScreen(int scale_, bool resizable_, bool fullscreen_, bool altFullscreen_, bool forceIntegerScaling_, bool vsyncHint_) +void SDLSetScreen(int scale_, WindowFrameOps newFrameOps, bool vsyncHint_) { + if (FORCE_WINDOW_FRAME_OPS == forceWindowFrameOpsEmbedded) + { + newFrameOps.resizable = false; + newFrameOps.fullscreen = false; + newFrameOps.changeResolution = false; + newFrameOps.forceIntegerScaling = false; + } + if (FORCE_WINDOW_FRAME_OPS == forceWindowFrameOpsHandheld) + { + newFrameOps.resizable = false; + newFrameOps.fullscreen = true; + newFrameOps.changeResolution = false; + newFrameOps.forceIntegerScaling = false; + } // bool changingScale = scale != scale_; - bool changingFullscreen = fullscreen_ != fullscreen || (altFullscreen_ != altFullscreen && fullscreen); - bool changingResizable = resizable != resizable_; + bool changingFullscreen = newFrameOps.fullscreen != currentFrameOps.fullscreen || (newFrameOps.changeResolution != currentFrameOps.changeResolution && currentFrameOps.fullscreen); + bool changingResizable = currentFrameOps.resizable != newFrameOps.resizable; bool changingVsync = vsyncHint != vsyncHint_; scale = scale_; - fullscreen = fullscreen_; - altFullscreen = altFullscreen_; - resizable = resizable_; - forceIntegerScaling = forceIntegerScaling_; + currentFrameOps.fullscreen = newFrameOps.fullscreen; + currentFrameOps.changeResolution = newFrameOps.changeResolution; + currentFrameOps.resizable = newFrameOps.resizable; + currentFrameOps.forceIntegerScaling = newFrameOps.forceIntegerScaling; vsyncHint = vsyncHint_; // Recreate the window when toggling fullscreen, due to occasional issues // Also recreate it when enabling resizable windows, to fix bugs on windows, // see https://github.com/jacob1/The-Powder-Toy/issues/24 - if (changingFullscreen || altFullscreen || (changingResizable && resizable && !fullscreen) || changingVsync) + if (changingFullscreen || currentFrameOps.changeResolution || (changingResizable && currentFrameOps.resizable && !currentFrameOps.fullscreen) || changingVsync) { RecreateWindow(); return; @@ -168,23 +179,23 @@ void SDLSetScreen(int scale_, bool resizable_, bool fullscreen_, bool altFullscr SDL_RestoreWindow(sdl_window); SDL_SetWindowSize(sdl_window, WINDOWW * scale, WINDOWH * scale); - SDL_RenderSetIntegerScale(sdl_renderer, forceIntegerScaling && fullscreen ? SDL_TRUE : SDL_FALSE); + SDL_RenderSetIntegerScale(sdl_renderer, currentFrameOps.forceIntegerScaling && currentFrameOps.fullscreen ? SDL_TRUE : SDL_FALSE); unsigned int flags = 0; - if (fullscreen) - flags = altFullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP; + if (currentFrameOps.fullscreen) + flags = currentFrameOps.changeResolution ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP; SDL_SetWindowFullscreen(sdl_window, flags); - if (fullscreen) + if (currentFrameOps.fullscreen) SDL_RaiseWindow(sdl_window); - SDL_SetWindowResizable(sdl_window, resizable ? SDL_TRUE : SDL_FALSE); + SDL_SetWindowResizable(sdl_window, currentFrameOps.resizable ? SDL_TRUE : SDL_FALSE); } bool RecreateWindow() { unsigned int flags = 0; unsigned int rendererFlags = 0; - if (fullscreen) - flags = altFullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP; - if (resizable && !fullscreen) + if (currentFrameOps.fullscreen) + flags = currentFrameOps.changeResolution ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP; + if (currentFrameOps.resizable && !currentFrameOps.fullscreen) flags |= SDL_WINDOW_RESIZABLE; if (vsyncHint) rendererFlags |= SDL_RENDERER_PRESENTVSYNC; @@ -219,7 +230,7 @@ bool RecreateWindow() return false; } SDL_RenderSetLogicalSize(sdl_renderer, WINDOWW, WINDOWH); - if (forceIntegerScaling && fullscreen) + if (currentFrameOps.forceIntegerScaling && currentFrameOps.fullscreen) SDL_RenderSetIntegerScale(sdl_renderer, SDL_TRUE); sdl_texture = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, WINDOWW, WINDOWH); SDL_RaiseWindow(sdl_window); @@ -390,14 +401,9 @@ void EngineProcess() drawingTimer = 0; auto wantVsync = bool(std::get_if(&fpsLimit)); - if (scale != engine.Scale || - fullscreen != engine.Fullscreen || - altFullscreen != engine.GetAltFullscreen() || - forceIntegerScaling != engine.GetForceIntegerScaling() || - resizable != engine.GetResizable() || - vsyncHint != wantVsync) + if (scale != engine.Scale || currentFrameOps != engine.GetWindowFrameOps() || vsyncHint != wantVsync) { - SDLSetScreen(engine.Scale, engine.GetResizable(), engine.Fullscreen, engine.GetAltFullscreen(), engine.GetForceIntegerScaling(), wantVsync); + SDLSetScreen(engine.Scale, engine.GetWindowFrameOps(), wantVsync); } blit(engine.g->Data()); diff --git a/src/PowderToySDL.h b/src/PowderToySDL.h index e54dc4703..85613f661 100644 --- a/src/PowderToySDL.h +++ b/src/PowderToySDL.h @@ -1,6 +1,7 @@ #pragma once #include "common/String.h" #include "graphics/Pixel.h" +#include "gui/WindowFrameOps.h" #include "FpsLimit.h" #include #include @@ -12,10 +13,8 @@ extern SDL_Window *sdl_window; extern SDL_Renderer *sdl_renderer; extern SDL_Texture *sdl_texture; extern int scale; -extern bool fullscreen; -extern bool altFullscreen; -extern bool forceIntegerScaling; -extern bool resizable; +extern bool vsyncHint; +extern WindowFrameOps currentFrameOps; extern bool momentumScroll; extern bool showAvatars; extern uint64_t lastTick; @@ -41,7 +40,7 @@ void CalculateMousePosition(int *x, int *y); void blit(pixel *vid); void SDLOpen(); void SDLClose(); -void SDLSetScreen(int scale_, bool resizable_, bool fullscreen_, bool altFullscreen_, bool forceIntegerScaling_); +void SDLSetScreen(int scale_, WindowFrameOps newFrameOps, bool vsyncHint_); void SetFpsLimit(FpsLimit newFpsLimit); bool RecreateWindow(); void LoadWindowPosition(); diff --git a/src/gui/WindowFrameOps.h b/src/gui/WindowFrameOps.h new file mode 100644 index 000000000..483b8f1c3 --- /dev/null +++ b/src/gui/WindowFrameOps.h @@ -0,0 +1,26 @@ +#pragma once + +struct WindowFrameOps +{ + bool resizable; + bool fullscreen; + bool changeResolution; + bool forceIntegerScaling; + + bool operator ==(const WindowFrameOps &other) const + { + if (resizable != other.resizable ) return false; + if (fullscreen != other.fullscreen) return false; + if (fullscreen) + { + if (changeResolution != other.changeResolution ) return false; + if (forceIntegerScaling != other.forceIntegerScaling) return false; + } + return true; + } + + bool operator !=(const WindowFrameOps &other) const + { + return !(*this == other); + } +}; diff --git a/src/gui/interface/Engine.cpp b/src/gui/interface/Engine.cpp index fd3a212b5..febe140a6 100644 --- a/src/gui/interface/Engine.cpp +++ b/src/gui/interface/Engine.cpp @@ -15,8 +15,6 @@ Engine::Engine(): Scale(1), Fullscreen(false), FrameIndex(0), - altFullscreen(false), - resizable(false), state_(NULL), windowTargetPosition(0, 0), FastQuit(1), diff --git a/src/gui/interface/Engine.h b/src/gui/interface/Engine.h index 4a39ce781..a048309e1 100644 --- a/src/gui/interface/Engine.h +++ b/src/gui/interface/Engine.h @@ -5,6 +5,7 @@ #include "common/ExplicitSingleton.h" #include "graphics/Pixel.h" #include "gui/interface/Point.h" +#include "gui/WindowFrameOps.h" #include #include "FpsLimit.h" @@ -47,16 +48,8 @@ namespace ui void SetDrawingFrequencyLimit(int limit) {drawingFrequencyLimit = limit;} inline int GetDrawingFrequencyLimit() {return drawingFrequencyLimit;} - void SetFullscreen(bool fullscreen) { Fullscreen = fullscreen; } - inline bool GetFullscreen() { return Fullscreen; } - void SetAltFullscreen(bool altFullscreen) { this->altFullscreen = altFullscreen; } - inline bool GetAltFullscreen() { return altFullscreen; } - void SetForceIntegerScaling(bool forceIntegerScaling) { this->forceIntegerScaling = forceIntegerScaling; } - inline bool GetForceIntegerScaling() { return forceIntegerScaling; } void SetScale(int scale) { Scale = scale; } inline int GetScale() { return Scale; } - void SetResizable(bool resizable) { this->resizable = resizable; } - inline bool GetResizable() { return resizable; } void SetFastQuit(bool fastquit) { FastQuit = fastquit; } inline bool GetFastQuit() {return FastQuit; } @@ -93,9 +86,6 @@ namespace ui unsigned int FrameIndex; private: FpsLimit fpsLimit; - bool altFullscreen; - bool forceIntegerScaling = true; - bool resizable; bool textInput = false; int lastTextEditingStart = INT_MAX; @@ -131,9 +121,31 @@ namespace ui String textEditingBuf; + WindowFrameOps windowFrameOps = { false, false, false, false }; + public: bool MomentumScroll = true; bool ShowAvatars = true; + bool TouchUI = false; + + inline WindowFrameOps GetWindowFrameOps() const + { + return windowFrameOps; + } + + inline void SetWindowFrameOps(WindowFrameOps newWindowFrameOps) + { + windowFrameOps = newWindowFrameOps; + } + + void SetFullscreen (bool newFullscreen ) { windowFrameOps.fullscreen = newFullscreen; } + void SetChangeResolution (bool setChangeResolution ) { windowFrameOps.changeResolution = setChangeResolution; } + void SetForceIntegerScaling(bool newForceIntegerScaling) { windowFrameOps.forceIntegerScaling = newForceIntegerScaling; } + void SetResizable (bool newResizable ) { windowFrameOps.resizable = newResizable; } + inline bool GetFullscreen () const { return windowFrameOps.fullscreen; } + inline bool GetChangeResolution () const { return windowFrameOps.changeResolution; } + inline bool GetForceIntegerScaling() const { return windowFrameOps.forceIntegerScaling; } + inline bool GetResizable () const { return windowFrameOps.resizable; } }; } diff --git a/src/gui/options/OptionsController.cpp b/src/gui/options/OptionsController.cpp index 4a67e2bd1..b6191927d 100644 --- a/src/gui/options/OptionsController.cpp +++ b/src/gui/options/OptionsController.cpp @@ -77,9 +77,9 @@ void OptionsController::SetFullscreen(bool fullscreen) model->SetFullscreen(fullscreen); } -void OptionsController::SetAltFullscreen(bool altFullscreen) +void OptionsController::SetChangeResolution(bool newChangeResolution) { - model->SetAltFullscreen(altFullscreen); + model->SetChangeResolution(newChangeResolution); } void OptionsController::SetForceIntegerScaling(bool forceIntegerScaling) diff --git a/src/gui/options/OptionsController.h b/src/gui/options/OptionsController.h index d211f981c..88c7aed01 100644 --- a/src/gui/options/OptionsController.h +++ b/src/gui/options/OptionsController.h @@ -25,7 +25,7 @@ public: void SetEdgeMode(int edgeMode); void SetTemperatureScale(int temperatureScale); void SetFullscreen(bool fullscreen); - void SetAltFullscreen(bool altFullscreen); + void SetChangeResolution(bool newChangeResolution); void SetForceIntegerScaling(bool forceIntegerScaling); void SetScale(int scale); void SetGraveExitsConsole(bool graveExitsConsole); diff --git a/src/gui/options/OptionsModel.cpp b/src/gui/options/OptionsModel.cpp index 7c49960b1..27442a9ce 100644 --- a/src/gui/options/OptionsModel.cpp +++ b/src/gui/options/OptionsModel.cpp @@ -191,15 +191,15 @@ void OptionsModel::SetFullscreen(bool fullscreen) notifySettingsChanged(); } -bool OptionsModel::GetAltFullscreen() +bool OptionsModel::GetChangeResolution() { - return ui::Engine::Ref().GetAltFullscreen(); + return ui::Engine::Ref().GetChangeResolution(); } -void OptionsModel::SetAltFullscreen(bool altFullscreen) +void OptionsModel::SetChangeResolution(bool newChangeResolution) { - ui::Engine::Ref().SetAltFullscreen(altFullscreen); - GlobalPrefs::Ref().Set("AltFullscreen", altFullscreen); + ui::Engine::Ref().SetChangeResolution(newChangeResolution); + GlobalPrefs::Ref().Set("AltFullscreen", newChangeResolution); notifySettingsChanged(); } diff --git a/src/gui/options/OptionsModel.h b/src/gui/options/OptionsModel.h index 23f340471..7adebe427 100644 --- a/src/gui/options/OptionsModel.h +++ b/src/gui/options/OptionsModel.h @@ -45,8 +45,8 @@ public: void SetResizable(bool resizable); bool GetFullscreen(); void SetFullscreen(bool fullscreen); - bool GetAltFullscreen(); - void SetAltFullscreen(bool oldFullscreen); + bool GetChangeResolution(); + void SetChangeResolution(bool newChangeResolution); bool GetForceIntegerScaling(); void SetForceIntegerScaling(bool forceIntegerScaling); bool GetFastQuit(); diff --git a/src/gui/options/OptionsView.cpp b/src/gui/options/OptionsView.cpp index b8700ebf9..cbb119220 100644 --- a/src/gui/options/OptionsView.cpp +++ b/src/gui/options/OptionsView.cpp @@ -228,8 +228,9 @@ OptionsView::OptionsView() : ui::Window(ui::Point(-1, -1), ui::Point(320, 340)) }, [this] { c->SetTemperatureScale(temperatureScale->GetOption().second); }); - addSeparator(); + if (FORCE_WINDOW_FRAME_OPS != forceWindowFrameOpsHandheld) { + addSeparator(); std::vector> options; int currentScale = ui::Engine::Ref().GetScale(); int scaleIndex = 1; @@ -252,7 +253,7 @@ OptionsView::OptionsView() : ui::Window(ui::Point(-1, -1), ui::Point(320, 340)) c->SetScale(scale->GetOption().second); }); } - if (ALLOW_WINDOW_FRAME_OPS) + if (FORCE_WINDOW_FRAME_OPS == forceWindowFrameOpsNone) { resizable = addCheckbox(0, "Resizable \bg- allow resizing and maximizing window", "", [this] { c->SetResizable(resizable->GetChecked()); @@ -260,8 +261,8 @@ OptionsView::OptionsView() : ui::Window(ui::Point(-1, -1), ui::Point(320, 340)) fullscreen = addCheckbox(0, "Fullscreen \bg- fill the entire screen", "", [this] { c->SetFullscreen(fullscreen->GetChecked()); }); - altFullscreen = addCheckbox(1, "Set optimal screen resolution", "", [this] { - c->SetAltFullscreen(altFullscreen->GetChecked()); + changeResolution = addCheckbox(1, "Set optimal screen resolution", "", [this] { + c->SetChangeResolution(changeResolution->GetChecked()); }); forceIntegerScaling = addCheckbox(1, "Force integer scaling \bg- less blurry", "", [this] { c->SetForceIntegerScaling(forceIntegerScaling->GetChecked()); @@ -427,7 +428,10 @@ void OptionsView::NotifySettingsChanged(OptionsModel * sender) customGravityY = sender->GetCustomGravityY(); decoSpace->SetOption(sender->GetDecoSpace()); edgeMode->SetOption(sender->GetEdgeMode()); - scale->SetOption(sender->GetScale()); + if (scale) + { + scale->SetOption(sender->GetScale()); + } if (resizable) { resizable->SetChecked(sender->GetResizable()); @@ -436,9 +440,9 @@ void OptionsView::NotifySettingsChanged(OptionsModel * sender) { fullscreen->SetChecked(sender->GetFullscreen()); } - if (altFullscreen) + if (changeResolution) { - altFullscreen->SetChecked(sender->GetAltFullscreen()); + changeResolution->SetChecked(sender->GetChangeResolution()); } if (forceIntegerScaling) { diff --git a/src/gui/options/OptionsView.h b/src/gui/options/OptionsView.h index fb67e64c1..8272ed3d8 100644 --- a/src/gui/options/OptionsView.h +++ b/src/gui/options/OptionsView.h @@ -29,7 +29,7 @@ class OptionsView: public ui::Window ui::DropDown * scale; ui::Checkbox * resizable; ui::Checkbox * fullscreen; - ui::Checkbox * altFullscreen; + ui::Checkbox * changeResolution; ui::Checkbox * forceIntegerScaling; ui::Checkbox * fastquit = nullptr; ui::DropDown * decoSpace; diff --git a/src/meson.build b/src/meson.build index 1ad17e6b3..96595a170 100644 --- a/src/meson.build +++ b/src/meson.build @@ -22,19 +22,25 @@ conf_data.set('USE_UPDATESERVER', (update_server != '').to_string()) enforce_https = get_option('enforce_https') allow_quit = true -allow_window_frame_ops = true +force_window_frame_ops = 'forceWindowFrameOpsNone' allow_data_folder = true if host_platform == 'emscripten' allow_quit = false - allow_window_frame_ops = false + force_window_frame_ops = 'forceWindowFrameOpsEmbedded' allow_data_folder = false endif +default_touch_ui = false +if host_platform == 'android' + default_touch_ui = true # TODO: some more sophisticated heuristic at runtime instead + force_window_frame_ops = 'forceWindowFrameOpsHandheld' +endif secure_ciphers_only = get_option('secure_ciphers_only') if not is_debug and not enforce_https error('refusing to build a release binary without enforcing HTTPS, configure with -Denforce_https=true to fix this error') endif conf_data.set('ALLOW_QUIT', allow_quit.to_string()) -conf_data.set('ALLOW_WINDOW_FRAME_OPS', allow_window_frame_ops.to_string()) +conf_data.set('FORCE_WINDOW_FRAME_OPS', force_window_frame_ops) +conf_data.set('DEFAULT_TOUCH_UI', default_touch_ui.to_string()) conf_data.set('ALLOW_DATA_FOLDER', allow_data_folder.to_string()) conf_data.set('ENFORCE_HTTPS', enforce_https.to_string()) conf_data.set('SECURE_CIPHERS_ONLY', secure_ciphers_only.to_string()) @@ -58,7 +64,12 @@ if host_platform == 'android' '', ] endif + android_properties = [] + if is_debug + android_properties += [ 'android:debuggable="true"' ] + endif conf_data.set('ANDROID_PERMISSIONS', '\n'.join(android_permissions)) + conf_data.set('ANDROID_PROPERTIES', '\n'.join(android_properties)) endif powder_files = files(