add a progressbar at game start

This commit is contained in:
Jérémy Rosen 2006-04-02 08:15:29 +00:00
parent ad5472f435
commit d76fec8f77
10 changed files with 295 additions and 2 deletions

View file

@ -296,6 +296,7 @@ Version 1.1.2:
* [effect] can modify attack/defense weight
* change in the [sound] tag. sounds must now be part of animation
* miscellaneous changes
* added a very simple progress bar while loading
* added a --load FILE command-line option, where FILE is a saved game
in the standard save game directory.
* reordered macro calls in game.cfg to fix no-AMLA bug for campaigns

View file

@ -496,6 +496,7 @@ Laurent Birtz
Patrick Parker (Sapient)
Rocco J Carello (rogue)
Tomasz Sikorski (Tomsik)
Joeri Melis
"
[/about]

View file

@ -334,6 +334,7 @@ noinst_HEADERS = \
ai_interface.hpp \
multiplayer_wait.hpp \
gettext.hpp \
loadscreen.hpp \
builder.hpp \
publish_campaign.hpp \
playlevel.hpp \
@ -415,6 +416,7 @@ libwesnoth_core_a_SOURCES = \
color_range.cpp \
game_config.cpp \
gettext.cpp \
loadscreen.cpp \
log.cpp \
map.cpp \
pathutils.cpp \

View file

