Moved VGA-emulating DirectX code from dispdib.c to a separate
file. Made it use a system timer and trap I/O accesses to the VGA DAC registers to accommodate DisplayDib-using programs that try to access the VGA hardware directly.
This commit is contained in:
parent
7f740cbb04
commit
1499a845ff
|
@ -17,6 +17,7 @@ C_SRCS = \
|
|||
mapping.c \
|
||||
painting.c \
|
||||
path.c \
|
||||
vga.c \
|
||||
wing.c
|
||||
|
||||
all: $(MODULE).o
|
||||
|
|
|
@ -7,17 +7,12 @@
|
|||
|
||||
#include <string.h>
|
||||
#include "windows.h"
|
||||
#include "miscemu.h"
|
||||
#include "dispdib.h"
|
||||
#include "compobj.h"
|
||||
#include "interfaces.h"
|
||||
#include "ddraw.h"
|
||||
#include "vga.h"
|
||||
#include "debug.h"
|
||||
|
||||
static int dispdib_multi = 0;
|
||||
static IDirectDraw *lpddraw = NULL;
|
||||
static IDirectDrawSurface *lpddsurf;
|
||||
static IDirectDrawPalette *lpddpal;
|
||||
static DDSURFACEDESC sdesc;
|
||||
|
||||
static WORD DISPDIB_Begin(WORD wFlags)
|
||||
{
|
||||
|
@ -33,60 +28,28 @@ static WORD DISPDIB_Begin(WORD wFlags)
|
|||
default:
|
||||
return DISPLAYDIB_NOTSUPPORTED;
|
||||
}
|
||||
if (!lpddraw) {
|
||||
DirectDrawCreate(NULL,&lpddraw,NULL);
|
||||
if (!lpddraw) {
|
||||
ERR(ddraw,"DirectDraw is not available\n");
|
||||
return DISPLAYDIB_NOTSUPPORTED;
|
||||
}
|
||||
if (lpddraw->lpvtbl->fnSetDisplayMode(lpddraw,Xres,Yres,Depth)) {
|
||||
ERR(ddraw,"DirectDraw does not support requested display mode\n");
|
||||
lpddraw->lpvtbl->fnRelease(lpddraw);
|
||||
return DISPLAYDIB_NOTSUPPORTED;
|
||||
}
|
||||
lpddraw->lpvtbl->fnCreatePalette(lpddraw,0,NULL,&lpddpal,NULL);
|
||||
memset(&sdesc,0,sizeof(sdesc));
|
||||
sdesc.dwSize=sizeof(sdesc);
|
||||
lpddraw->lpvtbl->fnCreateSurface(lpddraw,&sdesc,&lpddsurf,NULL);
|
||||
}
|
||||
if (VGA_SetMode(Xres,Yres,Depth)) return DISPLAYDIB_NOTSUPPORTED;
|
||||
return DISPLAYDIB_NOERROR;
|
||||
}
|
||||
|
||||
static void DISPDIB_End(void)
|
||||
{
|
||||
if (lpddraw) {
|
||||
lpddsurf->lpvtbl->fnRelease(lpddsurf);
|
||||
lpddraw->lpvtbl->fnRelease(lpddraw);
|
||||
lpddraw=NULL;
|
||||
}
|
||||
VGA_Exit();
|
||||
}
|
||||
|
||||
static void DISPDIB_Palette(LPBITMAPINFO lpbi)
|
||||
{
|
||||
PALETTEENTRY pal[256];
|
||||
int c;
|
||||
|
||||
for (c=0; c<256; c++) {
|
||||
pal[c].peRed =lpbi->bmiColors[c].rgbRed;
|
||||
pal[c].peGreen=lpbi->bmiColors[c].rgbGreen;
|
||||
pal[c].peBlue =lpbi->bmiColors[c].rgbBlue;
|
||||
pal[c].peFlags=0;
|
||||
}
|
||||
lpddpal->lpvtbl->fnSetEntries(lpddpal,0,0,256,pal);
|
||||
lpddsurf->lpvtbl->fnSetPalette(lpddsurf,lpddpal);
|
||||
VGA_SetQuadPalette(lpbi->bmiColors,0,256);
|
||||
}
|
||||
|
||||
static void DISPDIB_Show(LPBITMAPINFOHEADER lpbi,LPSTR lpBits,WORD uFlags)
|
||||
{
|
||||
int Xofs,Yofs,Width=lpbi->biWidth,Height=lpbi->biHeight,Delta;
|
||||
unsigned Pitch=(Width+3)&~3;
|
||||
LPSTR surf;
|
||||
unsigned Pitch=(Width+3)&~3,sPitch,sWidth,sHeight;
|
||||
LPSTR surf = DOSMEM_MapDosToLinear(0xa0000);
|
||||
|
||||
if (lpddsurf->lpvtbl->fnLock(lpddsurf,NULL,&sdesc,0,0)) {
|
||||
ERR(ddraw,"could not lock surface!\n");
|
||||
return;
|
||||
}
|
||||
/* size in sdesc.dwHeight, sdesc.dwWidth, pitch in sdesc.lPitch, ptr in sdesc.y.lpSurface */
|
||||
if (VGA_GetMode(&sHeight,&sWidth,NULL)) return;
|
||||
sPitch=320;
|
||||
|
||||
Delta=(Height<0)*2-1;
|
||||
Height*=-Delta; Pitch*=Delta;
|
||||
|
@ -94,16 +57,16 @@ static void DISPDIB_Show(LPBITMAPINFOHEADER lpbi,LPSTR lpBits,WORD uFlags)
|
|||
if (uFlags&DISPLAYDIB_NOCENTER) {
|
||||
Xofs=0; Yofs=0;
|
||||
} else {
|
||||
Xofs=(sdesc.dwWidth-Width)/2;
|
||||
Yofs=(sdesc.dwHeight-Height)/2;
|
||||
Xofs=(sWidth-Width)/2;
|
||||
Yofs=(sHeight-Height)/2;
|
||||
}
|
||||
surf=(LPSTR)sdesc.y.lpSurface + (Yofs*sdesc.lPitch)+Xofs;
|
||||
surf += (Yofs*sPitch)+Xofs;
|
||||
if (Pitch<0) lpBits-=Pitch*(Height-1);
|
||||
for (; Height; Height--,lpBits+=Pitch,surf+=sdesc.lPitch) {
|
||||
for (; Height; Height--,lpBits+=Pitch,surf+=sPitch) {
|
||||
memcpy(surf,lpBits,Width);
|
||||
}
|
||||
|
||||
lpddsurf->lpvtbl->fnUnlock(lpddsurf,sdesc.y.lpSurface);
|
||||
VGA_Poll();
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* VGA hardware emulation
|
||||
*
|
||||
* Copyright 1998 Ove Kåven (with some help from Marcus Meissner)
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "windows.h"
|
||||
#include "winbase.h"
|
||||
#include "miscemu.h"
|
||||
#include "vga.h"
|
||||
#include "compobj.h"
|
||||
#include "interfaces.h"
|
||||
#include "ddraw.h"
|
||||
#include "debug.h"
|
||||
|
||||
static IDirectDraw *lpddraw = NULL;
|
||||
static IDirectDrawSurface *lpddsurf;
|
||||
static IDirectDrawPalette *lpddpal;
|
||||
static DDSURFACEDESC sdesc;
|
||||
static WORD poll_timer;
|
||||
static CRITICAL_SECTION vga_crit;
|
||||
static int vga_polling;
|
||||
|
||||
int VGA_SetMode(unsigned Xres,unsigned Yres,unsigned Depth)
|
||||
{
|
||||
if (lpddraw) VGA_Exit();
|
||||
if (!lpddraw) {
|
||||
DirectDrawCreate(NULL,&lpddraw,NULL);
|
||||
if (!lpddraw) {
|
||||
ERR(ddraw,"DirectDraw is not available\n");
|
||||
return 1;
|
||||
}
|
||||
if (lpddraw->lpvtbl->fnSetDisplayMode(lpddraw,Xres,Yres,Depth)) {
|
||||
ERR(ddraw,"DirectDraw does not support requested display mode\n");
|
||||
lpddraw->lpvtbl->fnRelease(lpddraw);
|
||||
lpddraw=NULL;
|
||||
return 1;
|
||||
}
|
||||
lpddraw->lpvtbl->fnCreatePalette(lpddraw,0,NULL,&lpddpal,NULL);
|
||||
memset(&sdesc,0,sizeof(sdesc));
|
||||
sdesc.dwSize=sizeof(sdesc);
|
||||
if (lpddraw->lpvtbl->fnCreateSurface(lpddraw,&sdesc,&lpddsurf,NULL)||(!lpddsurf)) {
|
||||
ERR(ddraw,"DirectDraw surface is not available\n");
|
||||
lpddraw->lpvtbl->fnRelease(lpddraw);
|
||||
lpddraw=NULL;
|
||||
return 1;
|
||||
}
|
||||
InitializeCriticalSection(&vga_crit);
|
||||
/* poll every 20ms (50fps should provide adequate responsiveness) */
|
||||
poll_timer = CreateSystemTimer( 20, (FARPROC16)VGA_Poll );
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int VGA_GetMode(unsigned*Height,unsigned*Width,unsigned*Depth)
|
||||
{
|
||||
if (!lpddraw) return 1;
|
||||
if (!lpddsurf) return 1;
|
||||
if (Height) *Height=sdesc.dwHeight;
|
||||
if (Width) *Width=sdesc.dwWidth;
|
||||
if (Depth) *Depth=sdesc.ddpfPixelFormat.x.dwRGBBitCount;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void VGA_Exit(void)
|
||||
{
|
||||
if (lpddraw) {
|
||||
SYSTEM_KillSystemTimer(poll_timer);
|
||||
DeleteCriticalSection(&vga_crit);
|
||||
lpddsurf->lpvtbl->fnRelease(lpddsurf);
|
||||
lpddsurf=NULL;
|
||||
lpddraw->lpvtbl->fnRelease(lpddraw);
|
||||
lpddraw=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void VGA_SetPalette(PALETTEENTRY*pal,int start,int len)
|
||||
{
|
||||
if (!lpddraw) return;
|
||||
lpddpal->lpvtbl->fnSetEntries(lpddpal,0,start,len,pal);
|
||||
lpddsurf->lpvtbl->fnSetPalette(lpddsurf,lpddpal);
|
||||
}
|
||||
|
||||
void VGA_SetQuadPalette(RGBQUAD*color,int start,int len)
|
||||
{
|
||||
PALETTEENTRY pal[256];
|
||||
int c;
|
||||
|
||||
if (!lpddraw) return;
|
||||
for (c=0; c<len; c++) {
|
||||
pal[c].peRed =color[c].rgbRed;
|
||||
pal[c].peGreen=color[c].rgbGreen;
|
||||
pal[c].peBlue =color[c].rgbBlue;
|
||||
pal[c].peFlags=0;
|
||||
}
|
||||
lpddpal->lpvtbl->fnSetEntries(lpddpal,0,start,len,pal);
|
||||
lpddsurf->lpvtbl->fnSetPalette(lpddsurf,lpddpal);
|
||||
}
|
||||
|
||||
LPSTR VGA_Lock(unsigned*Pitch,unsigned*Height,unsigned*Width,unsigned*Depth)
|
||||
{
|
||||
if (!lpddraw) return NULL;
|
||||
if (!lpddsurf) return NULL;
|
||||
if (lpddsurf->lpvtbl->fnLock(lpddsurf,NULL,&sdesc,0,0)) {
|
||||
ERR(ddraw,"could not lock surface!\n");
|
||||
return NULL;
|
||||
}
|
||||
if (Pitch) *Pitch=sdesc.lPitch;
|
||||
if (Height) *Height=sdesc.dwHeight;
|
||||
if (Width) *Width=sdesc.dwWidth;
|
||||
if (Depth) *Depth=sdesc.ddpfPixelFormat.x.dwRGBBitCount;
|
||||
return sdesc.y.lpSurface;
|
||||
}
|
||||
|
||||
void VGA_Unlock(void)
|
||||
{
|
||||
lpddsurf->lpvtbl->fnUnlock(lpddsurf,sdesc.y.lpSurface);
|
||||
}
|
||||
|
||||
void VGA_Poll(void)
|
||||
{
|
||||
char *dat;
|
||||
unsigned Pitch,Height,Width;
|
||||
char *surf;
|
||||
int Y,X;
|
||||
|
||||
EnterCriticalSection(&vga_crit);
|
||||
if (!vga_polling) {
|
||||
vga_polling++;
|
||||
LeaveCriticalSection(&vga_crit);
|
||||
/* FIXME: optimize by doing this only if the data has actually changed
|
||||
* (in a way similar to DIBSection, perhaps) */
|
||||
surf = VGA_Lock(&Pitch,&Height,&Width,NULL);
|
||||
if (!surf) return;
|
||||
dat = DOSMEM_MapDosToLinear(0xa0000);
|
||||
/* copy from virtual VGA frame buffer to DirectDraw surface */
|
||||
for (Y=0; Y<Height; Y++,surf+=Pitch,dat+=Width) {
|
||||
memcpy(surf,dat,Width);
|
||||
for (X=0; X<Width; X++) if (dat[X]) TRACE(ddraw,"data(%d) at (%d,%d)\n",dat[X],X,Y);
|
||||
}
|
||||
VGA_Unlock();
|
||||
EnterCriticalSection(&vga_crit);
|
||||
vga_polling--;
|
||||
}
|
||||
LeaveCriticalSection(&vga_crit);
|
||||
}
|
||||
|
||||
static BYTE palreg,palcnt;
|
||||
static PALETTEENTRY paldat;
|
||||
|
||||
void VGA_ioport_out( WORD port, BYTE val )
|
||||
{
|
||||
switch (port) {
|
||||
case 0x3c8:
|
||||
palreg=val; palcnt=0; break;
|
||||
case 0x3c9:
|
||||
((BYTE*)&paldat)[palcnt++]=val << 2;
|
||||
if (palcnt==3) {
|
||||
VGA_SetPalette(&paldat,palreg,1);
|
||||
palreg++;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* VGA emulation
|
||||
*
|
||||
* Copyright 1998 Ove KÅven
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __WINE_VGA_H
|
||||
#define __WINE_VGA_H
|
||||
|
||||
#include "wintypes.h"
|
||||
|
||||
int VGA_SetMode(unsigned Xres,unsigned Yres,unsigned Depth);
|
||||
int VGA_GetMode(unsigned*Height,unsigned*Width,unsigned*Depth);
|
||||
void VGA_Exit(void);
|
||||
void VGA_SetPalette(PALETTEENTRY*pal,int start,int len);
|
||||
void VGA_SetQuadPalette(RGBQUAD*color,int start,int len);
|
||||
LPSTR VGA_Lock(unsigned*Pitch,unsigned*Height,unsigned*Width,unsigned*Depth);
|
||||
void VGA_Unlock(void);
|
||||
void VGA_Poll(void);
|
||||
void VGA_ioport_out(WORD port, BYTE val);
|
||||
|
||||
#endif /* __WINE_VGA_H */
|
|
@ -16,6 +16,7 @@
|
|||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include "windows.h"
|
||||
#include "vga.h"
|
||||
#include "options.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
@ -234,6 +235,10 @@ DWORD IO_inport( int port, int count )
|
|||
case 0x71:
|
||||
b = cmosimage[cmosaddress & 0x3f];
|
||||
break;
|
||||
case 0x200:
|
||||
case 0x201:
|
||||
b = 0xff; /* no joystick */
|
||||
break;
|
||||
default:
|
||||
WARN( int, "Direct I/O read attempted from port %x\n", port);
|
||||
b = 0xff;
|
||||
|
@ -293,6 +298,10 @@ void IO_outport( int port, int count, DWORD value )
|
|||
case 0x71:
|
||||
cmosimage[cmosaddress & 0x3f] = b;
|
||||
break;
|
||||
case 0x3c8:
|
||||
case 0x3c9:
|
||||
VGA_ioport_out( port, b );
|
||||
break;
|
||||
default:
|
||||
WARN(int, "Direct I/O write attempted to port %x\n", port );
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue