improve DOS text mode updating
Andreas Mohr
andi at rhlx01.fht-esslingen.de
Mon Jul 1 16:47:36 CDT 2002
Hi all,
added a DOS text mode memory buffer copy in order to be able to tell which
lines of text changed and thus which ones to update.
In order words: only refresh the lines of the text console (wineconsole)
that really changed.
I also freed the console copying from a 80 chars/line limitation.
This is another patch to make IDA/DOS some real joy to use...
(it's working almost beautifully now !)
--
Andreas Mohr Stauferstr. 6, D-71272 Renningen, Germany
-------------- next part --------------
Determining best CVS host...
Using CVSROOT :pserver:cvs at rhlx01.fht-esslingen.de:/home/wine
Index: dlls/winedos/vga.c
===================================================================
RCS file: /home/wine/wine/dlls/winedos/vga.c,v
retrieving revision 1.15
diff -u -r1.15 vga.c
--- dlls/winedos/vga.c 1 Jul 2002 18:13:52 -0000 1.15
+++ dlls/winedos/vga.c 1 Jul 2002 21:47:56 -0000
@@ -42,6 +42,7 @@
static int vga_height;
static int vga_depth;
static BYTE vga_text_attr;
+static char *textbuf_old = NULL;
static BOOL vga_mode_initialized = FALSE;
@@ -447,6 +448,25 @@
/*** TEXT MODE ***/
+/* prepare the text mode video memory copy that is used to only
+ * update the video memory line that did get updated. */
+void VGA_PrepareVideoMemCopy(unsigned Xres, unsigned Yres)
+{
+ char *p, *p2;
+ int i;
+
+ textbuf_old = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, textbuf_old, Xres * Yres * 2); /* char + attr */
+
+ p = VGA_AlphaBuffer();
+ p2 = textbuf_old;
+
+ /* make sure the video mem copy contains the exact opposite of our
+ * actual text mode memory area to make sure the screen
+ * does get updated fully initially */
+ for (i=0; i < Xres*Yres*2; i++)
+ *p2++ ^= *p++; /* XOR it */
+}
+
int VGA_SetAlphaMode(unsigned Xres,unsigned Yres)
{
COORD siz;
@@ -456,8 +476,10 @@
/* FIXME: Where to initialize text attributes? */
VGA_SetTextAttribute(0xf);
- /* the xterm is slow, so refresh only every 200ms (5fps) */
- VGA_InstallTimer(200);
+ VGA_PrepareVideoMemCopy(Xres, Yres);
+
+ /* poll every 30ms (33fps should provide adequate responsiveness) */
+ VGA_InstallTimer(30);
siz.X = Xres;
siz.Y = Yres;
@@ -671,6 +693,8 @@
/*** CONTROL ***/
+/* FIXME: optimize by doing this only if the data has actually changed
+ * (in a way similar to DIBSection, perhaps) */
static void VGA_Poll_Graphics(void)
{
unsigned int Pitch, Height, Width, X, Y;
@@ -725,29 +749,41 @@
static void VGA_Poll_Text(void)
{
- char *dat;
+ char *dat, *old, *p_line;
unsigned int Height,Width,Y,X;
- CHAR_INFO ch[80];
+ CHAR_INFO ch[256]; /* that should suffice for the largest text width */
COORD siz, off;
SMALL_RECT dest;
HANDLE con = VGA_AlphaConsole();
+ BOOL linechanged = FALSE; /* video memory area differs from stored copy ? */
VGA_GetAlphaMode(&Width,&Height);
dat = VGA_AlphaBuffer();
- siz.X = 80; siz.Y = 1;
+ old = textbuf_old; /* pointer to stored video mem copy */
+ siz.X = Width; siz.Y = 1;
off.X = 0; off.Y = 0;
/* copy from virtual VGA frame buffer to console */
for (Y=0; Y<Height; Y++) {
- dest.Top=Y; dest.Bottom=Y;
- for (X=0; X<Width; X++) {
- ch[X].Char.AsciiChar = *dat++;
- /* WriteConsoleOutputA doesn't like "dead" chars */
- if (ch[X].Char.AsciiChar == '\0')
- ch[X].Char.AsciiChar = ' ';
- ch[X].Attributes = *dat++;
- }
- dest.Left=0; dest.Right=Width+1;
- WriteConsoleOutputA(con, ch, siz, off, &dest);
+ linechanged = memcmp(dat, old, Width*2);
+ if (linechanged)
+ {
+ /*TRACE("line %d changed\n", Y);*/
+ p_line = dat;
+ for (X=0; X<Width; X++) {
+ ch[X].Char.AsciiChar = *p_line++;
+ /* WriteConsoleOutputA doesn't like "dead" chars */
+ if (ch[X].Char.AsciiChar == '\0')
+ ch[X].Char.AsciiChar = ' ';
+ ch[X].Attributes = *p_line++;
+ }
+ dest.Top=Y; dest.Bottom=Y;
+ dest.Left=0; dest.Right=Width+1;
+ WriteConsoleOutputA(con, ch, siz, off, &dest);
+ memcpy(old, dat, Width*2);
+ }
+ /* advance to next text line */
+ dat += Width*2;
+ old += Width*2;
}
}
@@ -756,8 +792,6 @@
if(!TryEnterCriticalSection(&vga_lock))
return;
- /* FIXME: optimize by doing this only if the data has actually changed
- * (in a way similar to DIBSection, perhaps) */
if (lpddraw) {
VGA_Poll_Graphics();
} else {
More information about the wine-patches
mailing list