Direct3D video output. Fixed redraw when DirectDraw/Direct3D device is lost.

This commit is contained in:
TomW 2013-08-13 19:20:28 +01:00
commit 72f934d141
43 changed files with 528 additions and 192 deletions

View file

@ -18,12 +18,12 @@ OBJ = 386.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o \
vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o vid_s3.o \
vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o vid_svga_render.o \
vid_tandy.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o \
vid_voodoo.o video.o wd76c10.o win.o win-ddraw.o win-keyboard.o win-midi.o \
vid_voodoo.o video.o wd76c10.o win.o win-d3d.o win-ddraw.o win-keyboard.o win-midi.o \
win-mouse.o win-timer.o win-video.o x86seg.o x87.o xtide.o pc.res
FMOBJ = fmopl.o ymf262.o
LIBS = -mwindows -lwinmm -lalut -lopenal32 -lddraw -ldinput -ldxguid
LIBS = -mwindows -lwinmm -lalut -lopenal32 -lddraw -ldinput -ldxguid -ld3d9
PCem.exe: $(OBJ) $(FMOBJ)
$(CC) $(OBJ) $(FMOBJ) -o "PCem.exe" $(LIBS)

View file

@ -58,6 +58,22 @@ void device_speed_changed()
}
}
void device_force_redraw()
{
int c;
for (c = 0; c < 256; c++)
{
if (devices[c] != NULL)
{
if (devices[c]->force_redraw != NULL)
{
devices[c]->force_redraw(device_priv[c]);
}
}
}
}
char *device_add_status_info(char *s, int max_len)
{
int c;

View file

@ -4,6 +4,7 @@ typedef struct device_t
void *(*init)();
void (*close)(void *p);
void (*speed_changed)(void *p);
void (*force_redraw)(void *p);
int (*add_status_info)(char *s, int max_len, void *p);
} device_t;
@ -11,4 +12,5 @@ void device_init();
void device_add(device_t *d);
void device_close_all();
void device_speed_changed();
void device_force_redraw();
char *device_add_status_info(char *s, int max_len);

View file

@ -367,6 +367,7 @@ extern uint8_t gdcreg[16];
extern int egareads,egawrites;
extern int cga_comp;
extern int vid_resize;
extern int vid_api;
extern int winsizex,winsizey;
extern int chain4;

View file

@ -35,7 +35,7 @@ int frame = 0;
int cdrom_enabled;
int CPUID;
int kb_win;
int vid_resize;
int vid_resize, vid_api;
int cycles_lost = 0;
@ -203,7 +203,6 @@ void initpc()
atfullspeed=0;
device_init();
pclog("Initvideo\n");
initvideo();
mem_init();
@ -264,7 +263,6 @@ void resetpchard()
mem_resize();
fdc_init();
model_init();
pclog("Video_init\n");
video_init();
speaker_init();
sound_card_init(sound_card_current);
@ -312,6 +310,8 @@ void runpc()
{
char s[200];
int done=0;
startblit();
clockrate = models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed;
if (is386) exec386(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100);
else if (AT) exec386(models[model].cpu[cpu_manufacturer].cpus[cpu].rspeed / 100);
@ -320,6 +320,8 @@ void runpc()
keyboard_process();
// checkkeys();
pollmouse();
endblit();
framecountx++;
framecount++;
if (framecountx>=100)
@ -461,6 +463,7 @@ void loadconfig()
kb_win = get_config_int(NULL, "kb_win", 0);
vid_resize = get_config_int(NULL, "vid_resize", 0);
vid_api = get_config_int(NULL, "vid_api", 0);
hdc[0].spt = get_config_int(NULL, "hdc_sectors", 0);
hdc[0].hpc = get_config_int(NULL, "hdc_heads", 0);
@ -501,6 +504,7 @@ void saveconfig()
set_config_int(NULL, "cdrom_enabled", cdrom_enabled);
set_config_int(NULL, "kb_win", kb_win);
set_config_int(NULL, "vid_resize", vid_resize);
set_config_int(NULL, "vid_api", vid_api);
set_config_int(NULL, "hdc_sectors", hdc[0].spt);
set_config_int(NULL, "hdc_heads", hdc[0].hpc);

View file

@ -27,6 +27,9 @@ BEGIN
POPUP "&Video"
BEGIN
MENUITEM "&Resizeable window",IDM_VID_RESIZE
MENUITEM SEPARATOR
MENUITEM "&DirectDraw", IDM_VID_DDRAW
MENUITEM "Direct&3D", IDM_VID_D3D
END
END
POPUP "&Misc"

View file

@ -11,6 +11,8 @@
#define IDM_KEY_ALLEGRO 40040
#define IDM_KEY_WINDOWS 40041
#define IDM_VID_RESIZE 40050
#define IDM_VID_DDRAW 40060
#define IDM_VID_D3D 40061
#define IDM_CDROM_EMPTY 40100
#define IDM_CDROM_REAL 40100
#define IDM_CDROM_DISABLED 40200
@ -57,3 +59,5 @@
#define IDC_STEXT7 1106
#define IDC_STEXT8 1107
#define IDC_STEXT_DEVICE 1108
#define WM_RESETD3D WM_USER

View file

@ -133,5 +133,6 @@ device_t sis496_device =
sis496_init,
sis496_close,
NULL,
NULL,
NULL
};

