Skip to content

Commit

Permalink
Add "Force Integer Scaling" option for fullscreen
Browse files Browse the repository at this point in the history
Also:
recreate the window when enabling resizable window, same workaround I applied to my mod for jacob1#24
recreate the window when toggling fullscreen, to work around some bugs where the window is sized incorrectly or the mouse position doesn't match where the cursor is
Don't capture mouse cursor when this is a debug build
  • Loading branch information
jacob1 committed Feb 19, 2019
1 parent a979917 commit 0c6ce20
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 42 deletions.
92 changes: 69 additions & 23 deletions src/PowderToySDL.cpp
Expand Up @@ -66,6 +66,7 @@ SDL_Texture * sdl_texture;
int scale = 1;
bool fullscreen = false;
bool altFullscreen = false;
bool forceIntegerScaling = true;
bool resizable = false;


Expand All @@ -91,6 +92,10 @@ void LoadWindowPosition()

int borderTop, borderLeft;
SDL_GetWindowBordersSize(sdl_window, &borderTop, &borderLeft, nullptr, nullptr);
// Sometimes (Windows), the border size may not be reported for 200+ frames
// So just have a default of 5 to ensure the window doesn't get stuck where it can't be moved
if (borderTop == 0)
borderTop = 5;

if (savedWindowX + borderLeft > 0 && savedWindowX + borderLeft < desktopWidth
&& savedWindowY + borderTop > 0 && savedWindowY + borderTop < desktopHeight)
Expand Down Expand Up @@ -139,6 +144,7 @@ void blit(pixel * vid)
}
#endif

void RecreateWindow();
int SDLOpen()
{
if (SDL_Init(SDL_INIT_VIDEO) < 0)
Expand All @@ -147,23 +153,7 @@ int SDLOpen()
return 1;
}

unsigned int flags = 0;
if (fullscreen)
flags = altFullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP;
if (resizable)
flags |= SDL_WINDOW_RESIZABLE;
sdl_window = SDL_CreateWindow("The Powder Toy", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOWW * scale, WINDOWH * scale,
flags);
sdl_renderer = SDL_CreateRenderer(sdl_window, -1, 0);
SDL_RenderSetLogicalSize(sdl_renderer, WINDOWW, WINDOWH);
//Uncomment this to force fullscreen to an integer resolution
//SDL_RenderSetIntegerScale(sdl_renderer, SDL_TRUE);
sdl_texture = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, WINDOWW, WINDOWH);
if (fullscreen)
SDL_RaiseWindow(sdl_window);
//Uncomment this to enable resizing
//SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
//SDL_SetWindowResizable(sdl_window, SDL_TRUE);
RecreateWindow();

int displayIndex = SDL_GetWindowDisplayIndex(sdl_window);
if (displayIndex >= 0)
Expand Down Expand Up @@ -203,13 +193,29 @@ int SDLOpen()
return 0;
}

