Peter Dons Tychsen : winedos: Add support for decoding and displaying the 4 bit CGA framebuffer.

Alexandre Julliard julliard at winehq.org
Mon Nov 10 07:43:53 CST 2008


Module: wine
Branch: master
Commit: e0b91a7aa78cdfe6b3fddb42d4d23a235ad977c1
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=e0b91a7aa78cdfe6b3fddb42d4d23a235ad977c1

Author: Peter Dons Tychsen <donpedro at tdcadsl.dk>
Date:   Sat Nov  8 16:21:03 2008 +0100

winedos: Add support for decoding and displaying the 4 bit CGA framebuffer.

---

 dlls/winedos/int10.c |    2 +-
 dlls/winedos/vga.c   |   80 +++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 73 insertions(+), 9 deletions(-)

diff --git a/dlls/winedos/int10.c b/dlls/winedos/int10.c
index 952212f..c1ec98b 100644
--- a/dlls/winedos/int10.c
+++ b/dlls/winedos/int10.c
@@ -171,7 +171,7 @@ static const INT10_MODE INT10_modelist[] =
     {0x0001,    TEXT, 40, 25,  9, 16,  360,  400,  0,  16, 8, TRUE},   /* VGA text mode 1 */
     {0x0002,    TEXT, 80, 25,  9, 16,  360,  400,  0,  16, 8, TRUE},   /* VGA text mode 2 */
     {0x0003,    TEXT, 80, 25,  9, 16,  360,  400,  0,  16, 8, TRUE},   /* VGA text mode 3 */
-    {0x0004, GRAPHIC, 40, 25,  8,  8,  320,  200,  2,   4, 1, FALSE},   /* VGA graphics mode 4 */
+    {0x0004, GRAPHIC, 40, 25,  8,  8,  320,  200,  2,   4, 1, TRUE},   /* VGA graphics mode 4 */
     {0x0005, GRAPHIC, 40, 25,  8,  8,  320,  200,  2,   4, 1, FALSE},   /* VGA graphics mode 5 */
     {0x0006, GRAPHIC, 80, 25,  8,  8,  640,  200,  1,   2, 1, FALSE},   /* VGA graphics mode 6 */
     {0x0007,    TEXT, 80, 25,  9, 16,  720,  400,  0,   0, 8, FALSE},   /* VGA text mode 7 - FIXME bad default address */
diff --git a/dlls/winedos/vga.c b/dlls/winedos/vga.c
index a5298e0..6a94d32 100644
--- a/dlls/winedos/vga.c
+++ b/dlls/winedos/vga.c
@@ -54,6 +54,12 @@ static BOOL vga_retrace_horizontal;
 #define VGA_WINDOW_START ((char *)0xa0000)
 
 /*
+ * Size and location of CGA controller window to framebuffer.
+ */
+#define CGA_WINDOW_SIZE  (32 * 1024)
+#define CGA_WINDOW_START ((char *)0xb8000)
+
+/*
  * VGA controller memory is emulated using linear framebuffer.
  * This frambuffer also acts as an interface
  * between VGA controller emulation and DirectDraw.
@@ -91,6 +97,8 @@ static int   vga_fb_offset;
 static int   vga_fb_size = 0;
 static char *vga_fb_data = 0;
 static int   vga_fb_window = 0;
+static int   vga_fb_window_size;
+static char *vga_fb_window_data;
 
 /*
  * VGA text mode data.
@@ -159,6 +167,16 @@ static void CALLBACK VGA_Poll( LPVOID arg, DWORD low, DWORD high );
 static HWND vga_hwnd = NULL;
 
 /*
+ * CGA palette 1
+ */
+static PALETTEENTRY cga_palette1[] = {
+  {0x00, 0x00, 0x00}, /* 0 - Black */
+  {0x00, 0x80, 0x80}, /* 1 - Cyan */
+  {0x80, 0x00, 0x80}, /* 2 - Magenta */
+  {0xFF, 0xFF, 0xFF}  /* 3 - White */
+};
+
+/*
  *  VGA Palette Registers, in actual 18 bit color
  *  port 3C0H - 6 bit rgbRGB format
  *
@@ -627,20 +645,20 @@ typedef struct {
  */
 static void VGA_SyncWindow( BOOL target_is_fb )
 {
-    int size = VGA_WINDOW_SIZE;
+    int size = vga_fb_window_size;
 
     /* Window does not overlap framebuffer. */
     if (vga_fb_window >= vga_fb_size)
         return;
 
     /* Check if window overlaps framebuffer only partially. */
-    if (vga_fb_size - vga_fb_window < VGA_WINDOW_SIZE)
+    if (vga_fb_size - vga_fb_window < vga_fb_window_size)
         size = vga_fb_size - vga_fb_window;
 
     if (target_is_fb)
-        memmove( vga_fb_data + vga_fb_window, VGA_WINDOW_START, size );
+        memmove( vga_fb_data + vga_fb_window, vga_fb_window_data, size );
     else
-        memmove( VGA_WINDOW_START, vga_fb_data + vga_fb_window, size );
+        memmove( vga_fb_window_data, vga_fb_data + vga_fb_window, size );
 }
 
 