View file

@ -59,5 +59,6 @@ device_t adlib_device =
adlib_init,
adlib_close,
NULL,
NULL,
NULL
};

View file

@ -594,5 +594,6 @@ device_t adgold_device =
adgold_init,
adgold_close,
NULL,
NULL,
NULL
};

View file

@ -176,5 +176,6 @@ device_t cms_device =
cms_init,
cms_close,
NULL,
NULL,
NULL
};

View file

@ -1104,5 +1104,6 @@ device_t gus_device =
gus_init,
gus_close,
gus_speed_changed,
NULL,
NULL
};

View file

@ -750,5 +750,6 @@ device_t pas16_device =
pas16_init,
pas16_close,
NULL,
NULL,
NULL
};

View file

@ -430,6 +430,7 @@ device_t sb_1_device =
sb_1_init,
sb_close,
sb_speed_changed,
NULL,
NULL
};
device_t sb_15_device =
@ -438,6 +439,7 @@ device_t sb_15_device =
sb_15_init,
sb_close,
sb_speed_changed,
NULL,
NULL
};
device_t sb_2_device =
@ -446,6 +448,7 @@ device_t sb_2_device =
sb_2_init,
sb_close,
sb_speed_changed,
NULL,
NULL
};
device_t sb_pro_v1_device =
@ -454,6 +457,7 @@ device_t sb_pro_v1_device =
sb_pro_v1_init,
sb_close,
sb_speed_changed,
NULL,
NULL
};
device_t sb_pro_v2_device =
@ -462,6 +466,7 @@ device_t sb_pro_v2_device =
sb_pro_v2_init,
sb_close,
sb_speed_changed,
NULL,
NULL
};
device_t sb_16_device =
@ -470,6 +475,7 @@ device_t sb_16_device =
sb_16_init,
sb_close,
sb_speed_changed,
NULL,
NULL
};
device_t sb_awe32_device =
@ -478,5 +484,6 @@ device_t sb_awe32_device =
sb_awe32_init,
sb_close,
sb_speed_changed,
NULL,
NULL
};

View file

@ -195,5 +195,6 @@ device_t sn76489_device =
sn76489_init,
sn76489_close,
NULL,
NULL,
NULL
};

View file

@ -304,5 +304,6 @@ device_t wss_device =
wss_init,
wss_close,
NULL,
NULL,
NULL
};

View file

@ -152,12 +152,20 @@ void ati18800_speed_changed(void *p)
svga_recalctimings(&ati18800->svga);
}
void ati18800_force_redraw(void *p)
{
ati18800_t *ati18800 = (ati18800_t *)p;
ati18800->svga.fullchange = changeframecount;
}
device_t ati18800_device =
{
"ATI-18800",
ati18800_init,
ati18800_close,
ati18800_speed_changed,
ati18800_force_redraw,
svga_add_status_info
};

View file

@ -173,11 +173,19 @@ void ati28800_speed_changed(void *p)
svga_recalctimings(&ati28800->svga);
}
void ati28800_force_redraw(void *p)
{
ati28800_t *ati28800 = (ati28800_t *)p;
ati28800->svga.fullchange = changeframecount;
}
device_t ati28800_device =
{
"ATI-28800",
ati28800_init,
ati28800_close,
ati28800_speed_changed,
ati28800_force_redraw,
svga_add_status_info
};

View file

@ -1848,11 +1848,19 @@ void mach64_speed_changed(void *p)
svga_recalctimings(&mach64->svga);
}
void mach64_force_redraw(void *p)
{
mach64_t *mach64 = (mach64_t *)p;
mach64->svga.fullchange = changeframecount;
}
device_t mach64gx_device =
{
"ATI Mach64GX",
mach64gx_init,
mach64_close,
mach64_speed_changed,
mach64_force_redraw,
svga_add_status_info
};

View file

@ -523,5 +523,6 @@ device_t cga_device =
cga_standalone_init,
cga_close,
cga_speed_changed,
NULL,
NULL
};

View file

@ -834,11 +834,19 @@ void gd5429_speed_changed(void *p)
svga_recalctimings(&gd5429->svga);
}
void gd5429_force_redraw(void *p)
{
gd5429_t *gd5429 = (gd5429_t *)p;
gd5429->svga.fullchange = changeframecount;
}
device_t gd5429_device =
{
"Cirrus Logic GD5429",
gd5429_init,
gd5429_close,
gd5429_speed_changed,
gd5429_force_redraw,
svga_add_status_info
};

