Permalink
Browse files

Add support for window scale modes other than 1 and 2

Window scale can now be anything between 1 and 10 (suggest something other than 10 for maximum scale?). This required a number of subtle changes:

 * made blit2 (PowderToySDL.cpp) handle scale modes correctly (it really only handled scale:2 correctly before)
 * replaced `bool scale` with `int scale` everywhere in the options view/model/controller
 * replaced the _large screen_ checkbox with a _window scale_ textbox in the options view

The new scale is only checked and applied when the options view is closed. There's no reason to not apply it live, I just chose not to.

This commit does *not* make TPT able to figure out an optimal scale mode at first run. It still suggests using scale:2 if it makes sense though.

I had doubts about using a second loop in blit2 but it doesn't seem to be an issue. If there's a more optimal way of going about what blit2 does, I haven't figured it out.

(Sublime seems to have eaten a few trailing spaces, hence there are a few seemingly identical pairs of lines in the diff.)
  • Loading branch information...
LBPHacker authored and jacob1 committed Nov 23, 2017
1 parent 62d57cc commit be29fad7e811d418cd3ce1dcfea886e66e3e8052
@@ -369,7 +369,7 @@ void blit2(pixel * vid, int currentScale)
int j, x = 0, y = 0, w = WINDOWW, h = WINDOWH, pitch = WINDOWW;
pixel *dst;
pixel px, lastpx, nextpx;
int i,k;
int i,k,sx;
if (SDL_MUSTLOCK(sdl_scrn))
if (SDL_LockSurface(sdl_scrn)<0)
return;
@@ -406,8 +406,8 @@ void blit2(pixel * vid, int currentScale)
green = (PIXG(px)>>fmt->Gloss)<<fmt->Gshift;
blue = (PIXB(px)>>fmt->Bloss)<<fmt->Bshift;
}
dst[i*2] = red|green|blue;
dst[i*2+1] = red|green|blue;
for (sx=0; sx<currentScale; sx++)
dst[i*currentScale+sx] = red|green|blue;
}
dst+=sdl_scrn->pitch/PIXELSIZE;
}
@@ -435,8 +435,8 @@ void blit2(pixel * vid, int currentScale)
blueshift = 255;
px = PIXRGB((int)(PIXR(lastpx)*.69f+redshift*.3f), (int)(PIXG(nextpx)*.3f), (int)(PIXB(nextpx)*.69f+blueshift*.3f));
}
dst[i*2] = px;
dst[i*2+1] = px;
for (sx=0; sx<currentScale; sx++)
dst[i*currentScale+sx] = px;
}
dst+=sdl_scrn->pitch/PIXELSIZE;
}
@@ -790,7 +790,7 @@ void EngineProcess()
#ifdef OGLI
blit();
#else
if(engine->Scale==2)
if(engine->Scale > 1)
blit2(engine->g->vid, engine->Scale);
else
blit(engine->g->vid);
@@ -945,7 +945,7 @@ void BlueScreen(const char * detailMessage){
#ifdef OGLI
blit();
#else
if(engine->Scale==2)
if(engine->Scale > 1)
blit2(engine->g->vid, engine->Scale);
else
blit(engine->g->vid);
@@ -1029,10 +1029,12 @@ int main(int argc, char * argv[])
Client::Ref().Initialise(proxyString);
if(tempScale != 1 && tempScale != 2)
// TODO: maybe bind the maximum allowed scale to screen size somehow
if(tempScale < 1 || tempScale > 10)
tempScale = 1;
SDLOpen();
// TODO: mabe make a nice loop that automagically finds the optimal scale
if (Client::Ref().IsFirstRun() && desktopWidth > WINDOWW*2+50 && desktopHeight > WINDOWH*2+50)
{
tempScale = 2;
@@ -1150,7 +1152,7 @@ int main(int argc, char * argv[])
#ifdef OGLI
blit();
#else
if(engine->Scale==2)
if(engine->Scale > 1)
blit2(engine->g->vid, engine->Scale);
else
blit(engine->g->vid);
@@ -1,13 +1,15 @@
#include "OptionsController.h"
#include "gui/dialogues/ErrorMessage.h"
#include "gui/interface/Engine.h"
#include "gui/game/GameModel.h"
OptionsController::OptionsController(GameModel * gModel_, ControllerCallback * callback_):
gModel(gModel_),
callback(callback_),
HasExited(false)
{
this->depth3d = ui::Engine::Ref().Get3dDepth();
this->newScale = ui::Engine::Ref().GetScale();
view = new OptionsView();
model = new OptionsModel(gModel);
model->AddObserver(view);
@@ -60,21 +62,9 @@ void OptionsController::SetShowAvatars(bool showAvatars)
model->SetShowAvatars(showAvatars);
}
void OptionsController::SetScale(bool scale)
void OptionsController::SetScale(int scale)
{
if(scale)
{
if(ui::Engine::Ref().GetMaxWidth() >= ui::Engine::Ref().GetWidth() * 2 && ui::Engine::Ref().GetMaxHeight() >= ui::Engine::Ref().GetHeight() * 2)
model->SetScale(scale);
else
{
new ErrorMessage("Screen resolution error", "Your screen size is too small to use this scale mode.");
model->SetScale(false);
}
}
else
model->SetScale(scale);
newScale = scale;
}
void OptionsController::SetFastQuit(bool fastquit)
@@ -97,6 +87,22 @@ void OptionsController::Exit()
view->CloseActiveWindow();
// only update on close, it would be hard to edit if the changes were live
ui::Engine::Ref().Set3dDepth(depth3d);
{
if (newScale < 1)
newScale = 1;
bool reduced_scale = false;
while (!(ui::Engine::Ref().GetMaxWidth() >= ui::Engine::Ref().GetWidth() * newScale && ui::Engine::Ref().GetMaxHeight() >= ui::Engine::Ref().GetHeight() * newScale) && newScale > 1)
{
newScale -= 1;
reduced_scale = true;
}
if (reduced_scale)
new ErrorMessage("Screen resolution error", "Your screen size is too small to use this scale mode. Using largest available scale.");
ui::Engine::Ref().SetScale(newScale);
Client::Ref().SetPref("Scale", newScale);
}
if (callback)
callback->ControllerExit();
HasExited = true;
@@ -14,7 +14,7 @@ class OptionsController {
OptionsView * view;
OptionsModel * model;
ControllerCallback * callback;
int depth3d;
int depth3d, newScale;
public:
bool HasExited;
OptionsController(GameModel * gModel_, ControllerCallback * callback_);
@@ -26,7 +26,7 @@ class OptionsController {
void SetAirMode(int airMode);
void SetEdgeMode(int edgeMode);
void SetFullscreen(bool fullscreen);
void SetScale(bool scale);
void SetScale(int scale);
void SetFastQuit(bool fastquit);
void SetShowAvatars(bool showAvatars);
void Set3dDepth(int depth);
@@ -90,17 +90,6 @@ void OptionsModel::SetGravityMode(int gravityMode)
notifySettingsChanged();
}
bool OptionsModel::GetScale()
{
return ui::Engine::Ref().GetScale()==2;
}
void OptionsModel::SetScale(bool doubleScale)
{
ui::Engine::Ref().SetScale(doubleScale?2:1);
Client::Ref().SetPref("Scale", int(doubleScale?2:1));
notifySettingsChanged();
}
bool OptionsModel::GetFullscreen()
{
@@ -35,8 +35,6 @@ class OptionsModel {
void SetFullscreen(bool fullscreen);
bool GetFastQuit();
void SetFastQuit(bool fastquit);
bool GetScale();
void SetScale(bool scale);
virtual ~OptionsModel();
};
@@ -142,20 +142,21 @@ OptionsView::OptionsView():
tempLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; tempLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
AddComponent(tempLabel);
class ScaleAction: public ui::CheckboxAction
class ScaleAction: public ui::TextboxAction
{
OptionsView * v;
public:
ScaleAction(OptionsView * v_){ v = v_; }
virtual void ActionCallback(ui::Checkbox * sender){ v->c->SetScale(sender->GetChecked()); }
ScaleAction(OptionsView * v_) { v = v_; }
virtual void TextChangedCallback(ui::Textbox * sender) { v->c->SetScale(format::StringToNumber<int>(sender->GetText())); }
};
scale = new ui::Checkbox(ui::Point(8, 210), ui::Point(Size.X-6, 16), "Large screen", "");
scale = new ui::Textbox(ui::Point(8, 210), ui::Point(25, 16), format::NumberToString<int>(ui::Engine::Ref().GetScale()));
scale->SetInputType(ui::Textbox::Numeric);
scale->SetActionCallback(new ScaleAction(this));
tempLabel = new ui::Label(ui::Point(scale->Position.X+Graphics::textwidth(scale->GetText().c_str())+20, scale->Position.Y), ui::Point(Size.X-28, 16), "\bg- Double window size for larger screens");
AddComponent(scale);
tempLabel = new ui::Label(ui::Point(scale->Position.X+scale->Size.X+3, scale->Position.Y), ui::Point(Size.X-28, 16), "\bg- Window scale factor for larger screens");
tempLabel->Appearance.HorizontalAlign = ui::Appearance::AlignLeft; tempLabel->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
AddComponent(tempLabel);
AddComponent(scale);
class FullscreenAction: public ui::CheckboxAction
@@ -285,7 +286,6 @@ void OptionsView::NotifySettingsChanged(OptionsModel * sender)
airMode->SetOption(sender->GetAirMode());
gravityMode->SetOption(sender->GetGravityMode());
edgeMode->SetOption(sender->GetEdgeMode());
scale->SetChecked(sender->GetScale());
fullscreen->SetChecked(sender->GetFullscreen());
fastquit->SetChecked(sender->GetFastQuit());
showAvatars->SetChecked(sender->GetShowAvatars());
@@ -19,7 +19,7 @@ class OptionsView: public ui::Window {
ui::DropDown * airMode;
ui::DropDown * gravityMode;
ui::DropDown * edgeMode;
ui::Checkbox * scale;
ui::Textbox * scale;
ui::Checkbox * fullscreen;
ui::Checkbox * fastquit;
ui::Checkbox * showAvatars;
@@ -887,14 +887,14 @@ int luatpt_setpause(lua_State* l)
int luatpt_togglepause(lua_State* l)
{
luacon_model->SetPaused(!luacon_model->GetPaused());
lua_pushnumber(l, luacon_model->GetPaused());
lua_pushnumber(l, luacon_model->GetPaused());
return 1;
}
int luatpt_togglewater(lua_State* l)
{
luacon_sim->water_equal_test=!luacon_sim->water_equal_test;
lua_pushnumber(l, luacon_sim->water_equal_test);
lua_pushnumber(l, luacon_sim->water_equal_test);
return 1;
}
@@ -1678,7 +1678,7 @@ int luatpt_input(lua_State* l)
shadow = std::string(luaL_optstring(l, 4, ""));
result = TextPrompt::Blocking(title, prompt, text, shadow, false);
lua_pushstring(l, result.c_str());
return 1;
}
@@ -1981,7 +1981,9 @@ int luatpt_setwindowsize(lua_State* l)
{
int scale = luaL_optint(l,1,1);
int kiosk = luaL_optint(l,2,0);
if (scale!=2) scale = 1;
// TODO: handle this the same way as it's handled in PowderToySDL.cpp
// > maybe bind the maximum allowed scale to screen size somehow
if (scale < 1 || scale > 10) scale = 1;
if (kiosk!=1) kiosk = 0;
ui::Engine::Ref().SetScale(scale);
ui::Engine::Ref().SetFullscreen(kiosk);

0 comments on commit be29fad

Please sign in to comment.