Commit MetaInfo

Revision82a0ecb626f69b53aab6a845bf24188fbcc035c6 (tree)
Time2021-09-04 03:11:23
Authoringlorion <homemicro@ingl...>
Commiteringlorion

Log Message

emulator: force redraw on expose and resize

This fixes two graphics glitches in the emulator:

- An expose event now causes all the screen contents to
be redrawn. Previously, the optimization to only redraw
changed areas meant that, if the screen hadn't changed,
nothing was drawn.
- A resize event now redraws the entire window, including
the border around the active screen area. This avoids
old content being left behind when resizing.

Change Summary

Incremental Difference

diff -r 95e4b5fdafa1 -r 82a0ecb626f6 emulator/main.c
--- a/emulator/main.c Fri Sep 03 11:06:06 2021 -0700
+++ b/emulator/main.c Fri Sep 03 11:11:23 2021 -0700
@@ -75,14 +75,15 @@
7575 event = xcb_poll_for_event(gui.xcb);
7676 if (!event) {
7777 if (redraw) {
78- update_display(&gui, ram);
78+ update_display(&gui, ram, /* force_redraw */ false);
7979 redraw = false;
8080 }
8181 continue;
8282 }
8383 switch (event->response_type & ~0x80) {
8484 case XCB_EXPOSE:
85- redraw = true;
85+ update_display(&gui, ram, /* force_redraw */ true);
86+ redraw = false;
8687 break;
8788 case XCB_KEY_PRESS:
8889 {
@@ -113,7 +114,8 @@
113114 xcb_configure_notify_event_t *cne =
114115 (xcb_configure_notify_event_t*) event;
115116 resize(&gui, cne->width, cne->height);
116- redraw = true;
117+ update_display(&gui, ram, /* force_redraw */ true);
118+ redraw = false;
117119 }
118120 break;
119121 case XCB_CLIENT_MESSAGE:
diff -r 95e4b5fdafa1 -r 82a0ecb626f6 emulator/xcb.c
--- a/emulator/xcb.c Fri Sep 03 11:06:06 2021 -0700
+++ b/emulator/xcb.c Fri Sep 03 11:11:23 2021 -0700
@@ -4,6 +4,20 @@
44 #include <stdlib.h>
55 #include <string.h>
66
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+
721 void get_window_size(xcb_data *gui,
822 unsigned int *width,
923 unsigned int *height) {
@@ -136,16 +150,17 @@
136150 gui->xoffset = (width - scale * 320) / 2;
137151 gui->yoffset = (height - scale * 200) / 2;
138152 xcb_generate_pixmap(gui);
153+ clear_rect(gui, gui->win, width, height);
139154 }
140155
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) {
142157 unsigned int idx, x, y;
143158 uint8_t gfx;
144159 for (y = 0; y < 200; y++) {
145160 for (x = 0; x < 40; x++) {
146161 idx = (320 * (y >> 3)) + (x << 3) + (y & 7);
147162 gfx = ram[0x2000 + idx];
148- if (gui->oldgfx[idx] == gfx) continue;
163+ if (!force_redraw && gui->oldgfx[idx] == gfx) continue;
149164 xcb_copy_area(gui->xcb, gui->pixmap, gui->win, gui->gc,
150165 0,
151166 (size_t) gfx * gui->scale,
@@ -170,13 +185,7 @@
170185 gui->scale * 8,
171186 gui->scale * 256);
172187
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);
180189
181190 values[0] = gui->screen->white_pixel;
182191 xcb_change_gc(gui->xcb, gui->gc, XCB_GC_FOREGROUND, values);
diff -r 95e4b5fdafa1 -r 82a0ecb626f6 emulator/xcb.h
--- a/emulator/xcb.h Fri Sep 03 11:06:06 2021 -0700
+++ b/emulator/xcb.h Fri Sep 03 11:11:23 2021 -0700
@@ -1,6 +1,8 @@
11 #ifndef HOMEMICRO_EMULATOR_XCB
22 #define HOMEMICRO_EMULATOR_XCB
33
4+#include <stdbool.h>
5+#include <stdint.h>
46 #include <xcb/xcb.h>
57
68 typedef struct {
@@ -23,7 +25,7 @@
2325 void resize(xcb_data *gui,
2426 unsigned int width,
2527 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);
2729 void xcb_generate_pixmap(xcb_data *gui);
2830
2931 #endif /* ndef HOMEMICRO_EMULATOR_XCB */
Show on old repository browser