@ -13,6 +13,8 @@
#include "global.hpp"
#include "loadscreen.hpp"
//include files for opendir(3), readdir(3), etc. These files may vary
//from platform to platform, since these functions are NOT ANSI-conforming
//functions. They may have to be altered to port to new platforms
@ -685,7 +687,7 @@ void get_file_tree_checksum_internal(const std::string& path, file_tree_checksum
{
std::vector<std::string> files, dirs;
get_files_in_dir(path,&files,&dirs,ENTIRE_FILE_PATH);
increment_filesystem_progress();
for(std::vector<std::string>::const_iterator i = files.begin(); i != files.end(); ++i) {
++res.nfiles;

View file

@ -30,6 +30,7 @@
#include "hotkeys.hpp"
#include "intro.hpp"
#include "language.hpp"
#include "loadscreen.hpp"
#include "multiplayer.hpp"
#include "network.hpp"
#include "playcampaign.hpp"
@ -1319,6 +1320,11 @@ void game_controller::read_game_cfg(const preproc_map& defines, config& cfg, boo
//read the file and then write to the cache
scoped_istream stream = preprocess_file("data/game.cfg", &defines_map);
//reset the parse counter before reading the game files
if (loadscreen::global_loadscreen) {
loadscreen::global_loadscreen->parser_counter = 0;
}
std::string error_log, user_error_log;
read(cfg, *stream, &error_log);
@ -1650,17 +1656,22 @@ int play_game(int argc, char** argv)
return 0;
}
loadscreen::global_loadscreen = new loadscreen(game.disp().video());
loadscreen::global_loadscreen->clear_screen();
res = game.init_language();
if(res == false) {
std::cerr << "could not initialize the language\n";
return 0;
}
loadscreen::global_loadscreen->increment_progress(5, "Loading game configuration.");
res = game.init_config();
if(res == false) {
std::cerr << "could not initialize game config\n";
return 0;
}
loadscreen::global_loadscreen->increment_progress(10, "Re-initialize fonts for the current language.");
res = font::load_font_config();
if(res == false) {
@ -1676,6 +1687,10 @@ int play_game(int argc, char** argv)
int ntip = -1;
config tips_of_day;
loadscreen::global_loadscreen->set_progress(100, "Loading title screen.");
delete loadscreen::global_loadscreen;
loadscreen::global_loadscreen = 0;
for(;;) {
//make sure the game config is always set to how it should be at the title screen
game.reset_game_cfg();

184
src/loadscreen.cpp Normal file
View file

@ -0,0 +1,184 @@
/*
Copyright (C) 2005 by Joeri Melis <joeri_melis@hotmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#include "loadscreen.hpp"
#include "font.hpp"
#include "marked-up_text.hpp"
//#include <iostream>
#define MIN_PERCENTAGE 0
#define MAX_PERCENTAGE 100
void loadscreen::set_progress(const int percentage, const std::string &text, const bool commit)
{
/* Saturate percentage. */
prcnt_ = percentage < MIN_PERCENTAGE ? MIN_PERCENTAGE: percentage > MAX_PERCENTAGE ? MAX_PERCENTAGE: percentage;
/* Set progress bar parameters. */
int fcr = 0, fcg = 0, fcb = 255; /* Finished piece. */
int lcr = 0, lcg = 0, lcb = 63; /* Leftover piece. */
int bcr = 255, bcg = 255, bcb = 255; /* Border color. */
int bw = 5; /* Border width. */
bw = 2*bw > screen_.getx() ? 0: 2*bw > screen_.gety() ? 0: bw;
int scrx = screen_.getx() - 2*bw; /* Available width. */
int scry = screen_.gety() - 2*bw; /* Available height. */
int pbw = scrx/2; /* Used width. */
int pbh = scry/16; /* Used heigth. */
int pbx = (scrx - pbw)/2; /* Horizontal location. */
int pby = (scry - pbh)/2; /* Vertical location. */
surface const gdis = screen_.getSurface();
SDL_Rect area;
/* Draw top border. */
area.x = pbx; area.y = pby;
area.w = pbw + 2*bw; area.h = bw;
SDL_FillRect(gdis,&area,SDL_MapRGB(gdis->format,bcr,bcg,bcb));
/* Draw bottom border. */
area.x = pbx; area.y = pby + pbh + bw;
area.w = pbw + 2*bw; area.h = bw;
SDL_FillRect(gdis,&area,SDL_MapRGB(gdis->format,bcr,bcg,bcb));
/* Draw left border. */
area.x = pbx; area.y = pby + bw;
area.w = bw; area.h = pbh;
SDL_FillRect(gdis,&area,SDL_MapRGB(gdis->format,bcr,bcg,bcb));
/* Draw right border. */
area.x = pbx + pbw + bw; area.y = pby + bw;
area.w = bw; area.h = pbh;
SDL_FillRect(gdis,&area,SDL_MapRGB(gdis->format,bcr,bcg,bcb));
/* Draw the finished bar area. */
area.x = pbx + bw; area.y = pby + bw;
area.w = (prcnt_ * pbw) / (MAX_PERCENTAGE - MIN_PERCENTAGE); area.h = pbh;
SDL_FillRect(gdis,&area,SDL_MapRGB(gdis->format,fcr,fcg,fcb));
/* Draw the leftover bar area. */
area.x = pbx + bw + (prcnt_ * pbw) / (MAX_PERCENTAGE - MIN_PERCENTAGE); area.y = pby + bw;
area.w = ((MAX_PERCENTAGE - prcnt_) * pbw) / (MAX_PERCENTAGE - MIN_PERCENTAGE); area.h = pbh;
SDL_FillRect(gdis,&area,SDL_MapRGB(gdis->format,lcr,lcg,lcb));
/* Clear the last text and draw new if text is provided. */
if(text.length()>0)
{
SDL_FillRect(gdis,&textarea_,SDL_MapRGB(gdis->format,0,0,0));
textarea_ = font::line_size(text, font::SIZE_NORMAL);
textarea_.x = scrx/2 + bw - textarea_.w / 2;
textarea_.y = pby + pbh + 4*bw;
textarea_ = font::draw_text(&screen_,textarea_,font::SIZE_NORMAL,font::NORMAL_COLOUR,text,textarea_.x,textarea_.y);
}
/* Flip the double buffering so the change becomes visible */
if(commit)
{
SDL_Flip(gdis);
}
}
void loadscreen::increment_progress(const int percentage, const std::string &text, const bool commit) {
set_progress(prcnt_ + percentage, text, commit);
}
void loadscreen::clear_screen(const bool commit)
{
int scrx = screen_.getx(); /* Screen width. */
int scry = screen_.gety(); /* Screen height. */
SDL_Rect area = {0, 0, scrx, scry}; /* Screen area. */
surface const disp(screen_.getSurface()); /* Screen surface. */
/* Make everything black. */
SDL_FillRect(disp,&area,SDL_MapRGB(disp->format,0,0,0));
if(commit)
{
SDL_Flip(disp); /* Flip the double buffering. */
}
}
loadscreen *loadscreen::global_loadscreen = 0;
#define CALLS_TO_FILESYSTEM 112
#define PRCNT_BY_FILESYSTEM 20
#define CALLS_TO_BINARYWML 9561
#define PRCNT_BY_BINARYWML 20
#define CALLS_TO_SETCONFIG 306
#define PRCNT_BY_SETCONFIG 30
#define CALLS_TO_PARSER 50448
#define PRCNT_BY_PARSER 20
void increment_filesystem_progress () {
unsigned newpct, oldpct;
// Only do something if the variable is filled in.
// I am assuming non parallel access here!
if (loadscreen::global_loadscreen != 0) {
if (loadscreen::global_loadscreen->filesystem_counter == 0) {
loadscreen::global_loadscreen->increment_progress(0, "Verifying cache.");
}
oldpct = (PRCNT_BY_FILESYSTEM * loadscreen::global_loadscreen->filesystem_counter) / CALLS_TO_FILESYSTEM;
newpct = (PRCNT_BY_FILESYSTEM * ++(loadscreen::global_loadscreen->filesystem_counter)) / CALLS_TO_FILESYSTEM;
//std::cerr << "Calls " << num;
if(oldpct != newpct) {
//std::cerr << " percent " << newpct;
loadscreen::global_loadscreen->increment_progress(newpct - oldpct);
}
//std::cerr << std::endl;
}
}
void increment_binary_wml_progress () {
unsigned newpct, oldpct;
// Only do something if the variable is filled in.
// I am assuming non parallel access here!
if (loadscreen::global_loadscreen != 0) {
if (loadscreen::global_loadscreen->binarywml_counter == 0) {
loadscreen::global_loadscreen->increment_progress(0, "Reading cache.");
}
oldpct = (PRCNT_BY_BINARYWML * loadscreen::global_loadscreen->binarywml_counter) / CALLS_TO_BINARYWML;
newpct = (PRCNT_BY_BINARYWML * ++(loadscreen::global_loadscreen->binarywml_counter)) / CALLS_TO_BINARYWML;
//std::cerr << "Calls " << num;
if(oldpct != newpct) {
//std::cerr << " percent " << newpct;
loadscreen::global_loadscreen->increment_progress(newpct - oldpct);
}
//std::cerr << std::endl;
}
}
void increment_set_config_progress () {
unsigned newpct, oldpct;
// Only do something if the variable is filled in.
// I am assuming non parallel access here!
if (loadscreen::global_loadscreen != 0) {
if (loadscreen::global_loadscreen->setconfig_counter == 0) {
loadscreen::global_loadscreen->increment_progress(0, "Reading unit files.");
}
oldpct = (PRCNT_BY_SETCONFIG * loadscreen::global_loadscreen->setconfig_counter) / CALLS_TO_SETCONFIG;
newpct = (PRCNT_BY_SETCONFIG * ++(loadscreen::global_loadscreen->setconfig_counter)) / CALLS_TO_SETCONFIG;
//std::cerr << "Calls " << num;
if(oldpct != newpct) {
//std::cerr << " percent " << newpct;
loadscreen::global_loadscreen->increment_progress(newpct - oldpct);
}
//std::cerr << std::endl;
}
}
void increment_parser_progress () {
unsigned newpct, oldpct;
// Only do something if the variable is filled in.
// I am assuming non parallel access here!
if (loadscreen::global_loadscreen != 0) {
if (loadscreen::global_loadscreen->parser_counter == 0) {
loadscreen::global_loadscreen->increment_progress(0, "Reading files and creating cache.");
}
oldpct = (PRCNT_BY_PARSER * loadscreen::global_loadscreen->parser_counter) / CALLS_TO_PARSER;
newpct = (PRCNT_BY_PARSER * ++(loadscreen::global_loadscreen->parser_counter)) / CALLS_TO_PARSER;
//std::cerr << "Calls " << loadscreen::global_loadscreen->parser_counter;
if(oldpct != newpct) {
// std::cerr << " percent " << newpct;
loadscreen::global_loadscreen->increment_progress(newpct - oldpct);
}
//std::cerr << std::endl;
}
}

79
src/loadscreen.hpp Normal file
View file

@ -0,0 +1,79 @@
#ifndef JM_LOADSCREEN_HPP
#define JM_LOADSCREEN_HPP
/*
Copyright (C) 2005 by Joeri Melis <joeri_melis@hotmail.com>
Part of the Battle for Wesnoth Project http://www.wesnoth.org/
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#include "SDL.h"
#include "font.hpp"
#include "video.hpp"
#include <iostream>
#include <string>
class loadscreen {
public:
// Preferred constructor
loadscreen(CVideo &screen, const int &percent = 0) :
filesystem_counter(0),
binarywml_counter(0),
setconfig_counter(0),
parser_counter(0),
screen_(screen), prcnt_(percent)
{
/* Nothing. */
}
// Keep default copy constructor
// Keep default copy assignment
// Destructor, dumps the counter values to stderr
~loadscreen()
{
std::cerr << "loadscreen: filesystem counter = " << filesystem_counter << std::endl;
std::cerr << "loadscreen: binarywml counter = " << binarywml_counter << std::endl;
std::cerr << "loadscreen: setconfig counter = " << setconfig_counter << std::endl;
std::cerr << "loadscreen: parser counter = " << parser_counter << std::endl;
}
// Function to display a load progress bar.
void set_progress(const int percentage=0, const std::string &text="", const bool commit=true);
// Function to increment the progress bar.
void increment_progress(const int percentage=1, const std::string &text="", const bool commit=true);
// Function to draw a blank screen.
void clear_screen(const bool commit=true);
// Counters
int filesystem_counter;
int binarywml_counter;
int setconfig_counter;
int parser_counter;
// A global loadscreen instance that can be used to avoid
// passing it on to functions that are many levels deep.
static loadscreen *global_loadscreen;
private:
// Prohibit default constructor
loadscreen();
// Data members
CVideo &screen_;
SDL_Rect textarea_;
int prcnt_;
};
// Global accessible functions that centralize the loadscreen related work.
void increment_filesystem_progress();
void increment_binary_wml_progress();
void increment_set_config_progress();
void increment_parser_progress();
#endif

View file

@ -15,6 +15,7 @@
#include "global.hpp"
#include "config.hpp"
#include "loadscreen.hpp"
#include "log.hpp"
#include "serialization/binary_wml.hpp"
@ -154,6 +155,7 @@ void write_compressed(std::ostream &out, config const &cfg, compression_schema &
static void read_compressed_internal(config &cfg, std::istream &in, compression_schema &schema, int level)
{
increment_binary_wml_progress();
if (level >= max_recursion_levels)
throw config::error("Too many recursion levels in compressed config read");

View file

@ -19,6 +19,7 @@
#include "filesystem.hpp"
#include "gettext.hpp"
#include "language.hpp"
#include "loadscreen.hpp"
#include "log.hpp"
#include "util.hpp"
#include "wassert.hpp"
@ -112,6 +113,7 @@ void parser::operator()(std::string* error_log)
*error_log += e.message + '\n';
}
increment_parser_progress();
} while (tok_.current_token().type != token::END);
// The main element should be there. If it is not, this is a parser error.

View file

@ -15,6 +15,7 @@
#include "game_config.hpp"
#include "gettext.hpp"
#include "loadscreen.hpp"
#include "log.hpp"
#include "unit_types.hpp"
#include "util.hpp"
@ -702,7 +703,7 @@ unit_type::unit_type(const unit_type& o)
genders_(o.genders_), defensive_animations_(o.defensive_animations_),
teleport_animations_(o.teleport_animations_), extra_animations_(o.extra_animations_),
death_animations_(o.death_animations_), movement_animations_(o.movement_animations_),
flag_rgb_(o.flag_rgb_),zoc_(o.zoc_)
flag_rgb_(o.flag_rgb_)
{
gender_types_[0] = o.gender_types_[0] != NULL ? new unit_type(*o.gender_types_[0]) : NULL;
gender_types_[1] = o.gender_types_[1] != NULL ? new unit_type(*o.gender_types_[1]) : NULL;
@ -1350,18 +1351,21 @@ void game_data::set_config(const config& cfg)
movement_types.insert(
std::pair<std::string,unit_movement_type>(move_type.name(),
move_type));
increment_set_config_progress();
}
for(config::const_child_itors r = cfg.child_range("race");
r.first != r.second; ++r.first) {
const unit_race race(**r.first);
races.insert(std::pair<std::string,unit_race>(race.name(),race));
increment_set_config_progress();
}
for(config::const_child_itors j = cfg.child_range("unit");
j.first != j.second; ++j.first) {
const unit_type u_type(**j.first,movement_types,races,unit_traits);
unit_types.insert(std::pair<std::string,unit_type>(u_type.id(),u_type));
increment_set_config_progress();
}
// fix up advance_from references
@ -1382,6 +1386,7 @@ void game_data::set_config(const config& cfg)
wassert(to_unit!=unit_types.end());
from_unit->second.add_advancement(to_unit->second,xp);
increment_set_config_progress();
}
}