Add support for decoding and displaying the 4 bit CGA framebuffer, which is one of the VGA legacy modes. This adds support for showing graphics in many old games. Addapted patch to latest changes

Peter Dons Tychsen donpedro at tdcadsl.dk
Sat Nov 8 09:21:03 CST 2008


---
 dlls/winedos/int10.c |    2 +-
 dlls/winedos/vga.c   |   82 ++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 74 insertions(+), 10 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..71ed3ee 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));
@@ -765,8 +789,24 @@ int VGA_SetMode(unsigned Xres,unsigned Yres,unsigned Depth)
       par.Xres = 640;
       par.Yres = 480;
     }
+  
+    /* 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;
+    } 
 
-    VGA_SetWindowStart((Depth < 8) ? -1 : 0);
+    /* 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];
-- 
1.5.4.3


--=-a87pef/k4BEz+p+uzz0G--




More information about the wine-patches mailing list