loadscreen.cpp

Go to the documentation of this file.
00001 /* $Id: loadscreen.cpp 24907 2008-03-20 19:03:51Z alink $ */
00002 /*
00003    Copyright (C) 2005 - 2008 by Joeri Melis <joeri_melis@hotmail.com>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License version 2
00008    or at your option any later version.
00009    This program is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY.
00011 
00012    See the COPYING file for more details.
00013 */
00014 
00015 //! @file loadscreen.cpp
00016 //! Screen with logo and "Loading ..."-progressbar during program-startup.
00017 
00018 #include "loadscreen.hpp"
00019 
00020 #include "font.hpp"
00021 #include "marked-up_text.hpp"
00022 #include "gettext.hpp"
00023 #include "filesystem.hpp"
00024 
00025 #include <iostream>
00026 
00027 #define MIN_PERCENTAGE   0
00028 #define MAX_PERCENTAGE 100
00029 
00030 loadscreen::global_loadscreen_manager::global_loadscreen_manager(CVideo& screen)
00031   : owns(global_loadscreen == NULL)
00032 {
00033     if(owns) {
00034         global_loadscreen = new loadscreen(screen);
00035         global_loadscreen->clear_screen();
00036     }
00037 }
00038 
00039 loadscreen::global_loadscreen_manager::~global_loadscreen_manager()
00040 {
00041     if(owns && global_loadscreen) {
00042         global_loadscreen->clear_screen();
00043         delete global_loadscreen;
00044         global_loadscreen = NULL;
00045     }
00046 }
00047 
00048 loadscreen::loadscreen(CVideo &screen, const int &percent):
00049     filesystem_counter(0),
00050     binarywml_counter(0),
00051     setconfig_counter(0),
00052     parser_counter(0),
00053     screen_(screen),
00054     logo_drawn_(false),
00055     pby_offset_(0),
00056     prcnt_(percent)
00057 {
00058     std::string path = get_binary_file_location("images","misc/logo.png");
00059     logo_surface_ = IMG_Load(path.c_str());
00060         if (!logo_surface_) {
00061             std::cerr << "loadscreen: Failed to load the logo: " << path << std::endl;
00062         }
00063     textarea_.x = textarea_.y = textarea_.w = textarea_.h = 0;
00064 }
00065 void loadscreen::set_progress(const int percentage, const std::string &text, const bool commit)
00066 {
00067     //! Saturate percentage.
00068     prcnt_ = percentage < MIN_PERCENTAGE ? MIN_PERCENTAGE: percentage > MAX_PERCENTAGE ? MAX_PERCENTAGE: percentage;
00069     // Set progress bar parameters:
00070     int fcr =  21, fcg =  53, fcb =  80;        // RGB-values for finished piece.
00071     int lcr =  21, lcg =  22, lcb =  24;        // Leftover piece.
00072     int bcr = 188, bcg = 176, bcb = 136;        // Border color.
00073     int bw = 1;                             //!< Border width.
00074     int bispw = 1;                              //!< Border inner spacing width.
00075     bw = 2*(bw+bispw) > screen_.getx() ? 0: 2*(bw+bispw) > screen_.gety() ? 0: bw;
00076     int scrx = screen_.getx() - 2*(bw+bispw);   //!< Available width.
00077     int scry = screen_.gety() - 2*(bw+bispw);   //!< Available height.
00078     int pbw = scrx/2;                           //!< Used width.
00079     int pbh = scry/16;                          //!< Used heigth.
00080     int lightning_thickness = 2;
00081     
00082     surface const gdis = screen_.getSurface();
00083     SDL_Rect area;
00084     // Draw logo if it was succesfully loaded.
00085     if (logo_surface_ && !logo_drawn_) {
00086         area.x = (screen_.getx () - logo_surface_->w) / 2;
00087         area.y = ((scry - logo_surface_->h) / 2) - pbh;
00088         area.w = logo_surface_->w;
00089         area.h = logo_surface_->h;
00090         // Check if we have enough pixels to display it.
00091         if (area.x > 0 && area.y > 0) {
00092             pby_offset_ = (pbh + area.h)/2;
00093             SDL_BlitSurface (logo_surface_, 0, gdis, &area);
00094         } else {
00095             std::cerr << "loadscreen: Logo image is too big." << std::endl;
00096         }
00097         logo_drawn_ = true;
00098         SDL_UpdateRect(gdis, area.x, area.y, area.w, area.h);
00099     }
00100     int pbx = (scrx - pbw)/2;                   // Horizontal location.
00101     int pby = (scry - pbh)/2 + pby_offset_;     // Vertical location.
00102 
00103     // Draw top border.
00104     area.x = pbx; area.y = pby;
00105     area.w = pbw + 2*(bw+bispw); area.h = bw;
00106     SDL_FillRect(gdis,&area,SDL_MapRGB(gdis->format,bcr,bcg,bcb));
00107     // Draw bottom border.
00108     area.x = pbx; area.y = pby + pbh + bw + 2*bispw;
00109     area.w = pbw + 2*(bw+bispw); area.h = bw;
00110     SDL_FillRect(gdis,&area,SDL_MapRGB(gdis->format,bcr,bcg,bcb));
00111     // Draw left border.
00112     area.x = pbx; area.y = pby + bw;
00113     area.w = bw; area.h = pbh + 2*bispw;
00114     SDL_FillRect(gdis,&area,SDL_MapRGB(gdis->format,bcr,bcg,bcb));
00115     // Draw right border.
00116     area.x = pbx + pbw + bw + 2*bispw; area.y = pby + bw;
00117     area.w = bw; area.h = pbh + 2*bispw;
00118     SDL_FillRect(gdis,&area,SDL_MapRGB(gdis->format,bcr,bcg,bcb));
00119     // Draw the finished bar area.
00120     area.x = pbx + bw + bispw; area.y = pby + bw + bispw;
00121     area.w = (prcnt_ * pbw) / (MAX_PERCENTAGE - MIN_PERCENTAGE); area.h = pbh;
00122     SDL_FillRect(gdis,&area,SDL_MapRGB(gdis->format,fcr,fcg,fcb));
00123 
00124     SDL_Rect lightning = area;
00125     lightning.h = lightning_thickness;
00126     //we add 25% of white to the color of the bar to simulate a light effect
00127     SDL_FillRect(gdis,&lightning,SDL_MapRGB(gdis->format,(fcr*3+255)/4,(fcg*3+255)/4,(fcb*3+255)/4));
00128     lightning.y = area.y+area.h-lightning.h;
00129     //remove 50% of color to simulate a shadow effect
00130     SDL_FillRect(gdis,&lightning,SDL_MapRGB(gdis->format,fcr/2,fcg/2,fcb/2));
00131 
00132     // Draw the leftover bar area.
00133     area.x = pbx + bw + bispw + (prcnt_ * pbw) / (MAX_PERCENTAGE - MIN_PERCENTAGE); area.y = pby + bw + bispw;
00134     area.w = ((MAX_PERCENTAGE - prcnt_) * pbw) / (MAX_PERCENTAGE - MIN_PERCENTAGE); area.h = pbh;
00135     SDL_FillRect(gdis,&area,SDL_MapRGB(gdis->format,lcr,lcg,lcb));
00136 
00137     // Clear the last text and draw new if text is provided.
00138     if(text.length() > 0 && commit)
00139     {
00140         SDL_Rect oldarea = textarea_;
00141         SDL_FillRect(gdis,&textarea_,SDL_MapRGB(gdis->format,0,0,0));
00142         textarea_ = font::line_size(text, font::SIZE_NORMAL);
00143         textarea_.x = scrx/2 + bw + bispw - textarea_.w / 2;
00144         textarea_.y = pby + pbh + 4*(bw + bispw);
00145         textarea_ = font::draw_text(&screen_,textarea_,font::SIZE_NORMAL,font::NORMAL_COLOUR,text,textarea_.x,textarea_.y);
00146         oldarea.x = minimum<int>(textarea_.x, oldarea.x);
00147         oldarea.y = minimum<int>(textarea_.y, oldarea.y);
00148         oldarea.w = maximum<int>(textarea_.w, oldarea.w);
00149         oldarea.h = maximum<int>(textarea_.h, oldarea.h);
00150         SDL_UpdateRect(gdis, oldarea.x, oldarea.y, oldarea.w, oldarea.h);
00151     }
00152     // Update the rectangle if needed
00153     if(commit)
00154     {
00155         SDL_UpdateRect(gdis, pbx, pby, pbw + 2*(bw + bispw), pbh + 2*(bw + bispw));
00156     }
00157 }
00158 
00159 void loadscreen::increment_progress(const int percentage, const std::string &text, const bool commit) {
00160     set_progress(prcnt_ + percentage, text, commit);
00161 }
00162 
00163 void loadscreen::clear_screen(const bool commit)
00164 {
00165     int scrx = screen_.getx();                  //!< Screen width.
00166     int scry = screen_.gety();                  //!< Screen height.
00167     SDL_Rect area = {0, 0, scrx, scry};     // Screen area.
00168     surface const disp(screen_.getSurface());   // Screen surface.
00169     // Make everything black.
00170     SDL_FillRect(disp,&area,SDL_MapRGB(disp->format,0,0,0));
00171     if(commit)
00172     {
00173         SDL_Flip(disp);                     // Flip the double buffering.
00174     }
00175 }
00176 
00177 loadscreen *loadscreen::global_loadscreen = 0;
00178 
00179 // Amount of work to expect during the startup-stages,
00180 // for scaling the progressbars:
00181 #define CALLS_TO_FILESYSTEM 112
00182 #define PRCNT_BY_FILESYSTEM  20
00183 #define CALLS_TO_BINARYWML 9561
00184 #define PRCNT_BY_BINARYWML   20
00185 #define CALLS_TO_SETCONFIG  306
00186 #define PRCNT_BY_SETCONFIG   30
00187 #define CALLS_TO_PARSER   50448
00188 #define PRCNT_BY_PARSER      20
00189 
00190 void increment_filesystem_progress () {
00191     unsigned newpct, oldpct;
00192     // Only do something if the variable is filled in.
00193     // I am assuming non parallel access here!
00194     if (loadscreen::global_loadscreen != 0) {
00195         if (loadscreen::global_loadscreen->filesystem_counter == 0) {
00196             loadscreen::global_loadscreen->increment_progress(0, _("Verifying cache."));
00197         }
00198         oldpct = (PRCNT_BY_FILESYSTEM * loadscreen::global_loadscreen->filesystem_counter) / CALLS_TO_FILESYSTEM;
00199         newpct = (PRCNT_BY_FILESYSTEM * ++(loadscreen::global_loadscreen->filesystem_counter)) / CALLS_TO_FILESYSTEM;
00200         //std::cerr << "Calls " << num;
00201         if(oldpct != newpct) {
00202             //std::cerr << " percent " << newpct;
00203             loadscreen::global_loadscreen->increment_progress(newpct - oldpct);
00204         }
00205         //std::cerr << std::endl;
00206     }
00207 }
00208 
00209 void increment_binary_wml_progress () {
00210     unsigned newpct, oldpct;
00211     // Only do something if the variable is filled in.
00212     // I am assuming non parallel access here!
00213     if (loadscreen::global_loadscreen != 0) {
00214         if (loadscreen::global_loadscreen->binarywml_counter == 0) {
00215             loadscreen::global_loadscreen->increment_progress(0, _("Reading cache."));
00216         }
00217         oldpct = (PRCNT_BY_BINARYWML * loadscreen::global_loadscreen->binarywml_counter) / CALLS_TO_BINARYWML;
00218         newpct = (PRCNT_BY_BINARYWML * ++(loadscreen::global_loadscreen->binarywml_counter)) / CALLS_TO_BINARYWML;
00219         //std::cerr << "Calls " << num;
00220         if(oldpct != newpct) {
00221             //std::cerr << " percent " << newpct;
00222             loadscreen::global_loadscreen->increment_progress(newpct - oldpct);
00223         }
00224         //std::cerr << std::endl;
00225     }
00226 }
00227 
00228 void increment_set_config_progress () {
00229     unsigned newpct, oldpct;
00230     // Only do something if the variable is filled in.
00231     // I am assuming non parallel access here!
00232     if (loadscreen::global_loadscreen != 0) {
00233         if (loadscreen::global_loadscreen->setconfig_counter == 0) {
00234             loadscreen::global_loadscreen->increment_progress(0, _("Reading unit files."));
00235         }
00236         oldpct = (PRCNT_BY_SETCONFIG * loadscreen::global_loadscreen->setconfig_counter) / CALLS_TO_SETCONFIG;
00237         newpct = (PRCNT_BY_SETCONFIG * ++(loadscreen::global_loadscreen->setconfig_counter)) / CALLS_TO_SETCONFIG;
00238         //std::cerr << "Calls " << num;
00239         if(oldpct != newpct) {
00240             //std::cerr << " percent " << newpct;
00241             loadscreen::global_loadscreen->increment_progress(newpct - oldpct);
00242         }
00243         //std::cerr << std::endl;
00244     }
00245 }
00246 
00247 void increment_parser_progress () {
00248     unsigned newpct, oldpct;
00249     // Only do something if the variable is filled in.
00250     // I am assuming non parallel access here!
00251     if (loadscreen::global_loadscreen != 0) {
00252         if (loadscreen::global_loadscreen->parser_counter == 0) {
00253             loadscreen::global_loadscreen->increment_progress(0, _("Reading files and creating cache."));
00254         }
00255         oldpct = (PRCNT_BY_PARSER * loadscreen::global_loadscreen->parser_counter) / CALLS_TO_PARSER;
00256         newpct = (PRCNT_BY_PARSER * ++(loadscreen::global_loadscreen->parser_counter)) / CALLS_TO_PARSER;
00257         //std::cerr << "Calls " << loadscreen::global_loadscreen->parser_counter;
00258         if(oldpct != newpct) {
00259         //  std::cerr << " percent " << newpct;
00260             loadscreen::global_loadscreen->increment_progress(newpct - oldpct);
00261         }
00262         //std::cerr << std::endl;
00263     }
00264 }

Generated by doxygen 1.5.5 on 23 May 2008 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs