Revision | 82a0ecb626f69b53aab6a845bf24188fbcc035c6 (tree) |
---|---|
Time | 2021-09-04 03:11:23 |
Author | inglorion <homemicro@ingl...> |
Commiter | inglorion |
emulator: force redraw on expose and resize
This fixes two graphics glitches in the emulator:
@@ -75,14 +75,15 @@ | ||
75 | 75 | event = xcb_poll_for_event(gui.xcb); |
76 | 76 | if (!event) { |
77 | 77 | if (redraw) { |
78 | - update_display(&gui, ram); | |
78 | + update_display(&gui, ram, /* force_redraw */ false); | |
79 | 79 | redraw = false; |
80 | 80 | } |
81 | 81 | continue; |
82 | 82 | } |
83 | 83 | switch (event->response_type & ~0x80) { |
84 | 84 | case XCB_EXPOSE: |
85 | - redraw = true; | |
85 | + update_display(&gui, ram, /* force_redraw */ true); | |
86 | + redraw = false; | |
86 | 87 | break; |
87 | 88 | case XCB_KEY_PRESS: |
88 | 89 | { |
@@ -113,7 +114,8 @@ | ||
113 | 114 | xcb_configure_notify_event_t *cne = |
114 | 115 | (xcb_configure_notify_event_t*) event; |
115 | 116 | resize(&gui, cne->width, cne->height); |
116 | - redraw = true; | |
117 | + update_display(&gui, ram, /* force_redraw */ true); | |
118 | + redraw = false; | |
117 | 119 | } |
118 | 120 | break; |
119 | 121 | case XCB_CLIENT_MESSAGE: |
@@ -4,6 +4,20 @@ | ||
4 | 4 | #include <stdlib.h> |
5 | 5 | #include <string.h> |
6 | 6 | |
7 | +static void clear_rect(xcb_data *gui, xcb_drawable_t drawable, | |
8 | + unsigned int width, unsigned int height) { | |
9 | + uint32_t values[1]; | |
10 | + xcb_rectangle_t rects[1]; | |
11 | + | |
12 | + values[0] = gui->screen->black_pixel; | |
13 | + xcb_change_gc(gui->xcb, gui->gc, XCB_GC_FOREGROUND, values); | |
14 | + rects[0].x = 0; | |
15 | + rects[0].y = 0; | |
16 | + rects[0].width = width; | |
17 | + rects[0].height = height; | |
18 | + xcb_poly_fill_rectangle(gui->xcb, drawable, gui->gc, 1, rects); | |
19 | +} | |
20 | + | |
7 | 21 | void get_window_size(xcb_data *gui, |
8 | 22 | unsigned int *width, |
9 | 23 | unsigned int *height) { |
@@ -136,16 +150,17 @@ | ||
136 | 150 | gui->xoffset = (width - scale * 320) / 2; |
137 | 151 | gui->yoffset = (height - scale * 200) / 2; |
138 | 152 | xcb_generate_pixmap(gui); |
153 | + clear_rect(gui, gui->win, width, height); | |
139 | 154 | } |
140 | 155 | |
141 | -void update_display(xcb_data *gui, const uint8_t *ram) { | |
156 | +void update_display(xcb_data *gui, const uint8_t *ram, bool force_redraw) { | |
142 | 157 | unsigned int idx, x, y; |
143 | 158 | uint8_t gfx; |
144 | 159 | for (y = 0; y < 200; y++) { |
145 | 160 | for (x = 0; x < 40; x++) { |
146 | 161 | idx = (320 * (y >> 3)) + (x << 3) + (y & 7); |
147 | 162 | gfx = ram[0x2000 + idx]; |
148 | - if (gui->oldgfx[idx] == gfx) continue; | |
163 | + if (!force_redraw && gui->oldgfx[idx] == gfx) continue; | |
149 | 164 | xcb_copy_area(gui->xcb, gui->pixmap, gui->win, gui->gc, |
150 | 165 | 0, |
151 | 166 | (size_t) gfx * gui->scale, |
@@ -170,13 +185,7 @@ | ||
170 | 185 | gui->scale * 8, |
171 | 186 | gui->scale * 256); |
172 | 187 | |
173 | - values[0] = gui->screen->black_pixel; | |
174 | - xcb_change_gc(gui->xcb, gui->gc, XCB_GC_FOREGROUND, values); | |
175 | - rects[0].x = 0; | |
176 | - rects[0].y = 0; | |
177 | - rects[0].width = gui->scale * 8; | |
178 | - rects[0].height = gui->scale * 256; | |
179 | - xcb_poly_fill_rectangle(gui->xcb, gui->pixmap, gui->gc, 1, rects); | |
188 | + clear_rect(gui, gui->pixmap, gui->scale * 8, gui->scale * 256); | |
180 | 189 | |
181 | 190 | values[0] = gui->screen->white_pixel; |
182 | 191 | xcb_change_gc(gui->xcb, gui->gc, XCB_GC_FOREGROUND, values); |
@@ -1,6 +1,8 @@ | ||
1 | 1 | #ifndef HOMEMICRO_EMULATOR_XCB |
2 | 2 | #define HOMEMICRO_EMULATOR_XCB |
3 | 3 | |
4 | +#include <stdbool.h> | |
5 | +#include <stdint.h> | |
4 | 6 | #include <xcb/xcb.h> |
5 | 7 | |
6 | 8 | typedef struct { |
@@ -23,7 +25,7 @@ | ||
23 | 25 | void resize(xcb_data *gui, |
24 | 26 | unsigned int width, |
25 | 27 | unsigned int height); |
26 | -void update_display(xcb_data *gui, const uint8_t *ram); | |
28 | +void update_display(xcb_data *gui, const uint8_t *ram, bool force_redraw); | |
27 | 29 | void xcb_generate_pixmap(xcb_data *gui); |
28 | 30 | |
29 | 31 | #endif /* ndef HOMEMICRO_EMULATOR_XCB */ |