attempt to workaround SDL bug

This commit is contained in:
uid68803 2004-02-19 22:45:17 +00:00
parent 8b53b65c48
commit ed7b903712
8 changed files with 55 additions and 75 deletions

View file

@ -12,7 +12,7 @@ alignment=chaotic
advanceto=null
cost=33
usage=fighter
unit_description="Armed with heavy maces, bandits, are adept at robbing and killing his victims at the night."
unit_description="Armed with heavy maces, bandits, are adept at robbing and killing his victims at night."
get_hit_sound=groan.wav
[attack]
name=mace
@ -26,4 +26,4 @@ get_hit_sound=groan.wav
image=neutral-bandit-attack.png
[/frame]
[/attack]
[/unit]
[/unit]

View file

@ -26,4 +26,4 @@ get_hit_sound=groan.wav
image=neutral-thug-attack.png
[/frame]
[/attack]
[/unit]
[/unit]

View file

@ -418,7 +418,7 @@ void config::read(const std::string& data,
std::string var;
std::string value;
bool in_quotes = false, has_quotes = false;
bool in_quotes = false, has_quotes = false, in_comment = false;
int line = 0;
@ -427,8 +427,18 @@ void config::read(const std::string& data,
if(c == '\r') //ignore any DOS-style newlines
continue;
if(c == '\n')
if(c == '\n') {
in_comment = false;
++line;
}
if(*i == '#' && !in_quotes) {
in_comment = true;
}
if(in_comment) {
continue;
}
switch(state) {
case ELEMENT_NAME:
@ -441,10 +451,11 @@ void config::read(const std::string& data,
std::stringstream err;
if(line_sources != NULL) {
const line_source src =
get_line_source(*line_sources,line);
const line_source src = get_line_source(*line_sources,line);
err << src.file << " " << src.fileline << ": ";
} else {
err << "line " << line << ": ";
}
err << "Found illegal end tag: '" << value
@ -477,7 +488,7 @@ void config::read(const std::string& data,
break;
}
;
elements.push(&elements.top()->add_child(value));
element_names.push(value);
state = IN_ELEMENT;

View file

@ -457,8 +457,6 @@ void draw_label(display& disp, SDL_Surface* target, const theme::label& label)
void display::draw(bool update,bool force)
{
image::verify_minimap("begin display::draw");
log_scope("display::draw");
if(!panelsDrawn_ && !teams_.empty()) {
SDL_Surface* const screen = screen_.getSurface();
@ -477,7 +475,6 @@ void display::draw(bool update,bool force)
}
//invalidate the reports so they are redrawn
std::cerr << "invalidating reports...\n";
std::fill(reports_,reports_+sizeof(reports_)/sizeof(*reports_),reports::report());
invalidateGameStatus_ = true;
panelsDrawn_ = true;
@ -500,18 +497,14 @@ void display::draw(bool update,bool force)
}
if(redrawMinimap_) {
std::cerr << "drawing minimap...\n";
redrawMinimap_ = false;
const SDL_Rect area = minimap_area();
draw_minimap(area.x,area.y,area.w,area.h);
std::cerr << "done drawing minimap...\n";
}
if(!map_.empty()) {
std::cerr << "sidebar...\n";
draw_sidebar();
std::cerr << "done sidebar...\n";
}
const int max_skips = 5;
@ -523,9 +516,7 @@ void display::draw(bool update,bool force)
//TODO: review whether this is the correct thing to do
SDL_Delay(maximum<int>(10,wait_time));
std::cerr << "up...\n";
if(update) {
std::cerr << "up+\n";
lastDraw_ = SDL_GetTicks();
if(wait_time >= 0 || drawSkips_ >= max_skips || force)
@ -534,9 +525,6 @@ void display::draw(bool update,bool force)
drawSkips_++;
}
std::cerr << "ret\n";
image::verify_minimap("end display::draw");
}
void display::update_display()

View file

@ -227,11 +227,8 @@ SDL_Surface* getMinimap(int w, int h, const gamemap& map,
int lawful_bonus,
const team* tm, const unit_map* units, const std::vector<team>* teams)
{
verify_minimap("start getMinimap");
SDL_Surface* minimap = NULL;
if(minimap == NULL) {
std::cerr << "x\n";
const int scale = 8;
minimap = SDL_CreateRGBSurface(SDL_SWSURFACE,
@ -246,13 +243,9 @@ SDL_Surface* getMinimap(int w, int h, const gamemap& map,
typedef mini_terrain_cache_map cache_map;
cache_map& cache = mini_terrain_cache;
//static cache_map cache;
std::cerr << "outputting map: " << map.x() << "," << map.y() << "\n";
for(int y = 0; y != map.y(); ++y) {
for(int x = 0; x != map.x(); ++x) {
std::cerr << x << "," << y << "\n";
std::cerr << "a\n";
SDL_Surface* surf = NULL;
scoped_sdl_surface scoped_surface(NULL);
@ -264,10 +257,7 @@ SDL_Surface* getMinimap(int w, int h, const gamemap& map,
const gamemap::TERRAIN terrain = shrouded ? gamemap::VOID_TERRAIN : map[x][y];
cache_map::iterator i = cache.find(terrain);
std::cerr << (int)terrain << " '" << (char)terrain << "'\n";
if(i == cache.end()) {
std::cerr << "b\n";
scoped_sdl_surface tile(get_image("terrain/" + map.get_terrain_info(terrain).default_image() + ".png",image::UNSCALED));
if(tile == NULL) {
@ -276,76 +266,38 @@ SDL_Surface* getMinimap(int w, int h, const gamemap& map,
continue;
}
std::cerr << "c\n";
surf = scale_surface_blended(tile,scale,scale);
std::cerr << "d\n";
if(surf == NULL) {
continue;
}
i = cache.insert(cache_map::value_type(terrain,surf)).first;
verify_minimap("after insert");
} else {
std::cerr << "e\n";
surf = i->second;
}
if(fogged) {
std::cerr << "f\n";
scoped_surface.assign(adjust_surface_colour(surf,-50,-50,-50));
if(scoped_surface == NULL) {
std::cerr << "ERROR: failed to adjust surface colour\n";
continue;
}
surf = scoped_surface;
}
std::cerr << "g\n";
assert(surf != NULL);
std::cerr << "h\n";
SDL_Rect maprect = {x*scale*0.75,y*scale + (is_odd(x) ? scale/2 : 0),0,0};
std::cerr << "i\n";
SDL_BlitSurface(surf, NULL, minimap, &maprect);
std::cerr << "j\n";
sdl_safe_blit(surf, NULL, minimap, &maprect);
}
}
}
}
verify_minimap("a end getMinimap");
std::cerr << "k\n";
if(minimap->w != w || minimap->h != h) {
std::cerr << "y\n";
SDL_Surface* const surf = minimap;
std::cerr << "z\n";
minimap = scale_surface_blended(surf,w,h);
std::cerr << "z1\n";
SDL_FreeSurface(surf);
std::cerr << "z2\n";
}
std::cerr << "xxx\n";
verify_minimap("end getMinimap");
return minimap;
}
void verify_minimap(const std::string& tag)
{
std::cerr << "BEGIN verify minimap: '" << tag << "'\n";
typedef mini_terrain_cache_map cache_map;
cache_map& cache = mini_terrain_cache;
for(cache_map::iterator i = cache.begin(); i != cache.end(); ++i) {
SDL_Surface* const surf = adjust_surface_colour(i->second,-50,-50,-50);
SDL_FreeSurface(surf);
}
std::cerr << "END verify minimap: '" << tag << "'\n";
}
}
}

View file

@ -67,8 +67,6 @@ namespace image {
//the surface returned must be freed by the user
SDL_Surface* getMinimap(int w, int h, const gamemap& map_, int lawful_bonus,
const team* tm=NULL, const unit_map* units=NULL, const std::vector<team>* teams=NULL);
void verify_minimap(const std::string& tag);
}
#endif

View file

@ -47,6 +47,7 @@ SDL_Surface* make_neutral_surface(SDL_Surface* surf)
}
SDL_Surface* const result = SDL_ConvertSurface(surf,&get_neutral_pixel_format(),SDL_SWSURFACE);
invalidate_sdl_surface_cache(surf);
if(result != NULL) {
SDL_SetAlpha(result,SDL_SRCALPHA,SDL_ALPHA_OPAQUE);
}
@ -115,6 +116,7 @@ SDL_Surface* clone_surface(SDL_Surface* surface)
return NULL;
SDL_Surface* const result = SDL_DisplayFormatAlpha(surface);
invalidate_sdl_surface_cache(surface);
if(result == surface) {
std::cerr << "resulting surface is the same as the source!!!\n";
}
@ -472,7 +474,7 @@ SDL_Surface* flop_surface(SDL_Surface* surface)
for(size_t y = 0; y != surface->h; ++y) {
SDL_Rect srcrect = {0,y,surface->w,1};
SDL_Rect dstrect = {0,surface->h-y-1,surface->w,1};
SDL_BlitSurface(surface,&srcrect,dest,&dstrect);
sdl_safe_blit(surface,&srcrect,dest,&dstrect);
}
return dest;
@ -505,7 +507,7 @@ SDL_Surface* get_surface_portion(SDL_Surface* src, SDL_Rect& area)
SDL_Rect dstarea = {0,0,0,0};
SDL_BlitSurface(src,&area,dst,&dstarea);
sdl_safe_blit(src,&area,dst,&dstarea);
return dst;
}
@ -627,7 +629,7 @@ surface_restorer::~surface_restorer()
void surface_restorer::restore()
{
if(surface_ != NULL) {
::SDL_BlitSurface(surface_,NULL,target_->getSurface(),&rect_);
sdl_safe_blit(surface_,NULL,target_->getSurface(),&rect_);
update_rect(rect_);
}
}
@ -643,4 +645,23 @@ void surface_restorer::update()
void surface_restorer::cancel()
{
surface_.assign(NULL);
}
//dummy definition of this SDL-private data structure, so that we can clear
//the surface's cache
struct SDL_BlitMap {
SDL_Surface* dst;
};
void invalidate_sdl_surface_cache(SDL_Surface* surf)
{
if(surf->map->dst != SDL_GetVideoSurface()) {
surf->map->dst = NULL;
}
}
void sdl_safe_blit(SDL_Surface* src, SDL_Rect* srcrect, SDL_Surface* dst, SDL_Rect* dstrect)
{
SDL_BlitSurface(src,srcrect,dst,dstrect);
invalidate_sdl_surface_cache(src);
}

View file

@ -198,4 +198,14 @@ private:
SDL_Rect rect;
};
//SDL 1.2.x has a bug where after a blit, a surface stores the surface it was last
//blitted to. This is a problem, because if the surface is freed, and then a new
//one created in the same memory location, it will think its blitter knows how to
//blit to that surface when it doesn't.
//
//This function will invalidate the cache, to keep the problem from occurring.
void invalidate_sdl_surface_cache(SDL_Surface* surf);
void sdl_safe_blit(SDL_Surface* src, SDL_Rect* srcrect, SDL_Surface* dst, SDL_Rect* dstrect);
#endif