1
0
Fork 0

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
This commit is contained in:
Peter Veenstra 2005-09-27 20:31:05 +00:00
parent 489ffd7d1c
commit 981aed10d4
2 changed files with 97 additions and 13 deletions

View file

@ -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<vga.draw.blocks;x++) {
Bitu val1=*reader++;
Bitu val2=convert16[val1&0xf];
val1=convert16[val1 >> 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;

View file

@ -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<Bit8u>(R*baseR),static_cast<Bit8u>(G*baseG),static_cast<Bit8u>(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;