@@ -712,9 +730,15 @@ static void WINAPI VGA_DoSetMode(ULONG_PTR arg)
             lpddraw=NULL;
             return;
         }
-        res=IDirectDrawPalette_SetEntries(lpddpal,0,0,256,vga_def_palette);
+
+        if(vga_fb_depth == 2){
+          res=IDirectDrawPalette_SetEntries(lpddpal,0,0,4,cga_palette1);
+        }
+        else{
+          res=IDirectDrawPalette_SetEntries(lpddpal,0,0,256,vga_def_palette);
+        }
         if (res != S_OK) {
-            ERR("Could not set default palette entries (res = 0x%x)\n", res);
+           ERR("Could not set default palette entries (res = 0x%x)\n", res);
         }
 
         memset(&sdesc,0,sizeof(sdesc));
@@ -766,7 +790,23 @@ int VGA_SetMode(unsigned Xres,unsigned Yres,unsigned Depth)
       par.Yres = 480;
     }
 
-    VGA_SetWindowStart((Depth < 8) ? -1 : 0);
+    /* Setup window */
+    if(vga_fb_depth >= 8)
+    {
+      vga_fb_window_data = VGA_WINDOW_START;
+      vga_fb_window_size = VGA_WINDOW_SIZE;
+    }
+    else
+    {
+      vga_fb_window_data = CGA_WINDOW_START;
+      vga_fb_window_size = CGA_WINDOW_SIZE;
+    }
+
+    /* Clean the HW buffer */
+    memset(vga_fb_window_data, 0x00, vga_fb_window_size);
+
+    /* Reset window start */
+    VGA_SetWindowStart(0);
 
     par.Depth = (Depth < 8) ? 8 : Depth;
 
@@ -1252,9 +1292,33 @@ static void VGA_Poll_Graphics(void)
       VGA_SyncWindow( TRUE );
 
   /*
+   * CGA framebuffer
+   */
+  if(vga_fb_depth == 2 && vga_fb_width == 320 && vga_fb_height == 200){
+    WORD off = 0;
+    BYTE bits = 6;
+    BYTE value;
+    /* Go thru rows */
+    for(Y=0; Y<vga_fb_height; Y++, surf+=(Pitch*2)){
+      for(X=0; X<vga_fb_width; X++){
+        off = Y & 1 ? (8 * 1024) : 0;
+        off += (80 * (Y/2));
+        off += X/4;
+        value = (dat[off] >> bits) & 0x3;
+        surf[(X*2)] = value;
+        surf[(X*2)+1] = value;
+        surf[(X*2)+Pitch] = value;
+        surf[(X*2)+Pitch+1] = value;
+        bits -= 2;
+        bits &= 7;
+      }
+    }
+  }
+
+  /*
    * Double VGA framebuffer (320x200 -> 640x400), if needed.
    */
-  if(Height >= 2 * vga_fb_height && Width >= 2 * vga_fb_width && bpp == 1)
+  else if(Height >= 2 * vga_fb_height && Width >= 2 * vga_fb_width && bpp == 1)
     for (Y=0; Y<vga_fb_height; Y++,surf+=Pitch*2,dat+=vga_fb_pitch)
       for (X=0; X<vga_fb_width; X++) {
        BYTE value = dat[X];




More information about the wine-cvs mailing list