ScalerGump.cpp

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2004-2006  The Pentagram Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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         // Skip the clipping rect/origin setting, since they will already be set
00055         // correctly by our parent.
00056         // (Or maybe I'm just to lazy to figure out the correct coordinates
00057         //  to use to compensate for the flipping... -wjp :-) )
00058 
00059         // Don't paint if hidden
00060         if (IsHidden()) return;
00061 
00062         // No scaling or filtering
00063         if (!buffer1) {
00064                 PaintChildren(surf, lerp_factor, scaled);
00065                 return;
00066         }
00067 
00068         // Render to texture
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         // Iterate all children
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                 // Paint if not closing
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         // Cheap and nasty method to use a 2x scaler to do a 2.4x scale vertically
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 // Convert a parent relative point to a gump point
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 // Convert a gump point to parent relative point
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         // Resize the gump to match the RenderSurface
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         // We don't care, we are not going to support filters, at least not at the moment
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 

Generated on Fri Jul 27 22:27:34 2007 for pentagram by  doxygen 1.4.7