Page 1 of 7
3DFX emulation
Posted: Sun 08 Mar, 2015 4:17 pm
by SarahWalker
Re: 3DFX emulation
Posted: Mon 09 Mar, 2015 9:26 pm
by Bloody
Great work, looks really awesome!
Re: 3DFX emulation
Posted: Wed 11 Mar, 2015 12:39 am
by leilei
Q3A hangs just seconds after initialization. (r_glDriver 3dfxogl, using vg-w9x-q3.exe driver set). Also the gamma extension (WGL_3DFX_gamma_control) doesn't appear to be working.
Virge works without hang though
Trying to figure out where and how to adapt
the filter via software
EDIT: Attempted a rough quick C port of the filter. It's slow and doesn't add purple lines yet nor can it work with the lack of dithering well. It's a start
Took a while because I could only test Turok. Tomb Raider crashed, Shadow Warrior refused to recognize the voodoo, and surprisingly Croc crashed.
Code: Select all
if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS)
{
if (voodoo->line < voodoo->v_disp)
{
uint32_t *p = &((uint32_t *)buffer32->line[voodoo->line])[32];
uint16_t *src = (uint16_t *)&voodoo->fb_mem[voodoo->front_offset + voodoo->line*voodoo->row_width];
int x;
// leilei - dac screen filter, this is a messy hack with bad comment conventions
// a ton of it could be refactored, optimized, and vectorized
// this is just a rough initial implementation by trial and error
if (voodoo->scrfilter){
unsigned rb[voodoo->h_disp];
unsigned gb[voodoo->h_disp];
unsigned bb[voodoo->h_disp];
int j;
for (j=0;j<4;j++) // we must do 4 passes of this
{
for (x = 0; x < voodoo->h_disp; x++)
{
#define FILTCAP (0.075 * 255)
#define FILTCAPG (FILTCAP / 2)
int ren;
int r1,g1,b1;
int r2,g2,b2;
int rd,gd,bd;
if (j==0){
// initial buffer grab
rb[x] = src[x] & 31;
gb[x] = (src[x] >> 5) & 63;
bb[x] = (src[x] >> 11) & 31;
rb[x+1] = src[x+1] & 31;
gb[x+1] = (src[x+1] >> 5) & 63;
bb[x+1] = (src[x+1] >> 11) & 31;
}
r1 = rb[x];
g1 = gb[x];
b1 = bb[x];
r2 = rb[x+1];
g2 = gb[x+1];
b2 = bb[x+1];
rd = r2 - r1;
gd = g2 - g1;
bd = b2 - b1;
if (rd > FILTCAP ) rd = FILTCAP;
if (gd > FILTCAPG) gd = FILTCAPG;
if (bd > FILTCAP ) bd = FILTCAP;
if (rd < -FILTCAP ) rd = -FILTCAP;
if (gd < -FILTCAPG) gd = -FILTCAPG;
if (bd < -FILTCAP ) bd = -FILTCAP;
r1 += (rd/4);
g1 += (gd/4);
b1 += (bd/4);
if (r1 < 0) r1 = 0;
if (g1 < 0) g1 = 0;
if (b1 < 0) b1 = 0;
if (r1 > 255) r1 = 255;
if (g1 > 255) g1 = 255;
if (b1 > 255) b1 = 255;
if (r2 < 0) r2 = 0;
if (g2 < 0) g2 = 0;
if (b2 < 0) b2 = 0;
if (r2 > 255) r2 = 255;
if (g2 > 255) g2 = 255;
if (b2 > 255) b2 = 255;
if (j==3) // final buffer write
p[x] = (r1 << 3 | g1 << 10 | b1 << 19);
else // feedback filter linear passes
{
rb[x] = r1;
gb[x] = g1;
bb[x] = b1;
}
}
}
}
else
{
for (x = 0; x < voodoo->h_disp; x++)
{
p[x] = video_16to32[src[x]];
}
}
}
it's not accurate because it's missing the faint purple lines, and it seems to do it bidirectional (when it should be 3 to the right, 1 to the left IIRC)
Re: 3DFX emulation
Posted: Sat 21 Mar, 2015 11:37 am
by SarahWalker
Quake III hang should be fixed as of rev 213.
- pcem_q3_3dfx_2.png (176.96 KiB) Viewed 56409 times
When you say Tomb Raider and Croc crashed, was that the emulator crashing or the games? What configuration are you using?
Re: 3DFX emulation
Posted: Sat 21 Mar, 2015 10:39 pm
by leilei
The emulator crashes. The configuration is the same seen in the screenshot, but also to mention the Stealth 3D 2000, Sound Blaster 16 and 32MB RAM being used.
I haven't tried the latest revision if that changed yet.
More filter WIP code, changed things into lookups
vid_voodoo.c
Code: Select all
uint32_t u;
} rgba_u;
// leilei stuff start
#include <math.h>
int gammer[256]; // gamma correction lookup table
int thefilter[256][256]; // pixel filter, feeding from one or two
int thefilterg[256][256]; // pixel filter, feeding from one or two
void voodoo_generate_gamma(void)
{
int g, h, i;
float color;
int thiscol;
for (g=0;g<256;g++){
color = g / 255;
thiscol = pow(color, 1.7) * 255; // THIS DOES NOT WORK YET
thiscol = g; // so just use the plain color
if (thiscol > 255) thiscol = 255;
if (thiscol < 0) thiscol = 0;
gammer[g] = thiscol;
}
};
#define FILTCAP (0.075 * 255)
#define FILTCAPG (FILTCAP / 2)
int purpleline[256];
// test
int vline[600];
void voodoo_generate_filter(void)
{
int g, h, i;
int difference, diffg;
float color;
int thiscol, thiscolg, lined;
for (g=0;g<256;g++){ // pixel 1
for (h=0;h<256;h++){ // pixel 2
difference = h - g;
diffg = difference;
if (difference > FILTCAP ) difference = FILTCAP;
if (difference < -FILTCAP ) difference = -FILTCAP;
if (diffg > FILTCAPG ) diffg = FILTCAPG;
if (diffg < -FILTCAPG ) diffg = -FILTCAPG;
thiscol = g + (difference/4);
thiscolg = g + (diffg/4);
if (thiscol < 0) thiscol = 0;
if (thiscol > 255) thiscol = 255;
if (thiscolg < 0) thiscolg = 0;
if (thiscolg > 255) thiscolg = 255;
thefilter[g][h] = thiscol;
thefilterg[g][h] = thiscolg;
}
lined = g + 1;
if (lined>24) lined = 24;
purpleline[g] = lined;
}
int vl, a = 1;
for (vl=0;vl<600;vl++)
{
a *= -1;
if (a == 1)
vline[vl] = 1;
else
vline[vl] = 0;
}
};
// leilei stuff end
static rgba_u rgb332[0x100], rgb565[0x10000], argb1555[0x10000], argb4444[0x10000];
Code: Select all
int scrfilter; /* leilei addition */
} voodoo_t;
Code: Select all
void voodoo_callback(void *p)
{
int line = 1;
voodoo_t *voodoo = (voodoo_t *)p;
voodoo->scrfilter = device_get_config_int("dacfilter");
if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS)
{
if (voodoo->line < voodoo->v_disp)
{
uint32_t *p = &((uint32_t *)buffer32->line[voodoo->line])[32];
uint16_t *src = (uint16_t *)&voodoo->fb_mem[voodoo->front_offset + voodoo->line*voodoo->row_width];
int x;
// leilei - dac screen filter, this is a messy hack with bad comment conventions
// a ton of it could be refactored, optimized, and vectorized
// this is just a rough initial implementation by trial and error
if (voodoo->scrfilter){
int j, offset;
unsigned rb[voodoo->h_disp];
unsigned gb[voodoo->h_disp];
unsigned bb[voodoo->h_disp];
for (j=0;j<4;j++) // we must do 4 passes of this
{
for (x = 0; x < voodoo->h_disp; x++)
{
int ren;
int r1,g1,b1;
int r2,g2,b2;
int rd,gd,bd;
if (j==0){
// initial buffer grab
rb[x] = src[x] & 31;
gb[x] = (src[x] >> 5) & 63;
bb[x] = (src[x] >> 11) & 31;
rb[x+1] = src[x+1] & 31;
gb[x+1] = (src[x+1] >> 5) & 63;
bb[x+1] = (src[x+1] >> 11) & 31;
// add lines
if (vline[voodoo->line] == 1){
rb[x] = purpleline[rb[x]];
bb[x] = purpleline[bb[x]];
rb[x+1] = purpleline[rb[x+1]];
bb[x+1] = purpleline[bb[x+1]];
}
}
// handle offset of 4x1, which is supposed to do 3 pixels to the right then one to the left
offset=1;
if (x>0 && j==3) offset=-1;
r1 = thefilter [rb[x]][rb[x+offset]];
g1 = thefilterg [gb[x]][gb[x+offset]];
b1 = thefilter [bb[x]][bb[x+offset]];
if (j==3){ // final buffer write
// TODO: Gamma
p[x] = (gammer[r1] << 3 | gammer[g1] << 10 | gammer[b1] << 19);
}
else // feedback filter linear passes
{
gb[x] = g1;
rb[x] = r1;
bb[x] = b1;
}
}
}
}
else
{
for (x = 0; x < voodoo->h_disp; x++)
{
p[x] = video_16to32[src[x]];
}
}
}
if (voodoo->line == voodoo->v_disp)
Code: Select all
voodoo_make_dither();
// leilei stuff
voodoo_generate_gamma(); // generate gamma lookup table
voodoo_generate_filter(); // generate filter lookup tables
pci_add(voodoo_pci_read, voodoo_pci_write, voodoo);
Code: Select all
.type = CONFIG_BINARY,
.default_int = 1
},
{
.name = "dacfilter",
.description = "Screen Filter",
.type = CONFIG_BINARY,
.default_int = 1
},
{
.type = -1
The line adding code is a bit troublesome and bad because it kept showing green for me, so the line effect isn't correct either
Re: 3DFX emulation
Posted: Sun 22 Mar, 2015 11:31 am
by SarahWalker
Rev 214 made some fairly major changes, so it might help.
If it doesn't, can you run it through GDB to get a backtrace?
Re: 3DFX emulation
Posted: Mon 23 Mar, 2015 1:30 am
by leilei
Latest revision still crashes Tomb Raider. I see two pixels on black before it does.
The Tomb Raider version i'm testing is the demo off the Diamond Monster3D disc which dates to 22 October 1996
I noticed Croc doesn't crash now though
Re: 3DFX emulation
Posted: Mon 23 Mar, 2015 9:10 pm
by SarahWalker
Rev 216 adds proper dithering, which might be of interest for the filter...
Re: 3DFX emulation
Posted: Wed 25 Mar, 2015 9:21 am
by Freddo
This is very cool
Anyone tried
Redguard to see how it runs?
Re: 3DFX emulation
Posted: Wed 25 Mar, 2015 6:43 pm
by SA1988
Have you guys tried Donald Duck Goin' Quackers for Windows 9x? It requires a Voodoo1 as a minimum 3D card but here it just stays black after initializing the resolutions (on PCem that is).
Re: 3DFX emulation
Posted: Wed 25 Mar, 2015 6:48 pm
by SarahWalker
You play some truly classy games SA1988.
Re: 3DFX emulation
Posted: Wed 25 Mar, 2015 6:50 pm
by SA1988
Well that game works perfectly under WinXP on VMware, but I thought of testing it on a Windows 95/98/ME guest on PCem would be quite retro :p
It originally came out in 2000 (between the releases of Windows 2000 and Windows ME to be precise) but also designed to work on Windows 95 and Windows 98 (including its Second Edition).
Re: 3DFX emulation
Posted: Mon 27 Apr, 2015 7:04 pm
by SarahWalker
Re: 3DFX emulation
Posted: Mon 27 Apr, 2015 10:27 pm
by leilei
I notice there's additional dither in the modulated muzzleflash plane of the pistol. Voodoo has a cutoff for that i think, though i don't know what its threshold is exactly. Also I don't know if this
Q3A "testing" mod will help with dither debugging, along with
these screenshots to compare with.
Turok has a texture color corruption bug when you have the filter off. Occurs with ARGB4444 textures
btw you're free to include my filter into the tree. Might need some comments and formatting altered here and there, and I can't think of any improvements to make to it at this point. except for the green line bug which i'm a little lost on anyhow, and i don't know any assembly or sse intrinsics to apply and I'm not sure about the performance improvement from using lookup tables.
Re: 3DFX emulation
Posted: Tue 28 Apr, 2015 7:11 pm
by SarahWalker
Fixed Turok in rev 231. One of these days I'll make a 3dfx commit that doesn't break it...
Re: 3DFX emulation
Posted: Wed 29 Apr, 2015 8:16 pm
by SarahWalker
Fixed Deus Ex dither in rev 232. Looks like the 4x4 dither pattern isn't good for blending.
Re: 3DFX emulation
Posted: Fri 01 May, 2015 8:46 pm
by leilei
More filter refactoring and improvement, fixed that green line thing (needed 31 instead of 24), and work with an interleaved thing
I'm very confused at this translating a pixel shader to cpu thing. I feel like i'm not getting enough precision to do this correctly, much of the dither is retained still :S and if it isn't, it'll streak to the right too much. It's like i'm trying to do it to a 16-bit buffer, but as far as I know I have converted it to a 24-bit buffer first?
lookup gen part
Code: Select all
#include <math.h>
int gammer[256]; // gamma correction lookup table
int thefilter[256][256]; // pixel filter, feeding from one or two
int thefilterg[256][256]; // pixel filter, feeding from one or two
void voodoo_generate_gamma(void)
{
int g, h, i;
float color;
int thiscol;
for (g=0;g<256;g++){
color = g / 255;
thiscol = pow(color, 1.7) * 255; // THIS DOES NOT WORK YET
thiscol = g; // so just use the plain color
if (thiscol > 255) thiscol = 255;
if (thiscol < 0) thiscol = 0;
gammer[g] = thiscol;
}
};
#define FILTCAP 2.0f
#define FILTCAPG (FILTCAP / 2)
int purpleline[256];
// test
int vline[600];
void voodoo_generate_filter(void)
{
int g, h, i;
float difference, diffg;
float color;
float thiscol, thiscolg, lined;
for (g=0;g<256;g++){ // pixel 1
for (h=0;h<256;h++){ // pixel 2
difference = h - g;
if (difference < 0) difference = 0; /* HACK: Remove ringing halo artifact */
diffg = difference;
if (difference > FILTCAP ) difference = FILTCAP;
if (difference < -FILTCAP ) difference = -FILTCAP;
if (diffg > FILTCAPG ) diffg = FILTCAPG;
if (diffg < -FILTCAPG ) diffg = -FILTCAPG;
thiscol = g + (difference / 2);
thiscolg = g + (diffg / 2);
if (thiscol < 0) thiscol = 0;
if (thiscol > 255) thiscol = 255;
if (thiscolg < 0) thiscolg = 0;
if (thiscolg > 255) thiscolg = 255;
thefilter[g][h] = thiscol;
thefilterg[g][h] = thiscolg;
}
lined = g + 1;
if (lined>31) lined = 31;
purpleline[g] = lined;
}
int vl, a = 1;
for (vl=0;vl<600;vl++)
{
a *= -1;
if (a == 1)
vline[vl] = 1;
else
vline[vl] = 0;
}
};
filter/callback part
Code: Select all
#define LOOKUP_FILTER
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
static voodoo_filterline(unsigned *fil, int column, int offset)
{
int x;
for (x=0; x<column-1;x++)
{
fil[x*3] = thefilter [fil[x*3]] [fil[(x+offset)*3]];
fil[x*3+1] = thefilterg [fil[x*3+1]] [fil[(x+offset)*3+1]];
fil[x*3+2] = thefilter [fil[x*3+2]] [fil[(x+offset)*3+2]];
}
};
void voodoo_callback(void *p)
{
voodoo_t *voodoo = (voodoo_t *)p;
if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS)
{
if (voodoo->line < voodoo->v_disp)
{
uint32_t *p = &((uint32_t *)buffer32->line[voodoo->line])[32];
uint16_t *src = (uint16_t *)&voodoo->fb_mem[voodoo->front_offset + voodoo->line*voodoo->row_width];
int x;
/* leilei - dac screen filter */
if (voodoo->scrfilter)
{
int j, offset;
unsigned fil[voodoo->h_disp * 3]; /* interleaved 24-bit RGB */
unsigned ail[voodoo->h_disp * 3]; /* interleaved 24-bit RGB */
for (j=0;j<5;j++)
{
for (x = 0; x < voodoo->h_disp; x++)
{
if (j==0) /* Grab from 16-bit buffer */
{
fil[x*3] = src[x] & 31;
fil[x*3+1] = (src[x] >> 5) & 63;
fil[x*3+2] = (src[x] >> 11) & 31;
if (vline[voodoo->line] == 1) /* Add alternating purple lines */
{
fil[x*3] = purpleline[fil[x*3]];
fil[x*3+2] = purpleline[fil[x*3+2]];
}
}
}
offset = 1;
voodoo_filterline(fil, voodoo->h_disp, offset);
}
for (x = 0; x < voodoo->h_disp; x++)
{
p[x] = (fil[x*3] << 3 | fil[x*3+1] << 10 | fil[x*3+2] << 19);
}
}
else
{
for (x = 0; x < voodoo->h_disp; x++)
{
p[x] = video_16to32[src[x]];
}
}
}
Non-PCem code follows: my initial C implementation of the shader in Q3's texture loader which doesn't have this weird precision issue
Code: Select all
scan = ((byte *)data);
int passes = 5;
int that;
#define FILTCAP (0.075 * 255)
#define FILTCAPG (FILTCAP / 2)
for (that=0;that<passes;that++){
for ( i = 0; i < c-1; i++ )
{
int ren;
int r1,g1,b1;
int r2,g2,b2;
int rd,gd,bd;
/* Grab Pixels to Sample From */
r1 = scan[i*4];
g1 = scan[i*4+1];
b1 = scan[i*4+2];
r2 = scan[(i+1)*4];
g2 = scan[(i+1)*4 + 1];
b2 = scan[(i+1)*4 + 2];
/* Find differences */
rd = r2 - r1;
gd = g2 - g1;
bd = b2 - b1;
if (rd > FILTCAP ) rd = FILTCAP;
if (gd > FILTCAPG) gd = FILTCAPG;
if (bd > FILTCAP ) bd = FILTCAP;
if (rd < -FILTCAP ) rd = -FILTCAP;
if (gd < -FILTCAPG) gd = -FILTCAPG;
if (bd < -FILTCAP ) bd = -FILTCAP;
/* Add our Differences */
r1 += (rd/3);
g1 += (gd/3);
b1 += (bd/3);
/* Obligatory clamping part */
if (r1 < 0) r1 = 0;
if (g1 < 0) g1 = 0;
if (b1 < 0) b1 = 0;
if (r1 > 255) r1 = 255;
if (g1 > 255) g1 = 255;
if (b1 > 255) b1 = 255;
if (r2 < 0) r2 = 0;
if (g2 < 0) g2 = 0;
if (b2 < 0) b2 = 0;
if (r2 > 255) r2 = 255;
if (g2 > 255) g2 = 255;
if (b2 > 255) b2 = 255;
/* Put processed image back into the buffer */
scan[i*4] = r1;
scan[i*4 + 1] = g1;
scan[i*4 + 2] = b1;
}
}
BTW what's the fastest way to test Glide? As in a DOS-based Voodoo demo that loads very quickly? (all the ones I know are for V2) It takes 3 minutes for me to get from compilation to 3dfx splash with Win98+Turok
Re: 3DFX emulation
Posted: Fri 01 May, 2015 9:16 pm
by SarahWalker
I used Trip (
http://www.pouet.net/prod.php?which=2844) as a quick DOS-based Glide test - it has a couple of bugs but is mostly okay, and can run from a clean boot. Tomb Raider and GTA also work well for this.
It's like i'm trying to do it to a 16-bit buffer, but as far as I know I have converted it to a 24-bit buffer first?
Maybe it would help to scale the extracted R/G/B components from 0-31/63 to 0-255? I might be missing something though, I haven't actually tried to run this yet.
Re: 3DFX emulation
Posted: Sat 02 May, 2015 3:16 am
by leilei
Ok i've scaled it, and also altered the buffer write to shift correctly to output so it's actually 24-bit now. The filter looks a lot closer to how i wanted it to be
There's still some precision issues though. it's not as smooth as it could be. compare a screenshot taken in Quake2 (written with 3dfxgl.dll's software filter) with a gamma 1.7'd printscreen capture on the same spot
Code: Select all
#include <math.h>
unsigned gamma_red[256]; // gamma correction lookup table for red
unsigned gamma_green[256]; // for green
unsigned gamma_blue[256]; // for blue
static uint8_t thefilter[256][256]; // pixel filter, feeding from one or two
static uint8_t thefilterg[256][256]; // for green
void voodoo_generate_gamma(void)
{
int g, h, i;
float color;
int thiscol;
float GAMMA_RED, GAMMA_GREEN, GAMMA_BLUE;
/* TODO: Read from 3dfx environment variables or whatever Glide provides. Default is 1.7 */
GAMMA_RED = 1.7f;
GAMMA_GREEN = 1.7f;
GAMMA_BLUE = 1.7f;
for (g=0;g<256;g++){
color = g;
thiscol = 255 * pow(g/255, GAMMA_RED);
if (thiscol > 255) thiscol = 255; if (thiscol < 0) thiscol = 0;
gamma_red[g] = thiscol;
thiscol = 255 * pow(g/255, GAMMA_GREEN);
if (thiscol > 255) thiscol = 255; if (thiscol < 0) thiscol = 0;
gamma_green[g] = thiscol;
thiscol = 255 * pow(g/255, GAMMA_BLUE);
if (thiscol > 255) thiscol = 255; if (thiscol < 0) thiscol = 0;
gamma_blue[g] = thiscol;
}
};
#define FILTCAP 16.0f /* Needs tuning to match DAC */
#define FILTCAPG (FILTCAP / 2)
uint8_t purpleline[256];
// test
uint8_t vline[600];
void voodoo_generate_filter(void)
{
int g, h, i;
float difference, diffg;
float color;
float thiscol, thiscolg, lined;
for (g=0;g<256;g++){ // pixel 1
for (h=0;h<256;h++){ // pixel 2
difference = h - g;
diffg = difference;
if (difference > FILTCAP ) difference = FILTCAP;
if (difference < -FILTCAP ) difference = -FILTCAP;
if (diffg > FILTCAPG ) diffg = FILTCAPG;
if (diffg < -FILTCAPG ) diffg = -FILTCAPG;
thiscol = g + (difference / 6); /* These two also need tuning */
thiscolg = g + (diffg / 6);
if (thiscol < 0) thiscol = 0;
if (thiscol > 255) thiscol = 255;
if (thiscolg < 0) thiscolg = 0;
if (thiscolg > 255) thiscolg = 255;
thefilter[g][h] = thiscol;
thefilterg[g][h] = thiscolg;
}
lined = g + 1;
if (lined>255) lined = 255;
purpleline[g] = lined;
}
int vl, a = 1;
for (vl=0;vl<600;vl++)
{
a *= -1;
if (a == 1)
vline[vl] = 1;
else
vline[vl] = 0;
}
};
filterline stuff
Code: Select all
static voodoo_filterline(uint8_t *fil, int column, int offset)
{
int x;
// hopefully i hope this will lead to less cache hits or something.
if (offset == 1)
for (x=0; x<column-1;x++)
{
fil[x*3] = thefilter [fil[x*3]] [fil[(x+1)*3]];
fil[x*3+1] = thefilterg [fil[x*3+1]] [fil[(x+1)*3+1]];
fil[x*3+2] = thefilter [fil[x*3+2]] [fil[(x+1)*3+2]];
}
else
for (x=1; x<column;x++)
{
fil[x*3] = thefilter [fil[x*3]] [fil[(x-1)*3]];
fil[x*3+1] = thefilterg [fil[x*3+1]] [fil[(x-1)*3+1]];
fil[x*3+2] = thefilter [fil[x*3+2]] [fil[(x-1)*3+2]];
}
};
callback stuff
Code: Select all
void voodoo_callback(void *p)
{
voodoo_t *voodoo = (voodoo_t *)p;
if (voodoo->fbiInit0 & FBIINIT0_VGA_PASS)
{
if (voodoo->line < voodoo->v_disp)
{
uint32_t *p = &((uint32_t *)buffer32->line[voodoo->line])[32];
uint16_t *src = (uint16_t *)&voodoo->fb_mem[voodoo->front_offset + voodoo->line*voodoo->row_width];
int x;
/* leilei - dac screen filter */
if (voodoo->scrfilter)
{
int j, offset;
uint8_t fil[voodoo->h_disp * 3]; /* interleaved 24-bit RGB */
for (j=0;j<5;j++)
{
for (x = 0; x < voodoo->h_disp; x++)
{
if (j==0){ /* Grab from 16-bit buffer */
/* Scale to meet */
fil[x*3] = (src[x] & 31) << 3;
fil[x*3+1] = ((src[x] >> 5) & 63) << 2;
fil[x*3+2] = ((src[x] >> 11) & 31) << 3;
if (vline[voodoo->line] == 1) /* Add alternating purple lines */
{
fil[x*3] = purpleline[fil[x*3]];
fil[x*3+2] = purpleline[fil[x*3+2]];
}
}
}
if (j==4) offset = 1; /* One pass shifts a pixel to the left. What order, i'm not sure */
else offset = -1;
voodoo_filterline(fil, voodoo->h_disp, offset);
}
for (x = 0; x < voodoo->h_disp; x++)
{
p[x] = (fil[x*3] << 0 | fil[x*3+1] << 8 | fil[x*3+2] << 16);
}
}
else
{
for (x = 0; x < voodoo->h_disp; x++)
{
p[x] = video_16to32[src[x]];
}
}
}
Re: 3DFX emulation
Posted: Mon 11 May, 2015 1:25 am
by Orchidsworn
Would love to see some examples of how the new mipmapping is looking. Either that or figure out how to compile this program for myself and give it a look.
Re: 3DFX emulation
Posted: Mon 11 May, 2015 7:02 pm
by SarahWalker
Without mipmapping:
- pcem_quake_nomipmap.png (332.73 KiB) Viewed 55156 times
With mipmapping:
- pcem_quake_mipmap.png (305.95 KiB) Viewed 55156 times
Re: 3DFX emulation
Posted: Tue 12 May, 2015 11:38 pm
by Orchidsworn
now that was a quick reply love the work. Thank you sir. Can't wait for your next release.
Re: 3DFX emulation
Posted: Thu 14 May, 2015 7:51 am
by leilei
For fun I tried getting my OA3 WIP working in there. It adds paletted texture extension support (same implementation as
this) and processes alpha channels into a paletted alpha texture. On Voodoo Graphics it'll need a MesaFX DLL for it to work (thanks sdl :/)
However I notice that there's a bug that the alpha doesn't work. Don't know if it's the driver's end, emulation end or not. apart from that alpha bug, everything looks okay.
On an actual Voodoo2 the paletted alpha stuff works with the January 2000 3dfx GL ICD driver. I don't have an actual Voodoo Graphics to check this.
Re: 3DFX emulation
Posted: Thu 14 May, 2015 7:38 pm
by SarahWalker
I fixed an alpha bug in rev 243, maybe try again?
Re: 3DFX emulation
Posted: Thu 14 May, 2015 9:56 pm
by leilei
Doesn't fix it in the latest rev.
Here's a screenshot showing r_ext_paletted_texture 1, r_textureBits 8 on MesaFX V0.6.2.0.2 in Q3V
The paletted alpha does work on nGlide, but that pretends as a Voodoo5, and I still don't know if this artifact is actual Voodoo Graphics behavior
Another bug I was going to mention was MDK2 (4.001) getting stuck at a black screen unable to fade in after loading, however I reproduced this with a software GL ICD (SGI OpenGL 1.1) and happens in the interpreter so i'm guessing that's a CPU bug.
Re: 3DFX emulation
Posted: Tue 19 May, 2015 9:09 am
by leilei
Dunno if known or not, Half-Life 1.0.1.5 in OpenGL mode (3dfx Mini Driver) screws up similar to Spectre VR. Also the uvmapping of chrome stuff is messed up (see hand)
Latest rev with fpu copy, Pentium 120Mhz, A lot cache, 128mb, Voodoo 4mb 4mb, Win98se
I should mention I compiled with -march=amdfam10, don't know if that's a factor in anything.
Re: 3DFX emulation
Posted: Sun 31 May, 2015 11:41 am
by startmenu
Tomb Raider (using X:\PATCHES\3DFX\TOMB.EXE ) hangs when callin' the menu (by hittin' ESC) during the game play while the normal TOMB.EXE won't. That is, the emulation hangs but you can access the emulator's menu, of course, with no command working, including hard reset...
I also tested the \PATCHES\3DFX\TOMB.EXE under DOSBox(with 3dfx patch). It doesn't have this issue.
Re: 3DFX emulation
Posted: Sun 31 May, 2015 3:49 pm
by SarahWalker
Fixed in rev 253.
Re: 3DFX emulation
Posted: Wed 03 Jun, 2015 8:25 pm
by SarahWalker
Re: 3DFX emulation
Posted: Wed 03 Jun, 2015 10:58 pm
by amadama
That is more impressive than I expected.
What are the specs of the host machine?