summaryrefslogtreecommitdiff
path: root/meme/gui.c
diff options
context:
space:
mode:
authorWerner Almesberger <werner@almesberger.net>2014-12-16 13:05:59 (GMT)
committerWerner Almesberger <werner@almesberger.net>2014-12-16 13:06:49 (GMT)
commit7f3fafe34e03e4d6ce4f75299341d9226bd55dc7 (patch)
tree78705dc9c95b4271403ff16ba19396e38cc7413a /meme/gui.c
parentceb37b8b2ecbf203f4c779181b7cdfdae71714cc (diff)
downloadmisc-7f3fafe34e03e4d6ce4f75299341d9226bd55dc7.zip
misc-7f3fafe34e03e4d6ce4f75299341d9226bd55dc7.tar.gz
misc-7f3fafe34e03e4d6ce4f75299341d9226bd55dc7.tar.bz2
meme/gui.c: roll back change in reverse order
This should remove all artefacts caused by wrong ordering. We can still get artefacts caused by lack of clipping.
Diffstat (limited to 'meme/gui.c')
-rw-r--r--meme/gui.c52
1 files changed, 33 insertions, 19 deletions
diff --git a/meme/gui.c b/meme/gui.c
index e351c76..e8ee0ca 100644
--- a/meme/gui.c
+++ b/meme/gui.c
@@ -433,8 +433,12 @@ static void draw(SDL_Surface *s)
static struct change {
SDL_Surface *s;
SDL_Rect r;
+ struct change *prev;
struct change *next;
-} *changes;
+} changes = {
+ .prev = &changes,
+ .next = &changes,
+};
static void change(SDL_Surface *s, int x, int y, int w, int h)
@@ -472,8 +476,12 @@ static void change(SDL_Surface *s, int x, int y, int w, int h)
fprintf(stderr, "SDL_BlitSurface failed\n");
exit(1);
}
- c->next = changes;
- changes = c;
+
+ /* append */
+ c->next = &changes;
+ c->prev = changes.prev;
+ changes.prev->next = c;
+ changes.prev = c;
}
@@ -481,40 +489,46 @@ static void apply_changes(SDL_Surface *s)
{
const struct change *c;
- for (c = changes; c; c = c->next)
+ for (c = changes.next; c != &changes; c = c->next)
SDL_UpdateRect(s, c->r.x, c->r.y, c->r.w, c->r.h);
}
+static void no_changes(void)
+{
+ changes.next = &changes;
+ changes.prev = &changes;
+}
+
+
static void rollback_changes(SDL_Surface *s)
{
- struct change *next;
+ struct change *c, *prev;
- while (changes) {
- next = changes->next;
- if (SDL_BlitSurface(changes->s, NULL, s, &changes->r)) {
+ for (c = changes.prev; c != &changes; c = prev) {
+ prev = c->prev;
+ if (SDL_BlitSurface(c->s, NULL, s, &c->r)) {
fprintf(stderr, "SDL_BlitSurface failed\n");
exit(1);
}
- SDL_FreeSurface(changes->s);
- SDL_UpdateRect(s,
- changes->r.x, changes->r.y, changes->r.w, changes->r.h);
- free(changes);
- changes = next;
+ SDL_FreeSurface(c->s);
+ SDL_UpdateRect(s, c->r.x, c->r.y, c->r.w, c->r.h);
+ free(c);
}
+ no_changes();
}
static void discard_changes(void)
{
- struct change *next;
+ struct change *c, *next;
- while (changes) {
- next = changes->next;
- SDL_FreeSurface(changes->s);
- free(changes);
- changes = next;
+ for (c = changes.next; c != &changes; c = next) {
+ next = c->next;
+ SDL_FreeSurface(c->s);
+ free(c);
}
+ no_changes();
}