CreditsGump.cpp

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) 2005  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 "CreditsGump.h"
00021 
00022 #include "GUIApp.h"
00023 #include "DesktopGump.h"
00024 #include "RenderSurface.h"
00025 #include "RenderedText.h"
00026 #include "Font.h"
00027 #include "FontManager.h"
00028 #include "MusicProcess.h"
00029 #include "SettingManager.h"
00030 
00031 DEFINE_RUNTIME_CLASSTYPE_CODE(CreditsGump,ModalGump);
00032 
00033 CreditsGump::CreditsGump()
00034         : ModalGump()
00035 {
00036 
00037 }
00038 
00039 CreditsGump::CreditsGump(const std::string& text_, int parskip_,
00040                                                  uint32 _Flags, sint32 layer)
00041         : ModalGump(0, 0, 320, 200, 0, _Flags, layer)
00042 {
00043         text = text_;
00044         parskip = parskip_;
00045 
00046         timer = 0;
00047         title = 0;
00048         nexttitle = 0;
00049         state = CS_PLAYING;
00050 }
00051 
00052 CreditsGump::~CreditsGump()
00053 {
00054         delete scroll[0];
00055         delete scroll[1];
00056         delete scroll[2];
00057         delete scroll[3];
00058 
00059         delete title;
00060         delete nexttitle;
00061 }
00062 
00063 void CreditsGump::InitGump(Gump* newparent, bool take_focus)
00064 {
00065         ModalGump::InitGump(newparent, take_focus);
00066 
00067         scroll[0] = RenderSurface::CreateSecondaryRenderSurface(256, 200);
00068         scroll[1] = RenderSurface::CreateSecondaryRenderSurface(256, 200);
00069         scroll[2] = RenderSurface::CreateSecondaryRenderSurface(256, 200);
00070         scroll[3] = RenderSurface::CreateSecondaryRenderSurface(256, 200);
00071         scroll[0]->Fill32(0xFF000000,0,0,256,200); // black background
00072         scroll[1]->Fill32(0xFF000000,0,0,256,200);
00073         scroll[2]->Fill32(0xFF000000,0,0,256,200);
00074         scroll[3]->Fill32(0xFF000000,0,0,256,200);
00075         scrollheight[0] = 156;
00076         scrollheight[1] = 0;
00077         scrollheight[2] = 0;
00078         scrollheight[3] = 0;
00079 
00080         currentsurface = 0;
00081         currenty = 0;
00082 
00083         GUIApp::get_instance()->pushMouseCursor();
00084         GUIApp::get_instance()->setMouseCursor(GUIApp::MOUSE_NONE);
00085 }
00086 
00087 void CreditsGump::Close(bool no_del)
00088 {
00089         GUIApp::get_instance()->popMouseCursor();
00090 
00091         ModalGump::Close(no_del);
00092 
00093         MusicProcess* musicproc = MusicProcess::get_instance();
00094         if (musicproc) musicproc->playMusic(0);
00095 }
00096 
00097 void CreditsGump::extractLine(std::string& text,
00098                                                           char& modifier, std::string& line)
00099 {
00100         if (text.empty()) {
00101                 line = "";
00102                 modifier = 0;
00103                 return;
00104         }
00105 
00106         if (text[0] == '+' || text[0] == '&' || text[0] == '}' || text[0] == '~' ||
00107                 text[0] == '@')
00108         {
00109                 modifier = text[0];
00110                 text.erase(0,1);
00111         } else {
00112                 modifier = 0;
00113         }
00114 
00115         std::string::size_type starpos = text.find('*');
00116 
00117         line = text.substr(0, starpos);
00118 
00119         // replace '%%' by '%'.
00120         // (Original interpreted these strings as format strings??)
00121         std::string::size_type ppos;
00122         while ((ppos = line.find("%%")) != std::string::npos) {
00123                 line.replace(ppos, 2, "%");
00124         }
00125 
00126         if (starpos != std::string::npos) starpos++;
00127         text.erase(0, starpos);
00128 }
00129 
00130 
00131 bool CreditsGump::Run(const uint32 framenum)
00132 {
00133         ModalGump::Run(framenum);
00134 
00135         if (timer) {
00136                 timer--;
00137                 return false;
00138         }
00139 
00140         if (state == CS_CLOSING) {
00141                 // pout << "CreditsGump: closing" << std::endl;
00142                 Close();
00143                 return true;
00144         }
00145 
00146         timer = 1;
00147 
00148         int available = scrollheight[currentsurface] - currenty;
00149         int nextblock = -1;
00150         for (int i = 1; i < 4; i++) {
00151                 available += scrollheight[(currentsurface+i)%4];
00152                 if (nextblock == -1 && scrollheight[(currentsurface+i)%4] == 0)
00153                         nextblock = (currentsurface+i)%4;
00154         }
00155         if (available == 0) nextblock = 0;
00156 
00157         if (state == CS_FINISHING && available <= 156) {
00158                 // pout << "CreditsGump: waiting before closing" << std::endl;
00159                 timer = 120;
00160                 state = CS_CLOSING;
00161 
00162                 if (!configkey.empty()) {
00163                         SettingManager* settingman = SettingManager::get_instance();
00164                         settingman->set(configkey, true);
00165                         settingman->write();
00166                 }
00167 
00168                 return true;
00169         }
00170 
00171         if (state == CS_PLAYING && available <= 160) {
00172                 // time to render next block
00173 
00174                 scroll[nextblock]->Fill32(0xFF000000,0,0,256,200);
00175                 // scroll[nextblock]->Fill32(0xFFFFFFFF,0,0,256,5); // block marker
00176                 scrollheight[nextblock] = 0;
00177                 
00178                 Pentagram::Font *redfont, *yellowfont;
00179                 
00180                 redfont = FontManager::get_instance()->getGameFont(6, true);
00181                 yellowfont = FontManager::get_instance()->getGameFont(8, true);
00182                 
00183                 bool done = false;
00184                 bool firstline = true;
00185                 while (!text.empty() && !done) {
00186                         std::string::size_type endline = text.find('\n');
00187                         std::string line = text.substr(0, endline);
00188                         
00189                         if (line.empty()) {
00190                                 text.erase(0, 1);
00191                                 continue;
00192                         }
00193                         
00194                         // pout << "Rendering paragraph: " << line << std::endl;
00195                         
00196                         if (line[0] == '+') {
00197                                 // set title
00198                                 if (!firstline) {
00199                                         // if this isn't the first line of the block,
00200                                         // postpone setting title until next block
00201                                         done = true;
00202                                         continue;
00203                                 }
00204                                 
00205                                 std::string titletext;
00206                                 char modifier;
00207                                 
00208                                 extractLine(line, modifier, titletext);
00209                                 
00210                                 unsigned int remaining;
00211                                 nexttitle = redfont->renderText(titletext, remaining, 192, 0,
00212                                                                                                 Pentagram::Font::TEXT_CENTER);
00213                                 
00214                                 if (!title) {
00215                                         title = nexttitle;
00216                                         nexttitle = 0;
00217                                 } else {
00218                                         nexttitlesurf = nextblock;
00219                                         scrollheight[nextblock] = 160; // skip some space
00220                                 }
00221                                 
00222                         } else {
00223                                 
00224                                 int height = 0;
00225                                 
00226                                 Pentagram::Font* font = redfont;
00227                                 Pentagram::Font::TextAlign align = Pentagram::Font::TEXT_LEFT;
00228                                 int indent = 0;
00229                                 
00230                                 while (!line.empty()) {
00231                                         std::string outline;
00232                                         char modifier;
00233                                         unsigned int remaining;
00234                                         extractLine(line, modifier, outline);
00235                                         
00236                                         // pout << "Rendering line: " << outline << std::endl;
00237                                         
00238                                         switch (modifier) {
00239                                         case '&':
00240                                                 font = yellowfont;
00241                                                 align = Pentagram::Font::TEXT_CENTER;
00242                                                 break;
00243                                         case '}':
00244                                                 font = redfont;
00245                                                 align = Pentagram::Font::TEXT_CENTER;
00246                                                 break;
00247                                         case '~':
00248                                                 font = yellowfont;
00249                                                 align = Pentagram::Font::TEXT_LEFT;
00250                                                 indent = 32;
00251                                                 break;
00252                                         case '@':
00253                                                 // pout << "CreditsGump: done, finishing" << std::endl;
00254                                                 state = CS_FINISHING;
00255                                                 break;
00256                                         default:
00257                                                 break;
00258                                         }
00259 
00260                                         if (!modifier && outline.empty()) {
00261                                                 height += 48;
00262                                                 continue;
00263                                         }
00264 
00265                                         if (outline[0] == '&') { 
00266                                                 // horizontal line
00267                                                 
00268                                                 if (scrollheight[nextblock]+height+7 > 200) {
00269                                                         done = true;
00270                                                         break;
00271                                                 }
00272                                                 
00273                                                 int linewidth = outline.size() * 8;
00274                                                 if (linewidth > 192) linewidth = 192;
00275                                                 
00276                                                 scroll[nextblock]->
00277                                                         Fill32(0xFFD43030,128-(linewidth/2),
00278                                                                    scrollheight[nextblock]+height+3,
00279                                                                    linewidth,1);
00280                                                 height += 7;
00281                                                 continue;
00282                                         }
00283                                         
00284                                         RenderedText* rt = font->renderText(outline, remaining,
00285                                                                                                                 256-indent, 0,
00286                                                                                                                 align);
00287                                         int xd,yd;
00288                                         rt->getSize(xd,yd);
00289                                         
00290                                         if (scrollheight[nextblock]+height+yd > 200) {
00291                                                 delete rt;
00292                                                 done = true;
00293                                                 break;
00294                                         }
00295                                         
00296                                         rt->draw(scroll[nextblock], indent,
00297                                                          scrollheight[nextblock]+height+
00298                                                          font->getBaseline());
00299                                         
00300                                         height += yd + rt->getVlead();
00301                                         
00302                                         delete rt;
00303                                 }
00304                                 
00305                                 if (state == CS_PLAYING)
00306                                         height += parskip;
00307 
00308                                 if (scrollheight[nextblock] + height > 200) {
00309                                         if (firstline) {
00310                                                 height = 200 - scrollheight[nextblock];
00311                                                 assert(height >= 0);
00312                                         } else {
00313                                                 done = true;
00314                                         }
00315                                 }
00316                                 
00317                                 if (done) break; // no room
00318                                 
00319                                 scrollheight[nextblock] += height;
00320                         }
00321                         
00322                         
00323                         if (endline != std::string::npos) endline++;
00324                         text.erase(0, endline);
00325                         
00326                         firstline = false;
00327                 }
00328         }
00329 
00330         currenty++;
00331 
00332         if (currenty >= scrollheight[currentsurface]) {
00333                 // next surface
00334                 currenty -= scrollheight[currentsurface];
00335                 scrollheight[currentsurface] = 0;
00336                 currentsurface = (currentsurface+1)%4;
00337 
00338                 if (nexttitle && currentsurface == nexttitlesurf) {
00339                         delete title;
00340                         title = nexttitle;
00341                         nexttitle = 0;
00342                 }
00343         }
00344 
00345         return true;
00346 }
00347 
00348 void CreditsGump::PaintThis(RenderSurface* surf, sint32 lerp_factor, bool scaled)
00349 {
00350         surf->Fill32(0xFF000000,0,0,320,200); // black background
00351         surf->Fill32(0xFFD43030,64,41,192,1); // line between title and scroller
00352 
00353         if (title)
00354                 title->draw(surf, 64, 34);
00355 
00356         Texture* tex = scroll[currentsurface]->GetSurfaceAsTexture();
00357         int h = scrollheight[currentsurface] - currenty;
00358         if (h > 156) h = 156;
00359         if (h > 0)
00360                 surf->Blit(tex, 0, currenty, 256, h, 32, 44);
00361 
00362         int y = h;
00363         for (int i = 1; i < 4; i++) {
00364                 if (h == 156) break;
00365 
00366                 int s = (currentsurface+i)%4;
00367                 tex = scroll[s]->GetSurfaceAsTexture();
00368                 h = scrollheight[s];
00369                 if (h > 156-y) h = 156-y;
00370                 if (h > 0)
00371                         surf->Blit(tex, 0, 0, 256, h, 32, 44+y);
00372                 y += h;
00373         }
00374 }
00375 
00376 bool CreditsGump::OnKeyDown(int key, int mod)
00377 {
00378         switch(key)
00379         {
00380         case SDLK_ESCAPE:
00381         {
00382                 Close();
00383         } break;
00384         default:
00385                 break;
00386         }
00387 
00388         return true;
00389 }

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