00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "pent_include.h"
00020 #include "ScalerGump.h"
00021
00022 #include "RenderSurface.h"
00023 #include "Texture.h"
00024 #include "Scaler.h"
00025 #include "ScalerManager.h"
00026 #include "SettingManager.h"
00027 #include "GUIApp.h"
00028
00029 DEFINE_RUNTIME_CLASSTYPE_CODE(ScalerGump,DesktopGump);
00030
00031 ScalerGump::ScalerGump(sint32 _x, sint32 _y, sint32 _width, sint32 _height) :
00032 DesktopGump(_x, _y, _width, _height),
00033 swidth1(_width), sheight1(_height), scaler1(0), buffer1(0),
00034 swidth2(_width), sheight2(_height), scaler2(0), buffer2(0),
00035 width(_width), height(_height)
00036 {
00037 con.AddConsoleCommand("ScalerGump::changeScaler",ConCmd_changeScaler);
00038 con.AddConsoleCommand("ScalerGump::listScalers",ConCmd_listScalers);
00039
00040 SetupScalers();
00041 }
00042
00043 ScalerGump::~ScalerGump()
00044 {
00045 con.RemoveConsoleCommand(ConCmd_changeScaler);
00046 con.RemoveConsoleCommand(ConCmd_listScalers);
00047
00048 FORGET_OBJECT(buffer1);
00049 FORGET_OBJECT(buffer2);
00050 }
00051
00052 void ScalerGump::Paint(RenderSurface* surf, sint32 lerp_factor, bool scaled)
00053 {
00054
00055
00056
00057
00058
00059
00060 if (IsHidden()) return;
00061
00062
00063 if (!buffer1) {
00064 PaintChildren(surf, lerp_factor, scaled);
00065 return;
00066 }
00067
00068
00069 buffer1->BeginPainting();
00070 PaintChildren(buffer1, lerp_factor, true);
00071 buffer1->EndPainting();
00072
00073 if (!buffer2) {
00074 DoScalerBlit(buffer1->GetSurfaceAsTexture(),swidth1, sheight1,surf,width,height,scaler1);
00075 }
00076 else {
00077 buffer2->BeginPainting();
00078 DoScalerBlit(buffer1->GetSurfaceAsTexture(),swidth1,sheight1,buffer2,swidth2,sheight2,scaler1);
00079 buffer2->EndPainting();
00080
00081 DoScalerBlit(buffer2->GetSurfaceAsTexture(),swidth2,sheight2,surf,width,height,scaler2);
00082 }
00083
00084 sint32 scalex = (width<<16)/swidth1;
00085 sint32 scaley = (height<<16)/sheight1;
00086
00087
00088 std::list<Gump*>::reverse_iterator it = children.rbegin();
00089 std::list<Gump*>::reverse_iterator end = children.rend();
00090
00091 while (it != end)
00092 {
00093 Gump *g = *it;
00094
00095 if (!g->IsClosing())
00096 g->PaintCompositing(surf, lerp_factor, scalex, scaley);
00097
00098 ++it;
00099 }
00100 }
00101
00102 void ScalerGump::DoScalerBlit(Texture* src, int swidth, int sheight, RenderSurface *dest, int dwidth, int dheight, const Pentagram::Scaler *scaler)
00103 {
00104 bool ok = true;
00105
00106
00107 if (dwidth==640 && swidth==320 && dheight==480 && sheight==200 && !scaler->ScaleArbitrary())
00108 {
00109 ok = dest->ScalerBlit(src, 0, 0, swidth, 1, 0, 0, dwidth, 2, scaler);
00110
00111 int d = 1, s = 0;
00112 while(d<468 && ok) {
00113 ok = dest->ScalerBlit(src, 0, s, swidth, 3, 0, d, dwidth, 6, scaler);
00114 d+=5; s+=2;
00115
00116 if (!ok) break;
00117
00118 ok = dest->ScalerBlit(src, 0, s, swidth, 4, 0, d, dwidth, 8, scaler);
00119 d+=7; s+=3;
00120 }
00121
00122 while(d<478 && ok) {
00123 ok = dest->ScalerBlit(src, 0, s, swidth, 3, 0, d, dwidth, 6, scaler);
00124 d+=5; s+=2;
00125 }
00126 }
00127 else
00128 {
00129 ok = dest->ScalerBlit(src, 0, 0, swidth, sheight, 0, 0, dwidth, dheight, scaler);
00130 }
00131
00132 if (!ok)
00133 {
00134 dest->StretchBlit(src, 0, 0, swidth, sheight, 0, 0, dwidth, dheight);
00135 }
00136 }
00137
00138
00139 void ScalerGump::ParentToGump(int &px, int &py, PointRoundDir r)
00140 {
00141 px -= x;
00142 px *= dims.w;
00143 if (px < 0 && r == ROUND_TOPLEFT) px -= (width - 1);
00144 if (px > 0 && r == ROUND_BOTTOMRIGHT) px += (width - 1);
00145 px /= width;
00146
00147 py -= y;
00148 py *= dims.h;
00149 if (py < 0 && r == ROUND_TOPLEFT) py -= (height - 1);
00150 if (py > 0 && r == ROUND_BOTTOMRIGHT) py += (height - 1);
00151 py /= height;
00152 }
00153
00154
00155 void ScalerGump::GumpToParent(int &gx, int &gy, PointRoundDir r)
00156 {
00157 gx *= width;
00158 if (gx < 0 && r == ROUND_TOPLEFT) gx -= (dims.w - 1);
00159 if (gx > 0 && r == ROUND_BOTTOMRIGHT) gx += (dims.w - 1);
00160 gx /= dims.w;
00161 gx += x;
00162
00163 gy *= height;
00164 if (gy < 0 && r == ROUND_TOPLEFT) gy -= (dims.h - 1);
00165 if (gy > 0 && r == ROUND_BOTTOMRIGHT) gy += (dims.h - 1);
00166 gy /= dims.h;
00167 gy += y;
00168 }
00169
00170 void ScalerGump::RenderSurfaceChanged()
00171 {
00172
00173 Pentagram::Rect new_dims;
00174 parent->GetDims(new_dims);
00175
00176 width = new_dims.w;
00177 height = new_dims.h;
00178
00179 SetupScalers();
00180
00181 Gump::RenderSurfaceChanged();
00182 }
00183
00184 void ScalerGump::ChangeScaler(std::string scalername, int scalex, int scaley)
00185 {
00186 SettingManager *settingman = SettingManager::get_instance();
00187
00188 if (scalex != 0) settingman->set("scalex", scalex);
00189 if (scaley != 0) settingman->set("scaley", scaley);
00190 if (scalername != "") settingman->set("scaler", scalername);
00191
00192 SetupScalers();
00193
00194 Gump::RenderSurfaceChanged();
00195 }
00196
00197 void ScalerGump::SetupScalers()
00198 {
00199 FORGET_OBJECT(buffer1);
00200 FORGET_OBJECT(buffer2);
00201
00202 SettingManager *settingman = SettingManager::get_instance();
00203
00204 settingman->setDefault("scalex", 320);
00205 settingman->setDefault("scaley", 200);
00206 settingman->setDefault("scaler", "point");
00207
00208 std::string scaler1name;
00209 settingman->get("scalex", swidth1);
00210 settingman->get("scaley", sheight1);
00211 settingman->get("scaler", scaler1name);
00212
00213 scaler1 = ScalerManager::get_instance()->GetScaler(scaler1name);
00214 if (!scaler1) scaler1 = ScalerManager::get_instance()->GetPointScaler();
00215
00216 if (swidth1 < 0) swidth1= -swidth1;
00217 else if (swidth1 < 100) swidth1 = width/swidth1;
00218
00219 if (sheight1 < 0) sheight1= -sheight1;
00220 else if (sheight1 < 100) sheight1 = height/sheight1;
00221
00222 dims.w = swidth1;
00223 dims.h = sheight1;
00224
00225
00226 if (swidth1 == width && sheight1 == height) return;
00227
00228 buffer1 = RenderSurface::CreateSecondaryRenderSurface(swidth1, sheight1);
00229 con.Printf(MM_INFO, "Using Scaler: %s. %s\n", scaler1->ScalerDesc(), scaler1->ScalerCopyright());
00230 }
00231
00232 void ScalerGump::ConCmd_changeScaler(const Console::ArgvType &argv)
00233 {
00234 if (argv.size() != 4 && argv.size() != 2)
00235 {
00236 pout << "Usage: ScalerGump::changeScaler scaler [scalex] [scaley]" << std::endl;
00237 return;
00238 }
00239
00240 ScalerGump *scalerGump = static_cast<ScalerGump*>(GUIApp::get_instance()->getDesktopGump()->FindGump<ScalerGump>());
00241
00242 if (scalerGump) {
00243 if (argv.size() != 2)
00244 scalerGump->ChangeScaler(argv[1], strtol(argv[2].c_str(), 0, 0), strtol(argv[3].c_str(), 0, 0));
00245 else
00246 scalerGump->ChangeScaler(argv[1], 0, 0);
00247 }
00248 }
00249
00250 void ScalerGump::ConCmd_listScalers(const Console::ArgvType &argv)
00251 {
00252 ScalerManager *scaleman = ScalerManager::get_instance();
00253 uint32 numScalers = scaleman->GetNumScalers();
00254
00255 for (uint32 i = 0; i < numScalers; i++) {
00256 const Pentagram::Scaler *s = scaleman->GetScaler(i);
00257
00258 pout << s->ScalerName() << ": " << s->ScalerDesc() << " -";
00259
00260 if (s->ScaleArbitrary()) pout << " Arbitrary";
00261 else for (int b = 0; b < 32; b++) if (s->ScaleBits() & (1<<b)) pout << " " << b << "x";
00262
00263 pout << std::endl;
00264 }
00265 }
00266