mirror of https://github.com/PCSX2/pcsx2.git
242 lines
5.4 KiB
C++
242 lines
5.4 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()
|
|
{
|
|
}
|
|
|
|
GSDevice7::~GSDevice7()
|
|
{
|
|
}
|
|
|
|
bool GSDevice7::Create(HWND hWnd, bool vsync)
|
|
{
|
|
if(!__super::Create(hWnd, vsync))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if(FAILED(DirectDrawCreateEx(NULL, (VOID**)&m_dd, IID_IDirectDraw7, NULL)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// 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, true);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool GSDevice7::Reset(int w, int h, bool fs)
|
|
{
|
|
if(!__super::Reset(w, h, fs))
|
|
return false;
|
|
|
|
m_backbuffer = NULL;
|
|
|
|
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;
|
|
|
|
if(FAILED(m_dd->CreateSurface(&desc, &m_backbuffer, NULL)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
CComPtr<IDirectDrawClipper> clipper;
|
|
|
|
if(FAILED(m_dd->CreateClipper(0, &clipper, NULL)))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
{
|
|
// ???
|
|
|
|
HRGN hrgn = CreateRectRgn(0, 0, w, h);
|
|
|
|
BYTE buff[1024];
|
|
|
|
GetRegionData(hrgn, sizeof(buff), (RGNDATA*)buff);
|
|
|
|
DeleteObject(hrgn);
|
|
|
|
clipper->SetClipList((RGNDATA*)buff, 0);
|
|
|
|
if(FAILED(m_backbuffer->SetClipper(clipper)))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void GSDevice7::Present(const CRect& r)
|
|
{
|
|
HRESULT hr;
|
|
|
|
CRect cr;
|
|
GetClientRect(m_hWnd, &cr);
|
|
|
|
DDSURFACEDESC2 desc;
|
|
memset(&desc, 0, sizeof(desc));
|
|
desc.dwSize = sizeof(desc);
|
|
|
|
hr = m_backbuffer->GetSurfaceDesc(&desc);
|
|
|
|
if(desc.dwWidth != cr.Width() || desc.dwHeight != cr.Height())
|
|
{
|
|
Reset(cr.Width(), cr.Height(), false);
|
|
}
|
|
|
|
DDBLTFX fx;
|
|
|
|
memset(&fx, 0, sizeof(fx));
|
|
|
|
fx.dwSize = sizeof(fx);
|
|
fx.dwFillColor = 0;
|
|
|
|
hr = m_backbuffer->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &fx);
|
|
|
|
CRect r2 = r;
|
|
|
|
hr = m_backbuffer->Blt(&r2, m_merge, NULL, DDBLT_WAIT, NULL);
|
|
|
|
r2 = cr;
|
|
|
|
MapWindowPoints(m_hWnd, HWND_DESKTOP, (POINT*)&r2, 2);
|
|
|
|
if(m_vsync)
|
|
{
|
|
hr = m_dd->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, NULL);
|
|
}
|
|
|
|
hr = m_primary->Blt(&r2, m_backbuffer, &cr, DDBLT_WAIT, NULL);
|
|
|
|
if(hr == DDERR_SURFACELOST)
|
|
{
|
|
// TODO
|
|
|
|
HRESULT hr = m_dd->TestCooperativeLevel();
|
|
|
|
if(hr == DDERR_WRONGMODE)
|
|
{
|
|
}
|
|
}
|
|
}
|
|
|
|
bool GSDevice7::Create(int type, Texture& t, int w, int h, int format)
|
|
{
|
|
HRESULT hr;
|
|
|
|
t = Texture();
|
|
|
|
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;
|
|
|
|
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 = Texture(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 = Texture(type, system);
|
|
break;
|
|
}
|
|
|
|
return !!t;
|
|
}
|
|
|
|
void GSDevice7::DoMerge(Texture* st, GSVector4* sr, GSVector4* dr, Texture& dt, bool slbg, bool mmod, GSVector4& c)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = dt->Blt(NULL, st[0], NULL, DDBLT_WAIT, NULL);
|
|
}
|
|
|
|
void GSDevice7::DoInterlace(Texture& st, Texture& dt, int shader, bool linear, float yoffset)
|
|
{
|
|
}
|