mirror of https://github.com/PCSX2/pcsx2.git
257 lines
5.7 KiB
C++
257 lines
5.7 KiB
C++
/*
|
|
* Copyright (C) 2007-2009 Gabest
|
|
* http://www.gabest.org
|
|
*
|
|
* This Program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This Program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with GNU Make; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
*
|
|
*/
|
|
|
|
// dumb device implementation, only good for simple image output
|
|
|
|
#include "stdafx.h"
|
|
#include "GSDevice7.h"
|
|
|
|
GSDevice7::GSDevice7()
|
|
: m_lost(false)
|
|
{
|
|
}
|
|
|
|
GSDevice7::~GSDevice7()
|
|
{
|
|
}
|
|
|
|
bool GSDevice7::Create(GSWnd* wnd, bool vsync)
|
|
{
|
|
if(!__super::Create(wnd, vsync))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if(FAILED(DirectDrawCreateEx(NULL, (VOID**)&m_dd, IID_IDirectDraw7, NULL)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
HWND hWnd = (HWND)m_wnd->GetHandle();
|
|
|
|
// TODO: fullscreen
|
|
|
|
if(FAILED(m_dd->SetCooperativeLevel(hWnd, DDSCL_NORMAL)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
DDSURFACEDESC2 desc;
|
|
|
|
memset(&desc, 0, sizeof(desc));
|
|
|
|
desc.dwSize = sizeof(desc);
|
|
desc.dwFlags = DDSD_CAPS;
|
|
desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
|
|
|
|
if(FAILED(m_dd->CreateSurface(&desc, &m_primary, NULL)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
CComPtr<IDirectDrawClipper> clipper;
|
|
|
|
if(FAILED(m_dd->CreateClipper(0, &clipper, NULL))
|
|
|| FAILED(clipper->SetHWnd(0, hWnd))
|
|
|| FAILED(m_primary->SetClipper(clipper)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Reset(1, 1, Windowed);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool GSDevice7::Reset(int w, int h, int mode)
|
|
{
|
|
if(!__super::Reset(w, h, mode))
|
|
return false;
|
|
|
|
DDSURFACEDESC2 desc;
|
|
|
|
memset(&desc, 0, sizeof(desc));
|
|
|
|
desc.dwSize = sizeof(desc);
|
|
desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
|
|
desc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_3DDEVICE;
|
|
desc.dwWidth = w;
|
|
desc.dwHeight = h;
|
|
|
|
CComPtr<IDirectDrawSurface7> backbuffer;
|
|
|
|
if(FAILED(m_dd->CreateSurface(&desc, &backbuffer, NULL)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
m_backbuffer = new GSTexture7(GSTexture::RenderTarget, backbuffer);
|
|
|
|
CComPtr<IDirectDrawClipper> clipper;
|
|
|
|
if(FAILED(m_dd->CreateClipper(0, &clipper, NULL)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
{
|
|
// ???
|
|
|
|
HRGN hrgn = CreateRectRgn(0, 0, w, h);
|
|
|
|
uint8 buff[1024];
|
|
|
|
GetRegionData(hrgn, sizeof(buff), (RGNDATA*)buff);
|
|
|
|
DeleteObject(hrgn);
|
|
|
|
clipper->SetClipList((RGNDATA*)buff, 0);
|
|
|
|
if(FAILED(backbuffer->SetClipper(clipper)))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
m_lost = false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void GSDevice7::Present(const GSVector4i& r, int shader, bool limit)
|
|
{
|
|
HRESULT hr;
|
|
|
|
GSVector4i cr = m_wnd->GetClientRect();
|
|
|
|
int w = std::max<int>(cr.width(), 1);
|
|
int h = std::max<int>(cr.height(), 1);
|
|
|
|
if(!m_backbuffer || m_backbuffer->GetWidth() != w || m_backbuffer->GetHeight() != h)
|
|
{
|
|
if(!Reset(w, h, DontCare))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
CComPtr<IDirectDrawSurface7> backbuffer = *(GSTexture7*)m_backbuffer;
|
|
|
|
DDBLTFX fx;
|
|
|
|
memset(&fx, 0, sizeof(fx));
|
|
|
|
fx.dwSize = sizeof(fx);
|
|
fx.dwFillColor = 0;
|
|
|
|
hr = backbuffer->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &fx);
|
|
|
|
GSVector4i r2 = r;
|
|
|
|
if(m_current)
|
|
{
|
|
hr = backbuffer->Blt(r2, *(GSTexture7*)m_current, NULL, DDBLT_WAIT, NULL);
|
|
}
|
|
|
|
// if ClearRenderTarget was implemented the parent class could handle these tasks until this point
|
|
|
|
r2 = cr;
|
|
|
|
MapWindowPoints((HWND)m_wnd->GetHandle(), HWND_DESKTOP, (POINT*)&r2, 2);
|
|
|
|
if(m_vsync && limit)
|
|
{
|
|
hr = m_dd->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL);
|
|
}
|
|
|
|
hr = m_primary->Blt(r2, backbuffer, cr, DDBLT_WAIT, NULL);
|
|
|
|
if(hr == DDERR_SURFACELOST)
|
|
{
|
|
m_lost = true;
|
|
|
|
// TODO
|
|
|
|
HRESULT hr = m_dd->TestCooperativeLevel();
|
|
|
|
if(hr == DDERR_WRONGMODE)
|
|
{
|
|
}
|
|
}
|
|
}
|
|
|
|
GSTexture* GSDevice7::Create(int type, int w, int h, bool msaa, int format)
|
|
{
|
|
HRESULT hr;
|
|
|
|
DDSURFACEDESC2 desc;
|
|
|
|
memset(&desc, 0, sizeof(desc));
|
|
|
|
desc.dwSize = sizeof(desc);
|
|
desc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
|
|
desc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
|
|
desc.dwWidth = w;
|
|
desc.dwHeight = h;
|
|
desc.ddpfPixelFormat.dwSize = sizeof(desc.ddpfPixelFormat);
|
|
desc.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
|
|
desc.ddpfPixelFormat.dwRGBBitCount = 32;
|
|
desc.ddpfPixelFormat.dwRGBAlphaBitMask = 0xff000000;
|
|
desc.ddpfPixelFormat.dwRBitMask = 0x00ff0000;
|
|
desc.ddpfPixelFormat.dwGBitMask = 0x0000ff00;
|
|
desc.ddpfPixelFormat.dwBBitMask = 0x000000ff;
|
|
|
|
GSTexture7* t = NULL;
|
|
|
|
CComPtr<IDirectDrawSurface7> system, video;
|
|
|
|
switch(type)
|
|
{
|
|
case GSTexture::RenderTarget:
|
|
case GSTexture::DepthStencil:
|
|
case GSTexture::Texture:
|
|
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
|
|
if(FAILED(hr = m_dd->CreateSurface(&desc, &system, NULL))) return false;
|
|
desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
|
|
if(FAILED(hr = m_dd->CreateSurface(&desc, &video, NULL))) return false;
|
|
t = new GSTexture7(type, system, video);
|
|
break;
|
|
case GSTexture::Offscreen:
|
|
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
|
|
if(FAILED(hr = m_dd->CreateSurface(&desc, &system, NULL))) return false;
|
|
t = new GSTexture7(type, system);
|
|
break;
|
|
}
|
|
|
|
return t;
|
|
}
|
|
|
|
void GSDevice7::DoMerge(GSTexture* st[2], GSVector4* sr, GSVector4* dr, GSTexture* dt, bool slbg, bool mmod, const GSVector4& c)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = (*(GSTexture7*)dt)->Blt(NULL, *(GSTexture7*)st[0], NULL, DDBLT_WAIT, NULL);
|
|
}
|
|
|
|
void GSDevice7::DoInterlace(GSTexture* st, GSTexture* dt, int shader, bool linear, float yoffset)
|
|
{
|
|
}
|