made display draw more efficiently

This commit is contained in:
Dave White 2003-10-31 05:38:14 +00:00
parent 5ba01842f9
commit a2b3c84ea0
10 changed files with 119 additions and 21 deletions

View file

@ -84,6 +84,8 @@ namespace {
const size_t Minimap_y = 11;
const size_t Minimap_w = 119;
const size_t Minimap_h = 146;
const size_t TimeOfDay_x = 13;
const size_t TimeOfDay_y = 167;
const std::string RightSideTop = "misc/rightside.png";
const std::string RightSideBot = "misc/rightside-bottom.png";
@ -447,6 +449,8 @@ void display::draw(bool update,bool force)
}
sideBarBgDrawn_ = true;
update_rect(mapx(),0,this->x()-mapx(),this->y());
}
if(invalidateAll_ && !map_.empty()) {
@ -545,12 +549,13 @@ void display::draw_game_status(int x, int y)
if(tod_surface != NULL) {
//hardcoded values as to where the time of day image appears
blit_surface(mapx() + 13,167,tod_surface);
blit_surface(mapx() + TimeOfDay_x,TimeOfDay_y,tod_surface);
update_rect(TimeOfDay_x,TimeOfDay_y,tod_surface->w,tod_surface->h);
}
if(gameStatusRect_.w > 0) {
SDL_Surface* const screen = screen_.getSurface();
SDL_Surface* const background=getImage(RightSideTop,UNSCALED);
SDL_Surface* const background = getImage(RightSideTop,UNSCALED);
if(background == NULL)
return;
@ -558,6 +563,7 @@ void display::draw_game_status(int x, int y)
SDL_Rect srcrect = gameStatusRect_;
srcrect.x -= mapx();
SDL_BlitSurface(background,&srcrect,screen,&gameStatusRect_);
update_rect(gameStatusRect_);
}
std::stringstream details;
@ -636,6 +642,7 @@ void display::draw_game_status(int x, int y)
gameStatusRect_ = font::draw_text(this,clipRect,13,font::NORMAL_COLOUR,
details.str(),x,y);
update_rect(gameStatusRect_);
}
void display::draw_unit_details(int x, int y, const gamemap::location& loc,
@ -661,6 +668,7 @@ void display::draw_unit_details(int x, int y, const gamemap::location& loc,
srcrect.x -= mapx();
SDL_BlitSurface(background_bot,&srcrect,screen,&description_rect);
update_rect(description_rect);
}
std::string status = string_table["healthy"];
@ -722,6 +730,8 @@ void display::draw_unit_details(int x, int y, const gamemap::location& loc,
font::draw_text(this,clipRect,13,font::NORMAL_COLOUR,
details.str(),x,y);
update_rect(description_rect);
y += description_rect.h;
SDL_Surface* const profile = getImage(u.type().image(),UNSCALED);
@ -739,6 +749,8 @@ void display::draw_unit_details(int x, int y, const gamemap::location& loc,
dstrect.x = profilex;
dstrect.y = profiley;
SDL_BlitSurface(profile,&srcrect,video().getSurface(),&dstrect);
update_rect(profilex,profiley,profilew,profileh);
}
}
@ -769,6 +781,8 @@ void display::draw_minimap(int x, int y, int w, int h)
SDL_Surface* const screen = screen_.getSurface();
gui::draw_rectangle(x+xbox,y+ybox,wbox,hbox,boxcolour,screen);
update_rect(minimap_location);
}
void display::draw_terrain_palette(int x, int y, gamemap::TERRAIN selected)
@ -811,6 +825,7 @@ void display::draw_terrain_palette(int x, int y, gamemap::TERRAIN selected)
}
invalid_rect.h = y - invalid_rect.y;
update_rect(invalid_rect);
}
gamemap::TERRAIN display::get_terrain_on(int palx, int paly, int x, int y)
@ -937,6 +952,8 @@ void display::draw_tile(int x, int y, SDL_Surface* unit_image,
if(xend < xpos || yend < ypos)
return;
update_rect(xpos,ypos,xend-xpos,yend-ypos);
SDL_Surface* energy_image = NULL;
double unit_energy = 0.0;
@ -2368,6 +2385,7 @@ void display::invalidate_all()
{
invalidateAll_ = true;
invalidated_.clear();
update_rect(0,0,mapx(),y());
}
void display::invalidate_unit()

View file

@ -22,7 +22,7 @@ namespace game_config
const int cure_amount = 8;
const int curer_heals_per_turn = 18;
const int recall_cost = 20;
const std::string version = "0.5";
const std::string version = "0.5-CVS";
bool debug = false;
#ifdef WESNOTH_PATH

View file

@ -17,6 +17,7 @@
#include "key.hpp"
#include "language.hpp"
#include "show_dialog.hpp"
#include "video.hpp"
#include "widgets/button.hpp"
#include <cstdlib>
@ -98,6 +99,7 @@ void show_intro(display& screen, config& data)
textx,texty);
next_button.draw();
skip_button.draw();
update_whole_screen();
screen.video().flip();
bool last = true;
@ -168,6 +170,7 @@ void show_map_scene(display& screen, config& data)
dstrect.h = image->h;
SDL_BlitSurface(image,NULL,screen.video().getSurface(),&dstrect);
update_whole_screen();
const std::string& id = data.values["id"];
const std::string& scenario_name = string_table[id];
@ -210,6 +213,7 @@ void show_map_scene(display& screen, config& data)
SDL_BlitSurface(img,NULL,image,&dot_rect);
SDL_BlitSurface(image,NULL,screen.video().getSurface(),&dstrect);
update_rect(dstrect);
for(int i = 0; i != 50; ++i) {
if(key[KEY_ESCAPE]) {
@ -241,10 +245,11 @@ void show_map_scene(display& screen, config& data)
static const SDL_Rect area = {0,0,screen.x(),screen.y()};
const SDL_Rect scenario_size =
font::draw_text(NULL,area,24,font::NORMAL_COLOUR,scenario,0,0);
font::draw_text(&screen,area,24,font::NORMAL_COLOUR,scenario,
dstrect.x,dstrect.y - scenario_size.h - 4);
update_rect(font::draw_text(&screen,area,24,font::NORMAL_COLOUR,scenario,
dstrect.x,dstrect.y - scenario_size.h - 4));
SDL_BlitSurface(image,NULL,screen.video().getSurface(),&dstrect);
update_rect(dstrect);
screen.video().flip();
bool last_state = true;

View file

@ -34,7 +34,6 @@ void draw_dialog_frame(int x, int y, int w, int h, display& disp)
{
draw_dialog_background(x,y,w,h,disp);
SDL_Surface* const top = disp.getImage("misc/menu-border-top.png",
display::UNSCALED);
SDL_Surface* const bot = disp.getImage("misc/menu-border-bottom.png",
@ -71,6 +70,8 @@ void draw_dialog_frame(int x, int y, int w, int h, display& disp)
disp.blit_surface(x+w,y,right_image.get());
}
update_rect(x-left->w,y-top->h,w+left->w+right->w,h+top->h+bot->h);
SDL_Surface* const top_left = disp.getImage("misc/menu-border-topleft.png",
display::UNSCALED);
SDL_Surface* const bot_left = disp.getImage("misc/menu-border-botleft.png",
@ -596,14 +597,15 @@ TITLE_RESULT show_title(display& screen)
const size_t versiony = screen.y() - version_area.h;
if(versiony < size_t(screen.y())) {
font::draw_text(&screen,screen.screen_area(),10,font::NORMAL_COLOUR,
version_str,0,versiony);
font::draw_text(&screen,screen.screen_area(),
10,font::NORMAL_COLOUR,version_str,0,versiony);
}
const int x = screen.x()/2 - title_surface->w/2;
const int y = 100;
screen.blit_surface(x,y,title_surface);
update_rect(x,y,title_surface->w,title_surface->h);
button tutorial_button(screen,string_table["tutorial_button"]);
button new_button(screen,string_table["campaign_button"]);
@ -641,6 +643,8 @@ TITLE_RESULT show_title(display& screen)
bool last_escape = key[KEY_ESCAPE];
update_whole_screen();
for(;;) {
int mousex, mousey;
const int mouse_flags = SDL_GetMouseState(&mousex,&mousey);

View file

@ -12,6 +12,7 @@
*/
#include <stdio.h>
#include <iostream>
#include <vector>
#include "mouse.hpp"
#include "preferences.hpp"
@ -23,7 +24,6 @@
#include <stdlib.h>
//test program takes three args - x-res y-res colour-depth
int main( int argc, char** argv )
{
@ -61,22 +61,72 @@ int main( int argc, char** argv )
#endif
namespace {
bool fullScreen = false;
bool fullScreen = false;
unsigned int get_flags(unsigned int flags)
{
//SDL under Windows doesn't seem to like hardware surfaces for
//some reason.
unsigned int get_flags(unsigned int flags)
{
//SDL under Windows doesn't seem to like hardware surfaces for
//some reason.
#if !(defined(_WIN32) || defined(__APPLE__))
flags |= SDL_HWSURFACE | SDL_DOUBLEBUF;
flags |= SDL_HWSURFACE;
#endif
if((flags&SDL_FULLSCREEN) == 0)
flags |= SDL_RESIZABLE;
if((flags&SDL_FULLSCREEN) == 0)
flags |= SDL_RESIZABLE;
return flags;
}
return flags;
}
std::vector<SDL_Rect> update_rects;
bool update_all = false;
bool rect_contains(const SDL_Rect& a, const SDL_Rect& b) {
return a.x <= b.x && a.y <= b.y && a.x+a.w >= b.x+b.w && a.y+a.h >= b.y+b.h;
}
void clear_updates()
{
update_all = false;
update_rects.clear();
}
}
void update_rect(size_t x, size_t y, size_t w, size_t h)
{
const SDL_Rect rect = {x,y,w,h};
update_rect(rect);
}
void update_rect(const SDL_Rect& rect)
{
if(update_all)
return;
for(std::vector<SDL_Rect>::iterator i = update_rects.begin();
i != update_rects.end(); ++i) {
if(rect_contains(*i,rect)) {
return;
}
if(rect_contains(rect,*i)) {
*i = rect;
for(++i; i != update_rects.end(); ++i) {
if(rect_contains(rect,*i)) {
i->w = 0;
}
}
return;
}
}
update_rects.push_back(rect);
}
void update_whole_screen()
{
update_all = true;
}
CVideo::CVideo() : frameBuffer(NULL)
{
const int res = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_NOPARACHUTE);
@ -161,7 +211,13 @@ int CVideo::getBlueMask()
void CVideo::flip()
{
::SDL_Flip(frameBuffer);
if(update_all) {
::SDL_Flip(frameBuffer);
} else {
SDL_UpdateRects(frameBuffer,update_rects.size(),&update_rects[0]);
}
clear_updates();
}
void CVideo::lock()

View file

@ -20,6 +20,10 @@
#define VIDEO_MEMORY SDL_HWSURFACE
#define SYSTEM_MEMORY SDL_SWSURFACE
void update_rect(size_t x, size_t y, size_t w, size_t h);
void update_rect(const SDL_Rect& rect);
void update_whole_screen();
class CVideo {
public:
CVideo();

View file

@ -14,6 +14,7 @@
#include "../game.hpp"
#include "../font.hpp"
#include "../util.hpp"
#include "../video.hpp"
namespace gui {
@ -152,6 +153,8 @@ void button::draw()
display_->blit_surface(x_,y_,image);
font::draw_text(display_,clipArea,font_size,
font::BUTTON_COLOUR,label_,textx,texty);
update_rect(x_,y_,width(),height());
}
bool button::hit(int x, int y) const

View file

@ -2,6 +2,7 @@
#include "../font.hpp"
#include "../show_dialog.hpp"
#include "../video.hpp"
#include <numeric>
@ -272,6 +273,8 @@ void menu::draw()
for(size_t i = 0; i != items_.size(); ++i)
draw_item(i);
update_rect(x_,y_,width(),height());
}
int menu::hit(int x, int y) const

View file

@ -10,7 +10,9 @@
See the COPYING file for more details.
*/
#include "slider.hpp"
#include "../video.hpp"
#include <algorithm>
#include <iostream>
@ -65,6 +67,8 @@ void slider::draw()
SDL_Rect slider = slider_area();
disp_.blit_surface(slider.x,slider.y,image);
update_rect(area_);
}
double slider::process(int mousex, int mousey, bool button)

View file

@ -13,6 +13,7 @@
#include "textbox.hpp"
#include "../font.hpp"
#include "../show_dialog.hpp"
#include "../video.hpp"
#include "SDL.h"
#include <algorithm>
@ -112,7 +113,7 @@ void textbox::draw() const
draw_cursor(pos-1);
}
disp_.video().flip();
update_rect(x_,y_,width(),height());
}
void textbox::handle_event(const SDL_Event& event)