X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=platform%2Fwin32%2FGenaDrive%2FDirect.cpp;h=07e874764cf228bfe0e41746b4f93c1d1e4bd4c4;hb=03a265e5ebabff7adbb4f97387f81e9b0428dbee;hp=8277bce91cdb1542599ef21af1f82419865d5b1b;hpb=8831ef19a03770189816740eb2304ad2cb9a07a7;p=picodrive.git diff --git a/platform/win32/GenaDrive/Direct.cpp b/platform/win32/GenaDrive/Direct.cpp index 8277bce..07e8747 100644 --- a/platform/win32/GenaDrive/Direct.cpp +++ b/platform/win32/GenaDrive/Direct.cpp @@ -1,6 +1,6 @@ - #include "app.h" +// d3d static IDirect3D8 *Direct3D=NULL; IDirect3DDevice8 *Device=NULL; IDirect3DSurface8 *DirectBack=NULL; // Back Buffer @@ -17,11 +17,145 @@ struct CustomVertex static CustomVertex VertexList[4]; +// ddraw +#include + +LPDIRECTDRAW7 m_pDD = NULL; +LPDIRECTDRAWSURFACE7 m_pddsFrontBuffer = NULL; +LPDIRECTDRAWSURFACE7 m_pddsBackBuffer = NULL; + +// quick and dirty stuff.. +static void DirectExitDDraw() +{ + RELEASE(m_pddsBackBuffer); + RELEASE(m_pddsFrontBuffer); + RELEASE(m_pDD); +} + +static int DirectDrawInit() +{ + HRESULT ret; + LPDIRECTDRAWCLIPPER pcClipper = NULL; + DDSURFACEDESC2 ddsd; + + ret = DirectDrawCreateEx(NULL, (VOID**)&m_pDD, IID_IDirectDraw7, NULL); + if (ret) { LOGFAIL(); return 1; } + + // Set cooperative level + ret = m_pDD->SetCooperativeLevel( FrameWnd, DDSCL_NORMAL ); + if (ret) { LOGFAIL(); goto fail; } + + // Create the primary surface + ZeroMemory( &ddsd, sizeof( ddsd ) ); + ddsd.dwSize = sizeof( ddsd ); + ddsd.dwFlags = DDSD_CAPS; + ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; + + ret = m_pDD->CreateSurface( &ddsd, &m_pddsFrontBuffer, NULL ); + if (ret) { LOGFAIL(); goto fail; } + + // Create the backbuffer surface + ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT; + ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE; + ddsd.dwWidth = EmuWidth; + ddsd.dwHeight = EmuHeight; + + ret = m_pDD->CreateSurface( &ddsd, &m_pddsBackBuffer, NULL ); + if (ret) { LOGFAIL(); goto fail; } + + // clipper + ret = m_pDD->CreateClipper( 0, &pcClipper, NULL ); + if (ret) { LOGFAIL(); goto fail; } + + ret = pcClipper->SetHWnd( 0, FrameWnd ); + if (ret) { LOGFAIL(); goto fail; } + + ret = m_pddsFrontBuffer->SetClipper( pcClipper ); + if (ret) { LOGFAIL(); goto fail; } + + RELEASE(pcClipper); + return 0; + +fail: + RELEASE(pcClipper); + DirectExitDDraw(); + return 1; +} + +static int DirectScreenDDraw() +{ + DDSURFACEDESC2 sd; + unsigned short *ps=EmuScreen; + int ret, x, y; + + memset(&sd, 0, sizeof(sd)); + sd.dwSize = sizeof(sd); + ret = m_pddsBackBuffer->Lock(NULL, &sd, DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_WRITEONLY, NULL); + if (ret) { LOGFAIL(); return 1; } + + //dprintf2("w: %i h: %i pi: %i pf: %i\n", sd.dwWidth, sd.dwHeight, sd.lPitch, sd.ddpfPixelFormat.dwRGBBitCount); + + if (sd.ddpfPixelFormat.dwRGBBitCount == 32) + { + int *dst = (int *)sd.lpSurface; + for (y = 0; y < EmuHeight; y++) + { + for (x = 0; x < EmuWidth; x++) + { + int s = *ps++; + dst[x] = ((s&0xf800)<<8) | ((s&0x07e0)<<5) | ((s&0x001f)<<3); + } + dst = (int *)((char *)dst + sd.lPitch); + } + } + else if (sd.ddpfPixelFormat.dwRGBBitCount == 16) + { + unsigned short *dst = (unsigned short *)sd.lpSurface; + for (y = 0; y < EmuHeight; y++) + { + memcpy(dst, ps, EmuWidth*2); + ps += EmuWidth; + dst = (unsigned short *)((char *)dst + sd.lPitch); + } + } + else + { + LOGFAIL(); + } + + ret = m_pddsBackBuffer->Unlock(NULL); + if (ret) { LOGFAIL(); return 1; } + return 0; +} + +static int DirectClearDDraw(unsigned int colour) +{ + int ret; + DDBLTFX ddbltfx; + ZeroMemory( &ddbltfx, sizeof(ddbltfx) ); + ddbltfx.dwSize = sizeof(ddbltfx); + ddbltfx.dwFillColor = colour; + + if (m_pddsBackBuffer != NULL) + ret = m_pddsBackBuffer->Blt( NULL, NULL, NULL, DDBLT_COLORFILL, &ddbltfx ); + if (ret) { LOGFAIL(); return 1; } + return 0; +} + +static int DirectPresentDDraw() +{ + int ret = m_pddsFrontBuffer->Blt(&FrameRectMy, m_pddsBackBuffer, NULL, DDBLT_WAIT, NULL); + if (ret) { LOGFAIL(); return 1; } + return 0; +} + + +/* D3D */ + int DirectInit() { - D3DPRESENT_PARAMETERS d3dpp; + D3DPRESENT_PARAMETERS d3dpp; D3DDISPLAYMODE mode; - D3DDEVTYPE dt = D3DDEVTYPE_HAL; int i,u,ret=0; memset(&d3dpp,0,sizeof(d3dpp)); @@ -34,6 +168,7 @@ int DirectInit() d3dpp.BackBufferHeight=MainHeight; d3dpp.BackBufferCount =1; d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD; + d3dpp.MultiSampleType =D3DMULTISAMPLE_NONE; #ifdef _XBOX d3dpp.BackBufferFormat=D3DFMT_X8R8G8B8; @@ -42,35 +177,50 @@ int DirectInit() Direct3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT,&mode); d3dpp.BackBufferFormat=mode.Format; d3dpp.Windowed=1; + d3dpp.hDeviceWindow=FrameWnd; #endif // Try to create a device with hardware vertex processing: - for (u=0;u<2;u++) + for (i=0;i<3;i++) { - for (i=0;i<4;i++) - { - int behave=D3DCREATE_HARDWARE_VERTEXPROCESSING; + int behave=D3DCREATE_HARDWARE_VERTEXPROCESSING; - // Try software vertex processing: - if (i==1) behave=D3DCREATE_MIXED_VERTEXPROCESSING; - if (i==2) behave=D3DCREATE_SOFTWARE_VERTEXPROCESSING; + // Try software vertex processing: + if (i==1) behave=D3DCREATE_MIXED_VERTEXPROCESSING; + if (i==2) behave=D3DCREATE_SOFTWARE_VERTEXPROCESSING; - Direct3D->CreateDevice(D3DADAPTER_DEFAULT,dt,FrameWnd,behave,&d3dpp,&Device); - if (Device) break; - } + Direct3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,FrameWnd, + behave|D3DCREATE_MULTITHREADED,&d3dpp,&Device); if (Device) break; - dt = D3DDEVTYPE_REF; } - if (Device==NULL) return 1; + if (Device==NULL) + { +#if 0 + // try ref + Direct3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_REF,FrameWnd, + D3DCREATE_SOFTWARE_VERTEXPROCESSING|D3DCREATE_MULTITHREADED,&d3dpp,&Device); + if (Device==NULL) goto fail0; + HMODULE test = LoadLibrary("d3d8d.dll"); + if (test != NULL) FreeLibrary(test); + else { + error("Sorry, but this program requires Direct3D with hardware acceleration.\n\n" + "You can try using Direct3D software emulation, but you have to install " + "DirectX SDK for it to work\n(it seems to be missing now)."); + goto fail1; + } +#else + goto fail1; +#endif + } Device->GetBackBuffer(0,D3DBACKBUFFER_TYPE_MONO,&DirectBack); - if (DirectBack==NULL) return 1; + if (DirectBack==NULL) goto fail1; Device->CreateVertexBuffer(sizeof(VertexList),0,D3DFVF_CUSTOMVERTEX,D3DPOOL_DEFAULT,&VertexBuffer); - if (VertexBuffer==NULL) return 1; + if (VertexBuffer==NULL) goto fail2; - ret=TexScreenInit(); if (ret) return 1; + ret=TexScreenInit(); if (ret) goto fail3; //FontInit(); @@ -79,18 +229,36 @@ int DirectInit() // Set up texture modes: Device->SetTextureStageState(0,D3DTSS_ADDRESSU,D3DTADDRESS_CLAMP); Device->SetTextureStageState(0,D3DTSS_ADDRESSV,D3DTADDRESS_CLAMP); + return 0; + +fail3: + RELEASE(VertexBuffer) +fail2: + RELEASE(DirectBack) +fail1: + RELEASE(Device) +fail0: + RELEASE(Direct3D) + + // error("Failed to use Direct3D, trying DirectDraw.."); + + // try DirectDraw + return DirectDrawInit(); } void DirectExit() { //FontExit(); - //TexScreenExit(); + TexScreenExit(); + // d3d RELEASE(VertexBuffer) RELEASE(DirectBack) RELEASE(Device) RELEASE(Direct3D) + + DirectExitDDraw(); } @@ -137,12 +305,18 @@ static int MakeVertexList() int DirectClear(unsigned int colour) { + if (Device == NULL) + return DirectClearDDraw(colour); + Device->Clear(0,NULL,D3DCLEAR_TARGET,colour,1.0f,0); return 0; } int DirectPresent() { + if (Device == NULL) + return DirectPresentDDraw(); + Device->Present(NULL,NULL,NULL,NULL); return 0; } @@ -156,7 +330,7 @@ static int SetupMatrices() float nudgex=0.0f,nudgey=0.0f; memset(&mat,0,sizeof(mat)); - + mat.m[0][0]=mat.m[1][1]=mat.m[2][2]=mat.m[3][3]=1.0f; Device->SetTransform(D3DTS_WORLD,&mat); @@ -183,6 +357,9 @@ int DirectScreen() unsigned char *lock=NULL; int ret; + if (Device == NULL) + return DirectScreenDDraw(); + // Copy the screen to the screen texture: #ifdef _XBOX TexScreenSwizzle(); @@ -201,14 +378,12 @@ int DirectScreen() memcpy(lock,VertexList,sizeof(VertexList)); VertexBuffer->Unlock(); - ret=Device->SetTexture(0,TexScreen); - if (ret) dprintf2("SetTexture failed\n"); - ret=Device->SetStreamSource(0,VertexBuffer,sizeof(CustomVertex)); - if (ret) dprintf2("SetStreamSource failed\n"); - ret=Device->SetVertexShader(D3DFVF_CUSTOMVERTEX); - if (ret) dprintf2("SetVertexShader failed\n"); - ret=Device->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2); - if (ret) dprintf2("DrawPrimitive failed\n"); + Device->BeginScene(); + Device->SetTexture(0,TexScreen); + Device->SetStreamSource(0,VertexBuffer,sizeof(CustomVertex)); + Device->SetVertexShader(D3DFVF_CUSTOMVERTEX); + Device->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2); + Device->EndScene(); return 0; }