Improved CGA composite filter. Filter by reengine, patch from Battler.
This commit is contained in:
parent
4ae8f2d260
commit
7818f459ee
7 changed files with 421 additions and 86 deletions
|
|
@ -33,7 +33,7 @@ vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_ps1_svga.c vid_s3.c vid_s3_virge.c vid_
|
|||
vid_stg_ramdac.c vid_svga.c vid_svga_render.c vid_tandy.c vid_tandysl.c vid_tgui9440.c \
|
||||
vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c vid_voodoo.c video.c wd76c10.c \
|
||||
x86seg.c x87.c xtide.c sound_dbopl.cc sound_resid.cc dosbox/dbopl.cpp \
|
||||
resid-fp/convolve.cc resid-fp/convolve-sse.cc resid-fp/envelope.cc \
|
||||
dosbox/vid_cga_comp.c resid-fp/convolve.cc resid-fp/convolve-sse.cc resid-fp/envelope.cc \
|
||||
resid-fp/extfilt.cc resid-fp/filter.cc resid-fp/pot.cc resid-fp/sid.cc \
|
||||
resid-fp/voice.cc resid-fp/wave6581_PS_.cc resid-fp/wave6581_PST.cc \
|
||||
resid-fp/wave6581_P_T.cc resid-fp/wave6581__ST.cc resid-fp/wave8580_PS_.cc \
|
||||
|
|
|
|||
|
|
@ -21,14 +21,14 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad
|
|||
vid_vga.o vid_voodoo.o video.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \
|
||||
win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \
|
||||
win-status.o win-time.o win-video.o x86seg.o x87.o xtide.o pc.res
|
||||
FMOBJ = dbopl.o
|
||||
DBOBJ = dbopl.o vid_cga_comp.o
|
||||
SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o
|
||||
|
||||
|
||||
LIBS = -mwindows -lwinmm -lalut -lopenal32 -lddraw -ldinput -ldxguid -ld3d9 -lstdc++
|
||||
|
||||
PCem.exe: $(OBJ) $(FMOBJ) $(SIDOBJ)
|
||||
$(CC) $(OBJ) $(FMOBJ) $(SIDOBJ) -o "PCem.exe" $(LIBS)
|
||||
PCem.exe: $(OBJ) $(DBOBJ) $(SIDOBJ)
|
||||
$(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem.exe" $(LIBS)
|
||||
|
||||
all : PCem.exe
|
||||
|
||||
|
|
|
|||
|
|
@ -21,14 +21,14 @@ OBJ = 386.o 386_dynarec.o 386_dynarec_ops.o 808x.o acer386sx.o ali1429.o amstrad
|
|||
vid_vga.o vid_voodoo.o video.o wd76c10.o win.o win-config.o win-d3d.o win-d3d-fs.o win-ddraw.o \
|
||||
win-ddraw-fs.o win-deviceconfig.o win-hdconf.o win-joystick.o win-joystickconfig.o win-keyboard.o win-midi.o win-mouse.o \
|
||||
win-status.o win-time.o win-video.o x86seg.o x87.o xtide.o pc.res
|
||||
FMOBJ = dbopl.o
|
||||
DBOBJ = dbopl.o vid_cga_comp.o
|
||||
SIDOBJ = convolve.o convolve-sse.o envelope.o extfilt.o filter.o pot.o sid.o voice.o wave6581__ST.o wave6581_P_T.o wave6581_PS_.o wave6581_PST.o wave8580__ST.o wave8580_P_T.o wave8580_PS_.o wave8580_PST.o wave.o
|
||||
|
||||
|
||||
LIBS = -mwindows -lwinmm -lopenal32 -lddraw -ldinput -ldxguid -ld3d9 -lstdc++
|
||||
|
||||
PCem64.exe: $(OBJ) $(FMOBJ) $(SIDOBJ)
|
||||
$(CC) $(OBJ) $(FMOBJ) $(SIDOBJ) -o "PCem64.exe" $(LIBS)
|
||||
PCem64.exe: $(OBJ) $(DBOBJ) $(SIDOBJ)
|
||||
$(CC) $(OBJ) $(DBOBJ) $(SIDOBJ) -o "PCem64.exe" $(LIBS)
|
||||
|
||||
all : PCem64.exe
|
||||
|
||||
|
|
|
|||
325
src/dosbox/vid_cga_comp.c
Normal file
325
src/dosbox/vid_cga_comp.c
Normal file
|
|
@ -0,0 +1,325 @@
|
|||
/* Code borrowed from DOSBox and adapted by OBattler.
|
||||
Original author: reenigne. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "../ibm.h"
|
||||
#include "../device.h"
|
||||
#include "../mem.h"
|
||||
#include "../vid_cga.h"
|
||||
#include "vid_cga_comp.h"
|
||||
|
||||
int CGA_Composite_Table[1024];
|
||||
|
||||
static double brightness = 0;
|
||||
static double contrast = 100;
|
||||
static double saturation = 100;
|
||||
static double sharpness = 0;
|
||||
static double hue_offset = 0;
|
||||
|
||||
// New algorithm by reenigne
|
||||
// Works in all CGA modes/color settings and can simulate older and newer CGA revisions
|
||||
|
||||
static const double tau = 6.28318531; // == 2*pi
|
||||
|
||||
static unsigned char chroma_multiplexer[256] = {
|
||||
2, 2, 2, 2, 114,174, 4, 3, 2, 1,133,135, 2,113,150, 4,
|
||||
133, 2, 1, 99, 151,152, 2, 1, 3, 2, 96,136, 151,152,151,152,
|
||||
2, 56, 62, 4, 111,250,118, 4, 0, 51,207,137, 1,171,209, 5,
|
||||
140, 50, 54,100, 133,202, 57, 4, 2, 50,153,149, 128,198,198,135,
|
||||
32, 1, 36, 81, 147,158, 1, 42, 33, 1,210,254, 34,109,169, 77,
|
||||
177, 2, 0,165, 189,154, 3, 44, 33, 0, 91,197, 178,142,144,192,
|
||||
4, 2, 61, 67, 117,151,112, 83, 4, 0,249,255, 3,107,249,117,
|
||||
147, 1, 50,162, 143,141, 52, 54, 3, 0,145,206, 124,123,192,193,
|
||||
72, 78, 2, 0, 159,208, 4, 0, 53, 58,164,159, 37,159,171, 1,
|
||||
248,117, 4, 98, 212,218, 5, 2, 54, 59, 93,121, 176,181,134,130,
|
||||
1, 61, 31, 0, 160,255, 34, 1, 1, 58,197,166, 0,177,194, 2,
|
||||
162,111, 34, 96, 205,253, 32, 1, 1, 57,123,125, 119,188,150,112,
|
||||
78, 4, 0, 75, 166,180, 20, 38, 78, 1,143,246, 42,113,156, 37,
|
||||
252, 4, 1,188, 175,129, 1, 37, 118, 4, 88,249, 202,150,145,200,
|
||||
61, 59, 60, 60, 228,252,117, 77, 60, 58,248,251, 81,212,254,107,
|
||||
198, 59, 58,169, 250,251, 81, 80, 100, 58,154,250, 251,252,252,252};
|
||||
|
||||
static double intensity[4] = {
|
||||
77.175381, 88.654656, 166.564623, 174.228438};
|
||||
|
||||
#define NEW_CGA(c,i,r,g,b) (((c)/0.72)*0.29 + ((i)/0.28)*0.32 + ((r)/0.28)*0.1 + ((g)/0.28)*0.22 + ((b)/0.28)*0.07)
|
||||
|
||||
double mode_brightness;
|
||||
double mode_contrast;
|
||||
double mode_hue;
|
||||
double min_v;
|
||||
double max_v;
|
||||
|
||||
double video_ri, video_rq, video_gi, video_gq, video_bi, video_bq;
|
||||
int video_sharpness;
|
||||
int tandy_mode_control = 0;
|
||||
|
||||
static bool new_cga = 0;
|
||||
static bool is_bw = 0;
|
||||
static bool is_bpp1 = 0;
|
||||
|
||||
static uint8_t comp_pal[256][3];
|
||||
|
||||
static Bit8u byte_clamp_other(int v) { return v < 0 ? 0 : (v > 255 ? 255 : v); }
|
||||
|
||||
FILE *df;
|
||||
|
||||
void update_cga16_color(cga_t *cga) {
|
||||
int x;
|
||||
Bit32u x2;
|
||||
|
||||
if (!new_cga) {
|
||||
min_v = chroma_multiplexer[0] + intensity[0];
|
||||
max_v = chroma_multiplexer[255] + intensity[3];
|
||||
}
|
||||
else {
|
||||
double i0 = intensity[0];
|
||||
double i3 = intensity[3];
|
||||
min_v = NEW_CGA(chroma_multiplexer[0], i0, i0, i0, i0);
|
||||
max_v = NEW_CGA(chroma_multiplexer[255], i3, i3, i3, i3);
|
||||
}
|
||||
mode_contrast = 256/(max_v - min_v);
|
||||
mode_brightness = -min_v*mode_contrast;
|
||||
if ((cga->cgamode & 3) == 1)
|
||||
mode_hue = 14;
|
||||
else
|
||||
mode_hue = 4;
|
||||
|
||||
mode_contrast *= contrast * (new_cga ? 1.2 : 1)/100; // new CGA: 120%
|
||||
mode_brightness += (new_cga ? brightness-10 : brightness)*5; // new CGA: -10
|
||||
double mode_saturation = (new_cga ? 4.35 : 2.9)*saturation/100; // new CGA: 150%
|
||||
|
||||
for (x = 0; x < 1024; ++x) {
|
||||
int phase = x & 3;
|
||||
int right = (x >> 2) & 15;
|
||||
int left = (x >> 6) & 15;
|
||||
int rc = right;
|
||||
int lc = left;
|
||||
if ((cga->cgamode & 4) != 0) {
|
||||
rc = (right & 8) | ((right & 7) != 0 ? 7 : 0);
|
||||
lc = (left & 8) | ((left & 7) != 0 ? 7 : 0);
|
||||
}
|
||||
double c =
|
||||
chroma_multiplexer[((lc & 7) << 5) | ((rc & 7) << 2) | phase];
|
||||
double i = intensity[(left >> 3) | ((right >> 2) & 2)];
|
||||
double v;
|
||||
if (!new_cga)
|
||||
v = c + i;
|
||||
else {
|
||||
double r = intensity[((left >> 2) & 1) | ((right >> 1) & 2)];
|
||||
double g = intensity[((left >> 1) & 1) | (right & 2)];
|
||||
double b = intensity[(left & 1) | ((right << 1) & 2)];
|
||||
v = NEW_CGA(c, i, r, g, b);
|
||||
}
|
||||
CGA_Composite_Table[x] = (int) (v*mode_contrast + mode_brightness);
|
||||
}
|
||||
|
||||
double i = CGA_Composite_Table[6*68] - CGA_Composite_Table[6*68 + 2];
|
||||
double q = CGA_Composite_Table[6*68 + 1] - CGA_Composite_Table[6*68 + 3];
|
||||
|
||||
double a = tau*(33 + 90 + hue_offset + mode_hue)/360.0;
|
||||
double c = cos(a);
|
||||
double s = sin(a);
|
||||
double r = 256*mode_saturation/sqrt(i*i+q*q);
|
||||
|
||||
double iq_adjust_i = -(i*c + q*s)*r;
|
||||
double iq_adjust_q = (q*c - i*s)*r;
|
||||
|
||||
static const double ri = 0.9563;
|
||||
static const double rq = 0.6210;
|
||||
static const double gi = -0.2721;
|
||||
static const double gq = -0.6474;
|
||||
static const double bi = -1.1069;
|
||||
static const double bq = 1.7046;
|
||||
|
||||
video_ri = (int) (ri*iq_adjust_i + rq*iq_adjust_q);
|
||||
video_rq = (int) (-ri*iq_adjust_q + rq*iq_adjust_i);
|
||||
video_gi = (int) (gi*iq_adjust_i + gq*iq_adjust_q);
|
||||
video_gq = (int) (-gi*iq_adjust_q + gq*iq_adjust_i);
|
||||
video_bi = (int) (bi*iq_adjust_i + bq*iq_adjust_q);
|
||||
video_bq = (int) (-bi*iq_adjust_q + bq*iq_adjust_i);
|
||||
video_sharpness = (int) (sharpness*256/100);
|
||||
}
|
||||
|
||||
static Bit8u byte_clamp(int v) {
|
||||
v >>= 13;
|
||||
return v < 0 ? 0 : (v > 255 ? 255 : v);
|
||||
}
|
||||
|
||||
/* 2048x1536 is the maximum we can possibly support. */
|
||||
#define SCALER_MAXWIDTH 2048
|
||||
|
||||
static int temp[SCALER_MAXWIDTH + 10]={0};
|
||||
static int atemp[SCALER_MAXWIDTH + 2]={0};
|
||||
static int btemp[SCALER_MAXWIDTH + 2]={0};
|
||||
|
||||
Bit8u * Composite_Process(cga_t *cga, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit8u *TempLine)
|
||||
{
|
||||
int x;
|
||||
Bit32u x2;
|
||||
|
||||
int w = blocks*4;
|
||||
|
||||
#define COMPOSITE_CONVERT(I, Q) do { \
|
||||
i[1] = (i[1]<<3) - ap[1]; \
|
||||
a = ap[0]; \
|
||||
b = bp[0]; \
|
||||
c = i[0]+i[0]; \
|
||||
d = i[-1]+i[1]; \
|
||||
y = ((c+d)<<8) + video_sharpness*(c-d); \
|
||||
rr = y + video_ri*(I) + video_rq*(Q); \
|
||||
gg = y + video_gi*(I) + video_gq*(Q); \
|
||||
bb = y + video_bi*(I) + video_bq*(Q); \
|
||||
++i; \
|
||||
++ap; \
|
||||
++bp; \
|
||||
*srgb = (byte_clamp(rr)<<16) | (byte_clamp(gg)<<8) | byte_clamp(bb); \
|
||||
++srgb; \
|
||||
} while (0)
|
||||
|
||||
#define OUT(v) do { *o = (v); ++o; } while (0)
|
||||
|
||||
// Simulate CGA composite output
|
||||
int* o = temp;
|
||||
Bit8u* rgbi = TempLine;
|
||||
int* b = &CGA_Composite_Table[border*68];
|
||||
for (x = 0; x < 4; ++x)
|
||||
OUT(b[(x+3)&3]);
|
||||
OUT(CGA_Composite_Table[(border<<6) | ((*rgbi)<<2) | 3]);
|
||||
for (x = 0; x < w-1; ++x) {
|
||||
OUT(CGA_Composite_Table[(rgbi[0]<<6) | (rgbi[1]<<2) | (x&3)]);
|
||||
++rgbi;
|
||||
}
|
||||
OUT(CGA_Composite_Table[((*rgbi)<<6) | (border<<2) | 3]);
|
||||
for (x = 0; x < 5; ++x)
|
||||
OUT(b[x&3]);
|
||||
|
||||
if ((cga->cgamode & 4) != 0) {
|
||||
// Decode
|
||||
int* i = temp + 5;
|
||||
Bit32u* srgb = (Bit32u *)TempLine;
|
||||
for (x2 = 0; x2 < blocks*4; ++x2) {
|
||||
int c = (i[0]+i[0])<<3;
|
||||
int d = (i[-1]+i[1])<<3;
|
||||
int y = ((c+d)<<8) + video_sharpness*(c-d);
|
||||
++i;
|
||||
*srgb = byte_clamp(y)*0x10101;
|
||||
++srgb;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Store chroma
|
||||
int* i = temp + 4;
|
||||
int* ap = atemp + 1;
|
||||
int* bp = btemp + 1;
|
||||
for (x = -1; x < w + 1; ++x) {
|
||||
ap[x] = i[-4]-((i[-2]-i[0]+i[2])<<1)+i[4];
|
||||
bp[x] = (i[-3]-i[-1]+i[1]-i[3])<<1;
|
||||
++i;
|
||||
}
|
||||
|
||||
// Decode
|
||||
i = temp + 5;
|
||||
i[-1] = (i[-1]<<3) - ap[-1];
|
||||
i[0] = (i[0]<<3) - ap[0];
|
||||
Bit32u* srgb = (Bit32u *)TempLine;
|
||||
for (x2 = 0; x2 < blocks; ++x2) {
|
||||
int y,a,b,c,d,rr,gg,bb;
|
||||
COMPOSITE_CONVERT(a, b);
|
||||
COMPOSITE_CONVERT(-b, a);
|
||||
COMPOSITE_CONVERT(-a, -b);
|
||||
COMPOSITE_CONVERT(b, -a);
|
||||
}
|
||||
}
|
||||
#undef COMPOSITE_CONVERT
|
||||
#undef OUT
|
||||
|
||||
return TempLine;
|
||||
}
|
||||
|
||||
void IncreaseHue(cga_t *cga)
|
||||
{
|
||||
hue_offset += 5.0;
|
||||
|
||||
update_cga16_color(cga);
|
||||
}
|
||||
|
||||
void DecreaseHue(cga_t *cga)
|
||||
{
|
||||
hue_offset -= 5.0;
|
||||
|
||||
update_cga16_color(cga);
|
||||
}
|
||||
|
||||
void IncreaseSaturation(cga_t *cga)
|
||||
{
|
||||
saturation += 5;
|
||||
|
||||
update_cga16_color(cga);
|
||||
}
|
||||
|
||||
void DecreaseSaturation(cga_t *cga)
|
||||
{
|
||||
saturation -= 5;
|
||||
|
||||
update_cga16_color(cga);
|
||||
}
|
||||
|
||||
void IncreaseContrast(cga_t *cga)
|
||||
{
|
||||
contrast += 5;
|
||||
|
||||
update_cga16_color(cga);
|
||||
}
|
||||
|
||||
void DecreaseContrast(cga_t *cga)
|
||||
{
|
||||
contrast -= 5;
|
||||
|
||||
update_cga16_color(cga);
|
||||
}
|
||||
|
||||
void IncreaseBrightness(cga_t *cga)
|
||||
{
|
||||
brightness += 5;
|
||||
|
||||
update_cga16_color(cga);
|
||||
}
|
||||
|
||||
void DecreaseBrightness(cga_t *cga)
|
||||
{
|
||||
brightness -= 5;
|
||||
|
||||
update_cga16_color(cga);
|
||||
}
|
||||
|
||||
void IncreaseSharpness(cga_t *cga)
|
||||
{
|
||||
sharpness += 10;
|
||||
|
||||
update_cga16_color(cga);
|
||||
}
|
||||
|
||||
void DecreaseSharpness(cga_t *cga)
|
||||
{
|
||||
sharpness -= 10;
|
||||
|
||||
update_cga16_color(cga);
|
||||
}
|
||||
|
||||
void cga_comp_init(cga_t *cga)
|
||||
{
|
||||
new_cga = cga->revision;
|
||||
|
||||
/* Making sure this gets reset after reset. */
|
||||
brightness = 0;
|
||||
contrast = 100;
|
||||
saturation = 100;
|
||||
sharpness = 0;
|
||||
hue_offset = 0;
|
||||
|
||||
update_cga16_color(cga);
|
||||
}
|
||||
8
src/dosbox/vid_cga_comp.h
Normal file
8
src/dosbox/vid_cga_comp.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#define Bit8u uint8_t
|
||||
#define Bit32u uint32_t
|
||||
#define Bitu unsigned int
|
||||
#define bool uint8_t
|
||||
|
||||
void update_cga16_color(cga_t *cga);
|
||||
void cga_comp_init(cga_t *cga);
|
||||
Bit8u * Composite_Process(cga_t *cga, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit8u *TempLine);
|
||||
157
src/vid_cga.c
157
src/vid_cga.c
|
|
@ -8,8 +8,13 @@
|
|||
#include "timer.h"
|
||||
#include "video.h"
|
||||
#include "vid_cga.h"
|
||||
#include "dosbox/vid_cga_comp.h"
|
||||
|
||||
static int i_filt[8],q_filt[8];
|
||||
#define CGA_RGB 0
|
||||
#define CGA_COMPOSITE 1
|
||||
|
||||
#define COMPOSITE_OLD 0
|
||||
#define COMPOSITE_NEW 1
|
||||
|
||||
static uint8_t crtcmask[32] =
|
||||
{
|
||||
|
|
@ -42,6 +47,11 @@ void cga_out(uint16_t addr, uint8_t val, void *p)
|
|||
}
|
||||
return;
|
||||
case 0x3D8:
|
||||
if (((cga->cgamode ^ val) & 5) != 0)
|
||||
{
|
||||
cga->cgamode = val;
|
||||
update_cga16_color(cga);
|
||||
}
|
||||
cga->cgamode = val;
|
||||
return;
|
||||
case 0x3D9:
|
||||
|
|
@ -112,18 +122,6 @@ void cga_recalctimings(cga_t *cga)
|
|||
cga->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
|
||||
}
|
||||
|
||||
static int ntsc_col[8][8]=
|
||||
{
|
||||
{0,0,0,0,0,0,0,0}, /*Black*/
|
||||
{0,0,1,1,1,1,0,0}, /*Blue*/
|
||||
{1,0,0,0,0,1,1,1}, /*Green*/
|
||||
{0,0,0,0,1,1,1,1}, /*Cyan*/
|
||||
{1,1,1,1,0,0,0,0}, /*Red*/
|
||||
{0,1,1,1,1,0,0,0}, /*Magenta*/
|
||||
{1,1,0,0,0,0,1,1}, /*Yellow*/
|
||||
{1,1,1,1,1,1,1,1} /*White*/
|
||||
};
|
||||
|
||||
void cga_poll(void *p)
|
||||
{
|
||||
cga_t *cga = (cga_t *)p;
|
||||
|
|
@ -136,10 +134,7 @@ void cga_poll(void *p)
|
|||
int cols[4];
|
||||
int col;
|
||||
int oldsc;
|
||||
int y_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, y_val, y_tot;
|
||||
int i_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, i_val, i_tot;
|
||||
int q_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0}, q_val, q_tot;
|
||||
int r, g, b;
|
||||
|
||||
if (!cga->linepos)
|
||||
{
|
||||
cga->vidtime += cga->dispofftime;
|
||||
|
|
@ -292,59 +287,13 @@ void cga_poll(void *p)
|
|||
|
||||
if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16;
|
||||
else x = (cga->crtc[1] << 4) + 16;
|
||||
if (cga_comp)
|
||||
|
||||
if (cga->composite)
|
||||
{
|
||||
for (c = 0; c < x; c++)
|
||||
{
|
||||
y_buf[(c << 1) & 6] = ntsc_col[buffer->line[cga->displine][c] & 7][(c << 1) & 6] ? 0x6000 : 0;
|
||||
y_buf[(c << 1) & 6] += (buffer->line[cga->displine][c] & 8) ? 0x3000 : 0;
|
||||
i_buf[(c << 1) & 6] = y_buf[(c << 1) & 6] * i_filt[(c << 1) & 6];
|
||||
q_buf[(c << 1) & 6] = y_buf[(c << 1) & 6] * q_filt[(c << 1) & 6];
|
||||
y_tot = y_buf[0] + y_buf[1] + y_buf[2] + y_buf[3] + y_buf[4] + y_buf[5] + y_buf[6] + y_buf[7];
|
||||
i_tot = i_buf[0] + i_buf[1] + i_buf[2] + i_buf[3] + i_buf[4] + i_buf[5] + i_buf[6] + i_buf[7];
|
||||
q_tot = q_buf[0] + q_buf[1] + q_buf[2] + q_buf[3] + q_buf[4] + q_buf[5] + q_buf[6] + q_buf[7];
|
||||
for (c = 0; c < x; c++)
|
||||
buffer32->line[cga->displine][c] = buffer->line[cga->displine][c] & 0xf;
|
||||
|
||||
y_val = y_tot >> 10;
|
||||
if (y_val > 255) y_val = 255;
|
||||
y_val <<= 16;
|
||||
i_val = i_tot >> 12;
|
||||
if (i_val > 39041) i_val = 39041;
|
||||
if (i_val < -39041) i_val = -39041;
|
||||
q_val = q_tot >> 12;
|
||||
if (q_val > 34249) q_val = 34249;
|
||||
if (q_val < -34249) q_val = -34249;
|
||||
|
||||
r = (y_val + 249*i_val + 159*q_val) >> 16;
|
||||
g = (y_val - 70*i_val - 166*q_val) >> 16;
|
||||
b = (y_val - 283*i_val + 436*q_val) >> 16;
|
||||
|
||||
y_buf[((c << 1) & 6) + 1] = ntsc_col[buffer->line[cga->displine][c] & 7][((c << 1) & 6) + 1] ? 0x6000 : 0;
|
||||
y_buf[((c << 1) & 6) + 1] += (buffer->line[cga->displine][c] & 8) ? 0x3000 : 0;
|
||||
i_buf[((c << 1) & 6) + 1] = y_buf[((c << 1) & 6) + 1] * i_filt[((c << 1) & 6) + 1];
|
||||
q_buf[((c << 1) & 6) + 1] = y_buf[((c << 1) & 6) + 1] * q_filt[((c << 1) & 6) + 1];
|
||||
y_tot = y_buf[0] + y_buf[1] + y_buf[2] + y_buf[3] + y_buf[4] + y_buf[5] + y_buf[6] + y_buf[7];
|
||||
i_tot = i_buf[0] + i_buf[1] + i_buf[2] + i_buf[3] + i_buf[4] + i_buf[5] + i_buf[6] + i_buf[7];
|
||||
q_tot = q_buf[0] + q_buf[1] + q_buf[2] + q_buf[3] + q_buf[4] + q_buf[5] + q_buf[6] + q_buf[7];
|
||||
|
||||
y_val = y_tot >> 10;
|
||||
if (y_val > 255) y_val = 255;
|
||||
y_val <<= 16;
|
||||
i_val = i_tot >> 12;
|
||||
if (i_val > 39041) i_val = 39041;
|
||||
if (i_val < -39041) i_val = -39041;
|
||||
q_val = q_tot >> 12;
|
||||
if (q_val > 34249) q_val = 34249;
|
||||
if (q_val < -34249) q_val = -34249;
|
||||
|
||||
r = (y_val + 249*i_val + 159*q_val) >> 16;
|
||||
g = (y_val - 70*i_val - 166*q_val) >> 16;
|
||||
b = (y_val - 283*i_val + 436*q_val) >> 16;
|
||||
if (r > 511) r = 511;
|
||||
if (g > 511) g = 511;
|
||||
if (b > 511) b = 511;
|
||||
|
||||
((uint32_t *)buffer32->line[cga->displine])[c] = makecol32(r / 2, g / 2, b / 2);
|
||||
}
|
||||
Composite_Process(cga, 0, x >> 2, buffer32->line[cga->displine]);
|
||||
}
|
||||
|
||||
cga->sc = oldsc;
|
||||
|
|
@ -357,7 +306,6 @@ void cga_poll(void *p)
|
|||
else
|
||||
{
|
||||
cga->vidtime += cga->dispontime;
|
||||
if (cga->cgadispon) cga->cgastat &= ~1;
|
||||
cga->linepos = 0;
|
||||
if (cga->vsynctime)
|
||||
{
|
||||
|
|
@ -410,7 +358,7 @@ void cga_poll(void *p)
|
|||
{
|
||||
cga->cgadispon = 0;
|
||||
cga->displine = 0;
|
||||
cga->vsynctime = (cga->crtc[3] >> 4) + 1;
|
||||
cga->vsynctime = 16;
|
||||
if (cga->crtc[7])
|
||||
{
|
||||
if (cga->cgamode & 1) x = (cga->crtc[1] << 3) + 16;
|
||||
|
|
@ -426,7 +374,7 @@ void cga_poll(void *p)
|
|||
}
|
||||
|
||||
startblit();
|
||||
if (cga_comp)
|
||||
if (cga->composite)
|
||||
video_blit_memtoscreen(0, cga->firstline - 4, 0, (cga->lastline - cga->firstline) + 8, xsize, (cga->lastline - cga->firstline) + 8);
|
||||
else
|
||||
video_blit_memtoscreen_8(0, cga->firstline - 4, xsize, (cga->lastline - cga->firstline) + 8);
|
||||
|
|
@ -468,6 +416,8 @@ endblit();
|
|||
cga->sc &= 31;
|
||||
cga->ma = cga->maback;
|
||||
}
|
||||
if (cga->cgadispon)
|
||||
cga->cgastat &= ~1;
|
||||
if ((cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1))))
|
||||
cga->con = 1;
|
||||
if (cga->cgadispon && (cga->cgamode & 1))
|
||||
|
|
@ -480,25 +430,26 @@ endblit();
|
|||
|
||||
void cga_init(cga_t *cga)
|
||||
{
|
||||
cga->composite = 0;
|
||||
}
|
||||
|
||||
void *cga_standalone_init()
|
||||
{
|
||||
int c;
|
||||
int cga_tint = -2;
|
||||
int display_type;
|
||||
cga_t *cga = malloc(sizeof(cga_t));
|
||||
memset(cga, 0, sizeof(cga_t));
|
||||
|
||||
display_type = device_get_config_int("display_type");
|
||||
cga->composite = (display_type != CGA_RGB);
|
||||
cga->revision = device_get_config_int("composite_type");
|
||||
|
||||
cga->vram = malloc(0x4000);
|
||||
|
||||
for (c = 0; c < 8; c++)
|
||||
{
|
||||
i_filt[c] = 512.0 * cos((3.14 * (cga_tint + c * 4) / 16.0) - 33.0 / 180.0);
|
||||
q_filt[c] = 512.0 * sin((3.14 * (cga_tint + c * 4) / 16.0) - 33.0 / 180.0);
|
||||
}
|
||||
cga_comp_init(cga);
|
||||
timer_add(cga_poll, &cga->vidtime, TIMER_ALWAYS_ENABLED, cga);
|
||||
mem_mapping_add(&cga->mapping, 0xb8000, 0x08000, cga_read, NULL, NULL, cga_write, NULL, NULL, NULL, 0, cga);
|
||||
io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, cga);
|
||||
|
||||
return cga;
|
||||
}
|
||||
|
||||
|
|
@ -517,6 +468,53 @@ void cga_speed_changed(void *p)
|
|||
cga_recalctimings(cga);
|
||||
}
|
||||
|
||||
static device_config_t cga_config[] =
|
||||
{
|
||||
{
|
||||
.name = "display_type",
|
||||
.description = "Display type",
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
{
|
||||
{
|
||||
.description = "RGB",
|
||||
.value = CGA_RGB
|
||||
},
|
||||
{
|
||||
.description = "Composite",
|
||||
.value = CGA_COMPOSITE
|
||||
},
|
||||
{
|
||||
.description = ""
|
||||
}
|
||||
},
|
||||
.default_int = CGA_RGB
|
||||
},
|
||||
{
|
||||
.name = "composite_type",
|
||||
.description = "Composite type",
|
||||
.type = CONFIG_SELECTION,
|
||||
.selection =
|
||||
{
|
||||
{
|
||||
.description = "Old",
|
||||
.value = COMPOSITE_OLD
|
||||
},
|
||||
{
|
||||
.description = "New",
|
||||
.value = COMPOSITE_NEW
|
||||
},
|
||||
{
|
||||
.description = ""
|
||||
}
|
||||
},
|
||||
.default_int = COMPOSITE_OLD
|
||||
},
|
||||
{
|
||||
.type = -1
|
||||
}
|
||||
};
|
||||
|
||||
device_t cga_device =
|
||||
{
|
||||
"CGA",
|
||||
|
|
@ -526,5 +524,6 @@ device_t cga_device =
|
|||
NULL,
|
||||
cga_speed_changed,
|
||||
NULL,
|
||||
NULL
|
||||
NULL,
|
||||
cga_config
|
||||
};
|
||||
|
|
|
|||
|
|
@ -27,6 +27,9 @@ typedef struct cga_t
|
|||
uint8_t *vram;
|
||||
|
||||
uint8_t charbuffer[256];
|
||||
|
||||
int revision;
|
||||
int composite;
|
||||
} cga_t;
|
||||
|
||||
void cga_init(cga_t *cga);
|
||||
|
|
|
|||
Loading…
Reference in a new issue