View file

@ -840,5 +840,6 @@ device_t ega_device =
ega_standalone_init,
ega_close,
ega_speed_changed,
NULL,
NULL
};

View file

@ -146,11 +146,19 @@ void et4000_speed_changed(void *p)
svga_recalctimings(&et4000->svga);
}
void et4000_force_redraw(void *p)
{
et4000_t *et4000 = (et4000_t *)p;
et4000->svga.fullchange = changeframecount;
}
device_t et4000_device =
{
"Tseng Labs ET4000AX",
et4000_init,
et4000_close,
et4000_speed_changed,
et4000_force_redraw,
svga_add_status_info
};

View file

@ -965,11 +965,19 @@ void et4000w32p_speed_changed(void *p)
svga_recalctimings(&et4000->svga);
}
void et4000w32p_force_redraw(void *p)
{
et4000w32p_t *et4000w32p = (et4000w32p_t *)p;
et4000w32p->svga.fullchange = changeframecount;
}
device_t et4000w32p_device =
{
"Tseng Labs ET4000/w32p",
et4000w32p_init,
et4000w32p_close,
et4000w32p_speed_changed,
et4000w32p_force_redraw,
svga_add_status_info
};

View file

@ -354,5 +354,6 @@ device_t hercules_device =
hercules_init,
hercules_close,
hercules_speed_changed,
NULL,
NULL
};

View file

@ -312,5 +312,6 @@ device_t mda_device =
mda_init,
mda_close,
mda_speed_changed,
NULL,
NULL
};

View file

@ -483,5 +483,6 @@ device_t m24_device =
m24_init,
m24_close,
m24_speed_changed,
NULL,
NULL
};

View file

@ -141,11 +141,19 @@ void oti067_speed_changed(void *p)
svga_recalctimings(&oti067->svga);
}
void oti067_force_redraw(void *p)
{
oti067_t *oti067 = (oti067_t *)p;
oti067->svga.fullchange = changeframecount;
}
device_t oti067_device =
{
"Oak OTI-067",
oti067_init,
oti067_close,
oti067_speed_changed,
oti067_force_redraw,
svga_add_status_info
};

View file

@ -319,12 +319,20 @@ void paradise_speed_changed(void *p)
svga_recalctimings(&paradise->svga);
}
void paradise_force_redraw(void *p)
{
paradise_t *paradise = (paradise_t *)p;
paradise->svga.fullchange = changeframecount;
}
device_t paradise_pvga1a_device =
{
"Paradise PVGA1A",
paradise_pvga1a_init,
paradise_close,
paradise_speed_changed,
paradise_force_redraw,
svga_add_status_info
};
device_t paradise_wd90c11_device =
@ -333,5 +341,6 @@ device_t paradise_wd90c11_device =
paradise_wd90c11_init,
paradise_close,
paradise_speed_changed,
paradise_force_redraw,
svga_add_status_info
};

View file

@ -482,5 +482,6 @@ device_t pc1512_device =
pc1512_init,
pc1512_close,
pc1512_speed_changed,
NULL,
NULL
};

View file

@ -141,5 +141,6 @@ device_t pc1640_device =
pc1640_init,
pc1640_close,
pc1640_speed_changed,
NULL,
NULL
};

View file

@ -135,5 +135,6 @@ device_t pc200_device =
pc200_init,
pc200_close,
pc200_speed_changed,
NULL,
NULL
};

View file

@ -1605,12 +1605,20 @@ void s3_speed_changed(void *p)
svga_recalctimings(&s3->svga);
}
void s3_force_redraw(void *p)
{
s3_t *s3 = (s3_t *)p;
s3->svga.fullchange = changeframecount;
}
device_t s3_bahamas64_device =
{
"Paradise Bahamas 64 (S3 Vision864)",
s3_bahamas64_init,
s3_close,
s3_speed_changed,
s3_force_redraw,
svga_add_status_info
};
@ -1620,5 +1628,6 @@ device_t s3_9fx_device =
s3_9fx_init,
s3_close,
s3_speed_changed,
s3_force_redraw,
svga_add_status_info
};

View file

@ -490,11 +490,19 @@ void s3_virge_speed_changed(void *p)
svga_recalctimings(&virge->svga);
}
void s3_virge_force_redraw(void *p)
{
virge_t *virge = (virge_t *)p;
virge->svga.fullchange = changeframecount;
}
device_t s3_virge_device =
{
"Diamond Stealth 3D 2000 (S3 VIRGE)",
s3_virge_init,
s3_virge_close,
s3_virge_speed_changed,
s3_virge_force_redraw,
svga_add_status_info
};

View file

@ -1116,16 +1116,15 @@ uint8_t svga_read_linear(uint32_t addr, void *p)
void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga)
{
pclog("svga_doblit start\n");
svga->frames++;
// pclog("doblit %i %i\n", y1, y2);
if (y1 > y2)
{
startblit();
video_blit_memtoscreen(32, 0, 0, 0, xsize, ysize);
endblit();
return;
}
startblit();
if ((wx!=xsize || wy!=ysize) && !vid_resize)
{
xsize=wx;
@ -1141,9 +1140,8 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga)
ysize = wy + 1;
}
video_blit_memtoscreen(32, 0, y1, y2, xsize, ysize);
if (readflash) rectfill(screen,winsizex-40,8,winsizex-8,14,0xFFFFFFFF);
endblit();
if (readflash) rectfill(screen,winsizex-40,8,winsizex-8,14,0xFFFFFFFF);
pclog("svga_doblit end\n");
}
void svga_writew(uint32_t addr, uint16_t val, void *p)

View file

@ -692,5 +692,6 @@ device_t tandy_device =
tandy_init,
tandy_close,
tandy_speed_changed,
NULL,
NULL
};

View file

@ -420,12 +420,20 @@ void tvga_speed_changed(void *p)
svga_recalctimings(&tvga->svga);
}
void tvga_force_redraw(void *p)
{
tvga_t *tvga = (tvga_t *)p;
tvga->svga.fullchange = changeframecount;
}
device_t tvga8900d_device =
{
"Trident TVGA 8900D",
tvga8900d_init,
tvga_close,
tvga_speed_changed,
tvga_force_redraw,
svga_add_status_info
};
device_t tgui9440_device =
@ -434,6 +442,7 @@ device_t tgui9440_device =
tgui9440_init,
tvga_close,
tvga_speed_changed,
tvga_force_redraw,
svga_add_status_info
};

View file

@ -106,11 +106,19 @@ void vga_speed_changed(void *p)
svga_recalctimings(&vga->svga);
}
void vga_force_redraw(void *p)
{
vga_t *vga = (vga_t *)p;
vga->svga.fullchange = changeframecount;
}
device_t vga_device =
{
"VGA",
vga_init,
vga_close,
vga_speed_changed,
vga_force_redraw,
svga_add_status_info
};

View file

@ -48,3 +48,5 @@ extern int video_timing_b, video_timing_w, video_timing_l;
extern int video_speed;
extern int video_res_x, video_res_y, video_bpp;
extern int vid_resize;

View file