void SDLSetScreen(int scale_, bool resizable_, bool fullscreen_, bool altFullscreen_)
void SDLSetScreen(int scale_, bool resizable_, bool fullscreen_, bool altFullscreen_, bool forceIntegerScaling_)
{
// bool changingScale = scale != scale_;
bool changingFullscreen = fullscreen_ != fullscreen;
bool changingResizable = resizable != resizable_;
scale = scale_;
fullscreen = fullscreen_;
altFullscreen = altFullscreen_;
resizable = resizable_;
forceIntegerScaling = forceIntegerScaling_;
// 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 || (changingResizable && resizable && !fullscreen))
{
RecreateWindow();
return;
}
if (changingResizable)
SDL_RestoreWindow(sdl_window);

SDL_SetWindowSize(sdl_window, WINDOWW * scale, WINDOWH * scale);
SDL_RenderSetIntegerScale(sdl_renderer, forceIntegerScaling && fullscreen ? SDL_TRUE : SDL_FALSE);
unsigned int flags = 0;
if (fullscreen)
flags = altFullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP;
Expand All @@ -219,6 +225,40 @@ void SDLSetScreen(int scale_, bool resizable_, bool fullscreen_, bool altFullscr
SDL_SetWindowResizable(sdl_window, resizable ? SDL_TRUE : SDL_FALSE);
}

void RecreateWindow()
{
unsigned int flags = 0;
if (fullscreen)
flags = altFullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP;
if (resizable && !fullscreen)
flags |= SDL_WINDOW_RESIZABLE;

if (sdl_texture)
SDL_DestroyTexture(sdl_texture);
if (sdl_renderer)
SDL_DestroyRenderer(sdl_renderer);
if (sdl_window)
{
SaveWindowPosition();
SDL_DestroyWindow(sdl_window);
}

sdl_window = SDL_CreateWindow("The Powder Toy", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WINDOWW * scale, WINDOWH * scale,
flags);
sdl_renderer = SDL_CreateRenderer(sdl_window, -1, 0);
SDL_RenderSetLogicalSize(sdl_renderer, WINDOWW, WINDOWH);
if (forceIntegerScaling && 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);
//Uncomment this to enable resizing
//SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
//SDL_SetWindowResizable(sdl_window, SDL_TRUE);

if (!Client::Ref().IsFirstRun())
LoadWindowPosition();
}

unsigned int GetTicks()
{
return SDL_GetTicks();
Expand Down Expand Up @@ -354,7 +394,9 @@ void EventProcess(SDL_Event event)
engine->onMouseClick(event.motion.x, event.motion.y, mouseButton);

mouseDown = true;
#if !defined(NDEBUG) && !defined(DEBUG)
SDL_CaptureMouse(SDL_TRUE);
#endif
break;
case SDL_MOUSEBUTTONUP:
// if mouse hasn't moved yet, sdl will send 0,0. We don't want that
Expand All @@ -367,7 +409,9 @@ void EventProcess(SDL_Event event)
engine->onMouseUnclick(mousex, mousey, mouseButton);

mouseDown = false;
#if !defined(NDEBUG) && !defined(DEBUG)
SDL_CaptureMouse(SDL_FALSE);
#endif
break;
case SDL_WINDOWEVENT:
{
Expand Down Expand Up @@ -447,10 +491,12 @@ void EngineProcess()
engine->Tick();
engine->Draw();

if (scale != engine->Scale || fullscreen != engine->Fullscreen
|| altFullscreen != engine->GetAltFullscreen() || resizable != engine->GetResizable())
if (scale != engine->Scale || fullscreen != engine->Fullscreen ||
altFullscreen != engine->GetAltFullscreen() ||
forceIntegerScaling != engine->GetForceIntegerScaling() || resizable != engine->GetResizable())
{
SDLSetScreen(engine->Scale, engine->GetResizable(), engine->Fullscreen, engine->GetAltFullscreen());
SDLSetScreen(engine->Scale, engine->GetResizable(), engine->Fullscreen, engine->GetAltFullscreen(),
engine->GetForceIntegerScaling());
}

#ifdef OGLI
Expand Down Expand Up @@ -591,6 +637,7 @@ int main(int argc, char * argv[])
resizable = Client::Ref().GetPrefBool("Resizable", false);
fullscreen = Client::Ref().GetPrefBool("Fullscreen", false);
altFullscreen = Client::Ref().GetPrefBool("AltFullscreen", false);
forceIntegerScaling = Client::Ref().GetPrefBool("ForceIntegerScaling", true);


if(arguments["kiosk"] == "true")
Expand Down Expand Up @@ -639,8 +686,6 @@ int main(int argc, char * argv[])
SDL_SetWindowSize(sdl_window, WINDOWW * 2, WINDOWH * 2);
showDoubleScreenDialog = true;
}
if (!Client::Ref().IsFirstRun())
LoadWindowPosition();

#ifdef OGLI
SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1);
Expand All @@ -659,6 +704,7 @@ int main(int argc, char * argv[])
ui::Engine::Ref().SetResizable(resizable);
ui::Engine::Ref().Fullscreen = fullscreen;
ui::Engine::Ref().SetAltFullscreen(altFullscreen);
ui::Engine::Ref().SetForceIntegerScaling(forceIntegerScaling);

engine = &ui::Engine::Ref();
engine->SetMaxSize(desktopWidth, desktopHeight);
Expand Down
18 changes: 1 addition & 17 deletions src/client/GameSave.cpp
Expand Up @@ -772,41 +772,25 @@ void GameSave::readOPS(char * data, int dataLength)
if (bson_iterator_type(&iter) == BSON_OBJECT)
{
int major = INT_MAX, minor = INT_MAX;
#ifdef RENDERER
int renderMajor = INT_MAX, renderMinor = INT_MAX;
#endif
bson_iterator subiter;
bson_iterator_subiterator(&iter, &subiter);
while (bson_iterator_next(&subiter))
{
if (bson_iterator_type(&subiter) == BSON_INT)
{
#ifdef RENDERER
if (!strcmp(bson_iterator_key(&subiter), "rendermajor"))
renderMajor = bson_iterator_int(&subiter);
else if (!strcmp(bson_iterator_key(&subiter), "renderminor"))
renderMinor = bson_iterator_int(&subiter);
#else
if (!strcmp(bson_iterator_key(&subiter), "major"))
major = bson_iterator_int(&subiter);
else if (!strcmp(bson_iterator_key(&subiter), "minor"))
minor = bson_iterator_int(&subiter);
#endif
}
}
#ifdef RENDERER
if (renderMajor > SAVE_VERSION || (renderMajor == SAVE_VERSION && renderMinor > MINOR_VERSION))
#elif defined(SNAPSHOT) || defined(DEBUG)
#if defined(SNAPSHOT) || defined(DEBUG)
if (major > FUTURE_SAVE_VERSION || (major == FUTURE_SAVE_VERSION && minor > FUTURE_MINOR_VERSION))
#else
if (major > SAVE_VERSION || (major == SAVE_VERSION && minor > MINOR_VERSION))
#endif
{
#ifdef RENDERER
String errorMessage = String::Build("Save from a newer version: Requires render version ", renderMajor, ".", renderMinor);
#else
String errorMessage = String::Build("Save from a newer version: Requires version ", major, ".", minor);
#endif
throw ParseException(ParseException::WrongVersion, errorMessage);
}
#if defined(SNAPSHOT) || defined(DEBUG)
Expand Down
3 changes: 3 additions & 0 deletions src/gui/interface/Engine.h
Expand Up @@ -48,6 +48,8 @@ namespace ui
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; }
Expand Down Expand Up @@ -84,6 +86,7 @@ namespace ui
unsigned int FrameIndex;
private:
bool altFullscreen;
bool forceIntegerScaling = true;
bool resizable;

float dt;
Expand Down
5 changes: 5 additions & 0 deletions src/gui/options/OptionsController.cpp
Expand Up @@ -60,6 +60,11 @@ void OptionsController::SetAltFullscreen(bool altFullscreen)
model->SetAltFullscreen(altFullscreen);
}

void OptionsController::SetForceIntegerScaling(bool forceIntegerScaling)
{
model->SetForceIntegerScaling(forceIntegerScaling);
}

void OptionsController::SetShowAvatars(bool showAvatars)
{
model->SetShowAvatars(showAvatars);
Expand Down
1 change: 1 addition & 0 deletions src/gui/options/OptionsController.h
Expand Up @@ -26,6 +26,7 @@ class OptionsController {
void SetEdgeMode(int edgeMode);
void SetFullscreen(bool fullscreen);
void SetAltFullscreen(bool altFullscreen);
void SetForceIntegerScaling(bool forceIntegerScaling);
void SetScale(int scale);
void SetResizable(bool resizable);
void SetFastQuit(bool fastquit);
Expand Down
12 changes: 12 additions & 0 deletions src/gui/options/OptionsModel.cpp
Expand Up @@ -137,6 +137,18 @@ void OptionsModel::SetAltFullscreen(bool altFullscreen)
notifySettingsChanged();
}

bool OptionsModel::GetForceIntegerScaling()
{
return ui::Engine::Ref().GetForceIntegerScaling();
}

void OptionsModel::SetForceIntegerScaling(bool forceIntegerScaling)
{
ui::Engine::Ref().SetForceIntegerScaling(forceIntegerScaling);
Client::Ref().SetPref("ForceIntegerScaling", forceIntegerScaling);
notifySettingsChanged();
}

bool OptionsModel::GetFastQuit()
{
return ui::Engine::Ref().GetFastQuit();
Expand Down
2 changes: 2 additions & 0 deletions src/gui/options/OptionsModel.h
Expand Up @@ -39,6 +39,8 @@ class OptionsModel {
void SetFullscreen(bool fullscreen);
bool GetAltFullscreen();
void SetAltFullscreen(bool oldFullscreen);
bool GetForceIntegerScaling();
void SetForceIntegerScaling(bool forceIntegerScaling);
bool GetFastQuit();
void SetFastQuit(bool fastquit);
virtual ~OptionsModel();
Expand Down
23 changes: 21 additions & 2 deletions src/gui/options/OptionsView.cpp
Expand Up @@ -17,7 +17,7 @@
#include "gui/dialogues/ErrorMessage.h"

OptionsView::OptionsView():
ui::Window(ui::Point(-1, -1), ui::Point(300, 369)){
ui::Window(ui::Point(-1, -1), ui::Point(300, 389)){

ui::Label * tempLabel = new ui::Label(ui::Point(4, 5), ui::Point(Size.X-8, 14), "Simulation Options");
tempLabel->SetTextColour(style::Colour::InformationTitle);
Expand Down Expand Up @@ -227,6 +227,24 @@ OptionsView::OptionsView():
AddComponent(tempLabel);
AddComponent(altFullscreen);

class ForceIntegerScalingAction: public ui::CheckboxAction
{
OptionsView * v;
public:
ForceIntegerScalingAction(OptionsView * v_) { v = v_; }
virtual void ActionCallback(ui::Checkbox * sender)
{
v->c->SetForceIntegerScaling(sender->GetChecked());
}
};

forceIntegerScaling = new ui::Checkbox(ui::Point(23, altFullscreen->Position.Y + 20), ui::Point(Size.X-6, 16), "Force Integer Scaling", "");
forceIntegerScaling->SetActionCallback(new ForceIntegerScalingAction(this));
tempLabel = new ui::Label(ui::Point(altFullscreen->Position.X+Graphics::textwidth(forceIntegerScaling->GetText().c_str())+20, forceIntegerScaling->Position.Y), ui::Point(Size.X-28, 16), "\bg- less blurry");
tempLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; tempLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
AddComponent(tempLabel);
AddComponent(forceIntegerScaling);


class FastQuitAction: public ui::CheckboxAction
{
Expand All @@ -236,7 +254,7 @@ OptionsView::OptionsView():
virtual void ActionCallback(ui::Checkbox * sender){ v->c->SetFastQuit(sender->GetChecked()); }
};

fastquit = new ui::Checkbox(ui::Point(8, altFullscreen->Position.Y + 20), ui::Point(Size.X-6, 16), "Fast Quit", "");
fastquit = new ui::Checkbox(ui::Point(8, forceIntegerScaling->Position.Y + 20), ui::Point(Size.X-6, 16), "Fast Quit", "");
fastquit->SetActionCallback(new FastQuitAction(this));
tempLabel = new ui::Label(ui::Point(fastquit->Position.X+Graphics::textwidth(fastquit->GetText().c_str())+20, fastquit->Position.Y), ui::Point(Size.X-28, 16), "\bg- Always exit completely when hitting close");
tempLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; tempLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
Expand Down Expand Up @@ -318,6 +336,7 @@ void OptionsView::NotifySettingsChanged(OptionsModel * sender)
resizable->SetChecked(sender->GetResizable());
fullscreen->SetChecked(sender->GetFullscreen());
altFullscreen->SetChecked(sender->GetAltFullscreen());
forceIntegerScaling->SetChecked(sender->GetForceIntegerScaling());
fastquit->SetChecked(sender->GetFastQuit());
showAvatars->SetChecked(sender->GetShowAvatars());
}
Expand Down
1 change: 1 addition & 0 deletions src/gui/options/OptionsView.h
Expand Up @@ -23,6 +23,7 @@ class OptionsView: public ui::Window {
ui::Checkbox * resizable;
ui::Checkbox * fullscreen;
ui::Checkbox * altFullscreen;
ui::Checkbox * forceIntegerScaling;
ui::Checkbox * fastquit;
ui::Checkbox * showAvatars;
public:
Expand Down

0 comments on commit 0c6ce20

Please sign in to comment.