more correct display functions
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sat, 9 Sep 2006 11:31:34 +0000 (11:31 +0000)
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>
Sat, 9 Sep 2006 11:31:34 +0000 (11:31 +0000)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2149 c046a42c-6fe2-441c-8c8c-71466251a162

hw/tcx.c

index ed32c94..1df7d24 100644 (file)
--- a/hw/tcx.c
+++ b/hw/tcx.c
@@ -34,11 +34,55 @@ typedef struct TCXState {
     ram_addr_t vram_offset;
     uint16_t width, height;
     uint8_t r[256], g[256], b[256];
+    uint32_t palette[256];
     uint8_t dac_index, dac_state;
 } TCXState;
 
 static void tcx_screen_dump(void *opaque, const char *filename);
 
+/* XXX: unify with vga draw line functions */
+static inline unsigned int rgb_to_pixel8(unsigned int r, unsigned int g, unsigned b)
+{
+    return ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6);
+}
+
+static inline unsigned int rgb_to_pixel15(unsigned int r, unsigned int g, unsigned b)
+{
+    return ((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3);
+}
+
+static inline unsigned int rgb_to_pixel16(unsigned int r, unsigned int g, unsigned b)
+{
+    return ((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3);
+}
+
+static inline unsigned int rgb_to_pixel32(unsigned int r, unsigned int g, unsigned b)
+{
+    return (r << 16) | (g << 8) | b;
+}
+
+static void update_palette_entries(TCXState *s, int start, int end)
+{
+    int i;
+    for(i = start; i < end; i++) {
+        switch(s->ds->depth) {
+        default:
+        case 8:
+            s->palette[i] = rgb_to_pixel8(s->r[i], s->g[i], s->b[i]);
+            break;
+        case 15:
+            s->palette[i] = rgb_to_pixel15(s->r[i], s->g[i], s->b[i]);
+            break;
+        case 16:
+            s->palette[i] = rgb_to_pixel16(s->r[i], s->g[i], s->b[i]);
+            break;
+        case 32:
+            s->palette[i] = rgb_to_pixel32(s->r[i], s->g[i], s->b[i]);
+            break;
+        }
+    }
+}
+
 static void tcx_draw_line32(TCXState *s1, uint8_t *d, 
                            const uint8_t *s, int width)
 {
@@ -47,14 +91,11 @@ static void tcx_draw_line32(TCXState *s1, uint8_t *d,
 
     for(x = 0; x < width; x++) {
        val = *s++;
-       *d++ = s1->b[val];
-       *d++ = s1->g[val];
-       *d++ = s1->r[val];
-       d++;
+        *((uint32_t *)d)++ = s1->palette[val];
     }
 }
 
-static void tcx_draw_line24(TCXState *s1, uint8_t *d, 
+static void tcx_draw_line16(TCXState *s1, uint8_t *d, 
                            const uint8_t *s, int width)
 {
     int x;
@@ -62,9 +103,7 @@ static void tcx_draw_line24(TCXState *s1, uint8_t *d,
 
     for(x = 0; x < width; x++) {
        val = *s++;
-       *d++ = s1->b[val];
-       *d++ = s1->g[val];
-       *d++ = s1->r[val];
+        *((uint16_t *)d)++ = s1->palette[val];
     }
 }
 
@@ -76,8 +115,7 @@ static void tcx_draw_line8(TCXState *s1, uint8_t *d,
 
     for(x = 0; x < width; x++) {
        val = *s++;
-       /* XXX translate between palettes? */
-       *d++ = val;
+        *d++ = s1->palette[val];
     }
 }
 
@@ -106,8 +144,9 @@ static void tcx_update_display(void *opaque)
     case 32:
        f = tcx_draw_line32;
        break;
-    case 24:
-       f = tcx_draw_line24;
+    case 15:
+    case 16:
+       f = tcx_draw_line16;
        break;
     default:
     case 8:
@@ -201,6 +240,7 @@ static int tcx_load(QEMUFile *f, void *opaque, int version_id)
     qemu_get_buffer(f, s->b, 256);
     qemu_get_8s(f, &s->dac_index);
     qemu_get_8s(f, &s->dac_state);
+    update_palette_entries(s, 0, 256);
     return 0;
 }
 
@@ -213,6 +253,7 @@ static void tcx_reset(void *opaque)
     memset(s->g, 0, 256);
     memset(s->b, 0, 256);
     s->r[255] = s->g[255] = s->b[255] = 255;
+    update_palette_entries(s, 0, 256);
     memset(s->vram, 0, MAXX*MAXY);
     cpu_physical_memory_reset_dirty(s->vram_offset, s->vram_offset + MAXX*MAXY,
                                     VGA_DIRTY_FLAG);
@@ -240,14 +281,17 @@ static void tcx_dac_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
        switch (s->dac_state) {
        case 0:
            s->r[s->dac_index] = val >> 24;
+            update_palette_entries(s, s->dac_index, s->dac_index + 1);
            s->dac_state++;
            break;
        case 1:
            s->g[s->dac_index] = val >> 24;
+            update_palette_entries(s, s->dac_index, s->dac_index + 1);
            s->dac_state++;
            break;
        case 2:
            s->b[s->dac_index] = val >> 24;
+            update_palette_entries(s, s->dac_index, s->dac_index + 1);
        default:
            s->dac_state = 0;
            break;