@ -2,127 +2,205 @@
#define BITMAP WINDOWS_BITMAP
#include <d3d9.h>
#undef BITMAP
#include "resources.h"
#include "win-d3d.h"
#include "video.h"
extern "C" void fatal(const char *format, ...);
extern "C" void pclog(const char *format, ...);
extern "C" void device_force_redraw();
void d3d_init_objects();
void d3d_close_objects();
void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h);
void d3d_blit_memtoscreen_8(int x, int y, int w, int h);
LPDIRECT3D9 d3d = NULL;
LPDIRECT3DDEVICE9 d3ddev = NULL;
LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;
LPDIRECT3DTEXTURE9 d3dTexture = NULL;
D3DPRESENT_PARAMETERS d3dpp;
static LPDIRECT3D9 d3d = NULL;
static LPDIRECT3DDEVICE9 d3ddev = NULL;
static LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL;
static LPDIRECT3DTEXTURE9 d3dTexture = NULL;
static D3DPRESENT_PARAMETERS d3dpp;
HWND d3d_hwnd;
static HWND d3d_hwnd;
struct CUSTOMVERTEX
{
FLOAT x, y, z, rhw; // from the D3DFVF_XYZRHW flag
DWORD color; // from the D3DFVF_DIFFUSE flag
FLOAT tu, tv;
};
CUSTOMVERTEX OurVertices[] =
static PALETTE cgapal=
{
{ 0.0f, 0.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), 0.0f, 0.0f},
{2048.0f, 2048.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 255, 0), 1.0f, 1.0f},
{ 0.0f, 2048.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 0), 0.0f, 1.0f},
{0,0,0},{0,42,0},{42,0,0},{42,21,0},
{0,0,0},{0,42,42},{42,0,42},{42,42,42},
{0,0,0},{21,63,21},{63,21,21},{63,63,21},
{0,0,0},{21,63,63},{63,21,63},{63,63,63},
{ 0.0f, 0.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 0, 255), 0.0f, 0.0f},
{2048.0f, 0.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(0, 255, 0), 1.0f, 0.0f},
{2048.0f, 2048.0f, 1.0f, 1.0f, D3DCOLOR_XRGB(255, 0, 0), 1.0f, 1.0f},
{0,0,0},{0,0,42},{0,42,0},{0,42,42},
{42,0,0},{42,0,42},{42,21,00},{42,42,42},
{21,21,21},{21,21,63},{21,63,21},{21,63,63},
{63,21,21},{63,21,63},{63,63,21},{63,63,63},
{0,0,0},{0,21,0},{0,0,42},{0,42,42},
{42,0,21},{21,10,21},{42,0,42},{42,0,63},
{21,21,21},{21,63,21},{42,21,42},{21,63,63},
{63,0,0},{42,42,0},{63,21,42},{41,41,41},
{0,0,0},{0,42,42},{42,0,0},{42,42,42},
{0,0,0},{0,42,42},{42,0,0},{42,42,42},
{0,0,0},{0,63,63},{63,0,0},{63,63,63},
{0,0,0},{0,63,63},{63,0,0},{63,63,63},
};
static uint32_t pal_lookup[256];
static CUSTOMVERTEX d3d_verts[] =
{
{ 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f},
{2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f},
{ 0.0f, 2048.0f, 1.0f, 1.0f, 0.0f, 1.0f},
{ 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f},
{2048.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f},
{2048.0f, 2048.0f, 1.0f, 1.0f, 1.0f, 1.0f},
};
void d3d_init(HWND h)
{
VOID* pVoid; // the void pointer
D3DLOCKED_RECT dr;
RECT r;
int x, y;
uint32_t *p;
int c;
HRESULT hr;
for (c = 0; c < 256; c++)
pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2);
d3d_hwnd = h;
d3d = Direct3DCreate9(D3D_SDK_VERSION);
memset(&d3dpp, 0, sizeof(d3dpp));
d3dpp.Flags = D3DPRESENTFLAG_VIDEO;
d3dpp.SwapEffect = D3DSWAPEFFECT_FLIP;
d3dpp.hDeviceWindow = h;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;
d3dpp.EnableAutoDepthStencil = false;
d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.Windowed = true;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.BackBufferWidth = 0;
d3dpp.BackBufferHeight = 0;
d3dpp.Flags = 0;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = h;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;
d3dpp.EnableAutoDepthStencil = false;
d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.Windowed = true;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.BackBufferWidth = 0;
d3dpp.BackBufferHeight = 0;
d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);
hr = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);
d3ddev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1);
d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);
d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_DISABLE);
d3ddev->SetSamplerState(0,D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
d3ddev->SetSamplerState(0,D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
// create the vertex and store the pointer into v_buffer, which is created globally
d3ddev->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX),
0,
D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1,
D3DPOOL_MANAGED,
&v_buffer,
NULL);
v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer
memcpy(pVoid, OurVertices, sizeof(OurVertices)); // copy the vertices to the locked buffer
v_buffer->Unlock(); // unlock the vertex buffer
d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL);
r.top = r.left = 0;
r.bottom = r.right = 2047;
if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0)))
fatal("LockRect failed\n");
for (y = 0; y < 2048; y++)
{
p = (uint32_t *)(dr.pBits + (y * dr.Pitch));
for (x = 0; x < 2048; x++)
{
p[x] = x + (y << 11);
}
}
d3dTexture->UnlockRect(0);
// atexit(d3d_close);
d3d_init_objects();
video_blit_memtoscreen = d3d_blit_memtoscreen;
video_blit_memtoscreen_8 = d3d_blit_memtoscreen_8;
}
void d3d_close_objects()
{
if (d3dTexture)
{
d3dTexture->Release();
d3dTexture = NULL;
}
if (v_buffer)
{
v_buffer->Release();
v_buffer = NULL;
}
}
void d3d_init_objects()
{
HRESULT hr;
D3DLOCKED_RECT dr;
int y;
RECT r;
hr = d3ddev->CreateVertexBuffer(6*sizeof(CUSTOMVERTEX),
0,
D3DFVF_XYZRHW | D3DFVF_TEX1,
D3DPOOL_MANAGED,
&v_buffer,
NULL);
d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL);
r.top = r.left = 0;
r.bottom = r.right = 2047;
if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0)))
fatal("LockRect failed\n");
for (y = 0; y < 2048; y++)
{
uint32_t *p = (uint32_t *)(dr.pBits + (y * dr.Pitch));
memset(p, 0, 2048 * 4);
}
d3dTexture->UnlockRect(0);
d3ddev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1);
d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);
d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_DISABLE);
d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
}
void d3d_resize(int x, int y)
{
// d3d_close();
// d3d_init(d3d_hwnd);
d3dpp.BackBufferWidth = 0;
d3dpp.BackBufferHeight = 0;
d3ddev->Reset(&d3dpp);
HRESULT hr;
d3dpp.BackBufferWidth = x;
d3dpp.BackBufferHeight = y;
d3d_reset();
}
void d3d_close()
void d3d_reset()
{
HRESULT hr;
memset(&d3dpp, 0, sizeof(d3dpp));
d3dpp.Flags = 0;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = d3d_hwnd;
d3dpp.BackBufferCount = 1;
d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE;
d3dpp.MultiSampleQuality = 0;
d3dpp.EnableAutoDepthStencil = false;
d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
d3dpp.Windowed = true;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.BackBufferWidth = 0;
d3dpp.BackBufferHeight = 0;
hr = d3ddev->Reset(&d3dpp);
if (hr == D3DERR_DEVICELOST)
return;
d3ddev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1);
d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE);
d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_DISABLE);
d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
device_force_redraw();
}
void d3d_close()
{
if (d3dTexture)
{
d3dTexture->Release();
@ -147,79 +225,155 @@ void d3d_close()
void d3d_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
{
HRESULT hr = D3D_OK;
VOID* pVoid;
float xmax, ymax;
D3DLOCKED_RECT dr;
RECT r;
uint32_t *p, *src;
int yy;
xmax = (float)w / 2048.0;
ymax = (float)h / 2048.0;
OurVertices[1].tu = OurVertices[4].tu = OurVertices[5].tu = xmax;
OurVertices[1].tv = OurVertices[2].tv = OurVertices[5].tv = ymax;
d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0;
d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0;
d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0;
d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0;
GetClientRect(d3d_hwnd, &r);
OurVertices[1].x = OurVertices[4].x = OurVertices[5].x = r.right - r.left;
OurVertices[1].y = OurVertices[2].y = OurVertices[5].y = r.bottom - r.top;
//pclog("Window %i, %i\n",
d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5;
d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5;
d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right - r.left) - 0.5;
d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom - r.top) - 0.5;
v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer
memcpy(pVoid, OurVertices, sizeof(OurVertices)); // copy the vertices to the locked buffer
v_buffer->Unlock(); // unlock the vertex buffer
// clear the window to a deep blue
//d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
if (hr == D3D_OK)
hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer
if (hr == D3D_OK)
memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer
if (hr == D3D_OK)
hr = v_buffer->Unlock(); // unlock the vertex buffer
r.top = y1;
r.left = 0;
r.bottom = y2;
r.right = 2047;
if (hr == D3D_OK)
{
if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0)))
fatal("LockRect failed\n");
if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0)))
fatal("LockRect failed\n");
for (yy = y1; yy < y2; yy++)
memcpy(dr.pBits + ((yy - y1) * dr.Pitch), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4);
d3dTexture->UnlockRect(0);
}
if (hr == D3D_OK)
hr = d3ddev->BeginScene();
if (hr == D3D_OK)
{
if (hr == D3D_OK)
hr = d3ddev->SetTexture(0, d3dTexture);
if (hr == D3D_OK)
hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
if (hr == D3D_OK)
hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
if (hr == D3D_OK)
hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
if (hr == D3D_OK)
hr = d3ddev->SetTexture(0, NULL);
if (hr == D3D_OK)
hr = d3ddev->EndScene();
}
if (hr == D3D_OK)
hr = d3ddev->Present(NULL, NULL, d3d_hwnd, NULL);
for (yy = y1; yy < y2; yy++)
memcpy(dr.pBits + (yy * dr.Pitch), &(((uint32_t *)buffer32->line[y + yy])[x]), w * 4);
d3dTexture->UnlockRect(0);
// d3dpp.BackBufferWidth = r.right - r.left;
// d3dpp.BackBufferHeight = r.bottom - r.top;
// d3ddev->Reset(&d3dpp);
d3ddev->BeginScene(); // begins the 3D scene
d3ddev->SetTexture( 0, d3dTexture );
// select which vertex format we are using
d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1);
// select the vertex buffer to display
d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
// copy the vertex buffer to the back buffer
d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
d3ddev->SetTexture( 0, NULL );
d3ddev->EndScene(); // ends the 3D scene
d3ddev->Present(NULL, NULL, d3d_hwnd, NULL); // displays the created frame
if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL)
PostMessage(d3d_hwnd, WM_RESETD3D, 0, 0);
}
void d3d_blit_memtoscreen_8(int x, int y, int w, int h)
{
// clear the window to a deep blue
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
VOID* pVoid;
D3DLOCKED_RECT dr;
RECT r;
uint32_t *p, *src;
int yy, xx;
HRESULT hr = D3D_OK;
d3ddev->BeginScene(); // begins the 3D scene
d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0;
d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0;
d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0;
d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0;
// do 3D rendering on the back buffer here
GetClientRect(d3d_hwnd, &r);
d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5;
d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5;
d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right - r.left) - 0.5;
d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom - r.top) - 0.5;
d3ddev->EndScene(); // ends the 3D scene
if (hr == D3D_OK)
hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer
if (hr == D3D_OK)
memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer
if (hr == D3D_OK)
hr = v_buffer->Unlock(); // unlock the vertex buffer
d3ddev->Present(NULL, NULL, NULL, NULL); // displays the created frame
r.top = 0;
r.left = 0;
r.bottom = h;
r.right = 2047;
if (hr == D3D_OK)
{
if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0)))
fatal("LockRect failed\n");
for (yy = 0; yy < h; yy++)
{
uint32_t *p = (uint32_t *)(dr.pBits + (yy * dr.Pitch));
if ((y + yy) >= 0 && (y + yy) < buffer->h)
{
for (xx = 0; xx < w; xx++)
p[xx] = pal_lookup[buffer->line[y + yy][x + xx]];
}
}
d3dTexture->UnlockRect(0);
}
if (hr == D3D_OK)
hr = d3ddev->BeginScene();
if (hr == D3D_OK)
{
if (hr == D3D_OK)
hr = d3ddev->SetTexture(0, d3dTexture);
if (hr == D3D_OK)
hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
if (hr == D3D_OK)
hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX));
if (hr == D3D_OK)
hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
if (hr == D3D_OK)
hr = d3ddev->SetTexture(0, NULL);
if (hr == D3D_OK)
hr = d3ddev->EndScene();
}
if (hr == D3D_OK)
hr = d3ddev->Present(NULL, NULL, d3d_hwnd, NULL);
if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL)
PostMessage(d3d_hwnd, WM_RESETD3D, 0, 0);
}

