attempt to workaround SDL bug
This commit is contained in:
parent
8b53b65c48
commit
ed7b903712
8 changed files with 55 additions and 75 deletions
|
@ -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]
|
||||
|
|
|
@ -26,4 +26,4 @@ get_hit_sound=groan.wav
|
|||
image=neutral-thug-attack.png
|
||||
[/frame]
|
||||
[/attack]
|
||||
[/unit]
|
||||
[/unit]
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue