From 981aed10d4361e14d3f8c432f4e09e1b332469c0 Mon Sep 17 00:00:00 2001 From: Peter Veenstra Date: Tue, 27 Sep 2005 20:31:05 +0000 Subject: [PATCH] Add a new way of drawing composite cga. Implement register 3d9 in cga mode.(NewRisingSun) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2323 --- src/hardware/vga_draw.cpp | 47 ++++++++++++++++++++-------- src/hardware/vga_other.cpp | 63 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 13 deletions(-) diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 253446b5..92172764 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -52,22 +52,43 @@ static Bit8u * VGA_Draw_2BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { return TempLine; } -static Bit8u convert16[16]={ - 0x0,0x2,0x1,0x3,0x5,0x7,0x4,0x9, - 0x6,0xa,0x8,0xb,0xd,0xe,0xc,0xf -}; +static Bitu temp[643]={0}; static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart,Bitu panning,Bitu line) { Bit8u * reader=&vga.mem.linear[vidstart + (line * 8 * 1024)]; Bit32u * draw=(Bit32u *)TempLine; + //Generate a temporary bitline to calculate the avarage + //over bit-2 bit-1 bit bit+1. + //Combine this number with the current colour to get + //an unigue index in the pallete. Or it with bit 7 as they are stored + //in the upperpart to keep them from interfering the regular cga stuff + + for(Bitu x = 0; x < 640; x++) + temp[x+2] = (( reader[(x>>3)] >> (7-(x&7)) )&1) << 4; + //shift 4 as that is for the index. + Bitu i = 0,temp1,temp2,temp3,temp4; for (Bitu x=0;x> 4]; - *draw++=(val1 << 0) | - (val1 << 8) | - (val2 << 16) | - (val2 << 24); + Bitu val1 = *reader++; + Bitu val2 = val1&0xf; + val1 >>= 4; + + temp1 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; + temp2 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; + temp3 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; + temp4 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; + + *draw++ = 0x80808080|(temp1|val1) | + ((temp2|val1) << 8) | + ((temp3|val1) <<16) | + ((temp4|val1) <<24); + temp1 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; + temp2 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; + temp3 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; + temp4 = temp[i] + temp[i+1] + temp[i+2] + temp[i+3]; i++; + *draw++ = 0x80808080|(temp1|val2) | + ((temp2|val2) << 8) | + ((temp3|val2) <<16) | + ((temp4|val2) <<24); } return TempLine; } @@ -426,10 +447,9 @@ void VGA_SetupDrawing(Bitu val) { VGA_DrawLine=VGA_Draw_EGA_Line; break; case M_CGA16: - doublewidth=true; doubleheight=true; vga.draw.blocks=width*2; - width<<=3; + width<<=4; VGA_DrawLine=VGA_Draw_CGA16_Line; break; case M_CGA4: @@ -482,6 +502,7 @@ void VGA_SetupDrawing(Bitu val) { VGA_DrawLine=VGA_Draw_4BPP_Line; break; case M_TANDY_TEXT: + LOG_MSG("tandy text"); doublewidth=(vga.tandy.mode_control & 0x1)==0; case M_HERC_TEXT: aspect_ratio=1; diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 5c92636a..0d7900da 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -20,6 +20,7 @@ #include "dosbox.h" #include "inout.h" #include "vga.h" +#include "render.h" static void write_crtc_index_other(Bitu port,Bitu val,Bitu iolen) { vga.other.index=val; @@ -123,6 +124,65 @@ static Bitu read_crtc_data_other(Bitu port,Bitu iolen) { return (Bitu)-1; } +static void cga16_color_select(Bit8u val) { +// Algorithm provided by NewRisingSun +// His/Her algorithm is more complex and gives better results than the one below +// However that algorithm doesn't fit in our vga pallette. +// Therefore a simple variant is used, but the colours are bit lighter. + +// It uses an avarage over the bits to give smooth transitions from colour to colour +// This is represented by the j variable. The i variable gives the 16 colours +// The draw handler calculates the needed avarage and combines this with the colour +// to match an entry that is generated here. + + int baseR=0, baseG=0, baseB=0; + double sinhue,coshue; + double I,Q,Y,pixelI,pixelQ,R,G,B; + Bitu colorBit1,colorBit2,colorBit3,colorBit4,index; + + if (val & 0x01) baseB += 0xa8; + if (val & 0x02) baseG += 0xa8; + if (val & 0x04) baseR += 0xa8; + if (val & 0x08) { baseR += 0x57; baseG += 0x57; baseB += 0x57; } + if (val & 0x20) { + //Hue = 33.0 + hueoffset (0) + sinhue=0.54463904; //sin(hue*PI/180); + coshue=0.83867057; //sin(hue*PI/180); + } else { + //Hue = 55.0 + hueoffset (0) + sinhue=0.81915204; //sin(hue*PI/180); + coshue=0.57357644; //cos(hue*PI/180); + } + for(Bitu i = 0; i < 16;i++) { + for(Bitu j = 0;j < 5;j++) { + index = 0x80|(j << 4)|i; //use upperpart of vga pallette + colorBit4 = (i&1)>>0; + colorBit3 = (i&2)>>1; + colorBit2 = (i&4)>>2; + colorBit1 = (i&8)>>3; + + //calculate lookup table + I = 0; Q = 0; + I += (double) colorBit1; + Q += (double) colorBit2; + I -= (double) colorBit3; + Q -= (double) colorBit4; + Y = (double) j / 4.0; //calculated avarage is over 4 bits + + pixelI = I * 1.0 / 3.0; //I* tvSaturnation / 3.0 + pixelQ = Q * 1.0 / 3.0; //Q* tvSaturnation / 3.0 + I = pixelI*coshue + pixelQ*sinhue; + Q = pixelQ*coshue - pixelI*sinhue; + + R = Y + 0.956*I + 0.621*Q; if (R < 0.0) R = 0.0; if (R > 1.0) R = 1.0; + G = Y - 0.272*I - 0.647*Q; if (G < 0.0) G = 0.0; if (G > 1.0) G = 1.0; + B = Y - 1.105*I + 1.702*Q; if (B < 0.0) B = 0.0; if (B > 1.0) B = 1.0; + + RENDER_SetPal(index,static_cast(R*baseR),static_cast(G*baseG),static_cast(B*baseB)); + } + } +} + static void write_color_select(Bit8u val) { vga.tandy.color_select=val; switch (vga.mode) { @@ -146,6 +206,9 @@ static void write_color_select(Bit8u val) { } } break; + case M_CGA16: + cga16_color_select(val); + break; case M_TEXT: case M_TANDY16: break;