View file

@ -3,6 +3,7 @@ extern "C" {
#endif
void d3d_init(HWND h);
void d3d_close();
void d3d_reset();
void d3d_resize(int x, int y);
#ifdef __cplusplus
}

View file

@ -8,6 +8,8 @@
extern "C" void fatal(const char *format, ...);
extern "C" void pclog(const char *format, ...);
extern "C" void device_force_redraw();
extern "C" void ddraw_init(HWND h);
extern "C" void ddraw_close();
extern "C" void ddraw_draw();
@ -157,7 +159,7 @@ void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
{
lpdds_back->Restore();
lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
fullchange = changeframecount;
device_force_redraw();
}
if (!ddsd.lpSurface) return;
for (yy = y1; yy < y2; yy++)
@ -190,7 +192,7 @@ void ddraw_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
{
lpdds_back2->Restore();
lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
fullchange = changeframecount;
device_force_redraw();
}
if (!ddsd.lpSurface) return;
for (yy = 8; yy < 14; yy++)
@ -229,7 +231,7 @@ void ddraw_blit_memtoscreen_8(int x, int y, int w, int h)
{
lpdds_back->Restore();
lpdds_back->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
fullchange = changeframecount;
device_force_redraw();
}
if (!ddsd.lpSurface) return;
for (yy = 0; yy < h; yy++)
@ -270,7 +272,7 @@ void ddraw_blit_memtoscreen_8(int x, int y, int w, int h)
{
lpdds_back2->Restore();
lpdds_back2->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
fullchange = changeframecount;
device_force_redraw();
}
if (!ddsd.lpSurface) return;
for (yy = 8; yy < 14; yy++)

