From 0f66f0ce1fb13c344a692c42bf79ba28e78642b4 Mon Sep 17 00:00:00 2001 From: waltje Date: Mon, 13 Nov 2017 02:06:00 -0500 Subject: [PATCH] Merged Direct3D modules, cleanup. Re-enabled optional CRASHDUMP module (CRASHDUMP=y in Makefile[.local] --- src/Makefile.local | 3 +- src/plat.h | 3 +- src/win/Makefile.mingw | 14 +- src/win/win.c | 12 +- src/win/win.h | 6 +- src/win/win_crashdump.c | 27 +- src/win/win_crashdump.h | 7 - src/win/win_d3d.cc | 788 ++++++++++++++++++++++++++-------------- src/win/win_d3d.h | 11 +- src/win/win_d3d_fs.cc | 430 ---------------------- src/win/win_video.c | 9 +- 11 files changed, 573 insertions(+), 737 deletions(-) delete mode 100644 src/win/win_crashdump.h delete mode 100644 src/win/win_d3d_fs.cc diff --git a/src/Makefile.local b/src/Makefile.local index ef2a7e2e4..d265c1e8c 100644 --- a/src/Makefile.local +++ b/src/Makefile.local @@ -10,7 +10,7 @@ # settings, so we can avoid changing the main one for all of # our local setups. # -# Version: @(#)Makefile.local 1.0.6 2017/10/26 +# Version: @(#)Makefile.local 1.0.7 2017/11/12 # # Author: Fred N. van Kempen, # @@ -61,6 +61,7 @@ EXTRAS := AUTODEP := n +CRASHDUMP := n DEBUG := n OPTIM := n X64 := n diff --git a/src/plat.h b/src/plat.h index 9005a6656..472535666 100644 --- a/src/plat.h +++ b/src/plat.h @@ -8,7 +8,7 @@ * * Define the various platform support functions. * - * Version: @(#)plat.h 1.0.17 2017/11/11 + * Version: @(#)plat.h 1.0.18 2017/11/12 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -61,6 +61,7 @@ GLOBAL int dopause, /* system is paused */ mouse_capture; /* mouse is captured in app */ GLOBAL uint64_t timer_freq; GLOBAL int infocus; +GLOBAL char emu_version[128]; /* version ID string */ /* System-related functions. */ diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 142acaadf..6d179d0fa 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -8,7 +8,7 @@ # # Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.75 2017/11/12 +# Version: @(#)Makefile.mingw 1.0.76 2017/11/12 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -33,6 +33,9 @@ endif ifndef AUTODEP AUTODEP := n endif +ifndef CRASHDUMP +CRASHCUMP := n +endif ifndef DEBUG DEBUG := n endif @@ -159,6 +162,9 @@ AFLAGS := -msse -msse2 -mfpmath=sse CFLAGS := $(OPTS) $(DFLAGS) $(COPTIM) $(AOPTIM) $(AFLAGS) \ -fomit-frame-pointer -mstackrealign -Wall RFLAGS := --input-format=rc -O coff +ifeq ($(CRASHDUMP), y) +CFLAGS += -DUSE_CRASHDUMP +endif ifeq ($(RELEASE), y) CFLAGS += -DRELEASE_BUILD RFLAGS += -DRELEASE_BUILD @@ -378,10 +384,10 @@ VIDOBJ := video.o \ vid_voodoo.o PLATOBJ := win.o \ - win_ddraw.o win_d3d.o win_d3d_fs.o win_png.o \ + win_crashdump.o win_ddraw.o win_d3d.o win_png.o \ win_dynld.o win_thread.o $(WSERIAL) win_video.o \ - win_cdrom.o win_cdrom_ioctl.o win_keyboard.o win_mouse.o \ - win_joystick.o win_midi.o \ + win_cdrom.o win_cdrom_ioctl.o win_keyboard.o \ + win_mouse.o win_joystick.o win_midi.o \ win_dialog.o win_about.o win_status.o win_stbar.o \ win_settings.o win_deviceconfig.o win_joystickconfig.o diff --git a/src/win/win.c b/src/win/win.c index 4cf1c67f4..b501eeb77 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -8,7 +8,7 @@ * * Platform main support module for Windows. * - * Version: @(#)win.c 1.0.34 2017/11/11 + * Version: @(#)win.c 1.0.35 2017/11/12 * * Authors: Sarah Walker, * Miran Grca, @@ -666,7 +666,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_RESETD3D: startblit(); if (video_fullscreen) - d3d_fs_reset(); + d3d_reset_fs(); else d3d_reset(); endblit(); @@ -885,6 +885,14 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nFunsterStil) /* We need this later. */ hinstance = hInst; + /* Set the application version ID string. */ + sprintf(emu_version, "%s v%s", EMU_NAME, EMU_VERSION); + +#ifdef USE_CRASHDUMP + /* Enable crash dump services. */ + InitCrashDump(); +#endif + /* First, set our (default) language. */ set_language(0x0409); diff --git a/src/win/win.h b/src/win/win.h index 98113c7a2..cc5e6505d 100644 --- a/src/win/win.h +++ b/src/win/win.h @@ -8,7 +8,7 @@ * * Platform support defintions for Win32. * - * Version: @(#)win.h 1.0.8 2017/10/24 + * Version: @(#)win.h 1.0.9 2017/11/12 * * Authors: Sarah Walker, * Miran Grca, @@ -65,6 +65,10 @@ extern WCHAR wopenfilestring[260]; extern "C" { #endif +#ifdef USE_CRASHDUMP +extern void InitCrashDump(void); +#endif + extern HICON LoadIconEx(PCTSTR pszIconName); /* Emulator start/stop support functions. */ diff --git a/src/win/win_crashdump.c b/src/win/win_crashdump.c index 957ce296e..d1757e226 100644 --- a/src/win/win_crashdump.c +++ b/src/win/win_crashdump.c @@ -6,25 +6,27 @@ #define _WIN32_WINNT 0x0501 #include #include -#include -#include #include +#include +#include +#include #include "../86box.h" -#include "win_crashdump.h" +#include "../plat.h" +#include "win.h" #define ExceptionHandlerBufferSize (10240) static PVOID hExceptionHandler; -static char *ExceptionHandlerBuffer; +static char *ExceptionHandlerBuffer, + *CurrentBufferPointer; LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) { SYSTEMTIME SystemTime; HANDLE hDumpFile; - DWORD Error; char *BufPtr; /* @@ -138,17 +140,17 @@ LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) // Start to put the crash-dump string into the buffer. sprintf(ExceptionHandlerBuffer, - "86Box version %s crashed on %d-%02d-%02d %02d:%02d:%02d.%03d\r\n\r\n" + "%s crashed on %d-%02d-%02d %02d:%02d:%02d.%03d\r\n\r\n" "" "Exception details:\r\n" - "Exception NTSTATUS code: 0x%08x\r\n" + "Exception NTSTATUS code: 0x%08lx\r\n" "Occured at address: 0x%p", - emulator_version, + emu_version, SystemTime.wYear, SystemTime.wMonth, SystemTime.wDay, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond, SystemTime.wMilliseconds, ExceptionInfo->ExceptionRecord->ExceptionCode, - ExceptionInfo->ExceptionRecord->ExceptionAddress); + (void *)ExceptionInfo->ExceptionRecord->ExceptionAddress); // If we found the module that the exception occured in, get the full path to the module the exception occured at and include it. BufPtr = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; @@ -166,7 +168,7 @@ LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) // Continue to create the crash-dump string. sprintf(BufPtr, "\r\n" - "Number of parameters: %d\r\n" + "Number of parameters: %lu\r\n" "Exception parameters: ", ExceptionInfo->ExceptionRecord->NumberParameters); @@ -174,7 +176,7 @@ LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) for (int i = 0; i < ExceptionInfo->ExceptionRecord->NumberParameters; i++) { BufPtr = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer)]; sprintf(BufPtr,"0x%p ", - ExceptionInfo->ExceptionRecord->ExceptionInformation[i]); + (void *)ExceptionInfo->ExceptionRecord->ExceptionInformation[i]); } BufPtr = &ExceptionHandlerBuffer[strlen(ExceptionHandlerBuffer) - 1]; @@ -185,7 +187,7 @@ LONG CALLBACK MakeCrashDump(PEXCEPTION_POINTERS ExceptionInfo) sprintf(BufPtr, "\r\n" "Register dump:\r\n" - "eax=0x%08x ebx=0x%08x ecx=0x%08x edx=0x%08x ebp=0x%08x esp=0x%08x esi=0x%08x edi=0x%08x eip=0x%08x\r\n" + "eax=0x%08lx ebx=0x%08lx ecx=0x%08lx edx=0x%08lx ebp=0x%08lx esp=0x%08lx esi=0x%08lx edi=0x%08lx eip=0x%08lx\r\n" "\r\n", Registers->Eax, Registers->Ebx, Registers->Ecx, Registers->Edx, Registers->Ebp, Registers->Esp, Registers->Esi, Registers->Edi, Registers->Eip); #else @@ -214,6 +216,7 @@ void InitCrashDump(void) * an amount which should be more than enough. */ ExceptionHandlerBuffer = malloc(ExceptionHandlerBufferSize); + CurrentBufferPointer = ExceptionHandlerBuffer; /* * Register the exception handler. diff --git a/src/win/win_crashdump.h b/src/win/win_crashdump.h deleted file mode 100644 index 8048cd7af..000000000 --- a/src/win/win_crashdump.h +++ /dev/null @@ -1,7 +0,0 @@ -/* Copyright holders: Riley - see COPYING for more details - - win-crashdump.c : Windows crash dump exception handler header file. -*/ - -void InitCrashDump(); \ No newline at end of file diff --git a/src/win/win_d3d.cc b/src/win/win_d3d.cc index a66ae23d9..483c89016 100644 --- a/src/win/win_d3d.cc +++ b/src/win/win_d3d.cc @@ -6,335 +6,593 @@ * * This file is part of the 86Box distribution. * - * Direct3D 9 rendererer and screenshots taking. + * Rendering module for Microsoft Direct3D 9. * - * Version: @(#)win_d3d.cc 1.0.5 2017/10/22 + * Version: @(#)win_d3d.cc 1.0.6 2017/11/12 * * Authors: Sarah Walker, * Miran Grca, + * Fred N. van Kempen, * * Copyright 2008-2017 Sarah Walker. * Copyright 2016,2017 Miran Grca. + * Copyright 2017 Fred N. van Kempen. */ +#include #include +#include "../86box.h" +#include "../device.h" #include "../video/video.h" +#include "../plat.h" #include "win.h" #include "win_d3d.h" -extern "C" void fatal(const char *format, ...); -extern "C" void pclog(const char *format, ...); - -extern "C" void device_force_redraw(void); - -extern "C" void d3d_take_screenshot(wchar_t *fn); - -void d3d_init_objects(void); -void d3d_close_objects(void); - -static void blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); - -static LPDIRECT3D9 d3d = NULL; -static LPDIRECT3DDEVICE9 d3ddev = NULL; -static LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL; -static LPDIRECT3DTEXTURE9 d3dTexture = NULL; -static D3DPRESENT_PARAMETERS d3dpp; - -static HWND d3d_hwnd; - -struct CUSTOMVERTEX -{ - FLOAT x, y, z, rhw; // from the D3DFVF_XYZRHW flag - DWORD color; - FLOAT tu, tv; +struct CUSTOMVERTEX { + FLOAT x, y, z, rhw; // from the D3DFVF_XYZRHW flag + DWORD color; + FLOAT tu, tv; }; -static CUSTOMVERTEX d3d_verts[] = -{ - { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f}, - { 0.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 1.0f}, - { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, - {2048.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f}, +static LPDIRECT3D9 d3d = NULL; +static LPDIRECT3DDEVICE9 d3ddev = NULL; +static LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL; +static LPDIRECT3DTEXTURE9 d3dTexture = NULL; +static D3DPRESENT_PARAMETERS d3dpp; +static HWND d3d_hwnd; +static HWND d3d_device_window; +static int d3d_w, + d3d_h; - { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f}, - { 0.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 1.0f}, +static CUSTOMVERTEX d3d_verts[] = { + { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f}, + { 0.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 1.0f}, - { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, - {2048.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f} + { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, + {2048.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f}, + + { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f}, + { 0.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 1.0f}, + + { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, + {2048.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 0.0f}, + {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f} }; - -int d3d_init(HWND h) + + +static void +d3d_size(RECT w_rect, double *l, double *t, double *r, double *b, int w, int h) { - int c; - - for (c = 0; c < 256; c++) - pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2); + int ratio_w, ratio_h; - d3d_hwnd = h; - - d3d = Direct3DCreate9(D3D_SDK_VERSION); + switch (video_fullscreen_scale) { + case FULLSCR_SCALE_FULL: + *l = -0.5; + *t = -0.5; + *r = (w_rect.right - w_rect.left) - 0.5; + *b = (w_rect.bottom - w_rect.top) - 0.5; + break; - memset(&d3dpp, 0, sizeof(d3dpp)); + case FULLSCR_SCALE_43: + *t = -0.5; + *b = (w_rect.bottom - w_rect.top) - 0.5; + *l = ((w_rect.right - w_rect.left) / 2) - (((w_rect.bottom - w_rect.top) * 4) / (3 * 2)) - 0.5; + *r = ((w_rect.right - w_rect.left) / 2) + (((w_rect.bottom - w_rect.top) * 4) / (3 * 2)) - 0.5; + if (*l < -0.5) { + *l = -0.5; + *r = (w_rect.right - w_rect.left) - 0.5; + *t = ((w_rect.bottom - w_rect.top) / 2) - (((w_rect.right - w_rect.left) * 3) / (4 * 2)) - 0.5; + *b = ((w_rect.bottom - w_rect.top) / 2) + (((w_rect.right - w_rect.left) * 3) / (4 * 2)) - 0.5; + } + break; - 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; + case FULLSCR_SCALE_SQ: + *t = -0.5; + *b = (w_rect.bottom - w_rect.top) - 0.5; + *l = ((w_rect.right - w_rect.left) / 2) - (((w_rect.bottom - w_rect.top) * w) / (h * 2)) - 0.5; + *r = ((w_rect.right - w_rect.left) / 2) + (((w_rect.bottom - w_rect.top) * w) / (h * 2)) - 0.5; + if (*l < -0.5) { + *l = -0.5; + *r = (w_rect.right - w_rect.left) - 0.5; + *t = ((w_rect.bottom - w_rect.top) / 2) - (((w_rect.right - w_rect.left) * h) / (w * 2)) - 0.5; + *b = ((w_rect.bottom - w_rect.top) / 2) + (((w_rect.right - w_rect.left) * h) / (w * 2)) - 0.5; + } + break; - if (FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev))) - fatal("CreateDevice failed\n"); - - d3d_init_objects(); - - video_setblit(blit_memtoscreen); - - return 1; + case FULLSCR_SCALE_INT: + ratio_w = (w_rect.right - w_rect.left) / w; + ratio_h = (w_rect.bottom - w_rect.top) / h; + if (ratio_h < ratio_w) + ratio_w = ratio_h; + *l = ((w_rect.right - w_rect.left) / 2) - ((w * ratio_w) / 2) - 0.5; + *r = ((w_rect.right - w_rect.left) / 2) + ((w * ratio_w) / 2) - 0.5; + *t = ((w_rect.bottom - w_rect.top) / 2) - ((h * ratio_w) / 2) - 0.5; + *b = ((w_rect.bottom - w_rect.top) / 2) + ((h * ratio_w) / 2) - 0.5; + break; + } } -void d3d_close_objects() + +static void +d3d_blit_fs(int x, int y, int y1, int y2, int w, int h) { - if (d3dTexture) - { - d3dTexture->Release(); - d3dTexture = NULL; - } - if (v_buffer) - { - v_buffer->Release(); - v_buffer = NULL; - } + HRESULT hr = D3D_OK; + VOID* pVoid; + D3DLOCKED_RECT dr; + RECT w_rect; + int yy; + double l = 0, t = 0, r = 0, b = 0; + + if ((y1 == y2) || (h <= 0)) { + video_blit_complete(); + return; /*Nothing to do*/ + } + + if (hr == D3D_OK && !(y1 == 0 && y2 == 0)) { + RECT lock_rect; + + lock_rect.top = y1; + lock_rect.left = 0; + lock_rect.bottom = y2; + lock_rect.right = 2047; + + hr = d3dTexture->LockRect(0, &dr, &lock_rect, 0); + if (hr == D3D_OK) { + for (yy = y1; yy < y2; yy++) + memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); + + video_blit_complete(); + d3dTexture->UnlockRect(0); + } else { + video_blit_complete(); + return; + } + } else + video_blit_complete(); + + d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0; + d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 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; + d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color = + d3d_verts[3].color = d3d_verts[4].color = d3d_verts[5].color = + d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color = + d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff; + + GetClientRect(d3d_device_window, &w_rect); + d3d_size(w_rect, &l, &t, &r, &b, w, h); + + d3d_verts[0].x = l; + d3d_verts[0].y = t; + d3d_verts[1].x = r; + d3d_verts[1].y = b; + d3d_verts[2].x = l; + d3d_verts[2].y = b; + d3d_verts[3].x = l; + d3d_verts[3].y = t; + d3d_verts[4].x = r; + d3d_verts[4].y = t; + d3d_verts[5].x = r; + d3d_verts[5].y = b; + d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = r - 40.5; + d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = t + 8.5; + d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = r - 8.5; + d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = t + 14.5; + + if (hr == D3D_OK) + hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); + if (hr == D3D_OK) + memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); + if (hr == D3D_OK) + hr = v_buffer->Unlock(); + + if (hr == D3D_OK) + hr = d3ddev->BeginScene(); + + if (hr == D3D_OK) { + if (hr == D3D_OK) + d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0, 0); + + if (hr == D3D_OK) + hr = d3ddev->SetTexture(0, d3dTexture); + + if (hr == D3D_OK) + hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | 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_device_window, NULL); + + if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL) + PostMessage(hwndMain, WM_RESETD3D, 0, 0); } -void d3d_init_objects() + +static void +d3d_blit(int x, int y, int y1, int y2, int w, int h) { - D3DLOCKED_RECT dr; - int y; - RECT r; + HRESULT hr = D3D_OK; + VOID* pVoid; + D3DLOCKED_RECT dr; + RECT r; + int yy; - if (FAILED(d3ddev->CreateVertexBuffer(12*sizeof(CUSTOMVERTEX), - 0, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1, - D3DPOOL_MANAGED, - &v_buffer, - NULL))) - fatal("CreateVertexBuffer failed\n"); + if ((y1 == y2) || (h <= 0)) { + video_blit_complete(); + return; /*Nothing to do*/ + } - if (FAILED(d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL))) - fatal("CreateTexture failed\n"); - - r.top = r.left = 0; - r.bottom = r.right = 2047; + r.top = y1; + r.left = 0; + r.bottom = y2; + 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 *)((uintptr_t)dr.pBits + (y * dr.Pitch)); - memset(p, 0, 2048 * 4); - } + hr = d3dTexture->LockRect(0, &dr, &r, 0); + if (hr == D3D_OK) { + for (yy = y1; yy < y2; yy++) { + if ((y + yy) >= 0 && (y + yy) < buffer32->h) + memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); + } - d3dTexture->UnlockRect(0); + video_blit_complete(); + d3dTexture->UnlockRect(0); + } else { + video_blit_complete(); + return; + } - d3ddev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1); - d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE); - d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_DISABLE); + 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; + d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color = + d3d_verts[3].color = d3d_verts[4].color = d3d_verts[5].color = + d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color = + d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff; - d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + 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; + d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = (r.right-r.left)-40.5; + d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = 8.5; + d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = (r.right-r.left)-8.5; + d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = 14.5; + + 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 + + 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_DIFFUSE | 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); } -void d3d_resize(int x, int y) + +static void +d3d_init_objects(void) { - d3dpp.BackBufferWidth = x; - d3dpp.BackBufferHeight = y; + D3DLOCKED_RECT dr; + RECT r; + int y; - d3d_reset(); -} - -void d3d_reset() -{ - HRESULT hr; + if (FAILED(d3ddev->CreateVertexBuffer(12*sizeof(CUSTOMVERTEX), + 0, + D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1, + D3DPOOL_MANAGED, + &v_buffer, + NULL))) + fatal("CreateVertexBuffer failed\n"); - if (!d3ddev) - return; - memset(&d3dpp, 0, sizeof(d3dpp)); + if (FAILED(d3ddev->CreateTexture(2048, 2048, 1, 0, + D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL))) + fatal("CreateTexture failed\n"); - 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; + r.top = r.left = 0; + r.bottom = r.right = 2047; - hr = d3ddev->Reset(&d3dpp); + if (FAILED(d3dTexture->LockRect(0, &dr, &r, 0))) + fatal("LockRect failed\n"); - if (hr == D3DERR_DEVICELOST) - return; + for (y = 0; y < 2048; y++) { + uint32_t *p = (uint32_t *)((uintptr_t)dr.pBits + (y * dr.Pitch)); + memset(p, 0, 2048 * 4); + } - d3ddev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1); - d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE); - d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_DISABLE); + d3dTexture->UnlockRect(0); - d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + d3ddev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1); + d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE); + d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_DISABLE); - device_force_redraw(); + d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); } -void d3d_close() + +int +d3d_init(HWND h) +{ + int c; + + 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 = 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; + + if (FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, h, + D3DCREATE_SOFTWARE_VERTEXPROCESSING, + &d3dpp, &d3ddev))) + fatal("CreateDevice failed\n"); + + d3d_init_objects(); + + video_setblit(d3d_blit); + + return(1); +} + + +int +d3d_init_fs(HWND h) +{ + WCHAR title[200]; + int c; + + d3d_w = GetSystemMetrics(SM_CXSCREEN); + d3d_h = GetSystemMetrics(SM_CYSCREEN); + + d3d_hwnd = h; + for (c = 0; c < 256; c++) + pal_lookup[c] = makecol(cgapal[c].r << 2, + cgapal[c].g << 2, cgapal[c].b << 2); + + /*FIXME: should be done once, in win.c */ + _swprintf(title, L"%s v%s", EMU_NAME_W, EMU_VERSION_W); + d3d_device_window = CreateWindowEx ( + 0, + SUB_CLASS_NAME, + title, + WS_POPUP, + CW_USEDEFAULT, + CW_USEDEFAULT, + 640, + 480, + HWND_DESKTOP, + NULL, + NULL, + NULL + ); + + d3d = Direct3DCreate9(D3D_SDK_VERSION); + + memset(&d3dpp, 0, sizeof(d3dpp)); + d3dpp.Flags = 0; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.hDeviceWindow = d3d_device_window; + d3dpp.BackBufferCount = 1; + d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; + d3dpp.MultiSampleQuality = 0; + d3dpp.EnableAutoDepthStencil = false; + d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN; + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + d3dpp.Windowed = false; + d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; + d3dpp.BackBufferWidth = d3d_w; + d3dpp.BackBufferHeight = d3d_h; + + if (FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, + D3DDEVTYPE_HAL, h, + D3DCREATE_SOFTWARE_VERTEXPROCESSING, + &d3dpp, &d3ddev))) + fatal("CreateDevice failed\n"); + + d3d_init_objects(); + + video_setblit(d3d_blit_fs); + + return(1); +} + + +static void +d3d_close_objects(void) +{ + if (d3dTexture) { + d3dTexture->Release(); + d3dTexture = NULL; + } + if (v_buffer) { + v_buffer->Release(); + v_buffer = NULL; + } +} + + +void +d3d_close(void) { - if (d3dTexture) - { - d3dTexture->Release(); - d3dTexture = NULL; - } - if (v_buffer) - { - v_buffer->Release(); - v_buffer = NULL; - } - if (d3ddev) - { - d3ddev->Release(); - d3ddev = NULL; - } - if (d3d) - { - d3d->Release(); - d3d = NULL; - } + d3d_close_objects(); + + if (d3ddev) { + d3ddev->Release(); + d3ddev = NULL; + } + if (d3d) { + d3d->Release(); + d3d = NULL; + } + + if (d3d_device_window != NULL) { + DestroyWindow(d3d_device_window); + d3d_device_window = NULL; + } } -int d3d_pause(void) + +void +d3d_reset(void) { - return(0); + HRESULT hr; + + if (! d3ddev) return; + + 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(); } -static void blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) + +void +d3d_reset_fs(void) { - HRESULT hr = D3D_OK; - VOID* pVoid; - D3DLOCKED_RECT dr; - RECT r; - int yy; + HRESULT hr; - if ((y1 == y2) || (h <= 0)) - { - video_blit_complete(); - return; /*Nothing to do*/ - } + memset(&d3dpp, 0, sizeof(d3dpp)); + d3dpp.Flags = 0; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.hDeviceWindow = d3d_device_window; + d3dpp.BackBufferCount = 1; + d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; + d3dpp.MultiSampleQuality = 0; + d3dpp.EnableAutoDepthStencil = false; + d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN; + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; + d3dpp.Windowed = false; + d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; + d3dpp.BackBufferWidth = d3d_w; + d3dpp.BackBufferHeight = d3d_h; - r.top = y1; - r.left = 0; - r.bottom = y2; - r.right = 2047; + hr = d3ddev->Reset(&d3dpp); + if (hr == D3DERR_DEVICELOST) return; - hr = d3dTexture->LockRect(0, &dr, &r, 0); - if (hr == D3D_OK) - { - for (yy = y1; yy < y2; yy++) - { - if ((y + yy) >= 0 && (y + yy) < buffer32->h) - memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); - } + d3ddev->SetTextureStageState(0,D3DTSS_COLOROP, D3DTOP_SELECTARG1); + d3ddev->SetTextureStageState(0,D3DTSS_COLORARG1, D3DTA_TEXTURE); + d3ddev->SetTextureStageState(0,D3DTSS_ALPHAOP, D3DTOP_DISABLE); - video_blit_complete(); - d3dTexture->UnlockRect(0); - } - else - { - video_blit_complete(); - return; - } + d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - 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; - d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color = - d3d_verts[3].color = d3d_verts[4].color = d3d_verts[5].color = - d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color = - d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff; - - 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; - d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = (r.right - r.left) - 40.5; - d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = 8.5; - d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = (r.right - r.left) - 8.5; - d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = 14.5; - - 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 - - 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_DIFFUSE | 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); + device_force_redraw(); } -void d3d_take_screenshot(wchar_t *fn) + +void +d3d_resize(int x, int y) { - LPDIRECT3DSURFACE9 d3dSurface = NULL; + d3dpp.BackBufferWidth = x; + d3dpp.BackBufferHeight = y; - if (!d3dTexture) return; - - d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dSurface); - D3DXSaveSurfaceToFile(fn, D3DXIFF_PNG, d3dSurface, NULL, NULL); - - d3dSurface->Release(); - d3dSurface = NULL; + d3d_reset(); +} + + +int +d3d_pause(void) +{ + return(0); +} + + +void +d3d_take_screenshot(wchar_t *fn) +{ + LPDIRECT3DSURFACE9 d3dSurface = NULL; + + if (! d3dTexture) return; + + d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dSurface); + D3DXSaveSurfaceToFile(fn, D3DXIFF_PNG, d3dSurface, NULL, NULL); + + d3dSurface->Release(); + d3dSurface = NULL; } diff --git a/src/win/win_d3d.h b/src/win/win_d3d.h index 2757d6902..18c7c9161 100644 --- a/src/win/win_d3d.h +++ b/src/win/win_d3d.h @@ -8,7 +8,7 @@ * * Direct3D 9 rendererer and screenshots taking. * - * Version: @(#)win_d3d.h 1.0.2 2017/10/13 + * Version: @(#)win_d3d.h 1.0.3 2017/11/12 * * Authors: Sarah Walker, * Miran Grca, @@ -30,19 +30,14 @@ extern "C" { #endif extern int d3d_init(HWND h); +extern int d3d_init_fs(HWND h); extern void d3d_close(void); extern void d3d_reset(void); +extern void d3d_reset_fs(void); extern int d3d_pause(void); extern void d3d_resize(int x, int y); extern void d3d_take_screenshot(wchar_t *fn); -extern int d3d_fs_init(HWND h); -extern void d3d_fs_close(void); -extern void d3d_fs_reset(void); -extern int d3d_fs_pause(void); -extern void d3d_fs_resize(int x, int y); -extern void d3d_fs_take_screenshot(wchar_t *fn); - #ifdef __cplusplus } #endif diff --git a/src/win/win_d3d_fs.cc b/src/win/win_d3d_fs.cc deleted file mode 100644 index 5f49e836e..000000000 --- a/src/win/win_d3d_fs.cc +++ /dev/null @@ -1,430 +0,0 @@ -/* - * 86Box A hypervisor and IBM PC system emulator that specializes in - * running old operating systems and software designed for IBM - * PC systems and compatibles from 1981 through fairly recent - * system designs based on the PCI bus. - * - * This file is part of the 86Box distribution. - * - * Direct3D 9 full-screen rendererer. - * - * Version: @(#)win_d3d_fs.cc 1.0.7 2017/10/22 - * - * Authors: Sarah Walker, - * Miran Grca, - * - * Copyright 2008-2017 Sarah Walker. - * Copyright 2016,2017 Miran Grca. - */ -#include -#include -#include "../86box.h" -#include "../video/video.h" -#include "win.h" -#include "win_d3d.h" - - -extern "C" void fatal(const char *format, ...); -extern "C" void pclog(const char *format, ...); - -extern "C" void device_force_redraw(void); - -extern "C" void video_blit_complete(void); - -extern "C" void d3d_fs_take_screenshot(wchar_t *fn); - -static void d3d_fs_init_objects(void); -static void d3d_fs_close_objects(void); -static void blit_memtoscreen(int x, int y, int y1, int y2, int w, int h); - - -static LPDIRECT3D9 d3d = NULL; -static LPDIRECT3DDEVICE9 d3ddev = NULL; -static LPDIRECT3DVERTEXBUFFER9 v_buffer = NULL; -static LPDIRECT3DTEXTURE9 d3dTexture = NULL; -static D3DPRESENT_PARAMETERS d3dpp; - -static HWND d3d_hwnd; -static HWND d3d_device_window; -static int d3d_fs_w, d3d_fs_h; - - -struct CUSTOMVERTEX -{ - FLOAT x, y, z, rhw; // from the D3DFVF_XYZRHW flag - DWORD color; - FLOAT tu, tv; -}; - - -static CUSTOMVERTEX d3d_verts[] = -{ - { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f}, - { 0.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 1.0f}, - - { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, - {2048.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f}, - - { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f}, - { 0.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 1.0f}, - - { 0.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 0.0f, 0.0f}, - {2048.0f, 0.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 0.0f}, - {2048.0f, 2048.0f, 1.0f, 1.0f, 0xffffff, 1.0f, 1.0f} -}; - - -int d3d_fs_init(HWND h) -{ - int c; - WCHAR emulator_title[200]; - - d3d_fs_w = GetSystemMetrics(SM_CXSCREEN); - d3d_fs_h = GetSystemMetrics(SM_CYSCREEN); - - d3d_hwnd = h; - for (c = 0; c < 256; c++) - pal_lookup[c] = makecol(cgapal[c].r << 2, cgapal[c].g << 2, cgapal[c].b << 2); - - /*FIXME: should be done once, in win.c */ - _swprintf(emulator_title, L"%s v%s", EMU_NAME_W, EMU_VERSION_W); - d3d_device_window = CreateWindowEx ( - 0, - SUB_CLASS_NAME, - emulator_title, - WS_POPUP, - CW_USEDEFAULT, - CW_USEDEFAULT, - 640, - 480, - HWND_DESKTOP, - NULL, - NULL, - NULL - ); - - d3d = Direct3DCreate9(D3D_SDK_VERSION); - - memset(&d3dpp, 0, sizeof(d3dpp)); - - d3dpp.Flags = 0; - d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - d3dpp.hDeviceWindow = d3d_device_window; - d3dpp.BackBufferCount = 1; - d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; - d3dpp.MultiSampleQuality = 0; - d3dpp.EnableAutoDepthStencil = false; - d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN; - d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - d3dpp.Windowed = false; - d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; - d3dpp.BackBufferWidth = d3d_fs_w; - d3dpp.BackBufferHeight = d3d_fs_h; - - if (FAILED(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, h, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev))) - fatal("CreateDevice failed\n"); - - d3d_fs_init_objects(); - - video_setblit(blit_memtoscreen); - - return 1; -} - -static void d3d_fs_close_objects() -{ - if (d3dTexture) - { - d3dTexture->Release(); - d3dTexture = NULL; - } - if (v_buffer) - { - v_buffer->Release(); - v_buffer = NULL; - } -} - -static void d3d_fs_init_objects() -{ - D3DLOCKED_RECT dr; - int y; - RECT r; - - if (FAILED(d3ddev->CreateVertexBuffer(12*sizeof(CUSTOMVERTEX), - 0, - D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1, - D3DPOOL_MANAGED, - &v_buffer, - NULL))) - fatal("CreateVertexBuffer failed\n"); - - if (FAILED(d3ddev->CreateTexture(2048, 2048, 1, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &d3dTexture, NULL))) - fatal("CreateTexture failed\n"); - - 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 *)((uintptr_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) -{ - HRESULT hr; - - d3dpp.BackBufferWidth = x; - d3dpp.BackBufferHeight = y; - - d3d_reset(); -}*/ - -void d3d_fs_reset() -{ - HRESULT hr; - - memset(&d3dpp, 0, sizeof(d3dpp)); - - d3dpp.Flags = 0; - d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; - d3dpp.hDeviceWindow = d3d_device_window; - d3dpp.BackBufferCount = 1; - d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; - d3dpp.MultiSampleQuality = 0; - d3dpp.EnableAutoDepthStencil = false; - d3dpp.AutoDepthStencilFormat = D3DFMT_UNKNOWN; - d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - d3dpp.Windowed = false; - d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; - d3dpp.BackBufferWidth = d3d_fs_w; - d3dpp.BackBufferHeight = d3d_fs_h; - - 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_fs_close() -{ - d3d_fs_close_objects(); - if (d3ddev) - { - d3ddev->Release(); - d3ddev = NULL; - } - if (d3d) - { - d3d->Release(); - d3d = NULL; - } - DestroyWindow(d3d_device_window); -} - -int d3d_fs_pause(void) -{ - return(0); -} - -static void d3d_fs_size(RECT window_rect, double *l, double *t, double *r, double *b, int w, int h) -{ - int ratio_w, ratio_h; - switch (video_fullscreen_scale) - { - case FULLSCR_SCALE_FULL: - *l = -0.5; - *t = -0.5; - *r = (window_rect.right - window_rect.left) - 0.5; - *b = (window_rect.bottom - window_rect.top) - 0.5; - break; - case FULLSCR_SCALE_43: - *t = -0.5; - *b = (window_rect.bottom - window_rect.top) - 0.5; - *l = ((window_rect.right - window_rect.left) / 2) - (((window_rect.bottom - window_rect.top) * 4) / (3 * 2)) - 0.5; - *r = ((window_rect.right - window_rect.left) / 2) + (((window_rect.bottom - window_rect.top) * 4) / (3 * 2)) - 0.5; - if (*l < -0.5) - { - *l = -0.5; - *r = (window_rect.right - window_rect.left) - 0.5; - *t = ((window_rect.bottom - window_rect.top) / 2) - (((window_rect.right - window_rect.left) * 3) / (4 * 2)) - 0.5; - *b = ((window_rect.bottom - window_rect.top) / 2) + (((window_rect.right - window_rect.left) * 3) / (4 * 2)) - 0.5; - } - break; - case FULLSCR_SCALE_SQ: - *t = -0.5; - *b = (window_rect.bottom - window_rect.top) - 0.5; - *l = ((window_rect.right - window_rect.left) / 2) - (((window_rect.bottom - window_rect.top) * w) / (h * 2)) - 0.5; - *r = ((window_rect.right - window_rect.left) / 2) + (((window_rect.bottom - window_rect.top) * w) / (h * 2)) - 0.5; - if (*l < -0.5) - { - *l = -0.5; - *r = (window_rect.right - window_rect.left) - 0.5; - *t = ((window_rect.bottom - window_rect.top) / 2) - (((window_rect.right - window_rect.left) * h) / (w * 2)) - 0.5; - *b = ((window_rect.bottom - window_rect.top) / 2) + (((window_rect.right - window_rect.left) * h) / (w * 2)) - 0.5; - } - break; - case FULLSCR_SCALE_INT: - ratio_w = (window_rect.right - window_rect.left) / w; - ratio_h = (window_rect.bottom - window_rect.top) / h; - if (ratio_h < ratio_w) - ratio_w = ratio_h; - *l = ((window_rect.right - window_rect.left) / 2) - ((w * ratio_w) / 2) - 0.5; - *r = ((window_rect.right - window_rect.left) / 2) + ((w * ratio_w) / 2) - 0.5; - *t = ((window_rect.bottom - window_rect.top) / 2) - ((h * ratio_w) / 2) - 0.5; - *b = ((window_rect.bottom - window_rect.top) / 2) + ((h * ratio_w) / 2) - 0.5; - break; - } -} - -static void blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) -{ - HRESULT hr = D3D_OK; - VOID* pVoid; - D3DLOCKED_RECT dr; - RECT window_rect; - int yy; - double l = 0, t = 0, r = 0, b = 0; - - if ((y1 == y2) || (h <= 0)) - { - video_blit_complete(); - return; /*Nothing to do*/ - } - - if (hr == D3D_OK && !(y1 == 0 && y2 == 0)) - { - RECT lock_rect; - - lock_rect.top = y1; - lock_rect.left = 0; - lock_rect.bottom = y2; - lock_rect.right = 2047; - - hr = d3dTexture->LockRect(0, &dr, &lock_rect, 0); - if (hr == D3D_OK) - { - for (yy = y1; yy < y2; yy++) - memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(((uint32_t *)buffer32->line[yy + y])[x]), w * 4); - - video_blit_complete(); - d3dTexture->UnlockRect(0); - } - else - { - video_blit_complete(); - return; - } - } - else - video_blit_complete(); - - d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0; - d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 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; - d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color = - d3d_verts[3].color = d3d_verts[4].color = d3d_verts[5].color = - d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color = - d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff; - - GetClientRect(d3d_device_window, &window_rect); - d3d_fs_size(window_rect, &l, &t, &r, &b, w, h); - - d3d_verts[0].x = l; - d3d_verts[0].y = t; - d3d_verts[1].x = r; - d3d_verts[1].y = b; - d3d_verts[2].x = l; - d3d_verts[2].y = b; - d3d_verts[3].x = l; - d3d_verts[3].y = t; - d3d_verts[4].x = r; - d3d_verts[4].y = t; - d3d_verts[5].x = r; - d3d_verts[5].y = b; - d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = r - 40.5; - d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = t + 8.5; - d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = r - 8.5; - d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = t + 14.5; - - if (hr == D3D_OK) - hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); - if (hr == D3D_OK) - memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); - if (hr == D3D_OK) - hr = v_buffer->Unlock(); - - if (hr == D3D_OK) - hr = d3ddev->BeginScene(); - - if (hr == D3D_OK) - { - if (hr == D3D_OK) - d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0, 0); - - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, d3dTexture); - - if (hr == D3D_OK) - hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | 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_device_window, NULL); - - if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL) - PostMessage(hwndMain, WM_RESETD3D, 0, 0); -} - - -void d3d_fs_take_screenshot(wchar_t *fn) -{ - LPDIRECT3DSURFACE9 d3dSurface = NULL; - - if (!d3dTexture) return; - - d3ddev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &d3dSurface); - D3DXSaveSurfaceToFile(fn, D3DXIFF_PNG, d3dSurface, NULL, NULL); - - d3dSurface->Release(); - d3dSurface = NULL; -} diff --git a/src/win/win_video.c b/src/win/win_video.c index cdb4014b0..bf2ce7181 100644 --- a/src/win/win_video.c +++ b/src/win/win_video.c @@ -8,7 +8,7 @@ * * Platform video API support for Win32. * - * Version: @(#)win_video.c 1.0.6 2017/11/12 + * Version: @(#)win_video.c 1.0.7 2017/11/12 * * Author: Fred N. van Kempen, * @@ -69,7 +69,7 @@ static struct { }, { { "DDraw", 1, (int(*)(void*))ddraw_init_fs, ddraw_close, NULL, ddraw_pause }, - { "D3D", 1, (int(*)(void*))d3d_fs_init, d3d_fs_close, NULL, d3d_fs_pause }, + { "D3D", 1, (int(*)(void*))d3d_init_fs, d3d_close, NULL, d3d_pause }, #ifdef USE_VNC { "VNC", 0, vnc_init, vnc_close, vnc_resize, vnc_pause }, #else @@ -266,10 +266,7 @@ take_screenshot(void) case 1: /* d3d9 */ wcsftime(fn, 128, L"%Y%m%d_%H%M%S.png", info); wcscat(path, fn); - if (video_fullscreen) - d3d_fs_take_screenshot(path); - else - d3d_take_screenshot(path); + d3d_take_screenshot(path); pclog("Screenshot: fn='%ls'\n", path); break;