142
src/win.c
View file

@ -22,9 +22,20 @@
#include "plat-keyboard.h"
#include "win-ddraw.h"
//#include "win-d3d.h"
#include "win-d3d.h"
//#include "win-opengl.h"
static struct
{
void (*init)(HWND h);
void (*close)();
void (*resize)(int x, int y);
} vid_apis[] =
{
ddraw_init, ddraw_close, NULL,
d3d_init, d3d_close, d3d_resize
};
#define TIMER_1SEC 1
int winsizex=640,winsizey=480;
@ -75,19 +86,15 @@ LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
char szClassName[ ] = "WindowsApp";
HWND ghwnd;
static int win_doresize = 0;
void updatewindowsize(int x, int y)
{
RECT r;
if (vid_resize) return;
winsizex=x; winsizey=y;
GetWindowRect(ghwnd,&r);
MoveWindow(ghwnd,r.left,r.top,
x+(GetSystemMetrics(SM_CXFIXEDFRAME)*2),
y+(GetSystemMetrics(SM_CYFIXEDFRAME)*2)+GetSystemMetrics(SM_CYMENUSIZE)+GetSystemMetrics(SM_CYCAPTION)+1,
TRUE);
// startblit();
// d3d_resize(x, y);
// endblit();
win_doresize = 1;
}
void releasemouse()
@ -153,55 +160,49 @@ void mainthread(LPVOID param)
int t = 0;
int frames = 0;
DWORD old_time, new_time;
mainthreadon=1;
// Sleep(500);
drawits=0;
old_time = GetTickCount();
while (!quited)
{
// if (infocus)
// {
/* if (!drawits)
if (updatestatus)
{
updatestatus=0;
if (statusopen) SendMessage(statushwnd,WM_USER,0,0);
}
new_time = GetTickCount();
drawits += new_time - old_time;
old_time = new_time;
if (drawits > 0 && !pause)
{
drawits-=10; if (drawits>50) drawits=0;
wokeups++;
runpc();
frames++;
if (frames >= 200 && nvr_dosave)
{
while (!drawits)
{
ResetEvent(frameobject);
WaitForSingleObject(frameobject,10);
}
}*/
if (updatestatus)
{
updatestatus=0;
if (statusopen) SendMessage(statushwnd,WM_USER,0,0);
frames = 0;
nvr_dosave = 0;
savenvr();
}
new_time = GetTickCount();
drawits += new_time - old_time;
old_time = new_time;
if (drawits > 0 && !pause)
{
// printf("Drawits %i\n",drawits);
drawits-=10;
if (drawits>50) drawits=0;
wokeups++;
startblit();
runpc();
// ddraw_draw();
endblit();
frames++;
if (frames >= 200 && nvr_dosave)
{
frames = 0;
nvr_dosave = 0;
savenvr();
}
//#if 0
//#endif
}
else
{
Sleep(1);
}
// }
}
else
{
Sleep(1);
}
if (win_doresize)
{
RECT r;
GetWindowRect(ghwnd, &r);
MoveWindow(ghwnd, r.left, r.top,
winsizex + (GetSystemMetrics(SM_CXFIXEDFRAME) * 2),
winsizey + (GetSystemMetrics(SM_CYFIXEDFRAME) * 2) + GetSystemMetrics(SM_CYMENUSIZE) + GetSystemMetrics(SM_CYCAPTION) + 1,
TRUE);
win_doresize = 0;
}
}
mainthreadon=0;
}
@ -300,13 +301,12 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
ghwnd=hwnd;
ddraw_init(hwnd);
midi_init();
atexit(midi_close);
// d3d_init(hwnd);
// opengl_init(hwnd);
initpc();
vid_apis[vid_api].init(ghwnd);
if (vid_resize) SetWindowLong(hwnd, GWL_STYLE, WS_OVERLAPPEDWINDOW|WS_VISIBLE);
else SetWindowLong(hwnd, GWL_STYLE, (WS_OVERLAPPEDWINDOW&~WS_SIZEBOX&~WS_THICKFRAME&~WS_MAXIMIZEBOX)|WS_VISIBLE);
@ -317,7 +317,7 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
CheckMenuItem(menu, IDM_CDROM_REAL + cdrom_drive, MF_CHECKED);
CheckMenuItem(menu, IDM_KEY_ALLEGRO + kb_win, MF_CHECKED);
if (vid_resize) CheckMenuItem(menu, IDM_VID_RESIZE, MF_CHECKED);
CheckMenuItem(menu, IDM_VID_DDRAW + vid_api, MF_CHECKED);
// set_display_switch_mode(SWITCH_BACKGROUND);
d=romset;
@ -462,6 +462,9 @@ InitializeCriticalSection(&cs);
// pclog("Closepc\n");
closepc();
// pclog("dumpregs\n");
vid_apis[vid_api].close();
timeEndPeriod(1);
// endsoundthread();
// dumpregs();
@ -1470,6 +1473,19 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
SetWindowPos(hwnd, 0, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, SWP_NOZORDER | SWP_FRAMECHANGED);
saveconfig();
break;
case IDM_VID_DDRAW: case IDM_VID_D3D:
startblit();
CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_UNCHECKED);
vid_apis[vid_api].close();
vid_api = LOWORD(wParam) - IDM_VID_DDRAW;
CheckMenuItem(hmenu, IDM_VID_DDRAW + vid_api, MF_CHECKED);
vid_apis[vid_api].init(ghwnd);
endblit();
saveconfig();
device_force_redraw();
break;
case IDM_KEY_ALLEGRO: case IDM_KEY_WINDOWS:
CheckMenuItem(hmenu,LOWORD(wParam),MF_CHECKED);
CheckMenuItem(hmenu,LOWORD(wParam)^1,MF_UNCHECKED);
@ -1583,14 +1599,24 @@ LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM
case WM_SIZE:
winsizex=lParam&0xFFFF;
winsizey=lParam>>16;
// startblit();
// d3d_resize(winsizex, winsizey);
// endblit();
if (vid_apis[vid_api].resize)
{
startblit();
vid_apis[vid_api].resize(winsizex, winsizey);
endblit();
}
break;
case WM_TIMER:
if (wParam == TIMER_1SEC)
onesec();
onesec();
break;
case WM_RESETD3D:
startblit();
d3d_reset();
endblit();
break;
case WM_KEYDOWN: